From 25fbda8e8b58a40e17e39d71d6503f246fa2f079 Mon Sep 17 00:00:00 2001 From: Hakase Date: Fri, 22 Feb 2019 12:53:31 +0900 Subject: [PATCH] Latest update --- CHANGES | 33 + Configurations/10-main.conf | 2 +- Configurations/unix-Makefile.tmpl | 4 +- Configure | 39 +- apps/build.info | 4 +- apps/{ => include}/apps.h | 0 apps/{ => include}/apps_ui.h | 0 apps/{ => include}/fmt.h | 0 apps/{ => include}/opt.h | 0 apps/{ => include}/s_apps.h | 0 apps/s_cb.c | 4 +- apps/s_client.c | 77 +- crypto/README.sparse_array | 155 ++++ crypto/aes/asm/aes-armv4.pl | 3 +- crypto/aes/asm/aes-mips.pl | 134 ++-- crypto/aes/asm/aes-x86_64.pl | 18 +- crypto/aes/asm/aesni-x86_64.pl | 16 + crypto/aes/asm/aesv8-armx.pl | 26 +- crypto/aes/asm/bsaes-armv7.pl | 7 +- crypto/aes/asm/bsaes-x86_64.pl | 6 + crypto/aes/asm/vpaes-armv8.pl | 294 ++++---- crypto/aes/asm/vpaes-x86_64.pl | 26 + crypto/armv4cpuid.pl | 3 +- crypto/bio/bss_file.c | 9 +- crypto/bn/asm/armv4-gf2m.pl | 13 +- crypto/bn/asm/armv4-mont.pl | 17 +- crypto/bn/asm/armv8-mont.pl | 20 +- crypto/bn/asm/rsaz-avx2.pl | 6 + crypto/bn/asm/x86_64-mont5.pl | 2 + crypto/bn/bn_ctx.c | 4 +- crypto/build.info | 6 +- crypto/chacha/asm/chacha-armv4.pl | 11 +- crypto/chacha/asm/chacha-armv8.pl | 27 +- crypto/chacha/asm/chacha-s390x.pl | 2 +- crypto/cms/cms_kari.c | 5 +- crypto/context.c | 110 +++ crypto/ec/asm/ecp_nistz256-armv4.pl | 4 +- crypto/ec/asm/ecp_nistz256-armv8.pl | 34 +- crypto/ec/asm/ecp_nistz256-x86_64.pl | 34 + crypto/ec/ec2_smpl.c | 18 +- crypto/ec/ec_err.c | 9 +- crypto/ec/ec_lcl.h | 11 + crypto/ec/ec_lib.c | 5 + crypto/ec/ecp_mont.c | 49 ++ crypto/ec/ecp_nist.c | 1 + crypto/ec/ecp_nistp224.c | 1 + crypto/ec/ecp_nistp256.c | 1 + crypto/ec/ecp_nistp521.c | 1 + crypto/ec/ecp_nistz256.c | 1 + crypto/ec/ecp_smpl.c | 49 +- crypto/engine/build.info | 3 - crypto/err/err_all.c | 4 +- crypto/err/openssl.ec | 1 + crypto/err/openssl.txt | 54 +- crypto/evp/build.info | 3 +- crypto/evp/e_chacha20_poly1305.c | 2 +- crypto/evp/encode.c | 2 +- crypto/evp/evp_err.c | 9 +- crypto/evp/evp_locl.h | 5 + crypto/evp/evp_pbe.c | 1 + crypto/evp/kdf_lib.c | 165 +++++ crypto/evp/p5_crpt2.c | 110 +-- crypto/evp/pbe_scrypt.c | 237 +----- crypto/evp/pkey_kdf.c | 255 +++++++ crypto/ex_data.c | 30 + crypto/include/internal/evp_int.h | 18 + crypto/include/internal/sparse_array.h | 80 ++ crypto/init.c | 34 +- crypto/kdf/build.info | 2 +- crypto/kdf/hkdf.c | 326 ++++----- crypto/kdf/kdf_err.c | 28 +- crypto/kdf/kdf_local.h | 22 + crypto/kdf/kdf_util.c | 73 ++ crypto/kdf/pbkdf2.c | 264 +++++++ crypto/kdf/scrypt.c | 478 +++++++++--- crypto/kdf/tls1_prf.c | 201 +++-- crypto/lhash/lhash.c | 12 +- crypto/modes/asm/ghash-armv4.pl | 3 +- crypto/modes/asm/ghash-x86_64.pl | 14 + crypto/modes/asm/ghashv8-armx.pl | 26 +- crypto/perlasm/arm-xlate.pl | 17 + crypto/perlasm/x86_64-xlate.pl | 17 +- crypto/poly1305/asm/poly1305-armv4.pl | 52 +- crypto/poly1305/asm/poly1305-armv8.pl | 33 +- crypto/property/README | 87 +++ crypto/property/build.info | 3 + crypto/property/defn_cache.c | 105 +++ crypto/property/properties.ebnf | 17 + crypto/property/properties.xhtml | 685 ++++++++++++++++++ crypto/property/property.c | 507 +++++++++++++ crypto/property/property_err.c | 61 ++ crypto/property/property_lcl.h | 51 ++ crypto/property/property_parse.c | 545 ++++++++++++++ crypto/property/property_string.c | 137 ++++ crypto/sha/asm/keccak1600-armv4.pl | 34 +- crypto/sha/asm/keccak1600-armv8.pl | 14 + crypto/sha/asm/sha1-armv4-large.pl | 20 +- crypto/sha/asm/sha1-armv8.pl | 30 +- crypto/sha/asm/sha256-armv4.pl | 18 +- crypto/sha/asm/sha512-armv4.pl | 20 +- crypto/sha/asm/sha512-armv8.pl | 25 +- crypto/sha/keccak1600.c | 9 +- crypto/sparse_array.c | 218 ++++++ doc/internal/man3/DEFINE_SPARSE_ARRAY_OF.pod | 120 +++ doc/internal/man3/OSSL_METHOD_STORE.pod | 116 +++ doc/internal/man3/openssl_ctx_get_data.pod | 112 +++ doc/man1/ciphers.pod | 2 +- doc/man1/dgst.pod | 4 +- doc/man1/s_client.pod | 17 +- doc/man3/CRYPTO_get_ex_new_index.pod | 19 +- doc/man3/EC_GROUP_copy.pod | 5 +- doc/man3/EVP_KDF_CTX.pod | 217 ++++++ doc/man3/OPENSSL_CTX.pod | 48 ++ doc/man3/OPENSSL_LH_COMPFUNC.pod | 11 +- doc/man3/RIPEMD160_Init.pod | 2 +- doc/man3/SSL_CONF_cmd.pod | 12 +- doc/man3/SSL_CTX_set_info_callback.pod | 14 +- doc/man3/SSL_CTX_set_options.pod | 12 +- doc/man7/EVP_KDF_HKDF.pod | 180 +++++ doc/man7/EVP_KDF_PBKDF2.pod | 78 ++ doc/man7/{scrypt.pod => EVP_KDF_SCRYPT.pod} | 100 ++- doc/man7/EVP_KDF_TLS1_PRF.pod | 142 ++++ doc/man7/openssl_user_macros.pod.in | 8 +- engines/build.info | 13 + engines/e_dasync.c | 3 +- .../eng_devcrypto.c => engines/e_devcrypto.c | 164 +++-- include/internal/cryptlib.h | 9 + include/internal/property.h | 35 + include/internal/propertyerr.h | 46 ++ include/openssl/crypto.h | 9 +- include/openssl/e_os2.h | 7 + include/openssl/ec.h | 6 + include/openssl/ecerr.h | 6 +- include/openssl/err.h | 2 + include/openssl/evperr.h | 8 +- include/openssl/kdf.h | 57 +- include/openssl/kdferr.h | 21 +- include/openssl/lhash.h | 33 +- include/openssl/ossl_typ.h | 4 + include/openssl/safestack.h | 48 +- include/openssl/ssl.h | 21 +- include/openssl/sslerr.h | 9 +- include/openssl/stack.h | 2 +- ssl/record/rec_layer_s3.c | 8 + ssl/ssl_conf.c | 3 +- ssl/ssl_err.c | 5 +- ssl/ssl_lib.c | 24 +- ssl/statem/extensions.c | 3 +- ssl/statem/extensions_clnt.c | 5 + ssl/statem/extensions_srvr.c | 3 + ssl/statem/statem.c | 6 +- ssl/statem/statem_lib.c | 11 +- ssl/statem/statem_srvr.c | 19 - test/bntest.c | 161 +++- test/build.info | 257 ++++--- test/cipherlist_test.c | 35 + test/clienthellotest.c | 3 +- test/context_internal_test.c | 95 +++ test/ec_internal_test.c | 205 ++++++ test/ecdsatest.c | 6 +- test/ectest.c | 38 + test/evp_kdf_test.c | 237 ++++++ test/evp_test.c | 168 ++++- test/exdatatest.c | 68 +- test/pkey_meth_kdf_test.c | 80 +- test/property_test.c | 374 ++++++++++ test/recipes/02-test_internal_context.t | 16 + test/recipes/02-test_sparse_array.t | 12 + test/recipes/03-test_internal_ec.t | 19 + test/recipes/03-test_property.t | 12 + test/recipes/30-test_evp.t | 4 +- test/recipes/30-test_evp_data/evpkdf.txt | 194 ++++- test/recipes/30-test_evp_data/evppkey_kdf.txt | 305 ++++++++ test/recipes/30-test_evp_kdf.t | 13 + test/recipes/70-test_sslrecords.t | 102 ++- test/recipes/80-test_ssl_new.t | 3 +- test/sparse_array_test.c | 198 +++++ test/ssl-tests/16-certstatus.conf | 0 test/ssl-tests/30-extended-master-secret.conf | 203 ++++++ .../30-extended-master-secret.conf.in | 122 ++++ test/sslapitest.c | 95 ++- test/ssltest_old.c | 51 +- test/testutil.h | 2 +- util/find-doc-nits | 26 +- util/libcrypto.num | 15 +- util/private.num | 2 + 186 files changed, 9758 insertions(+), 1640 deletions(-) rename apps/{ => include}/apps.h (100%) rename apps/{ => include}/apps_ui.h (100%) rename apps/{ => include}/fmt.h (100%) rename apps/{ => include}/opt.h (100%) rename apps/{ => include}/s_apps.h (100%) create mode 100644 crypto/README.sparse_array create mode 100644 crypto/context.c create mode 100644 crypto/evp/kdf_lib.c create mode 100644 crypto/evp/pkey_kdf.c create mode 100644 crypto/include/internal/sparse_array.h create mode 100644 crypto/kdf/kdf_local.h create mode 100644 crypto/kdf/kdf_util.c create mode 100644 crypto/kdf/pbkdf2.c create mode 100644 crypto/property/README create mode 100644 crypto/property/build.info create mode 100644 crypto/property/defn_cache.c create mode 100644 crypto/property/properties.ebnf create mode 100644 crypto/property/properties.xhtml create mode 100644 crypto/property/property.c create mode 100644 crypto/property/property_err.c create mode 100644 crypto/property/property_lcl.h create mode 100644 crypto/property/property_parse.c create mode 100644 crypto/property/property_string.c create mode 100644 crypto/sparse_array.c create mode 100644 doc/internal/man3/DEFINE_SPARSE_ARRAY_OF.pod create mode 100644 doc/internal/man3/OSSL_METHOD_STORE.pod create mode 100644 doc/internal/man3/openssl_ctx_get_data.pod create mode 100644 doc/man3/EVP_KDF_CTX.pod create mode 100644 doc/man3/OPENSSL_CTX.pod create mode 100644 doc/man7/EVP_KDF_HKDF.pod create mode 100644 doc/man7/EVP_KDF_PBKDF2.pod rename doc/man7/{scrypt.pod => EVP_KDF_SCRYPT.pod} (53%) create mode 100644 doc/man7/EVP_KDF_TLS1_PRF.pod rename crypto/engine/eng_devcrypto.c => engines/e_devcrypto.c (93%) create mode 100644 include/internal/property.h create mode 100644 include/internal/propertyerr.h create mode 100644 test/context_internal_test.c create mode 100644 test/ec_internal_test.c create mode 100644 test/evp_kdf_test.c create mode 100644 test/property_test.c create mode 100644 test/recipes/02-test_internal_context.t create mode 100644 test/recipes/02-test_sparse_array.t create mode 100644 test/recipes/03-test_internal_ec.t create mode 100644 test/recipes/03-test_property.t create mode 100644 test/recipes/30-test_evp_data/evppkey_kdf.txt create mode 100644 test/recipes/30-test_evp_kdf.t create mode 100644 test/sparse_array_test.c delete mode 100644 test/ssl-tests/16-certstatus.conf create mode 100644 test/ssl-tests/30-extended-master-secret.conf create mode 100644 test/ssl-tests/30-extended-master-secret.conf.in diff --git a/CHANGES b/CHANGES index 9d712f0d..5fcf6677 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,26 @@ Changes between 1.1.1 and 3.0.0 [xx XXX xxxx] + *) Added property based algorithm implementation selection framework to + the core. + [Paul Dale] + + *) Added SCA hardening for modular field inversion in EC_GROUP through + a new dedicated field_inv() pointer in EC_METHOD. + This also addresses a leakage affecting conversions from projective + to affine coordinates. + [Billy Bob Brumley, Nicola Tuveri] + + *) Added EVP_KDF, an EVP layer KDF API, to simplify adding KDF and PRF + implementations. This includes an EVP_PKEY to EVP_KDF bridge for + those algorithms that were already supported through the EVP_PKEY API + (scrypt, TLS1 PRF and HKDF). The low-level KDF functions for PBKDF2 + and scrypt are now wrappers that call EVP_KDF. + [David Makepeace] + + *) Build devcrypto engine as a dynamic engine. + [Eneas U de Queiroz] + *) Add keyed BLAKE2 to EVP_MAC. [Antoine Salon] @@ -109,6 +129,19 @@ applications with zero-copy system calls such as sendfile and splice. [Boris Pismenny] + Changes between 1.1.1a and 1.1.1b [xx XXX xxxx] + + *) Change the info callback signals for the start and end of a post-handshake + message exchange in TLSv1.3. In 1.1.1/1.1.1a we used SSL_CB_HANDSHAKE_START + and SSL_CB_HANDSHAKE_DONE. Experience has shown that many applications get + confused by this and assume that a TLSv1.2 renegotiation has started. This + can break KeyUpdate handling. Instead we no longer signal the start and end + of a post handshake message exchange (although the messages themselves are + still signalled). This could break some applications that were expecting + the old signals. However without this KeyUpdate is not usable for many + applications. + [Matt Caswell] + Changes between 1.1.1 and 1.1.1a [20 Nov 2018] *) Timing vulnerability in DSA signature generation diff --git a/Configurations/10-main.conf b/Configurations/10-main.conf index 1e491184..8b758a02 100644 --- a/Configurations/10-main.conf +++ b/Configurations/10-main.conf @@ -1098,7 +1098,7 @@ my %targets = ( dso_scheme => "dlfcn", shared_target => "aix", module_ldflags => "-Wl,-G,-bsymbolic,-bexpall", - shared_ldflag => "-Wl,-G,-bsymbolic", + shared_ldflag => "-Wl,-G,-bsymbolic,-bnoentry", shared_defflag => "-Wl,-bE:", perl_platform => 'AIX', }, diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl index 7705b03b..1e6709f2 100644 --- a/Configurations/unix-Makefile.tmpl +++ b/Configurations/unix-Makefile.tmpl @@ -622,7 +622,7 @@ install_runtime_libs: build_libs : {- output_off() unless windowsdll(); "" -}; \ $(ECHO) "install $$s -> $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \ cp $$s $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \ - chmod 644 $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \ + chmod 755 $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \ mv -f $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new \ $(DESTDIR)$(INSTALLTOP)/bin/$$fn; \ : {- output_on() unless windowsdll(); "" -}{- output_off() if windowsdll(); "" -}; \ @@ -721,7 +721,7 @@ generate: generate_apps generate_crypto_bn generate_crypto_objects \ generate_crypto_conf generate_crypto_asn1 generate_fuzz_oids .PHONY: doc-nits -doc-nits: +doc-nits: build_generated (cd $(SRCDIR); $(PERL) util/find-doc-nits -n -p ) >doc-nits @if [ -s doc-nits ] ; then cat doc-nits ; exit 1; \ else echo 'doc-nits: no errors.'; rm doc-nits ; fi diff --git a/Configure b/Configure index d6ae2bee..03053bc0 100755 --- a/Configure +++ b/Configure @@ -145,6 +145,8 @@ my $gcc_devteam_warn = "-DDEBUG_UNUSED" # -Wlanguage-extension-token -- no, we use asm() # -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc # -Wextended-offsetof -- no, needed in CMS ASN1 code +# -Wunused-function -- no, it forces header use of safestack et al +# DEFINE macros my $clang_devteam_warn = "" . " -Wswitch-default" . " -Wno-parentheses-equality" @@ -154,6 +156,7 @@ my $clang_devteam_warn = "" . " -Wincompatible-pointer-types-discards-qualifiers" . " -Wmissing-variable-declarations" . " -Wno-unknown-warning-option" + . " -Wno-unused-function" ; # This adds backtrace information to the memory leak info. Is only used @@ -749,7 +752,11 @@ while (@argvcopy) } elsif (/^--strict-warnings$/) { - $strict_warnings = 1; + # Pretend that our strict flags is a C flag, and replace it + # with the proper flags later on + push @{$useradd{CFLAGS}}, '--ossl-strict-warnings'; + push @{$useradd{CXXFLAGS}}, '--ossl-strict-warnings'; + $strict_warnings=1; } elsif (/^--debug$/) { @@ -1500,6 +1507,7 @@ $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".($apitable->{$config{api} // ""} // -1) ]; +my @strict_warnings_collection=(); if ($strict_warnings) { my $wopt; @@ -1507,26 +1515,17 @@ if ($strict_warnings) die "ERROR --strict-warnings requires gcc[>=4] or gcc-alike" unless $gccver >= 4; - foreach $wopt (split /\s+/, $gcc_devteam_warn) - { - push @{$config{cflags}}, $wopt - unless grep { $_ eq $wopt } @{$config{cflags}}; - push @{$config{cxxflags}}, $wopt - if ($config{CXX} - && !grep { $_ eq $wopt } @{$config{cxxflags}}); - } - if (defined($predefined{__clang__})) - { - foreach $wopt (split /\s+/, $clang_devteam_warn) - { - push @{$config{cflags}}, $wopt - unless grep { $_ eq $wopt } @{$config{cflags}}; - push @{$config{cxxflags}}, $wopt - if ($config{CXX} - && !grep { $_ eq $wopt } @{$config{cxxflags}}); - } - } + push @strict_warnings_collection, (split /\s+/, $gcc_devteam_warn); + push @strict_warnings_collection, (split /\s+/, $clang_devteam_warn) + if (defined($predefined{__clang__})); } +foreach (qw(CFLAGS CXXFLAGS)) + { + $useradd{$_} = [ map { $_ eq '--ossl-strict-warnings' + ? @strict_warnings_collection + : ( $_ ) } + @{$useradd{$_}} ]; + } unless ($disabled{"crypto-mdebug-backtrace"}) { diff --git a/apps/build.info b/apps/build.info index 7a5e8762..9b77c469 100644 --- a/apps/build.info +++ b/apps/build.info @@ -15,12 +15,12 @@ IF[{- !$disabled{apps} -}] LIBS{noinst}=libapps.a SOURCE[libapps.a]={- join(" ", @apps_lib_src) -} - INCLUDE[libapps.a]=.. ../include + INCLUDE[libapps.a]=.. ../include include PROGRAMS=openssl SOURCE[openssl]={- join(" ", @apps_init_src) -} SOURCE[openssl]={- join(" ", @apps_openssl_src) -} - INCLUDE[openssl]=.. ../include + INCLUDE[openssl]=.. ../include include DEPEND[openssl]=libapps.a ../libssl IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-)/ -}] diff --git a/apps/apps.h b/apps/include/apps.h similarity index 100% rename from apps/apps.h rename to apps/include/apps.h diff --git a/apps/apps_ui.h b/apps/include/apps_ui.h similarity index 100% rename from apps/apps_ui.h rename to apps/include/apps_ui.h diff --git a/apps/fmt.h b/apps/include/fmt.h similarity index 100% rename from apps/fmt.h rename to apps/include/fmt.h diff --git a/apps/opt.h b/apps/include/opt.h similarity index 100% rename from apps/opt.h rename to apps/include/opt.h diff --git a/apps/s_apps.h b/apps/include/s_apps.h similarity index 100% rename from apps/s_apps.h rename to apps/include/s_apps.h diff --git a/apps/s_cb.c b/apps/s_cb.c index af57c345..705550b6 100644 --- a/apps/s_cb.c +++ b/apps/s_cb.c @@ -24,7 +24,7 @@ #define COOKIE_SECRET_LENGTH 16 -VERIFY_CB_ARGS verify_args = { 0, 0, X509_V_OK, 0 }; +VERIFY_CB_ARGS verify_args = { -1, 0, X509_V_OK, 0 }; #ifndef OPENSSL_NO_SOCK static unsigned char cookie_secret[COOKIE_SECRET_LENGTH]; @@ -63,7 +63,7 @@ int verify_callback(int ok, X509_STORE_CTX *ctx) if (!ok) { BIO_printf(bio_err, "verify error:num=%d:%s\n", err, X509_verify_cert_error_string(err)); - if (verify_args.depth >= depth) { + if (verify_args.depth < 0 || verify_args.depth >= depth) { if (!verify_args.return_error) ok = 1; verify_args.error = err; diff --git a/apps/s_client.c b/apps/s_client.c index 2a8313d7..687e7553 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2005 Nokia. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -75,6 +75,7 @@ static int ocsp_resp_cb(SSL *s, void *arg); #endif static int ldap_ExtendedResponse_parse(const char *buf, long rem); static char *base64encode (const void *buf, size_t len); +static int is_dNS_name(const char *host); static int saved_errno; @@ -1138,6 +1139,7 @@ int s_client_main(int argc, char **argv) goto opthelp; break; case OPT_VERIFY_RET_ERROR: + verify = SSL_VERIFY_PEER; verify_args.return_error = 1; break; case OPT_VERIFY_QUIET: @@ -2012,9 +2014,11 @@ int s_client_main(int argc, char **argv) SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV); if (!noservername && (servername != NULL || dane_tlsa_domain == NULL)) { - if (servername == NULL) - servername = (host == NULL) ? "localhost" : host; - if (!SSL_set_tlsext_host_name(con, servername)) { + if (servername == NULL) { + if(host == NULL || is_dNS_name(host)) + servername = (host == NULL) ? "localhost" : host; + } + if (servername != NULL && !SSL_set_tlsext_host_name(con, servername)) { BIO_printf(bio_err, "Unable to set TLS servername extension.\n"); ERR_print_errors(bio_err); goto end; @@ -3553,4 +3557,69 @@ static char *base64encode (const void *buf, size_t len) return out; } +/* + * Host dNS Name verifier: used for checking that the hostname is in dNS format + * before setting it as SNI + */ +static int is_dNS_name(const char *host) +{ + const size_t MAX_LABEL_LENGTH = 63; + size_t i; + int isdnsname = 0; + size_t length = strlen(host); + size_t label_length = 0; + int all_numeric = 1; + + /* + * Deviation from strict DNS name syntax, also check names with '_' + * Check DNS name syntax, any '-' or '.' must be internal, + * and on either side of each '.' we can't have a '-' or '.'. + * + * If the name has just one label, we don't consider it a DNS name. + */ + for (i = 0; i < length && label_length < MAX_LABEL_LENGTH; ++i) { + char c = host[i]; + + if ((c >= 'a' && c <= 'z') + || (c >= 'A' && c <= 'Z') + || c == '_') { + label_length += 1; + all_numeric = 0; + continue; + } + + if (c >= '0' && c <= '9') { + label_length += 1; + continue; + } + + /* Dot and hyphen cannot be first or last. */ + if (i > 0 && i < length - 1) { + if (c == '-') { + label_length += 1; + continue; + } + /* + * Next to a dot the preceding and following characters must not be + * another dot or a hyphen. Otherwise, record that the name is + * plausible, since it has two or more labels. + */ + if (c == '.' + && host[i + 1] != '.' + && host[i - 1] != '-' + && host[i + 1] != '-') { + label_length = 0; + isdnsname = 1; + continue; + } + } + isdnsname = 0; + break; + } + + /* dNS name must not be all numeric and labels must be shorter than 64 characters. */ + isdnsname &= !all_numeric && !(label_length == MAX_LABEL_LENGTH); + + return isdnsname; +} #endif /* OPENSSL_NO_SOCK */ diff --git a/crypto/README.sparse_array b/crypto/README.sparse_array new file mode 100644 index 00000000..947c34db --- /dev/null +++ b/crypto/README.sparse_array @@ -0,0 +1,155 @@ +The sparse_array.c file contains an implementation of a sparse array that +attempts to be both space and time efficient. + +The sparse array is represented using a tree structure. Each node in the +tree contains a block of pointers to either the user supplied leaf values or +to another node. + +There are a number of parameters used to define the block size: + + OPENSSL_SA_BLOCK_BITS Specifies the number of bits covered by each block + SA_BLOCK_MAX Specifies the number of pointers in each block + SA_BLOCK_MASK Specifies a bit mask to perform modulo block size + SA_BLOCK_MAX_LEVELS Indicates the maximum possible height of the tree + +These constants are inter-related: + SA_BLOCK_MAX = 2 ^ OPENSSL_SA_BLOCK_BITS + SA_BLOCK_MASK = SA_BLOCK_MAX - 1 + SA_BLOCK_MAX_LEVELS = number of bits in size_t divided by + OPENSSL_SA_BLOCK_BITS rounded up to the next multiple + of OPENSSL_SA_BLOCK_BITS + +OPENSSL_SA_BLOCK_BITS can be defined at compile time and this overrides the +built in setting. + +As a space and performance optimisation, the height of the tree is usually +less than the maximum possible height. Only sufficient height is allocated to +accommodate the largest index added to the data structure. + +The largest index used to add a value to the array determines the tree height: + + +----------------------+---------------------+ + | Largest Added Index | Height of Tree | + +----------------------+---------------------+ + | SA_BLOCK_MAX - 1 | 1 | + | SA_BLOCK_MAX ^ 2 - 1 | 2 | + | SA_BLOCK_MAX ^ 3 - 1 | 3 | + | ... | ... | + | size_t max | SA_BLOCK_MAX_LEVELS | + +----------------------+---------------------+ + +The tree height is dynamically increased as needed based on additions. + +An empty tree is represented by a NULL root pointer. Inserting a value at +index 0 results in the allocation of a top level node full of null pointers +except for the single pointer to the user's data (N = SA_BLOCK_MAX for +breviety): + + +----+ + |Root| + |Node| + +-+--+ + | + | + | + v + +-+-+---+---+---+---+ + | 0 | 1 | 2 |...|N-1| + | |nil|nil|...|nil| + +-+-+---+---+---+---+ + | + | + | + v + +-+--+ + |User| + |Data| + +----+ + Index 0 + + +Inserting at element 2N+1 creates a new root node and pushes down the old root +node. It then creates a second second level node to hold the pointer to the +user's new data: + + +----+ + |Root| + |Node| + +-+--+ + | + | + | + v + +-+-+---+---+---+---+ + | 0 | 1 | 2 |...|N-1| + | |nil| |...|nil| + +-+-+---+-+-+---+---+ + | | + | +------------------+ + | | + v v + +-+-+---+---+---+---+ +-+-+---+---+---+---+ + | 0 | 1 | 2 |...|N-1| | 0 | 1 | 2 |...|N-1| + |nil| |nil|...|nil| |nil| |nil|...|nil| + +-+-+---+---+---+---+ +---+-+-+---+---+---+ + | | + | | + | | + v v + +-+--+ +-+--+ + |User| |User| + |Data| |Data| + +----+ +----+ + Index 0 Index 2N+1 + + +The nodes themselves are allocated in a sparse manner. Only nodes which exist +along a path from the root of the tree to an added leaf will be allocated. +The complexity is hidden and nodes are allocated on an as needed basis. +Because the data is expected to be sparse this doesn't result in a large waste +of space. + +Values can be removed from the sparse array by setting their index position to +NULL. The data structure does not attempt to reclaim nodes or reduce the +height of the tree on removal. For example, now setting index 0 to NULL would +result in: + + +----+ + |Root| + |Node| + +-+--+ + | + | + | + v + +-+-+---+---+---+---+ + | 0 | 1 | 2 |...|N-1| + | |nil| |...|nil| + +-+-+---+-+-+---+---+ + | | + | +------------------+ + | | + v v + +-+-+---+---+---+---+ +-+-+---+---+---+---+ + | 0 | 1 | 2 |...|N-1| | 0 | 1 | 2 |...|N-1| + |nil|nil|nil|...|nil| |nil| |nil|...|nil| + +---+---+---+---+---+ +---+-+-+---+---+---+ + | + | + | + v + +-+--+ + |User| + |Data| + +----+ + Index 2N+1 + + +Accesses to elements in the sparse array take O(log n) time where n is the +largest element. The base of the logarithm is SA_BLOCK_MAX, so for moderately +small indices (e.g. NIDs), single level (constant time) access is achievable. +Space usage is O(minimum(m, n log(n)) where m is the number of elements in the +array. + +Note: sparse arrays only include pointers to types. Thus, SPARSE_ARRAY_OF(char) +can be used to store a string. diff --git a/crypto/aes/asm/aes-armv4.pl b/crypto/aes/asm/aes-armv4.pl index abb2cc79..456a4696 100644 --- a/crypto/aes/asm/aes-armv4.pl +++ b/crypto/aes/asm/aes-armv4.pl @@ -76,7 +76,6 @@ $code=<<___; # define __ARM_ARCH__ __LINUX_ARM_ARCH__ #endif -.text #if defined(__thumb2__) && !defined(__APPLE__) .syntax unified .thumb @@ -85,6 +84,8 @@ $code=<<___; #undef __thumb2__ #endif +.text + .type AES_Te,%object .align 5 AES_Te: diff --git a/crypto/aes/asm/aes-mips.pl b/crypto/aes/asm/aes-mips.pl index 66c97cd3..c93edc6e 100644 --- a/crypto/aes/asm/aes-mips.pl +++ b/crypto/aes/asm/aes-mips.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2010-2018 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2010-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 @@ -34,6 +34,11 @@ # instead, code path is chosen upon pre-process time, pass -mips32r2 # or/and -msmartmips. +# February 2019 +# +# Normalize MIPS32R2 AES table address calculation by always using EXT +# instruction. This reduces the standard codebase by another 10%. + ###################################################################### # There is a number of MIPS ABI in use, O32 and N32/64 are most # widely used. Then there is a new contender: NUBI. It appears that if @@ -223,6 +228,33 @@ _mips_AES_encrypt: ext $i0,$s1,16,8 _xtr $i0,$s1,16-2 +#else +#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2) + move $i0,$Tbl + move $i1,$Tbl + move $i2,$Tbl + move $i3,$Tbl + ext $t0,$s1,16,8 +.Loop_enc: + ext $t1,$s2,16,8 + ext $t2,$s3,16,8 + ext $t3,$s0,16,8 + $PTR_INS $i0,$t0,2,8 + $PTR_INS $i1,$t1,2,8 + $PTR_INS $i2,$t2,2,8 + $PTR_INS $i3,$t3,2,8 + lw $t0,0($i0) # Te1[s1>>16] + ext $t4,$s2,8,8 + lw $t1,0($i1) # Te1[s2>>16] + ext $t5,$s3,8,8 + lw $t2,0($i2) # Te1[s3>>16] + ext $t6,$s0,8,8 + lw $t3,0($i3) # Te1[s0>>16] + ext $t7,$s1,8,8 + $PTR_INS $i0,$t4,2,8 + $PTR_INS $i1,$t5,2,8 + $PTR_INS $i2,$t6,2,8 + $PTR_INS $i3,$t7,2,8 #else _xtr $i0,$s1,16-2 .Loop_enc: @@ -237,16 +269,6 @@ _mips_AES_encrypt: $PTR_ADD $i1,$Tbl $PTR_ADD $i2,$Tbl $PTR_ADD $i3,$Tbl -#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2) - lw $t0,0($i0) # Te1[s1>>16] - _xtr $i0,$s2,8-2 - lw $t1,0($i1) # Te1[s2>>16] - _xtr $i1,$s3,8-2 - lw $t2,0($i2) # Te1[s3>>16] - _xtr $i2,$s0,8-2 - lw $t3,0($i3) # Te1[s0>>16] - _xtr $i3,$s1,8-2 -#else lwl $t0,3($i0) # Te1[s1>>16] lwl $t1,3($i1) # Te1[s2>>16] lwl $t2,3($i2) # Te1[s3>>16] @@ -259,7 +281,6 @@ _mips_AES_encrypt: _xtr $i2,$s0,8-2 lwr $t3,2($i3) # Te1[s0>>16] _xtr $i3,$s1,8-2 -#endif and $i0,0x3fc and $i1,0x3fc and $i2,0x3fc @@ -268,6 +289,7 @@ _mips_AES_encrypt: $PTR_ADD $i1,$Tbl $PTR_ADD $i2,$Tbl $PTR_ADD $i3,$Tbl +#endif #if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2) rotr $t0,$t0,8 rotr $t1,$t1,8 @@ -275,22 +297,18 @@ _mips_AES_encrypt: rotr $t3,$t3,8 # if defined(_MIPSEL) lw $t4,0($i0) # Te2[s2>>8] - _xtr $i0,$s3,0-2 + ext $t8,$s3,0,8 lw $t5,0($i1) # Te2[s3>>8] - _xtr $i1,$s0,0-2 + ext $t9,$s0,0,8 lw $t6,0($i2) # Te2[s0>>8] - _xtr $i2,$s1,0-2 + ext $t10,$s1,0,8 lw $t7,0($i3) # Te2[s1>>8] - _xtr $i3,$s2,0-2 + ext $t11,$s2,0,8 + $PTR_INS $i0,$t8,2,8 + $PTR_INS $i1,$t9,2,8 + $PTR_INS $i2,$t10,2,8 + $PTR_INS $i3,$t11,2,8 - and $i0,0x3fc - and $i1,0x3fc - and $i2,0x3fc - and $i3,0x3fc - $PTR_ADD $i0,$Tbl - $PTR_ADD $i1,$Tbl - $PTR_ADD $i2,$Tbl - $PTR_ADD $i3,$Tbl lw $t8,0($i0) # Te3[s3] $PTR_INS $i0,$s0,2,8 lw $t9,0($i1) # Te3[s0] @@ -411,6 +429,9 @@ _mips_AES_encrypt: xor $s3,$t3 .set noreorder bnez $cnt,.Loop_enc +#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2) + ext $t0,$s1,16,8 +#endif _xtr $i0,$s1,16-2 #endif @@ -811,6 +832,33 @@ _mips_AES_decrypt: ext $i0,$s3,16,8 _xtr $i0,$s3,16-2 +#else +#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2) + move $i0,$Tbl + move $i1,$Tbl + move $i2,$Tbl + move $i3,$Tbl + ext $t0,$s3,16,8 +.Loop_dec: + ext $t1,$s0,16,8 + ext $t2,$s1,16,8 + ext $t3,$s2,16,8 + $PTR_INS $i0,$t0,2,8 + $PTR_INS $i1,$t1,2,8 + $PTR_INS $i2,$t2,2,8 + $PTR_INS $i3,$t3,2,8 + lw $t0,0($i0) # Td1[s3>>16] + ext $t4,$s2,8,8 + lw $t1,0($i1) # Td1[s0>>16] + ext $t5,$s3,8,8 + lw $t2,0($i2) # Td1[s1>>16] + ext $t6,$s0,8,8 + lw $t3,0($i3) # Td1[s2>>16] + ext $t7,$s1,8,8 + $PTR_INS $i0,$t4,2,8 + $PTR_INS $i1,$t5,2,8 + $PTR_INS $i2,$t6,2,8 + $PTR_INS $i3,$t7,2,8 #else _xtr $i0,$s3,16-2 .Loop_dec: @@ -825,16 +873,6 @@ _mips_AES_decrypt: $PTR_ADD $i1,$Tbl $PTR_ADD $i2,$Tbl $PTR_ADD $i3,$Tbl -#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2) - lw $t0,0($i0) # Td1[s3>>16] - _xtr $i0,$s2,8-2 - lw $t1,0($i1) # Td1[s0>>16] - _xtr $i1,$s3,8-2 - lw $t2,0($i2) # Td1[s1>>16] - _xtr $i2,$s0,8-2 - lw $t3,0($i3) # Td1[s2>>16] - _xtr $i3,$s1,8-2 -#else lwl $t0,3($i0) # Td1[s3>>16] lwl $t1,3($i1) # Td1[s0>>16] lwl $t2,3($i2) # Td1[s1>>16] @@ -847,8 +885,6 @@ _mips_AES_decrypt: _xtr $i2,$s0,8-2 lwr $t3,2($i3) # Td1[s2>>16] _xtr $i3,$s1,8-2 -#endif - and $i0,0x3fc and $i1,0x3fc and $i2,0x3fc @@ -857,6 +893,7 @@ _mips_AES_decrypt: $PTR_ADD $i1,$Tbl $PTR_ADD $i2,$Tbl $PTR_ADD $i3,$Tbl +#endif #if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2) rotr $t0,$t0,8 rotr $t1,$t1,8 @@ -864,22 +901,17 @@ _mips_AES_decrypt: rotr $t3,$t3,8 # if defined(_MIPSEL) lw $t4,0($i0) # Td2[s2>>8] - _xtr $i0,$s1,0-2 + ext $t8,$s1,0,8 lw $t5,0($i1) # Td2[s3>>8] - _xtr $i1,$s2,0-2 + ext $t9,$s2,0,8 lw $t6,0($i2) # Td2[s0>>8] - _xtr $i2,$s3,0-2 + ext $t10,$s3,0,8 lw $t7,0($i3) # Td2[s1>>8] - _xtr $i3,$s0,0-2 - - and $i0,0x3fc - and $i1,0x3fc - and $i2,0x3fc - and $i3,0x3fc - $PTR_ADD $i0,$Tbl - $PTR_ADD $i1,$Tbl - $PTR_ADD $i2,$Tbl - $PTR_ADD $i3,$Tbl + ext $t11,$s0,0,8 + $PTR_INS $i0,$t8,2,8 + $PTR_INS $i1,$t9,2,8 + $PTR_INS $i2,$t10,2,8 + $PTR_INS $i3,$t11,2,8 lw $t8,0($i0) # Td3[s1] $PTR_INS $i0,$s0,2,8 lw $t9,0($i1) # Td3[s2] @@ -1001,6 +1033,10 @@ _mips_AES_decrypt: xor $s3,$t3 .set noreorder bnez $cnt,.Loop_dec +#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2) + ext $t0,$s3,16,8 +#endif + _xtr $i0,$s3,16-2 #endif diff --git a/crypto/aes/asm/aes-x86_64.pl b/crypto/aes/asm/aes-x86_64.pl index d84c6979..6e1dcef2 100755 --- a/crypto/aes/asm/aes-x86_64.pl +++ b/crypto/aes/asm/aes-x86_64.pl @@ -554,6 +554,7 @@ $code.=<<___; .type _x86_64_AES_encrypt_compact,\@abi-omnipotent .align 16 _x86_64_AES_encrypt_compact: +.cfi_startproc lea 128($sbox),$inp # size optimization mov 0-128($inp),$acc1 # prefetch Te4 mov 32-128($inp),$acc2 @@ -587,6 +588,7 @@ $code.=<<___; xor 8($key),$s2 xor 12($key),$s3 .byte 0xf3,0xc3 # rep ret +.cfi_endproc .size _x86_64_AES_encrypt_compact,.-_x86_64_AES_encrypt_compact ___ @@ -1161,6 +1163,7 @@ $code.=<<___; .type _x86_64_AES_decrypt_compact,\@abi-omnipotent .align 16 _x86_64_AES_decrypt_compact: +.cfi_startproc lea 128($sbox),$inp # size optimization mov 0-128($inp),$acc1 # prefetch Td4 mov 32-128($inp),$acc2 @@ -1203,6 +1206,7 @@ $code.=<<___; xor 8($key),$s2 xor 12($key),$s3 .byte 0xf3,0xc3 # rep ret +.cfi_endproc .size _x86_64_AES_decrypt_compact,.-_x86_64_AES_decrypt_compact ___ @@ -1365,6 +1369,7 @@ AES_set_encrypt_key: .type _x86_64_AES_set_encrypt_key,\@abi-omnipotent .align 16 _x86_64_AES_set_encrypt_key: +.cfi_startproc mov %esi,%ecx # %ecx=bits mov %rdi,%rsi # %rsi=userKey mov %rdx,%rdi # %rdi=key @@ -1546,6 +1551,7 @@ $code.=<<___; mov \$-1,%rax .Lexit: .byte 0xf3,0xc3 # rep ret +.cfi_endproc .size _x86_64_AES_set_encrypt_key,.-_x86_64_AES_set_encrypt_key ___ @@ -1728,7 +1734,9 @@ AES_cbc_encrypt: cmp \$0,%rdx # check length je .Lcbc_epilogue pushfq -.cfi_push 49 # %rflags +# This could be .cfi_push 49, but libunwind fails on registers it does not +# recognize. See https://bugzilla.redhat.com/show_bug.cgi?id=217087. +.cfi_adjust_cfa_offset 8 push %rbx .cfi_push %rbx push %rbp @@ -1751,6 +1759,7 @@ AES_cbc_encrypt: cmp \$0,%r9 cmoveq %r10,$sbox +.cfi_remember_state mov OPENSSL_ia32cap_P(%rip),%r10d cmp \$$speed_limit,%rdx jb .Lcbc_slow_prologue @@ -1986,6 +1995,7 @@ AES_cbc_encrypt: #--------------------------- SLOW ROUTINE ---------------------------# .align 16 .Lcbc_slow_prologue: +.cfi_restore_state # allocate aligned stack frame... lea -88(%rsp),%rbp and \$-64,%rbp @@ -1997,8 +2007,10 @@ AES_cbc_encrypt: sub %r10,%rbp xchg %rsp,%rbp +.cfi_def_cfa_register %rbp #add \$8,%rsp # reserve for return address! mov %rbp,$_rsp # save %rsp +.cfi_cfa_expression $_rsp,deref,+64 .Lcbc_slow_body: #mov %rdi,$_inp # save copy of inp #mov %rsi,$_out # save copy of out @@ -2187,7 +2199,9 @@ AES_cbc_encrypt: .cfi_def_cfa %rsp,16 .Lcbc_popfq: popfq -.cfi_pop 49 # %rflags +# This could be .cfi_pop 49, but libunwind fails on registers it does not +# recognize. See https://bugzilla.redhat.com/show_bug.cgi?id=217087. +.cfi_adjust_cfa_offset -8 .Lcbc_epilogue: ret .cfi_endproc diff --git a/crypto/aes/asm/aesni-x86_64.pl b/crypto/aes/asm/aesni-x86_64.pl index 50853398..406377a6 100644 --- a/crypto/aes/asm/aesni-x86_64.pl +++ b/crypto/aes/asm/aesni-x86_64.pl @@ -274,6 +274,7 @@ $code.=<<___; .type ${PREFIX}_encrypt,\@abi-omnipotent .align 16 ${PREFIX}_encrypt: +.cfi_startproc movups ($inp),$inout0 # load input mov 240($key),$rounds # key->rounds ___ @@ -284,12 +285,14 @@ $code.=<<___; movups $inout0,($out) # output pxor $inout0,$inout0 ret +.cfi_endproc .size ${PREFIX}_encrypt,.-${PREFIX}_encrypt .globl ${PREFIX}_decrypt .type ${PREFIX}_decrypt,\@abi-omnipotent .align 16 ${PREFIX}_decrypt: +.cfi_startproc movups ($inp),$inout0 # load input mov 240($key),$rounds # key->rounds ___ @@ -300,6 +303,7 @@ $code.=<<___; movups $inout0,($out) # output pxor $inout0,$inout0 ret +.cfi_endproc .size ${PREFIX}_decrypt, .-${PREFIX}_decrypt ___ } @@ -325,6 +329,7 @@ $code.=<<___; .type _aesni_${dir}rypt2,\@abi-omnipotent .align 16 _aesni_${dir}rypt2: +.cfi_startproc $movkey ($key),$rndkey0 shl \$4,$rounds $movkey 16($key),$rndkey1 @@ -350,6 +355,7 @@ _aesni_${dir}rypt2: aes${dir}last $rndkey0,$inout0 aes${dir}last $rndkey0,$inout1 ret +.cfi_endproc .size _aesni_${dir}rypt2,.-_aesni_${dir}rypt2 ___ } @@ -361,6 +367,7 @@ $code.=<<___; .type _aesni_${dir}rypt3,\@abi-omnipotent .align 16 _aesni_${dir}rypt3: +.cfi_startproc $movkey ($key),$rndkey0 shl \$4,$rounds $movkey 16($key),$rndkey1 @@ -391,6 +398,7 @@ _aesni_${dir}rypt3: aes${dir}last $rndkey0,$inout1 aes${dir}last $rndkey0,$inout2 ret +.cfi_endproc .size _aesni_${dir}rypt3,.-_aesni_${dir}rypt3 ___ } @@ -406,6 +414,7 @@ $code.=<<___; .type _aesni_${dir}rypt4,\@abi-omnipotent .align 16 _aesni_${dir}rypt4: +.cfi_startproc $movkey ($key),$rndkey0 shl \$4,$rounds $movkey 16($key),$rndkey1 @@ -442,6 +451,7 @@ _aesni_${dir}rypt4: aes${dir}last $rndkey0,$inout2 aes${dir}last $rndkey0,$inout3 ret +.cfi_endproc .size _aesni_${dir}rypt4,.-_aesni_${dir}rypt4 ___ } @@ -453,6 +463,7 @@ $code.=<<___; .type _aesni_${dir}rypt6,\@abi-omnipotent .align 16 _aesni_${dir}rypt6: +.cfi_startproc $movkey ($key),$rndkey0 shl \$4,$rounds $movkey 16($key),$rndkey1 @@ -503,6 +514,7 @@ _aesni_${dir}rypt6: aes${dir}last $rndkey0,$inout4 aes${dir}last $rndkey0,$inout5 ret +.cfi_endproc .size _aesni_${dir}rypt6,.-_aesni_${dir}rypt6 ___ } @@ -514,6 +526,7 @@ $code.=<<___; .type _aesni_${dir}rypt8,\@abi-omnipotent .align 16 _aesni_${dir}rypt8: +.cfi_startproc $movkey ($key),$rndkey0 shl \$4,$rounds $movkey 16($key),$rndkey1 @@ -574,6 +587,7 @@ _aesni_${dir}rypt8: aes${dir}last $rndkey0,$inout6 aes${dir}last $rndkey0,$inout7 ret +.cfi_endproc .size _aesni_${dir}rypt8,.-_aesni_${dir}rypt8 ___ } @@ -598,6 +612,7 @@ $code.=<<___; .type aesni_ecb_encrypt,\@function,5 .align 16 aesni_ecb_encrypt: +.cfi_startproc ___ $code.=<<___ if ($win64); lea -0x58(%rsp),%rsp @@ -943,6 +958,7 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .size aesni_ecb_encrypt,.-aesni_ecb_encrypt ___ diff --git a/crypto/aes/asm/aesv8-armx.pl b/crypto/aes/asm/aesv8-armx.pl index b61bdbae..81bc1cbf 100755 --- a/crypto/aes/asm/aesv8-armx.pl +++ b/crypto/aes/asm/aesv8-armx.pl @@ -53,18 +53,27 @@ open OUT,"| \"$^X\" $xlate $flavour $output"; $prefix="aes_v8"; +$_byte = ($flavour =~ /win/ ? "DCB" : ".byte"); + $code=<<___; #include "arm_arch.h" #if __ARM_MAX_ARCH__>=7 -.text ___ -$code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/); +$code.=".arch armv8-a+crypto\n.text\n" if ($flavour =~ /64/); $code.=<<___ if ($flavour !~ /64/); .arch armv7-a // don't confuse not-so-latest binutils with argv8 :-) .fpu neon +#ifdef __thumb2__ +.syntax unified +.thumb +# define INST(a,b,c,d) $_byte c,d|0xc,a,b +#else .code 32 -#undef __thumb2__ +# define INST(a,b,c,d) $_byte a,b,c,d +#endif + +.text ___ # Assembler mnemonics are an eclectic mix of 32- and 64-bit syntax, @@ -262,6 +271,7 @@ $code.=<<___; ${prefix}_set_decrypt_key: ___ $code.=<<___ if ($flavour =~ /64/); + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-16]! add x29,sp,#0 ___ @@ -305,6 +315,7 @@ $code.=<<___ if ($flavour !~ /64/); ___ $code.=<<___ if ($flavour =~ /64/); ldp x29,x30,[sp],#16 + .inst 0xd50323bf // autiasp ret ___ $code.=<<___; @@ -953,7 +964,7 @@ if ($flavour =~ /64/) { ######## 64-bit code # since ARMv7 instructions are always encoded little-endian. # correct solution is to use .inst directive, but older # assemblers don't implement it:-( - sprintf ".byte\t0x%02x,0x%02x,0x%02x,0x%02x\t@ %s %s", + sprintf "INST(0x%02x,0x%02x,0x%02x,0x%02x)\t@ %s %s", $word&0xff,($word>>8)&0xff, ($word>>16)&0xff,($word>>24)&0xff, $mnemonic,$arg; @@ -994,14 +1005,17 @@ if ($flavour =~ /64/) { ######## 64-bit code s/\],#[0-9]+/]!/o; s/[v]?(aes\w+)\s+([qv].*)/unaes($1,$2)/geo or - s/cclr\s+([^,]+),\s*([a-z]+)/mov$2 $1,#0/o or + s/cclr\s+([^,]+),\s*([a-z]+)/mov.$2 $1,#0/o or s/vtbl\.8\s+(.*)/unvtbl($1)/geo or s/vdup\.32\s+(.*)/unvdup32($1)/geo or s/vmov\.32\s+(.*)/unvmov32($1)/geo or s/^(\s+)b\./$1b/o or - s/^(\s+)mov\./$1mov/o or s/^(\s+)ret/$1bx\tlr/o; + if (s/^(\s+)mov\.([a-z]+)/$1mov$2/) { + print " it $2\n"; + } + print $_,"\n"; } } diff --git a/crypto/aes/asm/bsaes-armv7.pl b/crypto/aes/asm/bsaes-armv7.pl index 5df195b9..7f5219bc 100644 --- a/crypto/aes/asm/bsaes-armv7.pl +++ b/crypto/aes/asm/bsaes-armv7.pl @@ -728,7 +728,6 @@ $code.=<<___; .arch armv7-a .fpu neon -.text .syntax unified @ ARMv7-capable assembler is expected to handle this #if defined(__thumb2__) && !defined(__APPLE__) .thumb @@ -737,6 +736,8 @@ $code.=<<___; # undef __thumb2__ #endif +.text + .type _bsaes_decrypt8,%function .align 4 _bsaes_decrypt8: @@ -1125,9 +1126,9 @@ bsaes_cbc_encrypt: #ifndef __thumb__ blo AES_cbc_encrypt #else - bhs 1f + bhs .Lcbc_do_bsaes b AES_cbc_encrypt -1: +.Lcbc_do_bsaes: #endif #endif diff --git a/crypto/aes/asm/bsaes-x86_64.pl b/crypto/aes/asm/bsaes-x86_64.pl index 5a82ff63..44651d43 100644 --- a/crypto/aes/asm/bsaes-x86_64.pl +++ b/crypto/aes/asm/bsaes-x86_64.pl @@ -816,6 +816,7 @@ $code.=<<___; .type _bsaes_encrypt8,\@abi-omnipotent .align 64 _bsaes_encrypt8: +.cfi_startproc lea .LBS0(%rip), $const # constants table movdqa ($key), @XMM[9] # round 0 key @@ -875,11 +876,13 @@ $code.=<<___; pxor @XMM[8], @XMM[0] pxor @XMM[8], @XMM[1] ret +.cfi_endproc .size _bsaes_encrypt8,.-_bsaes_encrypt8 .type _bsaes_decrypt8,\@abi-omnipotent .align 64 _bsaes_decrypt8: +.cfi_startproc lea .LBS0(%rip), $const # constants table movdqa ($key), @XMM[9] # round 0 key @@ -937,6 +940,7 @@ $code.=<<___; pxor @XMM[8], @XMM[0] pxor @XMM[8], @XMM[1] ret +.cfi_endproc .size _bsaes_decrypt8,.-_bsaes_decrypt8 ___ } @@ -971,6 +975,7 @@ $code.=<<___; .type _bsaes_key_convert,\@abi-omnipotent .align 16 _bsaes_key_convert: +.cfi_startproc lea .Lmasks(%rip), $const movdqu ($inp), %xmm7 # load round 0 key lea 0x10($inp), $inp @@ -1049,6 +1054,7 @@ _bsaes_key_convert: movdqa 0x50($const), %xmm7 # .L63 #movdqa %xmm6, ($out) # don't save last round key ret +.cfi_endproc .size _bsaes_key_convert,.-_bsaes_key_convert ___ } diff --git a/crypto/aes/asm/vpaes-armv8.pl b/crypto/aes/asm/vpaes-armv8.pl index 1fce0c5a..f08ae583 100755 --- a/crypto/aes/asm/vpaes-armv8.pl +++ b/crypto/aes/asm/vpaes-armv8.pl @@ -150,12 +150,12 @@ my ($sb1u,$sb1t,$sb2u,$sb2t) = map("v$_.16b",(24..27)); my ($sb9u,$sb9t,$sbdu,$sbdt,$sbbu,$sbbt,$sbeu,$sbet)=map("v$_.16b",(24..31)); $code.=<<___; -## -## _aes_preheat -## -## Fills register %r10 -> .aes_consts (so you can -fPIC) -## and %xmm9-%xmm15 as specified below. -## +// +// _aes_preheat +// +// Fills register %r10 -> .aes_consts (so you can -fPIC) +// and %xmm9-%xmm15 as specified below. +// .type _vpaes_encrypt_preheat,%function .align 4 _vpaes_encrypt_preheat: @@ -167,21 +167,21 @@ _vpaes_encrypt_preheat: ret .size _vpaes_encrypt_preheat,.-_vpaes_encrypt_preheat -## -## _aes_encrypt_core -## -## AES-encrypt %xmm0. -## -## Inputs: -## %xmm0 = input -## %xmm9-%xmm15 as in _vpaes_preheat -## (%rdx) = scheduled keys -## -## Output in %xmm0 -## Clobbers %xmm1-%xmm5, %r9, %r10, %r11, %rax -## Preserves %xmm6 - %xmm8 so you get some local vectors -## -## +// +// _aes_encrypt_core +// +// AES-encrypt %xmm0. +// +// Inputs: +// %xmm0 = input +// %xmm9-%xmm15 as in _vpaes_preheat +// (%rdx) = scheduled keys +// +// Output in %xmm0 +// Clobbers %xmm1-%xmm5, %r9, %r10, %r11, %rax +// Preserves %xmm6 - %xmm8 so you get some local vectors +// +// .type _vpaes_encrypt_core,%function .align 4 _vpaes_encrypt_core: @@ -255,6 +255,7 @@ _vpaes_encrypt_core: .type vpaes_encrypt,%function .align 4 vpaes_encrypt: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-16]! add x29,sp,#0 @@ -264,6 +265,7 @@ vpaes_encrypt: st1 {v0.16b}, [$out] ldp x29,x30,[sp],#16 + .inst 0xd50323bf // autiasp ret .size vpaes_encrypt,.-vpaes_encrypt @@ -385,11 +387,11 @@ _vpaes_decrypt_preheat: ret .size _vpaes_decrypt_preheat,.-_vpaes_decrypt_preheat -## -## Decryption core -## -## Same API as encryption core. -## +// +// Decryption core +// +// Same API as encryption core. +// .type _vpaes_decrypt_core,%function .align 4 _vpaes_decrypt_core: @@ -486,6 +488,7 @@ _vpaes_decrypt_core: .type vpaes_decrypt,%function .align 4 vpaes_decrypt: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-16]! add x29,sp,#0 @@ -495,6 +498,7 @@ vpaes_decrypt: st1 {v0.16b}, [$out] ldp x29,x30,[sp],#16 + .inst 0xd50323bf // autiasp ret .size vpaes_decrypt,.-vpaes_decrypt @@ -639,11 +643,11 @@ my ($inp,$bits,$out,$dir)=("x0","w1","x2","w3"); my ($invlo,$invhi,$iptlo,$ipthi,$rcon) = map("v$_.16b",(18..21,8)); $code.=<<___; -######################################################## -## ## -## AES key schedule ## -## ## -######################################################## +//////////////////////////////////////////////////////// +// // +// AES key schedule // +// // +//////////////////////////////////////////////////////// .type _vpaes_key_preheat,%function .align 4 _vpaes_key_preheat: @@ -665,6 +669,7 @@ _vpaes_key_preheat: .type _vpaes_schedule_core,%function .align 4 _vpaes_schedule_core: + .inst 0xd503233f // paciasp stp x29, x30, [sp,#-16]! add x29,sp,#0 @@ -698,14 +703,14 @@ _vpaes_schedule_core: b.eq .Lschedule_192 // 128: fall though -## -## .schedule_128 -## -## 128-bit specific part of key schedule. -## -## This schedule is really simple, because all its parts -## are accomplished by the subroutines. -## +// +// .schedule_128 +// +// 128-bit specific part of key schedule. +// +// This schedule is really simple, because all its parts +// are accomplished by the subroutines. +// .Lschedule_128: mov $inp, #10 // mov \$10, %esi @@ -716,21 +721,21 @@ _vpaes_schedule_core: bl _vpaes_schedule_mangle // write output b .Loop_schedule_128 -## -## .aes_schedule_192 -## -## 192-bit specific part of key schedule. -## -## The main body of this schedule is the same as the 128-bit -## schedule, but with more smearing. The long, high side is -## stored in %xmm7 as before, and the short, low side is in -## the high bits of %xmm6. -## -## This schedule is somewhat nastier, however, because each -## round produces 192 bits of key material, or 1.5 round keys. -## Therefore, on each cycle we do 2 rounds and produce 3 round -## keys. -## +// +// .aes_schedule_192 +// +// 192-bit specific part of key schedule. +// +// The main body of this schedule is the same as the 128-bit +// schedule, but with more smearing. The long, high side is +// stored in %xmm7 as before, and the short, low side is in +// the high bits of %xmm6. +// +// This schedule is somewhat nastier, however, because each +// round produces 192 bits of key material, or 1.5 round keys. +// Therefore, on each cycle we do 2 rounds and produce 3 round +// keys. +// .align 4 .Lschedule_192: sub $inp, $inp, #8 @@ -754,16 +759,16 @@ _vpaes_schedule_core: bl _vpaes_schedule_192_smear b .Loop_schedule_192 -## -## .aes_schedule_256 -## -## 256-bit specific part of key schedule. -## -## The structure here is very similar to the 128-bit -## schedule, but with an additional "low side" in -## %xmm6. The low side's rounds are the same as the -## high side's, except no rcon and no rotation. -## +// +// .aes_schedule_256 +// +// 256-bit specific part of key schedule. +// +// The structure here is very similar to the 128-bit +// schedule, but with an additional "low side" in +// %xmm6. The low side's rounds are the same as the +// high side's, except no rcon and no rotation. +// .align 4 .Lschedule_256: ld1 {v0.16b}, [$inp] // vmovdqu 16(%rdi),%xmm0 # load key part 2 (unaligned) @@ -790,16 +795,16 @@ _vpaes_schedule_core: b .Loop_schedule_256 -## -## .aes_schedule_mangle_last -## -## Mangler for last round of key schedule -## Mangles %xmm0 -## when encrypting, outputs out(%xmm0) ^ 63 -## when decrypting, outputs unskew(%xmm0) -## -## Always called right before return... jumps to cleanup and exits -## +// +// .aes_schedule_mangle_last +// +// Mangler for last round of key schedule +// Mangles %xmm0 +// when encrypting, outputs out(%xmm0) ^ 63 +// when decrypting, outputs unskew(%xmm0) +// +// Always called right before return... jumps to cleanup and exits +// .align 4 .Lschedule_mangle_last: // schedule last round key from xmm0 @@ -829,23 +834,24 @@ _vpaes_schedule_core: eor v6.16b, v6.16b, v6.16b // vpxor %xmm6, %xmm6, %xmm6 eor v7.16b, v7.16b, v7.16b // vpxor %xmm7, %xmm7, %xmm7 ldp x29, x30, [sp],#16 + .inst 0xd50323bf // autiasp ret .size _vpaes_schedule_core,.-_vpaes_schedule_core -## -## .aes_schedule_192_smear -## -## Smear the short, low side in the 192-bit key schedule. -## -## Inputs: -## %xmm7: high side, b a x y -## %xmm6: low side, d c 0 0 -## %xmm13: 0 -## -## Outputs: -## %xmm6: b+c+d b+c 0 0 -## %xmm0: b+c+d b+c b a -## +// +// .aes_schedule_192_smear +// +// Smear the short, low side in the 192-bit key schedule. +// +// Inputs: +// %xmm7: high side, b a x y +// %xmm6: low side, d c 0 0 +// %xmm13: 0 +// +// Outputs: +// %xmm6: b+c+d b+c 0 0 +// %xmm0: b+c+d b+c b a +// .type _vpaes_schedule_192_smear,%function .align 4 _vpaes_schedule_192_smear: @@ -861,24 +867,24 @@ _vpaes_schedule_192_smear: ret .size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear -## -## .aes_schedule_round -## -## Runs one main round of the key schedule on %xmm0, %xmm7 -## -## Specifically, runs subbytes on the high dword of %xmm0 -## then rotates it by one byte and xors into the low dword of -## %xmm7. -## -## Adds rcon from low byte of %xmm8, then rotates %xmm8 for -## next rcon. -## -## Smears the dwords of %xmm7 by xoring the low into the -## second low, result into third, result into highest. -## -## Returns results in %xmm7 = %xmm0. -## Clobbers %xmm1-%xmm4, %r11. -## +// +// .aes_schedule_round +// +// Runs one main round of the key schedule on %xmm0, %xmm7 +// +// Specifically, runs subbytes on the high dword of %xmm0 +// then rotates it by one byte and xors into the low dword of +// %xmm7. +// +// Adds rcon from low byte of %xmm8, then rotates %xmm8 for +// next rcon. +// +// Smears the dwords of %xmm7 by xoring the low into the +// second low, result into third, result into highest. +// +// Returns results in %xmm7 = %xmm0. +// Clobbers %xmm1-%xmm4, %r11. +// .type _vpaes_schedule_round,%function .align 4 _vpaes_schedule_round: @@ -926,15 +932,15 @@ _vpaes_schedule_low_round: ret .size _vpaes_schedule_round,.-_vpaes_schedule_round -## -## .aes_schedule_transform -## -## Linear-transform %xmm0 according to tables at (%r11) -## -## Requires that %xmm9 = 0x0F0F... as in preheat -## Output in %xmm0 -## Clobbers %xmm1, %xmm2 -## +// +// .aes_schedule_transform +// +// Linear-transform %xmm0 according to tables at (%r11) +// +// Requires that %xmm9 = 0x0F0F... as in preheat +// Output in %xmm0 +// Clobbers %xmm1, %xmm2 +// .type _vpaes_schedule_transform,%function .align 4 _vpaes_schedule_transform: @@ -948,29 +954,29 @@ _vpaes_schedule_transform: ret .size _vpaes_schedule_transform,.-_vpaes_schedule_transform -## -## .aes_schedule_mangle -## -## Mangle xmm0 from (basis-transformed) standard version -## to our version. -## -## On encrypt, -## xor with 0x63 -## multiply by circulant 0,1,1,1 -## apply shiftrows transform -## -## On decrypt, -## xor with 0x63 -## multiply by "inverse mixcolumns" circulant E,B,D,9 -## deskew -## apply shiftrows transform -## -## -## Writes out to (%rdx), and increments or decrements it -## Keeps track of round number mod 4 in %r8 -## Preserves xmm0 -## Clobbers xmm1-xmm5 -## +// +// .aes_schedule_mangle +// +// Mangle xmm0 from (basis-transformed) standard version +// to our version. +// +// On encrypt, +// xor with 0x63 +// multiply by circulant 0,1,1,1 +// apply shiftrows transform +// +// On decrypt, +// xor with 0x63 +// multiply by "inverse mixcolumns" circulant E,B,D,9 +// deskew +// apply shiftrows transform +// +// +// Writes out to (%rdx), and increments or decrements it +// Keeps track of round number mod 4 in %r8 +// Preserves xmm0 +// Clobbers xmm1-xmm5 +// .type _vpaes_schedule_mangle,%function .align 4 _vpaes_schedule_mangle: @@ -1041,6 +1047,7 @@ _vpaes_schedule_mangle: .type vpaes_set_encrypt_key,%function .align 4 vpaes_set_encrypt_key: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-16]! add x29,sp,#0 stp d8,d9,[sp,#-16]! // ABI spec says so @@ -1056,6 +1063,7 @@ vpaes_set_encrypt_key: ldp d8,d9,[sp],#16 ldp x29,x30,[sp],#16 + .inst 0xd50323bf // autiasp ret .size vpaes_set_encrypt_key,.-vpaes_set_encrypt_key @@ -1063,6 +1071,7 @@ vpaes_set_encrypt_key: .type vpaes_set_decrypt_key,%function .align 4 vpaes_set_decrypt_key: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-16]! add x29,sp,#0 stp d8,d9,[sp,#-16]! // ABI spec says so @@ -1082,6 +1091,7 @@ vpaes_set_decrypt_key: ldp d8,d9,[sp],#16 ldp x29,x30,[sp],#16 + .inst 0xd50323bf // autiasp ret .size vpaes_set_decrypt_key,.-vpaes_set_decrypt_key ___ @@ -1098,6 +1108,7 @@ vpaes_cbc_encrypt: cmp w5, #0 // check direction b.eq vpaes_cbc_decrypt + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-16]! add x29,sp,#0 @@ -1120,6 +1131,7 @@ vpaes_cbc_encrypt: st1 {v0.16b}, [$ivec] // write ivec ldp x29,x30,[sp],#16 + .inst 0xd50323bf // autiasp .Lcbc_abort: ret .size vpaes_cbc_encrypt,.-vpaes_cbc_encrypt @@ -1127,6 +1139,7 @@ vpaes_cbc_encrypt: .type vpaes_cbc_decrypt,%function .align 4 vpaes_cbc_decrypt: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-16]! add x29,sp,#0 stp d8,d9,[sp,#-16]! // ABI spec says so @@ -1168,6 +1181,7 @@ vpaes_cbc_decrypt: ldp d10,d11,[sp],#16 ldp d8,d9,[sp],#16 ldp x29,x30,[sp],#16 + .inst 0xd50323bf // autiasp ret .size vpaes_cbc_decrypt,.-vpaes_cbc_decrypt ___ @@ -1177,6 +1191,7 @@ $code.=<<___; .type vpaes_ecb_encrypt,%function .align 4 vpaes_ecb_encrypt: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-16]! add x29,sp,#0 stp d8,d9,[sp,#-16]! // ABI spec says so @@ -1210,6 +1225,7 @@ vpaes_ecb_encrypt: ldp d10,d11,[sp],#16 ldp d8,d9,[sp],#16 ldp x29,x30,[sp],#16 + .inst 0xd50323bf // autiasp ret .size vpaes_ecb_encrypt,.-vpaes_ecb_encrypt @@ -1217,6 +1233,7 @@ vpaes_ecb_encrypt: .type vpaes_ecb_decrypt,%function .align 4 vpaes_ecb_decrypt: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-16]! add x29,sp,#0 stp d8,d9,[sp,#-16]! // ABI spec says so @@ -1250,6 +1267,7 @@ vpaes_ecb_decrypt: ldp d10,d11,[sp],#16 ldp d8,d9,[sp],#16 ldp x29,x30,[sp],#16 + .inst 0xd50323bf // autiasp ret .size vpaes_ecb_decrypt,.-vpaes_ecb_decrypt ___ diff --git a/crypto/aes/asm/vpaes-x86_64.pl b/crypto/aes/asm/vpaes-x86_64.pl index 1a95ac20..d3040031 100644 --- a/crypto/aes/asm/vpaes-x86_64.pl +++ b/crypto/aes/asm/vpaes-x86_64.pl @@ -91,6 +91,7 @@ $code.=<<___; .type _vpaes_encrypt_core,\@abi-omnipotent .align 16 _vpaes_encrypt_core: +.cfi_startproc mov %rdx, %r9 mov \$16, %r11 mov 240(%rdx),%eax @@ -171,6 +172,7 @@ _vpaes_encrypt_core: pxor %xmm4, %xmm0 # 0 = A pshufb %xmm1, %xmm0 ret +.cfi_endproc .size _vpaes_encrypt_core,.-_vpaes_encrypt_core ## @@ -181,6 +183,7 @@ _vpaes_encrypt_core: .type _vpaes_decrypt_core,\@abi-omnipotent .align 16 _vpaes_decrypt_core: +.cfi_startproc mov %rdx, %r9 # load key mov 240(%rdx),%eax movdqa %xmm9, %xmm1 @@ -277,6 +280,7 @@ _vpaes_decrypt_core: pxor %xmm4, %xmm0 # 0 = A pshufb %xmm2, %xmm0 ret +.cfi_endproc .size _vpaes_decrypt_core,.-_vpaes_decrypt_core ######################################################## @@ -287,6 +291,7 @@ _vpaes_decrypt_core: .type _vpaes_schedule_core,\@abi-omnipotent .align 16 _vpaes_schedule_core: +.cfi_startproc # rdi = key # rsi = size in bits # rdx = buffer @@ -453,6 +458,7 @@ _vpaes_schedule_core: pxor %xmm6, %xmm6 pxor %xmm7, %xmm7 ret +.cfi_endproc .size _vpaes_schedule_core,.-_vpaes_schedule_core ## @@ -472,6 +478,7 @@ _vpaes_schedule_core: .type _vpaes_schedule_192_smear,\@abi-omnipotent .align 16 _vpaes_schedule_192_smear: +.cfi_startproc pshufd \$0x80, %xmm6, %xmm1 # d c 0 0 -> c 0 0 0 pshufd \$0xFE, %xmm7, %xmm0 # b a _ _ -> b b b a pxor %xmm1, %xmm6 # -> c+d c 0 0 @@ -480,6 +487,7 @@ _vpaes_schedule_192_smear: movdqa %xmm6, %xmm0 movhlps %xmm1, %xmm6 # clobber low side with zeros ret +.cfi_endproc .size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear ## @@ -503,6 +511,7 @@ _vpaes_schedule_192_smear: .type _vpaes_schedule_round,\@abi-omnipotent .align 16 _vpaes_schedule_round: +.cfi_startproc # extract rcon from xmm8 pxor %xmm1, %xmm1 palignr \$15, %xmm8, %xmm1 @@ -556,6 +565,7 @@ _vpaes_schedule_low_round: pxor %xmm7, %xmm0 movdqa %xmm0, %xmm7 ret +.cfi_endproc .size _vpaes_schedule_round,.-_vpaes_schedule_round ## @@ -570,6 +580,7 @@ _vpaes_schedule_low_round: .type _vpaes_schedule_transform,\@abi-omnipotent .align 16 _vpaes_schedule_transform: +.cfi_startproc movdqa %xmm9, %xmm1 pandn %xmm0, %xmm1 psrld \$4, %xmm1 @@ -580,6 +591,7 @@ _vpaes_schedule_transform: pshufb %xmm1, %xmm0 pxor %xmm2, %xmm0 ret +.cfi_endproc .size _vpaes_schedule_transform,.-_vpaes_schedule_transform ## @@ -608,6 +620,7 @@ _vpaes_schedule_transform: .type _vpaes_schedule_mangle,\@abi-omnipotent .align 16 _vpaes_schedule_mangle: +.cfi_startproc movdqa %xmm0, %xmm4 # save xmm0 for later movdqa .Lk_mc_forward(%rip),%xmm5 test %rcx, %rcx @@ -672,6 +685,7 @@ _vpaes_schedule_mangle: and \$0x30, %r8 movdqu %xmm3, (%rdx) ret +.cfi_endproc .size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle # @@ -681,6 +695,7 @@ _vpaes_schedule_mangle: .type ${PREFIX}_set_encrypt_key,\@function,3 .align 16 ${PREFIX}_set_encrypt_key: +.cfi_startproc ___ $code.=<<___ if ($win64); lea -0xb8(%rsp),%rsp @@ -723,12 +738,14 @@ ___ $code.=<<___; xor %eax,%eax ret +.cfi_endproc .size ${PREFIX}_set_encrypt_key,.-${PREFIX}_set_encrypt_key .globl ${PREFIX}_set_decrypt_key .type ${PREFIX}_set_decrypt_key,\@function,3 .align 16 ${PREFIX}_set_decrypt_key: +.cfi_startproc ___ $code.=<<___ if ($win64); lea -0xb8(%rsp),%rsp @@ -776,12 +793,14 @@ ___ $code.=<<___; xor %eax,%eax ret +.cfi_endproc .size ${PREFIX}_set_decrypt_key,.-${PREFIX}_set_decrypt_key .globl ${PREFIX}_encrypt .type ${PREFIX}_encrypt,\@function,3 .align 16 ${PREFIX}_encrypt: +.cfi_startproc ___ $code.=<<___ if ($win64); lea -0xb8(%rsp),%rsp @@ -819,12 +838,14 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .size ${PREFIX}_encrypt,.-${PREFIX}_encrypt .globl ${PREFIX}_decrypt .type ${PREFIX}_decrypt,\@function,3 .align 16 ${PREFIX}_decrypt: +.cfi_startproc ___ $code.=<<___ if ($win64); lea -0xb8(%rsp),%rsp @@ -862,6 +883,7 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .size ${PREFIX}_decrypt,.-${PREFIX}_decrypt ___ { @@ -874,6 +896,7 @@ $code.=<<___; .type ${PREFIX}_cbc_encrypt,\@function,6 .align 16 ${PREFIX}_cbc_encrypt: +.cfi_startproc xchg $key,$len ___ ($len,$key)=($key,$len); @@ -944,6 +967,7 @@ ___ $code.=<<___; .Lcbc_abort: ret +.cfi_endproc .size ${PREFIX}_cbc_encrypt,.-${PREFIX}_cbc_encrypt ___ } @@ -957,6 +981,7 @@ $code.=<<___; .type _vpaes_preheat,\@abi-omnipotent .align 16 _vpaes_preheat: +.cfi_startproc lea .Lk_s0F(%rip), %r10 movdqa -0x20(%r10), %xmm10 # .Lk_inv movdqa -0x10(%r10), %xmm11 # .Lk_inv+16 @@ -966,6 +991,7 @@ _vpaes_preheat: movdqa 0x50(%r10), %xmm15 # .Lk_sb2 movdqa 0x60(%r10), %xmm14 # .Lk_sb2+16 ret +.cfi_endproc .size _vpaes_preheat,.-_vpaes_preheat ######################################################## ## ## diff --git a/crypto/armv4cpuid.pl b/crypto/armv4cpuid.pl index 3a7be6e5..f8aeec64 100644 --- a/crypto/armv4cpuid.pl +++ b/crypto/armv4cpuid.pl @@ -21,7 +21,6 @@ open OUT,"| \"$^X\" $xlate $flavour $output"; $code.=<<___; #include "arm_arch.h" -.text #if defined(__thumb2__) && !defined(__APPLE__) .syntax unified .thumb @@ -30,6 +29,8 @@ $code.=<<___; #undef __thumb2__ #endif +.text + .align 5 .global OPENSSL_atomic_add .type OPENSSL_atomic_add,%function diff --git a/crypto/bio/bss_file.c b/crypto/bio/bss_file.c index a2b8700f..93ba0069 100644 --- a/crypto/bio/bss_file.c +++ b/crypto/bio/bss_file.c @@ -253,9 +253,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) } # elif defined(OPENSSL_SYS_WIN32_CYGWIN) int fd = fileno((FILE *)ptr); - if (num & BIO_FP_TEXT) - setmode(fd, O_TEXT); - else + if (!(num & BIO_FP_TEXT)) setmode(fd, O_BINARY); # endif } @@ -279,11 +277,14 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) ret = 0; break; } -# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32_CYGWIN) +# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) if (!(num & BIO_FP_TEXT)) OPENSSL_strlcat(p, "b", sizeof(p)); else OPENSSL_strlcat(p, "t", sizeof(p)); +# elif defined(OPENSSL_SYS_WIN32_CYGWIN) + if (!(num & BIO_FP_TEXT)) + OPENSSL_strlcat(p, "b", sizeof(p)); # endif fp = openssl_fopen(ptr, p); if (fp == NULL) { diff --git a/crypto/bn/asm/armv4-gf2m.pl b/crypto/bn/asm/armv4-gf2m.pl index 442ae469..0bf6f63e 100644 --- a/crypto/bn/asm/armv4-gf2m.pl +++ b/crypto/bn/asm/armv4-gf2m.pl @@ -57,13 +57,14 @@ if ($flavour && $flavour ne "void") { $code=<<___; #include "arm_arch.h" -.text #if defined(__thumb2__) .syntax unified .thumb #else .code 32 #endif + +.text ___ ################ # private interface to mul_1x1_ialu @@ -176,11 +177,13 @@ bn_GF2m_mul_2x2: #if __ARM_MAX_ARCH__>=7 stmdb sp!,{r10,lr} ldr r12,.LOPENSSL_armcap +# if !defined(_WIN32) adr r10,.LOPENSSL_armcap ldr r12,[r12,r10] -#ifdef __APPLE__ +# endif +# if defined(__APPLE__) || defined(_WIN32) ldr r12,[r12] -#endif +# endif tst r12,#ARMV7_NEON itt ne ldrne r10,[sp],#8 @@ -310,7 +313,11 @@ $code.=<<___; #if __ARM_MAX_ARCH__>=7 .align 5 .LOPENSSL_armcap: +# ifdef _WIN32 +.word OPENSSL_armcap_P +# else .word OPENSSL_armcap_P-. +# endif #endif .asciz "GF(2^m) Multiplication for ARMv4/NEON, CRYPTOGAMS by " .align 5 diff --git a/crypto/bn/asm/armv4-mont.pl b/crypto/bn/asm/armv4-mont.pl index b4f6c066..7e0a4d81 100644 --- a/crypto/bn/asm/armv4-mont.pl +++ b/crypto/bn/asm/armv4-mont.pl @@ -97,7 +97,6 @@ $_num="$num,#15*4"; $_bpend=$_num; $code=<<___; #include "arm_arch.h" -.text #if defined(__thumb2__) .syntax unified .thumb @@ -105,10 +104,16 @@ $code=<<___; .code 32 #endif +.text + #if __ARM_MAX_ARCH__>=7 .align 5 .LOPENSSL_armcap: +# ifdef _WIN32 +.word OPENSSL_armcap_P +# else .word OPENSSL_armcap_P-.Lbn_mul_mont +# endif #endif .global bn_mul_mont @@ -122,12 +127,14 @@ bn_mul_mont: #if __ARM_MAX_ARCH__>=7 tst ip,#7 bne .Lialu - adr r0,.Lbn_mul_mont - ldr r2,.LOPENSSL_armcap + ldr r0,.LOPENSSL_armcap +#if !defined(_WIN32) + adr r2,.Lbn_mul_mont ldr r0,[r0,r2] -#ifdef __APPLE__ +# endif +# if defined(__APPLE__) || defined(_WIN32) ldr r0,[r0] -#endif +# endif tst r0,#ARMV7_NEON @ NEON available? ldmia sp, {r0,r2} beq .Lialu diff --git a/crypto/bn/asm/armv8-mont.pl b/crypto/bn/asm/armv8-mont.pl index 9a8ff6b9..c755555d 100755 --- a/crypto/bn/asm/armv8-mont.pl +++ b/crypto/bn/asm/armv8-mont.pl @@ -197,7 +197,7 @@ bn_mul_mont: mul $nlo,$nj,$m1 // np[j]*m1 adds $lo1,$lo1,$lo0 umulh $nhi,$nj,$m1 - str $lo1,[$tp,#-16] // tp[j-1] + stur $lo1,[$tp,#-16] // tp[j-1] cbnz $j,.Linner .Linner_skip: @@ -253,13 +253,13 @@ bn_mul_mont: csel $nj,$tj,$aj,lo // did it borrow? ldr $tj,[$tp],#8 ldr $aj,[$rp],#8 - str xzr,[$tp,#-16] // wipe tp - str $nj,[$rp,#-16] + stur xzr,[$tp,#-16] // wipe tp + stur $nj,[$rp,#-16] cbnz $num,.Lcond_copy csel $nj,$tj,$aj,lo - str xzr,[$tp,#-8] // wipe tp - str $nj,[$rp,#-8] + stur xzr,[$tp,#-8] // wipe tp + stur $nj,[$rp,#-8] ldp x19,x20,[x29,#16] mov sp,x29 @@ -287,6 +287,7 @@ __bn_sqr8x_mont: cmp $ap,$bp b.ne __bn_mul4x_mont .Lsqr8x_mont: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-128]! add x29,sp,#0 stp x19,x20,[sp,#16] @@ -595,7 +596,7 @@ __bn_sqr8x_mont: ldp $a4,$a5,[$tp,#8*4] ldp $a6,$a7,[$tp,#8*6] adds $acc0,$acc0,$a0 - ldr $n0,[$rp,#-8*8] + ldur $n0,[$rp,#-8*8] adcs $acc1,$acc1,$a1 ldp $a0,$a1,[$ap,#8*0] adcs $acc2,$acc2,$a2 @@ -793,7 +794,7 @@ $code.=<<___; //adc $carry,xzr,xzr // moved below cbz $cnt,.Lsqr8x8_post_condition - ldr $n0,[$tp,#-8*8] + ldur $n0,[$tp,#-8*8] ldp $a0,$a1,[$np,#8*0] ldp $a2,$a3,[$np,#8*2] ldp $a4,$a5,[$np,#8*4] @@ -851,7 +852,7 @@ $code.=<<___; ldp $a6,$a7,[$tp,#8*6] cbz $cnt,.Lsqr8x_tail_break - ldr $n0,[$rp,#-8*8] + ldur $n0,[$rp,#-8*8] adds $acc0,$acc0,$a0 adcs $acc1,$acc1,$a1 ldp $a0,$a1,[$np,#8*0] @@ -1040,6 +1041,7 @@ $code.=<<___; ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldr x29,[sp],#128 + .inst 0xd50323bf // autiasp ret .size __bn_sqr8x_mont,.-__bn_sqr8x_mont ___ @@ -1063,6 +1065,7 @@ $code.=<<___; .type __bn_mul4x_mont,%function .align 5 __bn_mul4x_mont: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-128]! add x29,sp,#0 stp x19,x20,[sp,#16] @@ -1496,6 +1499,7 @@ __bn_mul4x_mont: ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldr x29,[sp],#128 + .inst 0xd50323bf // autiasp ret .size __bn_mul4x_mont,.-__bn_mul4x_mont ___ diff --git a/crypto/bn/asm/rsaz-avx2.pl b/crypto/bn/asm/rsaz-avx2.pl index 9e6ec3a1..fddb12ff 100755 --- a/crypto/bn/asm/rsaz-avx2.pl +++ b/crypto/bn/asm/rsaz-avx2.pl @@ -1492,6 +1492,7 @@ $code.=<<___; .type rsaz_1024_red2norm_avx2,\@abi-omnipotent .align 32 rsaz_1024_red2norm_avx2: +.cfi_startproc sub \$-128,$inp # size optimization xor %rax,%rax ___ @@ -1525,12 +1526,14 @@ ___ } $code.=<<___; ret +.cfi_endproc .size rsaz_1024_red2norm_avx2,.-rsaz_1024_red2norm_avx2 .globl rsaz_1024_norm2red_avx2 .type rsaz_1024_norm2red_avx2,\@abi-omnipotent .align 32 rsaz_1024_norm2red_avx2: +.cfi_startproc sub \$-128,$out # size optimization mov ($inp),@T[0] mov \$0x1fffffff,%eax @@ -1562,6 +1565,7 @@ $code.=<<___; mov @T[0],`8*($j+2)-128`($out) mov @T[0],`8*($j+3)-128`($out) ret +.cfi_endproc .size rsaz_1024_norm2red_avx2,.-rsaz_1024_norm2red_avx2 ___ } @@ -1573,6 +1577,7 @@ $code.=<<___; .type rsaz_1024_scatter5_avx2,\@abi-omnipotent .align 32 rsaz_1024_scatter5_avx2: +.cfi_startproc vzeroupper vmovdqu .Lscatter_permd(%rip),%ymm5 shl \$4,$power @@ -1592,6 +1597,7 @@ rsaz_1024_scatter5_avx2: vzeroupper ret +.cfi_endproc .size rsaz_1024_scatter5_avx2,.-rsaz_1024_scatter5_avx2 .globl rsaz_1024_gather5_avx2 diff --git a/crypto/bn/asm/x86_64-mont5.pl b/crypto/bn/asm/x86_64-mont5.pl index 8fa233ca..6331566c 100755 --- a/crypto/bn/asm/x86_64-mont5.pl +++ b/crypto/bn/asm/x86_64-mont5.pl @@ -2910,6 +2910,7 @@ bn_powerx5: .align 32 bn_sqrx8x_internal: __bn_sqrx8x_internal: +.cfi_startproc ################################################################## # Squaring part: # @@ -3542,6 +3543,7 @@ __bn_sqrx8x_reduction: cmp 8+8(%rsp),%r8 # end of t[]? jb .Lsqrx8x_reduction_loop ret +.cfi_endproc .size bn_sqrx8x_internal,.-bn_sqrx8x_internal ___ } diff --git a/crypto/bn/bn_ctx.c b/crypto/bn/bn_ctx.c index 5106878d..d6e7605b 100644 --- a/crypto/bn/bn_ctx.c +++ b/crypto/bn/bn_ctx.c @@ -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 @@ -227,6 +227,8 @@ BIGNUM *BN_CTX_get(BN_CTX *ctx) } /* OK, make sure the returned bignum is "zero" */ BN_zero(ret); + /* clear BN_FLG_CONSTTIME if leaked from previous frames */ + ret->flags &= (~BN_FLG_CONSTTIME); ctx->used++; CTXDBG_RET(ctx, ret); return ret; diff --git a/crypto/build.info b/crypto/build.info index 5e879ea9..94ed06e6 100644 --- a/crypto/build.info +++ b/crypto/build.info @@ -1,7 +1,7 @@ # Note that these directories are filtered in Configure. Look for %skipdir # there for further explanations. SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 x509v3 conf \ - txt_db pkcs7 pkcs12 ui kdf store \ + txt_db pkcs7 pkcs12 ui kdf store property \ md2 md4 md5 sha mdc2 gmac hmac ripemd whrlpool poly1305 blake2 \ siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \ seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \ @@ -12,8 +12,8 @@ SOURCE[../libcrypto]=\ cryptlib.c mem.c mem_dbg.c cversion.c ex_data.c cpt_err.c \ ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fopen.c ctype.c \ threads_pthread.c threads_win.c threads_none.c getenv.c \ - o_init.c o_fips.c mem_sec.c init.c {- $target{cpuid_asm_src} -} \ - {- $target{uplink_aux_src} -} + o_init.c o_fips.c mem_sec.c init.c context.c sparse_array.c \ + {- $target{cpuid_asm_src} -} {- $target{uplink_aux_src} -} DEPEND[cversion.o]=buildinf.h GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(CC) $(LIB_CFLAGS) $(CPPFLAGS_Q)" "$(PLATFORM)" diff --git a/crypto/chacha/asm/chacha-armv4.pl b/crypto/chacha/asm/chacha-armv4.pl index 9bbfc6b3..c4402961 100755 --- a/crypto/chacha/asm/chacha-armv4.pl +++ b/crypto/chacha/asm/chacha-armv4.pl @@ -171,7 +171,6 @@ my @ret; $code.=<<___; #include "arm_arch.h" -.text #if defined(__thumb2__) || defined(__clang__) .syntax unified #endif @@ -185,6 +184,8 @@ $code.=<<___; #define ldrhsb ldrbhs #endif +.text + .align 5 .Lsigma: .long 0x61707865,0x3320646e,0x79622d32,0x6b206574 @ endian-neutral @@ -192,7 +193,11 @@ $code.=<<___; .long 1,0,0,0 #if __ARM_MAX_ARCH__>=7 .LOPENSSL_armcap: +# ifdef _WIN32 +.word OPENSSL_armcap_P +# else .word OPENSSL_armcap_P-.LChaCha20_ctr32 +# endif #else .word -1 #endif @@ -219,8 +224,10 @@ ChaCha20_ctr32: cmp r2,#192 @ test len bls .Lshort ldr r4,[r14,#-32] +# if !defined(_WIN32) ldr r4,[r14,r4] -# ifdef __APPLE__ +# endif +# if defined(__APPLE__) || defined(_WIN32) ldr r4,[r4] # endif tst r4,#ARMV7_NEON diff --git a/crypto/chacha/asm/chacha-armv8.pl b/crypto/chacha/asm/chacha-armv8.pl index 20cd7070..56ba1c36 100755 --- a/crypto/chacha/asm/chacha-armv8.pl +++ b/crypto/chacha/asm/chacha-armv8.pl @@ -131,12 +131,6 @@ $code.=<<___; .quad 0x3320646e61707865,0x6b20657479622d32 // endian-neutral .Lone: .long 1,0,0,0 -.LOPENSSL_armcap_P: -#ifdef __ILP32__ -.long OPENSSL_armcap_P-. -#else -.quad OPENSSL_armcap_P-. -#endif .asciz "ChaCha20 for ARMv8, CRYPTOGAMS by " .globl ChaCha20_ctr32 @@ -144,19 +138,16 @@ $code.=<<___; .align 5 ChaCha20_ctr32: cbz $len,.Labort - adr @x[0],.LOPENSSL_armcap_P cmp $len,#192 b.lo .Lshort -#ifdef __ILP32__ - ldrsw @x[1],[@x[0]] -#else - ldr @x[1],[@x[0]] -#endif - ldr w17,[@x[1],@x[0]] + + adrp x17,OPENSSL_armcap_P + ldr w17,[x17,#:lo12:OPENSSL_armcap_P] tst w17,#ARMV7_NEON - b.ne ChaCha20_neon + b.ne .LChaCha20_neon .Lshort: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-96]! add x29,sp,#0 @@ -276,6 +267,7 @@ $code.=<<___; ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldp x29,x30,[sp],#96 + .inst 0xd50323bf // autiasp .Labort: ret @@ -332,6 +324,7 @@ $code.=<<___; ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldp x29,x30,[sp],#96 + .inst 0xd50323bf // autiasp ret .size ChaCha20_ctr32,.-ChaCha20_ctr32 ___ @@ -377,6 +370,8 @@ $code.=<<___; .type ChaCha20_neon,%function .align 5 ChaCha20_neon: +.LChaCha20_neon: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-96]! add x29,sp,#0 @@ -575,6 +570,7 @@ $code.=<<___; ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldp x29,x30,[sp],#96 + .inst 0xd50323bf // autiasp ret .Ltail_neon: @@ -684,6 +680,7 @@ $code.=<<___; ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldp x29,x30,[sp],#96 + .inst 0xd50323bf // autiasp ret .size ChaCha20_neon,.-ChaCha20_neon ___ @@ -696,6 +693,7 @@ $code.=<<___; .type ChaCha20_512_neon,%function .align 5 ChaCha20_512_neon: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-96]! add x29,sp,#0 @@ -1114,6 +1112,7 @@ $code.=<<___; ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldp x29,x30,[sp],#96 + .inst 0xd50323bf // autiasp ret .size ChaCha20_512_neon,.-ChaCha20_512_neon ___ diff --git a/crypto/chacha/asm/chacha-s390x.pl b/crypto/chacha/asm/chacha-s390x.pl index 005c810e..abf7283d 100755 --- a/crypto/chacha/asm/chacha-s390x.pl +++ b/crypto/chacha/asm/chacha-s390x.pl @@ -225,7 +225,7 @@ LABEL ("ChaCha20_ctr32"); larl ("%r1","OPENSSL_s390xcap_P"); lghi ("%r0",64); -&{$z? \&cgr:\&cr} ($len,"%r0"); +&{$z? \&clgr:\&clr} ($len,"%r0"); jle ("_s390x_chacha_novx"); lg ("%r0","S390X_STFLE+16(%r1)"); diff --git a/crypto/cms/cms_kari.c b/crypto/cms/cms_kari.c index 4ee7017c..9f1f5d55 100644 --- a/crypto/cms/cms_kari.c +++ b/crypto/cms/cms_kari.c @@ -282,7 +282,7 @@ static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari, return rv; } -/* Initialise a ktri based on passed certificate and key */ +/* Initialise a kari based on passed certificate and key */ int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *pk, unsigned int flags) @@ -299,6 +299,9 @@ int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, kari->version = 3; rek = M_ASN1_new_of(CMS_RecipientEncryptedKey); + if (rek == NULL) + return 0; + if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) { M_ASN1_free_of(rek, CMS_RecipientEncryptedKey); return 0; diff --git a/crypto/context.c b/crypto/context.c new file mode 100644 index 00000000..752711b9 --- /dev/null +++ b/crypto/context.c @@ -0,0 +1,110 @@ +/* + * 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 "internal/cryptlib.h" +#include "internal/thread_once.h" + +struct openssl_ctx_st { + CRYPTO_RWLOCK *lock; + CRYPTO_EX_DATA data; +}; + +static OPENSSL_CTX default_context; + +static int context_init(OPENSSL_CTX *ctx) +{ + return (ctx->lock = CRYPTO_THREAD_lock_new()) != NULL + && CRYPTO_new_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL, + &ctx->data); +} + +static int context_deinit(OPENSSL_CTX *ctx) +{ + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL, &ctx->data); + CRYPTO_THREAD_lock_free(ctx->lock); + return 1; +} + +static CRYPTO_ONCE default_context_init = CRYPTO_ONCE_STATIC_INIT; +static void do_default_context_deinit(void) +{ + context_deinit(&default_context); +} +DEFINE_RUN_ONCE_STATIC(do_default_context_init) +{ + return OPENSSL_init_crypto(0, NULL) + && context_init(&default_context) + && OPENSSL_atexit(do_default_context_deinit); +} + +OPENSSL_CTX *OPENSSL_CTX_new(void) +{ + OPENSSL_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + + if (ctx != NULL && !context_init(ctx)) { + OPENSSL_CTX_free(ctx); + ctx = NULL; + } + return ctx; +} + +void OPENSSL_CTX_free(OPENSSL_CTX *ctx) +{ + if (ctx != NULL) + context_deinit(ctx); + OPENSSL_free(ctx); +} + +static void openssl_ctx_generic_new(void *parent_ign, void *ptr_ign, + CRYPTO_EX_DATA *ad, int index, + long argl_ign, void *argp) +{ + const OPENSSL_CTX_METHOD *meth = argp; + void *ptr = meth->new_func(); + + if (ptr != NULL) + CRYPTO_set_ex_data(ad, index, ptr); +} +static void openssl_ctx_generic_free(void *parent_ign, void *ptr, + CRYPTO_EX_DATA *ad, int index, + long argl_ign, void *argp) +{ + const OPENSSL_CTX_METHOD *meth = argp; + + meth->free_func(ptr); +} +int openssl_ctx_new_index(const OPENSSL_CTX_METHOD *meth) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_OPENSSL_CTX, 0, (void *)meth, + openssl_ctx_generic_new, NULL, + openssl_ctx_generic_free); +} + +void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index) +{ + void *data = NULL; + + if (ctx == NULL) { + if (!RUN_ONCE(&default_context_init, do_default_context_init)) + return 0; + ctx = &default_context; + } + + CRYPTO_THREAD_read_lock(ctx->lock); + + /* The alloc call ensures there's a value there */ + if (CRYPTO_alloc_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL, + &ctx->data, index)) + data = CRYPTO_get_ex_data(&ctx->data, index); + + CRYPTO_THREAD_unlock(ctx->lock); + + return data; +} + diff --git a/crypto/ec/asm/ecp_nistz256-armv4.pl b/crypto/ec/asm/ecp_nistz256-armv4.pl index 4005a6fb..43a675b4 100755 --- a/crypto/ec/asm/ecp_nistz256-armv4.pl +++ b/crypto/ec/asm/ecp_nistz256-armv4.pl @@ -51,7 +51,6 @@ if ($flavour && $flavour ne "void") { $code.=<<___; #include "arm_arch.h" -.text #if defined(__thumb2__) .syntax unified .thumb @@ -80,6 +79,7 @@ close TABLE; die "insane number of elements" if ($#arr != 64*16*37-1); $code.=<<___; +.rodata .globl ecp_nistz256_precomputed .type ecp_nistz256_precomputed,%object .align 12 @@ -104,6 +104,8 @@ for(1..37) { } $code.=<<___; .size ecp_nistz256_precomputed,.-ecp_nistz256_precomputed + +.text .align 5 .LRR: @ 2^512 mod P precomputed for NIST P256 polynomial .long 0x00000003, 0x00000000, 0xffffffff, 0xfffffffb diff --git a/crypto/ec/asm/ecp_nistz256-armv8.pl b/crypto/ec/asm/ecp_nistz256-armv8.pl index 87364e86..8914f1a6 100644 --- a/crypto/ec/asm/ecp_nistz256-armv8.pl +++ b/crypto/ec/asm/ecp_nistz256-armv8.pl @@ -119,6 +119,7 @@ $code.=<<___; .type ecp_nistz256_to_mont,%function .align 6 ecp_nistz256_to_mont: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-32]! add x29,sp,#0 stp x19,x20,[sp,#16] @@ -134,6 +135,7 @@ ecp_nistz256_to_mont: ldp x19,x20,[sp,#16] ldp x29,x30,[sp],#32 + .inst 0xd50323bf // autiasp ret .size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont @@ -142,6 +144,7 @@ ecp_nistz256_to_mont: .type ecp_nistz256_from_mont,%function .align 4 ecp_nistz256_from_mont: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-32]! add x29,sp,#0 stp x19,x20,[sp,#16] @@ -157,6 +160,7 @@ ecp_nistz256_from_mont: ldp x19,x20,[sp,#16] ldp x29,x30,[sp],#32 + .inst 0xd50323bf // autiasp ret .size ecp_nistz256_from_mont,.-ecp_nistz256_from_mont @@ -166,6 +170,7 @@ ecp_nistz256_from_mont: .type ecp_nistz256_mul_mont,%function .align 4 ecp_nistz256_mul_mont: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-32]! add x29,sp,#0 stp x19,x20,[sp,#16] @@ -180,6 +185,7 @@ ecp_nistz256_mul_mont: ldp x19,x20,[sp,#16] ldp x29,x30,[sp],#32 + .inst 0xd50323bf // autiasp ret .size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont @@ -188,6 +194,7 @@ ecp_nistz256_mul_mont: .type ecp_nistz256_sqr_mont,%function .align 4 ecp_nistz256_sqr_mont: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-32]! add x29,sp,#0 stp x19,x20,[sp,#16] @@ -201,6 +208,7 @@ ecp_nistz256_sqr_mont: ldp x19,x20,[sp,#16] ldp x29,x30,[sp],#32 + .inst 0xd50323bf // autiasp ret .size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont @@ -210,6 +218,7 @@ ecp_nistz256_sqr_mont: .type ecp_nistz256_add,%function .align 4 ecp_nistz256_add: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-16]! add x29,sp,#0 @@ -223,6 +232,7 @@ ecp_nistz256_add: bl __ecp_nistz256_add ldp x29,x30,[sp],#16 + .inst 0xd50323bf // autiasp ret .size ecp_nistz256_add,.-ecp_nistz256_add @@ -231,6 +241,7 @@ ecp_nistz256_add: .type ecp_nistz256_div_by_2,%function .align 4 ecp_nistz256_div_by_2: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-16]! add x29,sp,#0 @@ -242,6 +253,7 @@ ecp_nistz256_div_by_2: bl __ecp_nistz256_div_by_2 ldp x29,x30,[sp],#16 + .inst 0xd50323bf // autiasp ret .size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2 @@ -250,6 +262,7 @@ ecp_nistz256_div_by_2: .type ecp_nistz256_mul_by_2,%function .align 4 ecp_nistz256_mul_by_2: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-16]! add x29,sp,#0 @@ -265,6 +278,7 @@ ecp_nistz256_mul_by_2: bl __ecp_nistz256_add // ret = a+a // 2*a ldp x29,x30,[sp],#16 + .inst 0xd50323bf // autiasp ret .size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2 @@ -273,6 +287,7 @@ ecp_nistz256_mul_by_2: .type ecp_nistz256_mul_by_3,%function .align 4 ecp_nistz256_mul_by_3: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-16]! add x29,sp,#0 @@ -299,6 +314,7 @@ ecp_nistz256_mul_by_3: bl __ecp_nistz256_add // ret += a // 2*a+a=3*a ldp x29,x30,[sp],#16 + .inst 0xd50323bf // autiasp ret .size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3 @@ -308,6 +324,7 @@ ecp_nistz256_mul_by_3: .type ecp_nistz256_sub,%function .align 4 ecp_nistz256_sub: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-16]! add x29,sp,#0 @@ -319,6 +336,7 @@ ecp_nistz256_sub: bl __ecp_nistz256_sub_from ldp x29,x30,[sp],#16 + .inst 0xd50323bf // autiasp ret .size ecp_nistz256_sub,.-ecp_nistz256_sub @@ -327,6 +345,7 @@ ecp_nistz256_sub: .type ecp_nistz256_neg,%function .align 4 ecp_nistz256_neg: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-16]! add x29,sp,#0 @@ -341,6 +360,7 @@ ecp_nistz256_neg: bl __ecp_nistz256_sub_from ldp x29,x30,[sp],#16 + .inst 0xd50323bf // autiasp ret .size ecp_nistz256_neg,.-ecp_nistz256_neg @@ -701,6 +721,7 @@ $code.=<<___; .type ecp_nistz256_point_double,%function .align 5 ecp_nistz256_point_double: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-80]! add x29,sp,#0 stp x19,x20,[sp,#16] @@ -835,6 +856,7 @@ ecp_nistz256_point_double: ldp x19,x20,[x29,#16] ldp x21,x22,[x29,#32] ldp x29,x30,[sp],#80 + .inst 0xd50323bf // autiasp ret .size ecp_nistz256_point_double,.-ecp_nistz256_point_double ___ @@ -857,6 +879,7 @@ $code.=<<___; .type ecp_nistz256_point_add,%function .align 5 ecp_nistz256_point_add: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-80]! add x29,sp,#0 stp x19,x20,[sp,#16] @@ -1094,12 +1117,13 @@ $code.=<<___; stp $acc2,$acc3,[$rp_real,#$i+16] .Ladd_done: - add sp,x29,#0 // destroy frame + add sp,x29,#0 // destroy frame ldp x19,x20,[x29,#16] ldp x21,x22,[x29,#32] ldp x23,x24,[x29,#48] ldp x25,x26,[x29,#64] ldp x29,x30,[sp],#80 + .inst 0xd50323bf // autiasp ret .size ecp_nistz256_point_add,.-ecp_nistz256_point_add ___ @@ -1121,6 +1145,7 @@ $code.=<<___; .type ecp_nistz256_point_add_affine,%function .align 5 ecp_nistz256_point_add_affine: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-80]! add x29,sp,#0 stp x19,x20,[sp,#16] @@ -1309,6 +1334,7 @@ $code.=<<___; ldp x23,x24,[x29,#48] ldp x25,x26,[x29,#64] ldp x29,x30,[sp],#80 + .inst 0xd50323bf // autiasp ret .size ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine ___ @@ -1628,7 +1654,7 @@ ecp_nistz256_scatter_w5: ldp x4,x5,[$inp] // X ldp x6,x7,[$inp,#16] - str w4,[$out,#64*0-4] + stur w4,[$out,#64*0-4] lsr x4,x4,#32 str w5,[$out,#64*1-4] lsr x5,x5,#32 @@ -1644,7 +1670,7 @@ ecp_nistz256_scatter_w5: ldp x4,x5,[$inp,#32] // Y ldp x6,x7,[$inp,#48] - str w4,[$out,#64*0-4] + stur w4,[$out,#64*0-4] lsr x4,x4,#32 str w5,[$out,#64*1-4] lsr x5,x5,#32 @@ -1660,7 +1686,7 @@ ecp_nistz256_scatter_w5: ldp x4,x5,[$inp,#64] // Z ldp x6,x7,[$inp,#80] - str w4,[$out,#64*0-4] + stur w4,[$out,#64*0-4] lsr x4,x4,#32 str w5,[$out,#64*1-4] lsr x5,x5,#32 diff --git a/crypto/ec/asm/ecp_nistz256-x86_64.pl b/crypto/ec/asm/ecp_nistz256-x86_64.pl index 0579f458..a28ee8e9 100755 --- a/crypto/ec/asm/ecp_nistz256-x86_64.pl +++ b/crypto/ec/asm/ecp_nistz256-x86_64.pl @@ -1674,6 +1674,7 @@ $code.=<<___; .type __ecp_nistz256_mul_montq,\@abi-omnipotent .align 32 __ecp_nistz256_mul_montq: +.cfi_startproc ######################################################################## # Multiply a by b[0] mov %rax, $t1 @@ -1885,6 +1886,7 @@ __ecp_nistz256_mul_montq: mov $acc1, 8*3($r_ptr) ret +.cfi_endproc .size __ecp_nistz256_mul_montq,.-__ecp_nistz256_mul_montq ################################################################################ @@ -1968,6 +1970,7 @@ $code.=<<___; .type __ecp_nistz256_sqr_montq,\@abi-omnipotent .align 32 __ecp_nistz256_sqr_montq: +.cfi_startproc mov %rax, $acc5 mulq $acc6 # a[1]*a[0] mov %rax, $acc1 @@ -2125,6 +2128,7 @@ __ecp_nistz256_sqr_montq: mov $acc7, 8*3($r_ptr) ret +.cfi_endproc .size __ecp_nistz256_sqr_montq,.-__ecp_nistz256_sqr_montq ___ @@ -2133,6 +2137,7 @@ $code.=<<___; .type __ecp_nistz256_mul_montx,\@abi-omnipotent .align 32 __ecp_nistz256_mul_montx: +.cfi_startproc ######################################################################## # Multiply by b[0] mulx $acc1, $acc0, $acc1 @@ -2295,11 +2300,13 @@ __ecp_nistz256_mul_montx: mov $acc1, 8*3($r_ptr) ret +.cfi_endproc .size __ecp_nistz256_mul_montx,.-__ecp_nistz256_mul_montx .type __ecp_nistz256_sqr_montx,\@abi-omnipotent .align 32 __ecp_nistz256_sqr_montx: +.cfi_startproc mulx $acc6, $acc1, $acc2 # a[0]*a[1] mulx $acc7, $t0, $acc3 # a[0]*a[2] xor %eax, %eax @@ -2423,6 +2430,7 @@ __ecp_nistz256_sqr_montx: mov $acc7, 8*3($r_ptr) ret +.cfi_endproc .size __ecp_nistz256_sqr_montx,.-__ecp_nistz256_sqr_montx ___ } @@ -2578,6 +2586,7 @@ ecp_nistz256_scatter_w5: .type ecp_nistz256_gather_w5,\@abi-omnipotent .align 32 ecp_nistz256_gather_w5: +.cfi_startproc ___ $code.=<<___ if ($avx>1); mov OPENSSL_ia32cap_P+8(%rip), %eax @@ -2666,6 +2675,7 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .LSEH_end_ecp_nistz256_gather_w5: .size ecp_nistz256_gather_w5,.-ecp_nistz256_gather_w5 @@ -2694,6 +2704,7 @@ ecp_nistz256_scatter_w7: .type ecp_nistz256_gather_w7,\@abi-omnipotent .align 32 ecp_nistz256_gather_w7: +.cfi_startproc ___ $code.=<<___ if ($avx>1); mov OPENSSL_ia32cap_P+8(%rip), %eax @@ -2771,6 +2782,7 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .LSEH_end_ecp_nistz256_gather_w7: .size ecp_nistz256_gather_w7,.-ecp_nistz256_gather_w7 ___ @@ -2787,6 +2799,7 @@ $code.=<<___; .type ecp_nistz256_avx2_gather_w5,\@abi-omnipotent .align 32 ecp_nistz256_avx2_gather_w5: +.cfi_startproc .Lavx2_gather_w5: vzeroupper ___ @@ -2874,6 +2887,7 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .LSEH_end_ecp_nistz256_avx2_gather_w5: .size ecp_nistz256_avx2_gather_w5,.-ecp_nistz256_avx2_gather_w5 ___ @@ -2893,6 +2907,7 @@ $code.=<<___; .type ecp_nistz256_avx2_gather_w7,\@abi-omnipotent .align 32 ecp_nistz256_avx2_gather_w7: +.cfi_startproc .Lavx2_gather_w7: vzeroupper ___ @@ -2995,6 +3010,7 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .LSEH_end_ecp_nistz256_avx2_gather_w7: .size ecp_nistz256_avx2_gather_w7,.-ecp_nistz256_avx2_gather_w7 ___ @@ -3064,6 +3080,7 @@ $code.=<<___; .type __ecp_nistz256_add_toq,\@abi-omnipotent .align 32 __ecp_nistz256_add_toq: +.cfi_startproc xor $t4,$t4 add 8*0($b_ptr), $a0 adc 8*1($b_ptr), $a1 @@ -3091,11 +3108,13 @@ __ecp_nistz256_add_toq: mov $a3, 8*3($r_ptr) ret +.cfi_endproc .size __ecp_nistz256_add_toq,.-__ecp_nistz256_add_toq .type __ecp_nistz256_sub_fromq,\@abi-omnipotent .align 32 __ecp_nistz256_sub_fromq: +.cfi_startproc sub 8*0($b_ptr), $a0 sbb 8*1($b_ptr), $a1 mov $a0, $t0 @@ -3122,11 +3141,13 @@ __ecp_nistz256_sub_fromq: mov $a3, 8*3($r_ptr) ret +.cfi_endproc .size __ecp_nistz256_sub_fromq,.-__ecp_nistz256_sub_fromq .type __ecp_nistz256_subq,\@abi-omnipotent .align 32 __ecp_nistz256_subq: +.cfi_startproc sub $a0, $t0 sbb $a1, $t1 mov $t0, $a0 @@ -3149,11 +3170,13 @@ __ecp_nistz256_subq: cmovnz $t3, $a3 ret +.cfi_endproc .size __ecp_nistz256_subq,.-__ecp_nistz256_subq .type __ecp_nistz256_mul_by_2q,\@abi-omnipotent .align 32 __ecp_nistz256_mul_by_2q: +.cfi_startproc xor $t4, $t4 add $a0, $a0 # a0:a3+a0:a3 adc $a1, $a1 @@ -3181,6 +3204,7 @@ __ecp_nistz256_mul_by_2q: mov $a3, 8*3($r_ptr) ret +.cfi_endproc .size __ecp_nistz256_mul_by_2q,.-__ecp_nistz256_mul_by_2q ___ } @@ -3620,7 +3644,9 @@ $code.=<<___; movq %xmm1, $a_ptr # restore $a_ptr movq %xmm0, $r_ptr # restore $r_ptr add \$`32*(18-5)`, %rsp # difference in frame sizes +.cfi_adjust_cfa_offset `-32*(18-5)` jmp .Lpoint_double_shortcut$x +.cfi_adjust_cfa_offset `32*(18-5)` .align 32 .Ladd_proceed$x: @@ -4156,6 +4182,7 @@ $code.=<<___; .type __ecp_nistz256_add_tox,\@abi-omnipotent .align 32 __ecp_nistz256_add_tox: +.cfi_startproc xor $t4, $t4 adc 8*0($b_ptr), $a0 adc 8*1($b_ptr), $a1 @@ -4184,11 +4211,13 @@ __ecp_nistz256_add_tox: mov $a3, 8*3($r_ptr) ret +.cfi_endproc .size __ecp_nistz256_add_tox,.-__ecp_nistz256_add_tox .type __ecp_nistz256_sub_fromx,\@abi-omnipotent .align 32 __ecp_nistz256_sub_fromx: +.cfi_startproc xor $t4, $t4 sbb 8*0($b_ptr), $a0 sbb 8*1($b_ptr), $a1 @@ -4217,11 +4246,13 @@ __ecp_nistz256_sub_fromx: mov $a3, 8*3($r_ptr) ret +.cfi_endproc .size __ecp_nistz256_sub_fromx,.-__ecp_nistz256_sub_fromx .type __ecp_nistz256_subx,\@abi-omnipotent .align 32 __ecp_nistz256_subx: +.cfi_startproc xor $t4, $t4 sbb $a0, $t0 sbb $a1, $t1 @@ -4246,11 +4277,13 @@ __ecp_nistz256_subx: cmovc $t3, $a3 ret +.cfi_endproc .size __ecp_nistz256_subx,.-__ecp_nistz256_subx .type __ecp_nistz256_mul_by_2x,\@abi-omnipotent .align 32 __ecp_nistz256_mul_by_2x: +.cfi_startproc xor $t4, $t4 adc $a0, $a0 # a0:a3+a0:a3 adc $a1, $a1 @@ -4279,6 +4312,7 @@ __ecp_nistz256_mul_by_2x: mov $a3, 8*3($r_ptr) ret +.cfi_endproc .size __ecp_nistz256_mul_by_2x,.-__ecp_nistz256_mul_by_2x ___ } diff --git a/crypto/ec/ec2_smpl.c b/crypto/ec/ec2_smpl.c index f9d7d086..7bd2a632 100644 --- a/crypto/ec/ec2_smpl.c +++ b/crypto/ec/ec2_smpl.c @@ -810,7 +810,7 @@ int ec_GF2m_simple_ladder_post(const EC_GROUP *group, || !group->meth->field_mul(group, t2, t2, t0, ctx) || !BN_GF2m_add(t1, t2, t1) || !group->meth->field_mul(group, t2, p->X, t0, ctx) - || !BN_GF2m_mod_inv(t2, t2, group->field, ctx) + || !group->meth->field_inv(group, t2, t2, ctx) || !group->meth->field_mul(group, t1, t1, t2, ctx) || !group->meth->field_mul(group, r->X, r->Z, t2, ctx) || !BN_GF2m_add(t2, p->X, r->X) @@ -889,6 +889,21 @@ int ec_GF2m_simple_points_mul(const EC_GROUP *group, EC_POINT *r, return ret; } +/*- + * Computes the multiplicative inverse of a in GF(2^m), storing the result in r. + * If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error. + * SCA hardening is with blinding: BN_GF2m_mod_inv does that. + */ +static int ec_GF2m_simple_field_inv(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, BN_CTX *ctx) +{ + int ret; + + if (!(ret = BN_GF2m_mod_inv(r, a, group->field, ctx))) + ECerr(EC_F_EC_GF2M_SIMPLE_FIELD_INV, EC_R_CANNOT_INVERT); + return ret; +} + const EC_METHOD *EC_GF2m_simple_method(void) { static const EC_METHOD ret = { @@ -929,6 +944,7 @@ const EC_METHOD *EC_GF2m_simple_method(void) ec_GF2m_simple_field_mul, ec_GF2m_simple_field_sqr, ec_GF2m_simple_field_div, + ec_GF2m_simple_field_inv, 0, /* field_encode */ 0, /* field_decode */ 0, /* field_set_to_one */ diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c index 1ede7c2e..b7cf95bd 100644 --- a/crypto/ec/ec_err.c +++ b/crypto/ec/ec_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-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 @@ -66,6 +66,8 @@ static const ERR_STRING_DATA EC_str_functs[] = { "ec_asn1_group2fieldid"}, {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, 0), "ec_GF2m_montgomery_point_multiply"}, + {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_FIELD_INV, 0), + "ec_GF2m_simple_field_inv"}, {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0), "ec_GF2m_simple_group_check_discriminant"}, {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, 0), @@ -90,6 +92,8 @@ static const ERR_STRING_DATA EC_str_functs[] = { "ec_GFp_mont_field_decode"}, {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_ENCODE, 0), "ec_GFp_mont_field_encode"}, + {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_INV, 0), + "ec_GFp_mont_field_inv"}, {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_MUL, 0), "ec_GFp_mont_field_mul"}, {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, 0), @@ -124,6 +128,8 @@ static const ERR_STRING_DATA EC_str_functs[] = { "ec_GFp_nist_group_set_curve"}, {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, 0), "ec_GFp_simple_blind_coordinates"}, + {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_FIELD_INV, 0), + "ec_GFp_simple_field_inv"}, {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0), "ec_GFp_simple_group_check_discriminant"}, {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, 0), @@ -287,6 +293,7 @@ static const ERR_STRING_DATA EC_str_reasons[] = { {ERR_PACK(ERR_LIB_EC, 0, EC_R_BAD_SIGNATURE), "bad signature"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_BUFFER_TOO_SMALL), "buffer too small"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_CANNOT_INVERT), "cannot invert"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_COORDINATES_OUT_OF_RANGE), "coordinates out of range"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH), diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h index 3153e4fa..312b5389 100644 --- a/crypto/ec/ec_lcl.h +++ b/crypto/ec/ec_lcl.h @@ -154,6 +154,13 @@ struct ec_method_st { int (*field_sqr) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); int (*field_div) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *); + /*- + * 'field_inv' computes the multipicative inverse of a in the field, + * storing the result in r. + * + * If 'a' is zero (or equivalent), you'll get an EC_R_CANNOT_INVERT error. + */ + int (*field_inv) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. to Montgomery */ int (*field_encode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); @@ -390,6 +397,8 @@ int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *); int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); +int ec_GFp_simple_field_inv(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx); int ec_GFp_simple_ladder_pre(const EC_GROUP *group, @@ -413,6 +422,8 @@ int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *); int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); +int ec_GFp_mont_field_inv(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index c14d1a11..2623b537 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -364,6 +364,11 @@ int EC_GROUP_get_curve_name(const EC_GROUP *group) return group->curve_name; } +const BIGNUM *EC_GROUP_get0_field(const EC_GROUP *group) +{ + return group->field; +} + void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) { group->asn1_flag = flag; diff --git a/crypto/ec/ecp_mont.c b/crypto/ec/ecp_mont.c index d3d770d2..1654d595 100644 --- a/crypto/ec/ecp_mont.c +++ b/crypto/ec/ecp_mont.c @@ -50,6 +50,7 @@ const EC_METHOD *EC_GFp_mont_method(void) ec_GFp_mont_field_mul, ec_GFp_mont_field_sqr, 0 /* field_div */ , + ec_GFp_mont_field_inv, ec_GFp_mont_field_encode, ec_GFp_mont_field_decode, ec_GFp_mont_field_set_to_one, @@ -206,6 +207,54 @@ int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx); } +/*- + * Computes the multiplicative inverse of a in GF(p), storing the result in r. + * If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error. + * We have a Mont structure, so SCA hardening is FLT inversion. + */ +int ec_GFp_mont_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) +{ + BIGNUM *e = NULL; + BN_CTX *new_ctx = NULL; + int ret = 0; + + if (group->field_data1 == NULL) + return 0; + + if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) + return 0; + + BN_CTX_start(ctx); + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + + /* Inverse in constant time with Fermats Little Theorem */ + if (!BN_set_word(e, 2)) + goto err; + if (!BN_sub(e, group->field, e)) + goto err; + /*- + * Exponent e is public. + * No need for scatter-gather or BN_FLG_CONSTTIME. + */ + if (!BN_mod_exp_mont(r, a, e, group->field, ctx, group->field_data1)) + goto err; + + /* throw an error on zero */ + if (BN_is_zero(r)) { + ECerr(EC_F_EC_GFP_MONT_FIELD_INV, EC_R_CANNOT_INVERT); + goto err; + } + + ret = 1; + + err: + BN_CTX_end(ctx); + BN_CTX_free(new_ctx); + return ret; +} + int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) { diff --git a/crypto/ec/ecp_nist.c b/crypto/ec/ecp_nist.c index 151e8ad7..9f9045b5 100644 --- a/crypto/ec/ecp_nist.c +++ b/crypto/ec/ecp_nist.c @@ -52,6 +52,7 @@ const EC_METHOD *EC_GFp_nist_method(void) ec_GFp_nist_field_mul, ec_GFp_nist_field_sqr, 0 /* field_div */ , + ec_GFp_simple_field_inv, 0 /* field_encode */ , 0 /* field_decode */ , 0, /* field_set_to_one */ diff --git a/crypto/ec/ecp_nistp224.c b/crypto/ec/ecp_nistp224.c index cd8b8c42..65396595 100644 --- a/crypto/ec/ecp_nistp224.c +++ b/crypto/ec/ecp_nistp224.c @@ -279,6 +279,7 @@ const EC_METHOD *EC_GFp_nistp224_method(void) ec_GFp_nist_field_mul, ec_GFp_nist_field_sqr, 0 /* field_div */ , + ec_GFp_simple_field_inv, 0 /* field_encode */ , 0 /* field_decode */ , 0, /* field_set_to_one */ diff --git a/crypto/ec/ecp_nistp256.c b/crypto/ec/ecp_nistp256.c index 3c609769..ee5508fa 100644 --- a/crypto/ec/ecp_nistp256.c +++ b/crypto/ec/ecp_nistp256.c @@ -1810,6 +1810,7 @@ const EC_METHOD *EC_GFp_nistp256_method(void) ec_GFp_nist_field_mul, ec_GFp_nist_field_sqr, 0 /* field_div */ , + ec_GFp_simple_field_inv, 0 /* field_encode */ , 0 /* field_decode */ , 0, /* field_set_to_one */ diff --git a/crypto/ec/ecp_nistp521.c b/crypto/ec/ecp_nistp521.c index 653b8663..a32f3023 100644 --- a/crypto/ec/ecp_nistp521.c +++ b/crypto/ec/ecp_nistp521.c @@ -1647,6 +1647,7 @@ const EC_METHOD *EC_GFp_nistp521_method(void) ec_GFp_nist_field_mul, ec_GFp_nist_field_sqr, 0 /* field_div */ , + ec_GFp_simple_field_inv, 0 /* field_encode */ , 0 /* field_decode */ , 0, /* field_set_to_one */ diff --git a/crypto/ec/ecp_nistz256.c b/crypto/ec/ecp_nistz256.c index 82affd6e..c0772ca2 100644 --- a/crypto/ec/ecp_nistz256.c +++ b/crypto/ec/ecp_nistz256.c @@ -1677,6 +1677,7 @@ const EC_METHOD *EC_GFp_nistz256_method(void) ec_GFp_mont_field_mul, ec_GFp_mont_field_sqr, 0, /* field_div */ + ec_GFp_mont_field_inv, ec_GFp_mont_field_encode, ec_GFp_mont_field_decode, ec_GFp_mont_field_set_to_one, diff --git a/crypto/ec/ecp_smpl.c b/crypto/ec/ecp_smpl.c index 7e8fe4fb..f80f98a1 100644 --- a/crypto/ec/ecp_smpl.c +++ b/crypto/ec/ecp_smpl.c @@ -51,6 +51,7 @@ const EC_METHOD *EC_GFp_simple_method(void) ec_GFp_simple_field_mul, ec_GFp_simple_field_sqr, 0 /* field_div */ , + ec_GFp_simple_field_inv, 0 /* field_encode */ , 0 /* field_decode */ , 0, /* field_set_to_one */ @@ -553,7 +554,7 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, } } } else { - if (!BN_mod_inverse(Z_1, Z_, group->field, ctx)) { + if (!group->meth->field_inv(group, Z_1, Z_, ctx)) { ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB); goto err; @@ -1266,7 +1267,7 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, * points[i]->Z by its inverse. */ - if (!BN_mod_inverse(tmp, prod_Z[num - 1], group->field, ctx)) { + if (!group->meth->field_inv(group, tmp, prod_Z[num - 1], ctx)) { ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB); goto err; } @@ -1369,6 +1370,50 @@ int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, return BN_mod_sqr(r, a, group->field, ctx); } +/*- + * Computes the multiplicative inverse of a in GF(p), storing the result in r. + * If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error. + * Since we don't have a Mont structure here, SCA hardening is with blinding. + */ +int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) +{ + BIGNUM *e = NULL; + BN_CTX *new_ctx = NULL; + int ret = 0; + + if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) + return 0; + + BN_CTX_start(ctx); + if ((e = BN_CTX_get(ctx)) == NULL) + goto err; + + do { + if (!BN_priv_rand_range(e, group->field)) + goto err; + } while (BN_is_zero(e)); + + /* r := a * e */ + if (!group->meth->field_mul(group, r, a, e, ctx)) + goto err; + /* r := 1/(a * e) */ + if (!BN_mod_inverse(r, r, group->field, ctx)) { + ECerr(EC_F_EC_GFP_SIMPLE_FIELD_INV, EC_R_CANNOT_INVERT); + goto err; + } + /* r := e/(a * e) = 1/a */ + if (!group->meth->field_mul(group, r, r, e, ctx)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + BN_CTX_free(new_ctx); + return ret; +} + /*- * Apply randomization of EC point projective coordinates: * diff --git a/crypto/engine/build.info b/crypto/engine/build.info index e00802a3..47fe9489 100644 --- a/crypto/engine/build.info +++ b/crypto/engine/build.info @@ -6,6 +6,3 @@ SOURCE[../../libcrypto]=\ tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c tb_eckey.c \ eng_openssl.c eng_cnf.c eng_dyn.c \ eng_rdrand.c -IF[{- !$disabled{devcryptoeng} -}] - SOURCE[../../libcrypto]=eng_devcrypto.c -ENDIF diff --git a/crypto/err/err_all.c b/crypto/err/err_all.c index 3911ecc5..4bf020c2 100644 --- a/crypto/err/err_all.c +++ b/crypto/err/err_all.c @@ -39,6 +39,7 @@ #include #include #include +#include "internal/propertyerr.h" int err_load_crypto_strings_int(void) { @@ -96,7 +97,8 @@ int err_load_crypto_strings_int(void) ERR_load_ASYNC_strings() == 0 || #endif ERR_load_KDF_strings() == 0 || - ERR_load_OSSL_STORE_strings() == 0) + ERR_load_OSSL_STORE_strings() == 0 || + ERR_load_PROP_strings() == 0) return 0; return 1; diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec index 94d46d06..901a847d 100644 --- a/crypto/err/openssl.ec +++ b/crypto/err/openssl.ec @@ -35,6 +35,7 @@ L KDF include/openssl/kdf.h crypto/kdf/kdf_err.c L SM2 crypto/include/internal/sm2.h crypto/sm2/sm2_err.c L OSSL_STORE include/openssl/store.h crypto/store/store_err.c L ESS include/openssl/ess.h crypto/ess/ess_err.c +L PROP include/internal/property.h crypto/property/property_err.c # additional header files to be scanned for function names L NONE include/openssl/x509_vfy.h NONE diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index ca2309d7..82c33f02 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -521,6 +521,7 @@ EC_F_ECX_PUB_ENCODE:268:ecx_pub_encode EC_F_EC_ASN1_GROUP2CURVE:153:ec_asn1_group2curve EC_F_EC_ASN1_GROUP2FIELDID:154:ec_asn1_group2fieldid EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY:208:ec_GF2m_montgomery_point_multiply +EC_F_EC_GF2M_SIMPLE_FIELD_INV:296:ec_GF2m_simple_field_inv EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT:159:\ ec_GF2m_simple_group_check_discriminant EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE:195:ec_GF2m_simple_group_set_curve @@ -537,6 +538,7 @@ EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES:164:\ ec_GF2m_simple_set_compressed_coordinates EC_F_EC_GFP_MONT_FIELD_DECODE:133:ec_GFp_mont_field_decode EC_F_EC_GFP_MONT_FIELD_ENCODE:134:ec_GFp_mont_field_encode +EC_F_EC_GFP_MONT_FIELD_INV:297:ec_GFp_mont_field_inv EC_F_EC_GFP_MONT_FIELD_MUL:131:ec_GFp_mont_field_mul EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE:209:ec_GFp_mont_field_set_to_one EC_F_EC_GFP_MONT_FIELD_SQR:132:ec_GFp_mont_field_sqr @@ -557,6 +559,7 @@ EC_F_EC_GFP_NIST_FIELD_MUL:200:ec_GFp_nist_field_mul EC_F_EC_GFP_NIST_FIELD_SQR:201:ec_GFp_nist_field_sqr EC_F_EC_GFP_NIST_GROUP_SET_CURVE:202:ec_GFp_nist_group_set_curve EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES:287:ec_GFp_simple_blind_coordinates +EC_F_EC_GFP_SIMPLE_FIELD_INV:298:ec_GFp_simple_field_inv EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT:165:\ ec_GFp_simple_group_check_discriminant EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE:166:ec_GFp_simple_group_set_curve @@ -753,6 +756,9 @@ EVP_F_EVP_DIGESTINIT_EX:128:EVP_DigestInit_ex EVP_F_EVP_ENCRYPTDECRYPTUPDATE:219:evp_EncryptDecryptUpdate EVP_F_EVP_ENCRYPTFINAL_EX:127:EVP_EncryptFinal_ex EVP_F_EVP_ENCRYPTUPDATE:167:EVP_EncryptUpdate +EVP_F_EVP_KDF_CTRL:224:EVP_KDF_ctrl +EVP_F_EVP_KDF_CTRL_STR:225:EVP_KDF_ctrl_str +EVP_F_EVP_KDF_CTX_NEW_ID:226:EVP_KDF_CTX_new_id EVP_F_EVP_MAC_CTRL:209:EVP_MAC_ctrl EVP_F_EVP_MAC_CTRL_STR:210:EVP_MAC_ctrl_str EVP_F_EVP_MAC_CTX_COPY:211:EVP_MAC_CTX_copy @@ -823,6 +829,7 @@ EVP_F_PKCS5_PBE_KEYIVGEN:117:PKCS5_PBE_keyivgen EVP_F_PKCS5_V2_PBE_KEYIVGEN:118:PKCS5_v2_PBE_keyivgen EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN:164:PKCS5_v2_PBKDF2_keyivgen EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN:180:PKCS5_v2_scrypt_keyivgen +EVP_F_PKEY_KDF_CTRL:227:pkey_kdf_ctrl EVP_F_PKEY_MAC_INIT:214:pkey_mac_init EVP_F_PKEY_SET_TYPE:158:pkey_set_type EVP_F_POLY1305_CTRL:216:poly1305_ctrl @@ -830,7 +837,25 @@ EVP_F_RC2_MAGIC_TO_METH:109:rc2_magic_to_meth EVP_F_RC5_CTRL:125:rc5_ctrl EVP_F_S390X_AES_GCM_CTRL:201:s390x_aes_gcm_ctrl EVP_F_S390X_AES_GCM_TLS_CIPHER:208:s390x_aes_gcm_tls_cipher +EVP_F_SCRYPT_ALG:228:scrypt_alg EVP_F_UPDATE:173:update +KDF_F_HKDF_EXTRACT:112:HKDF_Extract +KDF_F_KDF_HKDF_DERIVE:113:kdf_hkdf_derive +KDF_F_KDF_HKDF_NEW:114:kdf_hkdf_new +KDF_F_KDF_HKDF_SIZE:115:kdf_hkdf_size +KDF_F_KDF_MD2CTRL:116:kdf_md2ctrl +KDF_F_KDF_PBKDF2_CTRL_STR:117:kdf_pbkdf2_ctrl_str +KDF_F_KDF_PBKDF2_DERIVE:118:kdf_pbkdf2_derive +KDF_F_KDF_PBKDF2_NEW:119:kdf_pbkdf2_new +KDF_F_KDF_SCRYPT_CTRL_STR:120:kdf_scrypt_ctrl_str +KDF_F_KDF_SCRYPT_CTRL_UINT32:121:kdf_scrypt_ctrl_uint32 +KDF_F_KDF_SCRYPT_CTRL_UINT64:122:kdf_scrypt_ctrl_uint64 +KDF_F_KDF_SCRYPT_DERIVE:123:kdf_scrypt_derive +KDF_F_KDF_SCRYPT_NEW:124:kdf_scrypt_new +KDF_F_KDF_TLS1_PRF_CTRL_STR:125:kdf_tls1_prf_ctrl_str +KDF_F_KDF_TLS1_PRF_DERIVE:126:kdf_tls1_prf_derive +KDF_F_KDF_TLS1_PRF_NEW:127:kdf_tls1_prf_new +KDF_F_PBKDF2_SET_MEMBUF:128:pbkdf2_set_membuf KDF_F_PKEY_HKDF_CTRL_STR:103:pkey_hkdf_ctrl_str KDF_F_PKEY_HKDF_DERIVE:102:pkey_hkdf_derive KDF_F_PKEY_HKDF_INIT:108:pkey_hkdf_init @@ -842,6 +867,7 @@ KDF_F_PKEY_SCRYPT_SET_MEMBUF:107:pkey_scrypt_set_membuf 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_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 @@ -1018,6 +1044,14 @@ PKCS7_F_PKCS7_SIGNER_INFO_SIGN:139:PKCS7_SIGNER_INFO_sign PKCS7_F_PKCS7_SIGN_ADD_SIGNER:137:PKCS7_sign_add_signer PKCS7_F_PKCS7_SIMPLE_SMIMECAP:119:PKCS7_simple_smimecap PKCS7_F_PKCS7_VERIFY:117:PKCS7_verify +PROP_F_OSSL_PARSE_PROPERTY:100:ossl_parse_property +PROP_F_OSSL_PARSE_QUERY:101:ossl_parse_query +PROP_F_PARSE_HEX:102:parse_hex +PROP_F_PARSE_NAME:103:parse_name +PROP_F_PARSE_NUMBER:104:parse_number +PROP_F_PARSE_OCT:105:parse_oct +PROP_F_PARSE_STRING:106:parse_string +PROP_F_PARSE_UNQUOTED:107:parse_unquoted RAND_F_DRBG_BYTES:101:drbg_bytes RAND_F_DRBG_GET_ENTROPY:105:drbg_get_entropy RAND_F_DRBG_SETUP:117:drbg_setup @@ -2134,6 +2168,7 @@ EC_R_ASN1_ERROR:115:asn1 error EC_R_BAD_SIGNATURE:156:bad signature EC_R_BIGNUM_OUT_OF_RANGE:144:bignum out of range EC_R_BUFFER_TOO_SMALL:100:buffer too small +EC_R_CANNOT_INVERT:165:cannot invert EC_R_COORDINATES_OUT_OF_RANGE:146:coordinates out of range EC_R_CURVE_DOES_NOT_SUPPORT_ECDH:160:curve does not support ecdh EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING:159:curve does not support signing @@ -2284,6 +2319,7 @@ EVP_R_ONLY_ONESHOT_SUPPORTED:177:only oneshot supported EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:150:\ operation not supported for this keytype EVP_R_OPERATON_NOT_INITIALIZED:151:operaton not initialized +EVP_R_PARAMETER_TOO_LARGE:187:parameter too large EVP_R_PARTIALLY_OVERLAPPING:162:partially overlapping buffers EVP_R_PBKDF2_ERROR:181:pbkdf2 error EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED:179:\ @@ -2320,6 +2356,7 @@ KDF_R_MISSING_SEED:106:missing seed KDF_R_UNKNOWN_PARAMETER_TYPE:103:unknown parameter 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 OBJ_R_OID_EXISTS:102:oid exists OBJ_R_UNKNOWN_NID:101:unknown nid OCSP_R_CERTIFICATE_VERIFY_ERROR:101:certificate verify error @@ -2468,6 +2505,17 @@ PKCS7_R_UNSUPPORTED_CIPHER_TYPE:111:unsupported cipher type PKCS7_R_UNSUPPORTED_CONTENT_TYPE:112:unsupported content type PKCS7_R_WRONG_CONTENT_TYPE:113:wrong content type PKCS7_R_WRONG_PKCS7_TYPE:114:wrong pkcs7 type +PROP_R_NAME_TOO_LONG:100:name too long +PROP_R_NOT_AN_ASCII_CHARACTER:101:not an ascii character +PROP_R_NOT_AN_HEXADECIMAL_DIGIT:102:not an hexadecimal digit +PROP_R_NOT_AN_IDENTIFIER:103:not an identifier +PROP_R_NOT_AN_OCTAL_DIGIT:104:not an octal digit +PROP_R_NOT_A_DECIMAL_DIGIT:105:not a decimal digit +PROP_R_NO_MATCHING_STRING_DELIMETER:106:no matching string delimeter +PROP_R_NO_VALUE:107:no value +PROP_R_PARSE_FAILED:108:parse failed +PROP_R_STRING_TOO_LONG:109:string too long +PROP_R_TRAILING_CHARACTERS:110:trailing characters RAND_R_ADDITIONAL_INPUT_TOO_LONG:102:additional input too long RAND_R_ALREADY_INSTANTIATED:103:already instantiated RAND_R_ARGUMENT_OUT_OF_RANGE:105:argument out of range @@ -2748,8 +2796,8 @@ SSL_R_MISSING_SRP_PARAM:358:can't find SRP server param SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION:209:missing supported groups extension SSL_R_MISSING_TMP_DH_KEY:171:missing tmp dh key SSL_R_MISSING_TMP_ECDH_KEY:311:missing tmp ecdh key -SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS:293:mixed special operator with groups -SSL_R_NESTED_GROUP:294:nested group +SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA:293:\ + mixed handshake and non handshake data SSL_R_NOT_ON_RECORD_BOUNDARY:182:not on record boundary SSL_R_NOT_REPLACING_CERTIFICATE:289:not replacing certificate SSL_R_NOT_SERVER:284:not server @@ -2858,9 +2906,7 @@ SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES:242:unable to load ssl3 md5 routines SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES:243:unable to load ssl3 sha1 routines SSL_R_UNEXPECTED_CCS_MESSAGE:262:unexpected ccs message SSL_R_UNEXPECTED_END_OF_EARLY_DATA:178:unexpected end of early data -SSL_R_UNEXPECTED_GROUP_CLOSE:295:unexpected group close SSL_R_UNEXPECTED_MESSAGE:244:unexpected message -SSL_R_UNEXPECTED_OPERATOR_IN_GROUP:296:unexpected operator in group SSL_R_UNEXPECTED_RECORD:245:unexpected record SSL_R_UNINITIALIZED:276:uninitialized SSL_R_UNKNOWN_ALERT_TYPE:246:unknown alert type diff --git a/crypto/evp/build.info b/crypto/evp/build.info index 84193b09..862afa83 100644 --- a/crypto/evp/build.info +++ b/crypto/evp/build.info @@ -9,7 +9,8 @@ SOURCE[../../libcrypto]=\ p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \ bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \ c_allc.c c_alld.c evp_lib.c bio_ok.c \ - evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \ + evp_pkey.c kdf_lib.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \ + pkey_kdf.c \ e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \ e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \ e_chacha20_poly1305.c cmeth_lib.c \ diff --git a/crypto/evp/e_chacha20_poly1305.c b/crypto/evp/e_chacha20_poly1305.c index 5a3516d6..9b1b36f8 100644 --- a/crypto/evp/e_chacha20_poly1305.c +++ b/crypto/evp/e_chacha20_poly1305.c @@ -14,8 +14,8 @@ # include # include -# include "evp_locl.h" # include "internal/evp_int.h" +# include "evp_locl.h" # include "internal/chacha.h" typedef struct { diff --git a/crypto/evp/encode.c b/crypto/evp/encode.c index 5a54a9fe..3519e3b1 100644 --- a/crypto/evp/encode.c +++ b/crypto/evp/encode.c @@ -11,8 +11,8 @@ #include #include "internal/cryptlib.h" #include -#include "evp_locl.h" #include "internal/evp_int.h" +#include "evp_locl.h" static unsigned char conv_ascii2bin(unsigned char a, const unsigned char *table); diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index a4dd97b5..ef889b0a 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-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 @@ -60,6 +60,9 @@ static const ERR_STRING_DATA EVP_str_functs[] = { {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, 0), "EVP_EncryptFinal_ex"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTUPDATE, 0), "EVP_EncryptUpdate"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTRL, 0), "EVP_KDF_ctrl"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTRL_STR, 0), "EVP_KDF_ctrl_str"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTX_NEW_ID, 0), "EVP_KDF_CTX_new_id"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTRL, 0), "EVP_MAC_ctrl"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTRL_STR, 0), "EVP_MAC_ctrl_str"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTX_COPY, 0), "EVP_MAC_CTX_copy"}, @@ -159,6 +162,7 @@ static const ERR_STRING_DATA EVP_str_functs[] = { "PKCS5_v2_PBKDF2_keyivgen"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, 0), "PKCS5_v2_scrypt_keyivgen"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_KDF_CTRL, 0), "pkey_kdf_ctrl"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_MAC_INIT, 0), "pkey_mac_init"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_SET_TYPE, 0), "pkey_set_type"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_POLY1305_CTRL, 0), "poly1305_ctrl"}, @@ -167,6 +171,7 @@ static const ERR_STRING_DATA EVP_str_functs[] = { {ERR_PACK(ERR_LIB_EVP, EVP_F_S390X_AES_GCM_CTRL, 0), "s390x_aes_gcm_ctrl"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_S390X_AES_GCM_TLS_CIPHER, 0), "s390x_aes_gcm_tls_cipher"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_SCRYPT_ALG, 0), "scrypt_alg"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_UPDATE, 0), "update"}, {0, NULL} }; @@ -254,6 +259,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { "operation not supported for this keytype"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARAMETER_TOO_LARGE), + "parameter too large"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARTIALLY_OVERLAPPING), "partially overlapping buffers"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PBKDF2_ERROR), "pbkdf2 error"}, diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h index fe690673..95a9d5c5 100644 --- a/crypto/evp/evp_locl.h +++ b/crypto/evp/evp_locl.h @@ -46,6 +46,11 @@ struct evp_mac_ctx_st { void *data; /* Individual method data */ } /* EVP_MAC_CTX */; +struct evp_kdf_ctx_st { + const EVP_KDF_METHOD *kmeth; + EVP_KDF_IMPL *impl; /* Algorithm-specific data */ +} /* EVP_KDF_CTX */ ; + int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md, diff --git a/crypto/evp/evp_pbe.c b/crypto/evp/evp_pbe.c index eb099ab4..8162a5e4 100644 --- a/crypto/evp/evp_pbe.c +++ b/crypto/evp/evp_pbe.c @@ -12,6 +12,7 @@ #include #include #include +#include "internal/evp_int.h" #include "evp_locl.h" /* Password based encryption (PBE) functions */ diff --git a/crypto/evp/kdf_lib.c b/crypto/evp/kdf_lib.c new file mode 100644 index 00000000..05f5cec3 --- /dev/null +++ b/crypto/evp/kdf_lib.c @@ -0,0 +1,165 @@ +/* + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2018, 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 + */ + +#include +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include +#include "internal/asn1_int.h" +#include "internal/evp_int.h" +#include "internal/numbers.h" +#include "evp_locl.h" + +typedef int sk_cmp_fn_type(const char *const *a, const char *const *b); + +/* This array needs to be in order of NIDs */ +static const EVP_KDF_METHOD *standard_methods[] = { + &pbkdf2_kdf_meth, +#ifndef OPENSSL_NO_SCRYPT + &scrypt_kdf_meth, +#endif + &tls1_prf_kdf_meth, + &hkdf_kdf_meth +}; + +DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_KDF_METHOD *, const EVP_KDF_METHOD *, + kmeth); + +static int kmeth_cmp(const EVP_KDF_METHOD *const *a, + const EVP_KDF_METHOD *const *b) +{ + return ((*a)->type - (*b)->type); +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_KDF_METHOD *, const EVP_KDF_METHOD *, + kmeth); + +static const EVP_KDF_METHOD *kdf_meth_find(int type) +{ + EVP_KDF_METHOD tmp; + const EVP_KDF_METHOD *t = &tmp, **ret; + + tmp.type = type; + ret = OBJ_bsearch_kmeth(&t, standard_methods, + OSSL_NELEM(standard_methods)); + if (ret == NULL || *ret == NULL) + return NULL; + + return *ret; +} + +EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id) +{ + EVP_KDF_CTX *ret; + const EVP_KDF_METHOD *kmeth; + + kmeth = kdf_meth_find(id); + if (kmeth == NULL) { + EVPerr(EVP_F_EVP_KDF_CTX_NEW_ID, EVP_R_UNSUPPORTED_ALGORITHM); + return NULL; + } + + ret = OPENSSL_zalloc(sizeof(*ret)); + if (ret == NULL) { + EVPerr(EVP_F_EVP_KDF_CTX_NEW_ID, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (kmeth->new != NULL && (ret->impl = kmeth->new()) == NULL) { + EVP_KDF_CTX_free(ret); + return NULL; + } + + ret->kmeth = kmeth; + return ret; +} + +void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx) +{ + if (ctx == NULL) + return; + + ctx->kmeth->free(ctx->impl); + OPENSSL_free(ctx); +} + +void EVP_KDF_reset(EVP_KDF_CTX *ctx) +{ + if (ctx == NULL) + return; + + if (ctx->kmeth->reset != NULL) + ctx->kmeth->reset(ctx->impl); +} + +int EVP_KDF_ctrl(EVP_KDF_CTX *ctx, int cmd, ...) +{ + int ret; + va_list args; + + va_start(args, cmd); + ret = EVP_KDF_vctrl(ctx, cmd, args); + va_end(args); + + if (ret == -2) + EVPerr(EVP_F_EVP_KDF_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); + + return ret; +} + +int EVP_KDF_vctrl(EVP_KDF_CTX *ctx, int cmd, va_list args) +{ + if (ctx == NULL) + return 0; + + return ctx->kmeth->ctrl(ctx->impl, cmd, args); +} + +int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value) +{ + int ret; + + if (ctx == NULL) + return 0; + + if (ctx->kmeth->ctrl_str == NULL) { + EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + + ret = ctx->kmeth->ctrl_str(ctx->impl, type, value); + if (ret == -2) + EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); + + return ret; +} + +size_t EVP_KDF_size(EVP_KDF_CTX *ctx) +{ + if (ctx == NULL) + return 0; + + if (ctx->kmeth->size == NULL) + return SIZE_MAX; + + return ctx->kmeth->size(ctx->impl); +} + +int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen) +{ + if (ctx == NULL) + return 0; + + return ctx->kmeth->derive(ctx->impl, key, keylen); +} + diff --git a/crypto/evp/p5_crpt2.c b/crypto/evp/p5_crpt2.c index a5a15599..4210e516 100644 --- a/crypto/evp/p5_crpt2.c +++ b/crypto/evp/p5_crpt2.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,105 +10,51 @@ #include #include #include "internal/cryptlib.h" -# include -# include -# include -# include "evp_locl.h" +#include +#include +#include +#include +#include "internal/evp_int.h" +#include "evp_locl.h" /* set this to print out info about the keygen algorithm */ /* #define OPENSSL_DEBUG_PKCS5V2 */ -# ifdef OPENSSL_DEBUG_PKCS5V2 +#ifdef OPENSSL_DEBUG_PKCS5V2 static void h__dump(const unsigned char *p, int len); -# endif - -/* - * This is an implementation of PKCS#5 v2.0 password based encryption key - * derivation function PBKDF2. SHA1 version verified against test vectors - * posted by Peter Gutmann to the PKCS-TNG mailing list. - */ +#endif int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, const EVP_MD *digest, int keylen, unsigned char *out) { const char *empty = ""; - unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; - int cplen, j, k, tkeylen, mdlen; - unsigned long i = 1; - HMAC_CTX *hctx_tpl = NULL, *hctx = NULL; + int rv = 1; + EVP_KDF_CTX *kctx; - mdlen = EVP_MD_size(digest); - if (mdlen < 0) - return 0; - - hctx_tpl = HMAC_CTX_new(); - if (hctx_tpl == NULL) - return 0; - p = out; - tkeylen = keylen; + /* Keep documented behaviour. */ if (pass == NULL) { pass = empty; passlen = 0; } else if (passlen == -1) { passlen = strlen(pass); } - if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL)) { - HMAC_CTX_free(hctx_tpl); + if (salt == NULL && saltlen == 0) + salt = (unsigned char *)empty; + + kctx = EVP_KDF_CTX_new_id(EVP_KDF_PBKDF2); + if (kctx == NULL) return 0; - } - hctx = HMAC_CTX_new(); - if (hctx == NULL) { - HMAC_CTX_free(hctx_tpl); - return 0; - } - while (tkeylen) { - if (tkeylen > mdlen) - cplen = mdlen; - else - cplen = tkeylen; - /* - * We are unlikely to ever use more than 256 blocks (5120 bits!) but - * just in case... - */ - itmp[0] = (unsigned char)((i >> 24) & 0xff); - itmp[1] = (unsigned char)((i >> 16) & 0xff); - itmp[2] = (unsigned char)((i >> 8) & 0xff); - itmp[3] = (unsigned char)(i & 0xff); - if (!HMAC_CTX_copy(hctx, hctx_tpl)) { - HMAC_CTX_free(hctx); - HMAC_CTX_free(hctx_tpl); - return 0; - } - if (!HMAC_Update(hctx, salt, saltlen) - || !HMAC_Update(hctx, itmp, 4) - || !HMAC_Final(hctx, digtmp, NULL)) { - HMAC_CTX_free(hctx); - HMAC_CTX_free(hctx_tpl); - return 0; - } - memcpy(p, digtmp, cplen); - for (j = 1; j < iter; j++) { - if (!HMAC_CTX_copy(hctx, hctx_tpl)) { - HMAC_CTX_free(hctx); - HMAC_CTX_free(hctx_tpl); - return 0; - } - if (!HMAC_Update(hctx, digtmp, mdlen) - || !HMAC_Final(hctx, digtmp, NULL)) { - HMAC_CTX_free(hctx); - HMAC_CTX_free(hctx_tpl); - return 0; - } - for (k = 0; k < cplen; k++) - p[k] ^= digtmp[k]; - } - tkeylen -= cplen; - i++; - p += cplen; - } - HMAC_CTX_free(hctx); - HMAC_CTX_free(hctx_tpl); + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, pass, (size_t)passlen) != 1 + || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, + salt, (size_t)saltlen) != 1 + || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, iter) != 1 + || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, digest) != 1 + || EVP_KDF_derive(kctx, out, keylen) != 1) + rv = 0; + + EVP_KDF_CTX_free(kctx); + # ifdef OPENSSL_DEBUG_PKCS5V2 fprintf(stderr, "Password:\n"); h__dump(pass, passlen); @@ -118,7 +64,7 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, fprintf(stderr, "Key:\n"); h__dump(out, keylen); # endif - return 1; + return rv; } int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, diff --git a/crypto/evp/pbe_scrypt.c b/crypto/evp/pbe_scrypt.c index 0a394321..72240252 100644 --- a/crypto/evp/pbe_scrypt.c +++ b/crypto/evp/pbe_scrypt.c @@ -7,135 +7,12 @@ * https://www.openssl.org/source/license.html */ -#include -#include -#include #include #include -#include "internal/numbers.h" +#include #ifndef OPENSSL_NO_SCRYPT -#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) -static void salsa208_word_specification(uint32_t inout[16]) -{ - int i; - uint32_t x[16]; - memcpy(x, inout, sizeof(x)); - for (i = 8; i > 0; i -= 2) { - x[4] ^= R(x[0] + x[12], 7); - x[8] ^= R(x[4] + x[0], 9); - x[12] ^= R(x[8] + x[4], 13); - x[0] ^= R(x[12] + x[8], 18); - x[9] ^= R(x[5] + x[1], 7); - x[13] ^= R(x[9] + x[5], 9); - x[1] ^= R(x[13] + x[9], 13); - x[5] ^= R(x[1] + x[13], 18); - x[14] ^= R(x[10] + x[6], 7); - x[2] ^= R(x[14] + x[10], 9); - x[6] ^= R(x[2] + x[14], 13); - x[10] ^= R(x[6] + x[2], 18); - x[3] ^= R(x[15] + x[11], 7); - x[7] ^= R(x[3] + x[15], 9); - x[11] ^= R(x[7] + x[3], 13); - x[15] ^= R(x[11] + x[7], 18); - x[1] ^= R(x[0] + x[3], 7); - x[2] ^= R(x[1] + x[0], 9); - x[3] ^= R(x[2] + x[1], 13); - x[0] ^= R(x[3] + x[2], 18); - x[6] ^= R(x[5] + x[4], 7); - x[7] ^= R(x[6] + x[5], 9); - x[4] ^= R(x[7] + x[6], 13); - x[5] ^= R(x[4] + x[7], 18); - x[11] ^= R(x[10] + x[9], 7); - x[8] ^= R(x[11] + x[10], 9); - x[9] ^= R(x[8] + x[11], 13); - x[10] ^= R(x[9] + x[8], 18); - x[12] ^= R(x[15] + x[14], 7); - x[13] ^= R(x[12] + x[15], 9); - x[14] ^= R(x[13] + x[12], 13); - x[15] ^= R(x[14] + x[13], 18); - } - for (i = 0; i < 16; ++i) - inout[i] += x[i]; - OPENSSL_cleanse(x, sizeof(x)); -} - -static void scryptBlockMix(uint32_t *B_, uint32_t *B, uint64_t r) -{ - uint64_t i, j; - uint32_t X[16], *pB; - - memcpy(X, B + (r * 2 - 1) * 16, sizeof(X)); - pB = B; - for (i = 0; i < r * 2; i++) { - for (j = 0; j < 16; j++) - X[j] ^= *pB++; - salsa208_word_specification(X); - memcpy(B_ + (i / 2 + (i & 1) * r) * 16, X, sizeof(X)); - } - OPENSSL_cleanse(X, sizeof(X)); -} - -static void scryptROMix(unsigned char *B, uint64_t r, uint64_t N, - uint32_t *X, uint32_t *T, uint32_t *V) -{ - unsigned char *pB; - uint32_t *pV; - uint64_t i, k; - - /* Convert from little endian input */ - for (pV = V, i = 0, pB = B; i < 32 * r; i++, pV++) { - *pV = *pB++; - *pV |= *pB++ << 8; - *pV |= *pB++ << 16; - *pV |= (uint32_t)*pB++ << 24; - } - - for (i = 1; i < N; i++, pV += 32 * r) - scryptBlockMix(pV, pV - 32 * r, r); - - scryptBlockMix(X, V + (N - 1) * 32 * r, r); - - for (i = 0; i < N; i++) { - uint32_t j; - j = X[16 * (2 * r - 1)] % N; - pV = V + 32 * r * j; - for (k = 0; k < 32 * r; k++) - T[k] = X[k] ^ *pV++; - scryptBlockMix(X, T, r); - } - /* Convert output to little endian */ - for (i = 0, pB = B; i < 32 * r; i++) { - uint32_t xtmp = X[i]; - *pB++ = xtmp & 0xff; - *pB++ = (xtmp >> 8) & 0xff; - *pB++ = (xtmp >> 16) & 0xff; - *pB++ = (xtmp >> 24) & 0xff; - } -} - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t)-1) -#endif - -/* - * Maximum power of two that will fit in uint64_t: this should work on - * most (all?) platforms. - */ - -#define LOG2_UINT64_MAX (sizeof(uint64_t) * 8 - 1) - -/* - * Maximum value of p * r: - * p <= ((2^32-1) * hLen) / MFLen => - * p <= ((2^32-1) * 32) / (128 * r) => - * p * r <= (2^30-1) - * - */ - -#define SCRYPT_PR_MAX ((1 << 30) - 1) - /* * Maximum permitted memory allow this to be overridden with Configuration * option: e.g. -DSCRYPT_MAX_MEM=0 for maximum possible. @@ -160,107 +37,39 @@ int EVP_PBE_scrypt(const char *pass, size_t passlen, uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, unsigned char *key, size_t keylen) { - int rv = 0; - unsigned char *B; - uint32_t *X, *V, *T; - uint64_t i, Blen, Vlen; + const char *empty = ""; + int rv = 1; + EVP_KDF_CTX *kctx; - /* Sanity check parameters */ - /* initial check, r,p must be non zero, N >= 2 and a power of 2 */ - if (r == 0 || p == 0 || N < 2 || (N & (N - 1))) - return 0; - /* Check p * r < SCRYPT_PR_MAX avoiding overflow */ - if (p > SCRYPT_PR_MAX / r) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); + if (r > UINT32_MAX || p > UINT32_MAX) { + EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_PARAMETER_TOO_LARGE); return 0; } - /* - * Need to check N: if 2^(128 * r / 8) overflows limit this is - * automatically satisfied since N <= UINT64_MAX. - */ - - if (16 * r <= LOG2_UINT64_MAX) { - if (N >= (((uint64_t)1) << (16 * r))) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); - return 0; - } + /* Maintain existing behaviour. */ + if (pass == NULL) { + pass = empty; + passlen = 0; } - - /* Memory checks: check total allocated buffer size fits in uint64_t */ - - /* - * B size in section 5 step 1.S - * Note: we know p * 128 * r < UINT64_MAX because we already checked - * p * r < SCRYPT_PR_MAX - */ - Blen = p * 128 * r; - /* - * Yet we pass it as integer to PKCS5_PBKDF2_HMAC... [This would - * have to be revised when/if PKCS5_PBKDF2_HMAC accepts size_t.] - */ - if (Blen > INT_MAX) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); - return 0; - } - - /* - * Check 32 * r * (N + 2) * sizeof(uint32_t) fits in uint64_t - * This is combined size V, X and T (section 4) - */ - i = UINT64_MAX / (32 * sizeof(uint32_t)); - if (N + 2 > i / r) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); - return 0; - } - Vlen = 32 * r * (N + 2) * sizeof(uint32_t); - - /* check total allocated size fits in uint64_t */ - if (Blen > UINT64_MAX - Vlen) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); - return 0; - } - if (maxmem == 0) maxmem = SCRYPT_MAX_MEM; - /* Check that the maximum memory doesn't exceed a size_t limits */ - if (maxmem > SIZE_MAX) - maxmem = SIZE_MAX; - - if (Blen + Vlen > maxmem) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); + kctx = EVP_KDF_CTX_new_id(EVP_KDF_SCRYPT); + if (kctx == NULL) return 0; - } - /* If no key return to indicate parameters are OK */ - if (key == NULL) - return 1; + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, pass, (size_t)passlen) != 1 + || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, + salt, (size_t)saltlen) != 1 + || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_N, N) != 1 + || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_R, (uint32_t)r) != 1 + || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_P, (uint32_t)p) != 1 + || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAXMEM_BYTES, maxmem) != 1 + || EVP_KDF_derive(kctx, key, keylen) != 1) + rv = 0; - B = OPENSSL_malloc((size_t)(Blen + Vlen)); - if (B == NULL) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, ERR_R_MALLOC_FAILURE); - return 0; - } - X = (uint32_t *)(B + Blen); - T = X + 32 * r; - V = T + 32 * r; - if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, EVP_sha256(), - (int)Blen, B) == 0) - goto err; - - for (i = 0; i < p; i++) - scryptROMix(B + 128 * r * i, r, N, X, T, V); - - if (PKCS5_PBKDF2_HMAC(pass, passlen, B, (int)Blen, 1, EVP_sha256(), - keylen, key) == 0) - goto err; - rv = 1; - err: - if (rv == 0) - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_PBKDF2_ERROR); - - OPENSSL_clear_free(B, (size_t)(Blen + Vlen)); + EVP_KDF_CTX_free(kctx); return rv; } + #endif diff --git a/crypto/evp/pkey_kdf.c b/crypto/evp/pkey_kdf.c new file mode 100644 index 00000000..ddb682c1 --- /dev/null +++ b/crypto/evp/pkey_kdf.c @@ -0,0 +1,255 @@ +/* + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2018, 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 + */ + +#include +#include +#include +#include +#include "internal/evp_int.h" + +static int pkey_kdf_init(EVP_PKEY_CTX *ctx) +{ + EVP_KDF_CTX *kctx; + + kctx = EVP_KDF_CTX_new_id(ctx->pmeth->pkey_id); + if (kctx == NULL) + return 0; + + ctx->data = kctx; + return 1; +} + +static void pkey_kdf_cleanup(EVP_PKEY_CTX *ctx) +{ + EVP_KDF_CTX *kctx = ctx->data; + + EVP_KDF_CTX_free(kctx); +} + +static int pkey_kdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + EVP_KDF_CTX *kctx = ctx->data; + uint64_t u64_value; + int cmd; + int ret; + + switch (type) { + case EVP_PKEY_CTRL_PASS: + cmd = EVP_KDF_CTRL_SET_PASS; + break; + case EVP_PKEY_CTRL_HKDF_SALT: + case EVP_PKEY_CTRL_SCRYPT_SALT: + cmd = EVP_KDF_CTRL_SET_SALT; + break; + case EVP_PKEY_CTRL_TLS_MD: + case EVP_PKEY_CTRL_HKDF_MD: + cmd = EVP_KDF_CTRL_SET_MD; + break; + case EVP_PKEY_CTRL_TLS_SECRET: + cmd = EVP_KDF_CTRL_SET_TLS_SECRET; + ret = EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_RESET_TLS_SEED); + if (ret < 1) + return ret; + break; + case EVP_PKEY_CTRL_TLS_SEED: + cmd = EVP_KDF_CTRL_ADD_TLS_SEED; + break; + case EVP_PKEY_CTRL_HKDF_KEY: + cmd = EVP_KDF_CTRL_SET_KEY; + break; + case EVP_PKEY_CTRL_HKDF_INFO: + cmd = EVP_KDF_CTRL_ADD_HKDF_INFO; + break; + case EVP_PKEY_CTRL_HKDF_MODE: + cmd = EVP_KDF_CTRL_SET_HKDF_MODE; + break; + case EVP_PKEY_CTRL_SCRYPT_N: + cmd = EVP_KDF_CTRL_SET_SCRYPT_N; + break; + case EVP_PKEY_CTRL_SCRYPT_R: + cmd = EVP_KDF_CTRL_SET_SCRYPT_R; + break; + case EVP_PKEY_CTRL_SCRYPT_P: + cmd = EVP_KDF_CTRL_SET_SCRYPT_P; + break; + case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES: + cmd = EVP_KDF_CTRL_SET_MAXMEM_BYTES; + break; + default: + return -2; + } + + switch (cmd) { + case EVP_KDF_CTRL_SET_PASS: + case EVP_KDF_CTRL_SET_SALT: + case EVP_KDF_CTRL_SET_KEY: + case EVP_KDF_CTRL_SET_TLS_SECRET: + case EVP_KDF_CTRL_ADD_TLS_SEED: + case EVP_KDF_CTRL_ADD_HKDF_INFO: + return EVP_KDF_ctrl(kctx, cmd, (const unsigned char *)p2, (size_t)p1); + + case EVP_KDF_CTRL_SET_MD: + return EVP_KDF_ctrl(kctx, cmd, (const EVP_MD *)p2); + + case EVP_KDF_CTRL_SET_HKDF_MODE: + return EVP_KDF_ctrl(kctx, cmd, (int)p1); + + case EVP_KDF_CTRL_SET_SCRYPT_R: + case EVP_KDF_CTRL_SET_SCRYPT_P: + u64_value = *(uint64_t *)p2; + if (u64_value > UINT32_MAX) { + EVPerr(EVP_F_PKEY_KDF_CTRL, EVP_R_PARAMETER_TOO_LARGE); + return 0; + } + + return EVP_KDF_ctrl(kctx, cmd, (uint32_t)u64_value); + + case EVP_KDF_CTRL_SET_SCRYPT_N: + case EVP_KDF_CTRL_SET_MAXMEM_BYTES: + return EVP_KDF_ctrl(kctx, cmd, *(uint64_t *)p2); + + default: + return 0; + } +} + +static int pkey_kdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, + const char *value) +{ + EVP_KDF_CTX *kctx = ctx->data; + + if (strcmp(type, "md") == 0) + return EVP_KDF_ctrl_str(kctx, "digest", value); + return EVP_KDF_ctrl_str(kctx, type, value); +} + +static int pkey_kdf_derive_init(EVP_PKEY_CTX *ctx) +{ + EVP_KDF_CTX *kctx = ctx->data; + + EVP_KDF_reset(kctx); + return 1; +} + +/* + * For fixed-output algorithms the keylen parameter is an "out" parameter + * otherwise it is an "in" parameter. + */ +static int pkey_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, + size_t *keylen) +{ + EVP_KDF_CTX *kctx = ctx->data; + size_t outlen = EVP_KDF_size(kctx); + + if (outlen == 0 || outlen == SIZE_MAX) { + /* Variable-output algorithm */ + if (key == NULL) + return 0; + } else { + /* Fixed-output algorithm */ + *keylen = outlen; + if (key == NULL) + return 1; + } + return EVP_KDF_derive(kctx, key, *keylen); +} + +#ifndef OPENSSL_NO_SCRYPT +const EVP_PKEY_METHOD scrypt_pkey_meth = { + EVP_PKEY_SCRYPT, + 0, + pkey_kdf_init, + 0, + pkey_kdf_cleanup, + + 0, 0, + 0, 0, + + 0, + 0, + + 0, + 0, + + 0, 0, + + 0, 0, 0, 0, + + 0, 0, + + 0, 0, + + pkey_kdf_derive_init, + pkey_kdf_derive, + pkey_kdf_ctrl, + pkey_kdf_ctrl_str +}; +#endif + +const EVP_PKEY_METHOD tls1_prf_pkey_meth = { + EVP_PKEY_TLS1_PRF, + 0, + pkey_kdf_init, + 0, + pkey_kdf_cleanup, + + 0, 0, + 0, 0, + + 0, + 0, + + 0, + 0, + + 0, 0, + + 0, 0, 0, 0, + + 0, 0, + + 0, 0, + + pkey_kdf_derive_init, + pkey_kdf_derive, + pkey_kdf_ctrl, + pkey_kdf_ctrl_str +}; + +const EVP_PKEY_METHOD hkdf_pkey_meth = { + EVP_PKEY_HKDF, + 0, + pkey_kdf_init, + 0, + pkey_kdf_cleanup, + + 0, 0, + 0, 0, + + 0, + 0, + + 0, + 0, + + 0, 0, + + 0, 0, 0, 0, + + 0, 0, + + 0, 0, + + pkey_kdf_derive_init, + pkey_kdf_derive, + pkey_kdf_ctrl, + pkey_kdf_ctrl_str +}; + diff --git a/crypto/ex_data.c b/crypto/ex_data.c index 33f43bf2..a728bfbb 100644 --- a/crypto/ex_data.c +++ b/crypto/ex_data.c @@ -362,6 +362,36 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) ad->sk = NULL; } +/* + * Allocate a given CRYPTO_EX_DATA item using the class specific allocation + * function + */ +int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad, + int idx) +{ + EX_CALLBACK *f; + EX_CALLBACKS *ip; + void *curval; + + curval = CRYPTO_get_ex_data(ad, idx); + + /* Already there, no need to allocate */ + if (curval != NULL) + return 1; + + ip = get_and_lock(class_index); + f = sk_EX_CALLBACK_value(ip->meth, idx); + CRYPTO_THREAD_unlock(ex_data_lock); + + /* + * This should end up calling CRYPTO_set_ex_data(), which allocates + * everything necessary to support placing the new data in the right spot. + */ + f->new_func(obj, curval, ad, idx, f->argl, f->argp); + + return 1; +} + /* * For a given CRYPTO_EX_DATA variable, set the value corresponding to a * particular index in the class used by this variable diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h index 189d8aa5..b3dbbe23 100644 --- a/crypto/include/internal/evp_int.h +++ b/crypto/include/internal/evp_int.h @@ -151,6 +151,24 @@ const EVP_MD *evp_keccak_kmac256(void); */ int EVP_add_mac(const EVP_MAC *mac); +/* struct evp_kdf_impl_st is defined by the implementation */ +typedef struct evp_kdf_impl_st EVP_KDF_IMPL; +typedef struct { + int type; + EVP_KDF_IMPL *(*new) (void); + void (*free) (EVP_KDF_IMPL *impl); + void (*reset) (EVP_KDF_IMPL *impl); + int (*ctrl) (EVP_KDF_IMPL *impl, int cmd, va_list args); + int (*ctrl_str) (EVP_KDF_IMPL *impl, const char *type, const char *value); + size_t (*size) (EVP_KDF_IMPL *impl); + int (*derive) (EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen); +} EVP_KDF_METHOD; + +extern const EVP_KDF_METHOD pbkdf2_kdf_meth; +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; + struct evp_md_st { int type; int pkey_type; diff --git a/crypto/include/internal/sparse_array.h b/crypto/include/internal/sparse_array.h new file mode 100644 index 00000000..648e41a2 --- /dev/null +++ b/crypto/include/internal/sparse_array.h @@ -0,0 +1,80 @@ +/* + * 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 + */ + +#ifndef HEADER_SPARSE_ARRAY_H +# define HEADER_SPARSE_ARRAY_H + +# include + +# ifdef __cplusplus +extern "C" { +# endif + +# define SPARSE_ARRAY_OF(type) struct sparse_array_st_ ## type + +# define DEFINE_SPARSE_ARRAY_OF(type) \ + SPARSE_ARRAY_OF(type); \ + static ossl_unused ossl_inline SPARSE_ARRAY_OF(type) * \ + ossl_sa_##type##_new(void) \ + { \ + return (SPARSE_ARRAY_OF(type) *)OPENSSL_SA_new(); \ + } \ + static ossl_unused ossl_inline void ossl_sa_##type##_free(SPARSE_ARRAY_OF(type) *sa) \ + { \ + OPENSSL_SA_free((OPENSSL_SA *)sa); \ + } \ + static ossl_unused ossl_inline void ossl_sa_##type##_free_leaves(SPARSE_ARRAY_OF(type) *sa) \ + { \ + OPENSSL_SA_free_leaves((OPENSSL_SA *)sa); \ + } \ + static ossl_unused ossl_inline size_t ossl_sa_##type##_num(const SPARSE_ARRAY_OF(type) *sa) \ + { \ + return OPENSSL_SA_num((OPENSSL_SA *)sa); \ + } \ + static ossl_unused ossl_inline void ossl_sa_##type##_doall(const SPARSE_ARRAY_OF(type) *sa, \ + void (*leaf)(size_t, type *)) \ + { \ + OPENSSL_SA_doall((OPENSSL_SA *)sa, (void (*)(size_t, void *))leaf); \ + } \ + static ossl_unused ossl_inline \ + void ossl_sa_##type##_doall_arg(const SPARSE_ARRAY_OF(type) *sa, \ + void (*leaf)(size_t, type *, void *), \ + void *arg) \ + { \ + OPENSSL_SA_doall_arg((OPENSSL_SA *)sa, (void (*)(size_t, void *, void *))leaf, \ + arg); \ + } \ + static ossl_unused ossl_inline type *ossl_sa_##type##_get(const SPARSE_ARRAY_OF(type) *sa, \ + size_t n) \ + { \ + return (type *)OPENSSL_SA_get((OPENSSL_SA *)sa, n); \ + } \ + static ossl_unused ossl_inline int ossl_sa_##type##_set(SPARSE_ARRAY_OF(type) *sa, \ + size_t n, type *val) \ + { \ + return OPENSSL_SA_set((OPENSSL_SA *)sa, n, (void *)val); \ + } \ + SPARSE_ARRAY_OF(type) + +typedef struct sparse_array_st OPENSSL_SA; +OPENSSL_SA *OPENSSL_SA_new(void); +void OPENSSL_SA_free(OPENSSL_SA *sa); +void OPENSSL_SA_free_leaves(OPENSSL_SA *sa); +size_t OPENSSL_SA_num(const OPENSSL_SA *sa); +void OPENSSL_SA_doall(const OPENSSL_SA *sa, void (*leaf)(size_t, void *)); +void OPENSSL_SA_doall_arg(const OPENSSL_SA *sa, + void (*leaf)(size_t, void *, void *), void *); +void *OPENSSL_SA_get(const OPENSSL_SA *sa, size_t n); +int OPENSSL_SA_set(OPENSSL_SA *sa, size_t n, void *val); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/crypto/init.c b/crypto/init.c index 22d28a98..ddea63ae 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -353,18 +353,6 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl) engine_load_openssl_int(); return 1; } -# ifndef OPENSSL_NO_DEVCRYPTOENG -static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT; -DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto) -{ -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: " - "engine_load_devcrypto_int()\n"); -# endif - engine_load_devcrypto_int(); - return 1; -} -# endif # ifndef OPENSSL_NO_RDRAND static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT; @@ -389,6 +377,18 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic) return 1; } # ifndef OPENSSL_NO_STATIC_ENGINE +# ifndef OPENSSL_NO_DEVCRYPTOENG +static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT; +DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto) +{ +# ifdef OPENSSL_INIT_DEBUG + fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: " + "engine_load_devcrypto_int()\n"); +# endif + engine_load_devcrypto_int(); + return 1; +} +# endif # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK) static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock) @@ -747,11 +747,6 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) if ((opts & OPENSSL_INIT_ENGINE_OPENSSL) && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl)) return 0; -# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_DEVCRYPTOENG) - if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV) - && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto)) - return 0; -# endif # ifndef OPENSSL_NO_RDRAND if ((opts & OPENSSL_INIT_ENGINE_RDRAND) && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand)) @@ -761,6 +756,11 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic)) return 0; # ifndef OPENSSL_NO_STATIC_ENGINE +# ifndef OPENSSL_NO_DEVCRYPTOENG + if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV) + && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto)) + return 0; +# endif # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK) if ((opts & OPENSSL_INIT_ENGINE_PADLOCK) && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock)) diff --git a/crypto/kdf/build.info b/crypto/kdf/build.info index c166399d..dce960e9 100644 --- a/crypto/kdf/build.info +++ b/crypto/kdf/build.info @@ -1,3 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - tls1_prf.c kdf_err.c hkdf.c scrypt.c + tls1_prf.c kdf_err.c kdf_util.c hkdf.c scrypt.c pbkdf2.c diff --git a/crypto/kdf/hkdf.c b/crypto/kdf/hkdf.c index dc2ead66..5540da35 100644 --- a/crypto/kdf/hkdf.c +++ b/crypto/kdf/hkdf.c @@ -8,32 +8,33 @@ */ #include +#include #include #include -#include #include +#include #include "internal/cryptlib.h" #include "internal/evp_int.h" +#include "kdf_local.h" #define HKDF_MAXBUF 1024 -static unsigned char *HKDF(const EVP_MD *evp_md, - const unsigned char *salt, size_t salt_len, - const unsigned char *key, size_t key_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len); +static void kdf_hkdf_reset(EVP_KDF_IMPL *impl); +static int HKDF(const EVP_MD *evp_md, + const unsigned char *salt, size_t salt_len, + const unsigned char *key, size_t key_len, + const unsigned char *info, size_t info_len, + unsigned char *okm, size_t okm_len); +static int HKDF_Extract(const EVP_MD *evp_md, + const unsigned char *salt, size_t salt_len, + const unsigned char *key, size_t key_len, + unsigned char *prk, size_t prk_len); +static int HKDF_Expand(const EVP_MD *evp_md, + const unsigned char *prk, size_t prk_len, + const unsigned char *info, size_t info_len, + unsigned char *okm, size_t okm_len); -static unsigned char *HKDF_Extract(const EVP_MD *evp_md, - const unsigned char *salt, size_t salt_len, - const unsigned char *key, size_t key_len, - unsigned char *prk, size_t *prk_len); - -static unsigned char *HKDF_Expand(const EVP_MD *evp_md, - const unsigned char *prk, size_t prk_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len); - -typedef struct { +struct evp_kdf_impl_st { int mode; const EVP_MD *md; unsigned char *salt; @@ -42,230 +43,208 @@ typedef struct { size_t key_len; unsigned char info[HKDF_MAXBUF]; size_t info_len; -} HKDF_PKEY_CTX; +}; -static int pkey_hkdf_init(EVP_PKEY_CTX *ctx) +static EVP_KDF_IMPL *kdf_hkdf_new(void) { - HKDF_PKEY_CTX *kctx; + EVP_KDF_IMPL *impl; - if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL) { - KDFerr(KDF_F_PKEY_HKDF_INIT, ERR_R_MALLOC_FAILURE); - return 0; - } - - ctx->data = kctx; - - return 1; + if ((impl = OPENSSL_zalloc(sizeof(*impl))) == NULL) + KDFerr(KDF_F_KDF_HKDF_NEW, ERR_R_MALLOC_FAILURE); + return impl; } -static void pkey_hkdf_cleanup(EVP_PKEY_CTX *ctx) +static void kdf_hkdf_free(EVP_KDF_IMPL *impl) { - HKDF_PKEY_CTX *kctx = ctx->data; - OPENSSL_clear_free(kctx->salt, kctx->salt_len); - OPENSSL_clear_free(kctx->key, kctx->key_len); - OPENSSL_cleanse(kctx->info, kctx->info_len); - OPENSSL_free(kctx); + kdf_hkdf_reset(impl); + OPENSSL_free(impl); } -static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +static void kdf_hkdf_reset(EVP_KDF_IMPL *impl) { - HKDF_PKEY_CTX *kctx = ctx->data; + OPENSSL_free(impl->salt); + OPENSSL_clear_free(impl->key, impl->key_len); + OPENSSL_cleanse(impl->info, impl->info_len); + memset(impl, 0, sizeof(*impl)); +} - switch (type) { - case EVP_PKEY_CTRL_HKDF_MD: - if (p2 == NULL) +static int kdf_hkdf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args) +{ + const unsigned char *p; + size_t len; + const EVP_MD *md; + + switch (cmd) { + case EVP_KDF_CTRL_SET_MD: + md = va_arg(args, const EVP_MD *); + if (md == NULL) return 0; - kctx->md = p2; + impl->md = md; return 1; - case EVP_PKEY_CTRL_HKDF_MODE: - kctx->mode = p1; + case EVP_KDF_CTRL_SET_HKDF_MODE: + impl->mode = va_arg(args, int); return 1; - case EVP_PKEY_CTRL_HKDF_SALT: - if (p1 == 0 || p2 == NULL) + case EVP_KDF_CTRL_SET_SALT: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + if (len == 0 || p == NULL) return 1; - if (p1 < 0) + OPENSSL_free(impl->salt); + impl->salt = OPENSSL_memdup(p, len); + if (impl->salt == NULL) return 0; - if (kctx->salt != NULL) - OPENSSL_clear_free(kctx->salt, kctx->salt_len); - - kctx->salt = OPENSSL_memdup(p2, p1); - if (kctx->salt == NULL) - return 0; - - kctx->salt_len = p1; + impl->salt_len = len; return 1; - case EVP_PKEY_CTRL_HKDF_KEY: - if (p1 < 0) + case EVP_KDF_CTRL_SET_KEY: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + OPENSSL_clear_free(impl->key, impl->key_len); + impl->key = OPENSSL_memdup(p, len); + if (impl->key == NULL) return 0; - if (kctx->key != NULL) - OPENSSL_clear_free(kctx->key, kctx->key_len); - - kctx->key = OPENSSL_memdup(p2, p1); - if (kctx->key == NULL) - return 0; - - kctx->key_len = p1; + impl->key_len = len; return 1; - case EVP_PKEY_CTRL_HKDF_INFO: - if (p1 == 0 || p2 == NULL) + case EVP_KDF_CTRL_RESET_HKDF_INFO: + OPENSSL_cleanse(impl->info, impl->info_len); + impl->info_len = 0; + return 1; + + case EVP_KDF_CTRL_ADD_HKDF_INFO: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + if (len == 0 || p == NULL) return 1; - if (p1 < 0 || p1 > (int)(HKDF_MAXBUF - kctx->info_len)) + if (len > (HKDF_MAXBUF - impl->info_len)) return 0; - memcpy(kctx->info + kctx->info_len, p2, p1); - kctx->info_len += p1; + memcpy(impl->info + impl->info_len, p, len); + impl->info_len += len; return 1; default: return -2; - } } -static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, - const char *value) +static int kdf_hkdf_ctrl_str(EVP_KDF_IMPL *impl, const char *type, + const char *value) { if (strcmp(type, "mode") == 0) { int mode; if (strcmp(value, "EXTRACT_AND_EXPAND") == 0) - mode = EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND; + mode = EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND; else if (strcmp(value, "EXTRACT_ONLY") == 0) - mode = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY; + mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY; else if (strcmp(value, "EXPAND_ONLY") == 0) - mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY; + mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY; else return 0; - return EVP_PKEY_CTX_hkdf_mode(ctx, mode); + return call_ctrl(kdf_hkdf_ctrl, impl, EVP_KDF_CTRL_SET_HKDF_MODE, mode); } - if (strcmp(type, "md") == 0) - return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_DERIVE, - EVP_PKEY_CTRL_HKDF_MD, value); + if (strcmp(type, "digest") == 0) + return kdf_md2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_SET_MD, value); if (strcmp(type, "salt") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value); + return kdf_str2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_SET_SALT, value); if (strcmp(type, "hexsalt") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value); + return kdf_hex2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_SET_SALT, value); if (strcmp(type, "key") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value); + return kdf_str2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_SET_KEY, value); if (strcmp(type, "hexkey") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value); + return kdf_hex2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_SET_KEY, value); if (strcmp(type, "info") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value); + return kdf_str2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_ADD_HKDF_INFO, + value); if (strcmp(type, "hexinfo") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value); + return kdf_hex2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_ADD_HKDF_INFO, + value); - KDFerr(KDF_F_PKEY_HKDF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE); return -2; } -static int pkey_hkdf_derive_init(EVP_PKEY_CTX *ctx) +static size_t kdf_hkdf_size(EVP_KDF_IMPL *impl) { - HKDF_PKEY_CTX *kctx = ctx->data; + if (impl->mode != EVP_KDF_HKDF_MODE_EXTRACT_ONLY) + return SIZE_MAX; - OPENSSL_clear_free(kctx->key, kctx->key_len); - OPENSSL_clear_free(kctx->salt, kctx->salt_len); - OPENSSL_cleanse(kctx->info, kctx->info_len); - memset(kctx, 0, sizeof(*kctx)); - - return 1; + if (impl->md == NULL) { + KDFerr(KDF_F_KDF_HKDF_SIZE, KDF_R_MISSING_MESSAGE_DIGEST); + return 0; + } + return EVP_MD_size(impl->md); } -static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen) +static int kdf_hkdf_derive(EVP_KDF_IMPL *impl, unsigned char *key, + size_t keylen) { - HKDF_PKEY_CTX *kctx = ctx->data; - - if (kctx->md == NULL) { - KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST); + if (impl->md == NULL) { + KDFerr(KDF_F_KDF_HKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST); return 0; } - if (kctx->key == NULL) { - KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_KEY); + if (impl->key == NULL) { + KDFerr(KDF_F_KDF_HKDF_DERIVE, KDF_R_MISSING_KEY); return 0; } - switch (kctx->mode) { - case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND: - return HKDF(kctx->md, kctx->salt, kctx->salt_len, kctx->key, - kctx->key_len, kctx->info, kctx->info_len, key, - *keylen) != NULL; + switch (impl->mode) { + case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND: + return HKDF(impl->md, impl->salt, impl->salt_len, impl->key, + impl->key_len, impl->info, impl->info_len, key, + keylen); - case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY: - if (key == NULL) { - *keylen = EVP_MD_size(kctx->md); - return 1; - } - return HKDF_Extract(kctx->md, kctx->salt, kctx->salt_len, kctx->key, - kctx->key_len, key, keylen) != NULL; + case EVP_KDF_HKDF_MODE_EXTRACT_ONLY: + return HKDF_Extract(impl->md, impl->salt, impl->salt_len, impl->key, + impl->key_len, key, keylen); - case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY: - return HKDF_Expand(kctx->md, kctx->key, kctx->key_len, kctx->info, - kctx->info_len, key, *keylen) != NULL; + case EVP_KDF_HKDF_MODE_EXPAND_ONLY: + return HKDF_Expand(impl->md, impl->key, impl->key_len, impl->info, + impl->info_len, key, keylen); default: return 0; } } -const EVP_PKEY_METHOD hkdf_pkey_meth = { - EVP_PKEY_HKDF, - 0, - pkey_hkdf_init, - 0, - pkey_hkdf_cleanup, - - 0, 0, - 0, 0, - - 0, - 0, - - 0, - 0, - - 0, 0, - - 0, 0, 0, 0, - - 0, 0, - - 0, 0, - - pkey_hkdf_derive_init, - pkey_hkdf_derive, - pkey_hkdf_ctrl, - pkey_hkdf_ctrl_str +const EVP_KDF_METHOD hkdf_kdf_meth = { + EVP_KDF_HKDF, + kdf_hkdf_new, + kdf_hkdf_free, + kdf_hkdf_reset, + kdf_hkdf_ctrl, + kdf_hkdf_ctrl_str, + kdf_hkdf_size, + kdf_hkdf_derive }; -static unsigned char *HKDF(const EVP_MD *evp_md, - const unsigned char *salt, size_t salt_len, - const unsigned char *key, size_t key_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len) +static int HKDF(const EVP_MD *evp_md, + const unsigned char *salt, size_t salt_len, + const unsigned char *key, size_t key_len, + const unsigned char *info, size_t info_len, + unsigned char *okm, size_t okm_len) { unsigned char prk[EVP_MAX_MD_SIZE]; - unsigned char *ret; - size_t prk_len; + int ret; + size_t prk_len = EVP_MD_size(evp_md); - if (!HKDF_Extract(evp_md, salt, salt_len, key, key_len, prk, &prk_len)) - return NULL; + if (!HKDF_Extract(evp_md, salt, salt_len, key, key_len, prk, prk_len)) + return 0; ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len); OPENSSL_cleanse(prk, sizeof(prk)); @@ -273,43 +252,38 @@ static unsigned char *HKDF(const EVP_MD *evp_md, return ret; } -static unsigned char *HKDF_Extract(const EVP_MD *evp_md, - const unsigned char *salt, size_t salt_len, - const unsigned char *key, size_t key_len, - unsigned char *prk, size_t *prk_len) +static int HKDF_Extract(const EVP_MD *evp_md, + const unsigned char *salt, size_t salt_len, + const unsigned char *key, size_t key_len, + unsigned char *prk, size_t prk_len) { - unsigned int tmp_len; - - if (!HMAC(evp_md, salt, salt_len, key, key_len, prk, &tmp_len)) - return NULL; - - *prk_len = tmp_len; - return prk; + if (prk_len != (size_t)EVP_MD_size(evp_md)) { + KDFerr(KDF_F_HKDF_EXTRACT, KDF_R_WRONG_OUTPUT_BUFFER_SIZE); + return 0; + } + return HMAC(evp_md, salt, salt_len, key, key_len, prk, NULL) != NULL; } -static unsigned char *HKDF_Expand(const EVP_MD *evp_md, - const unsigned char *prk, size_t prk_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len) +static int HKDF_Expand(const EVP_MD *evp_md, + const unsigned char *prk, size_t prk_len, + const unsigned char *info, size_t info_len, + unsigned char *okm, size_t okm_len) { HMAC_CTX *hmac; - unsigned char *ret = NULL; - + int ret = 0; unsigned int i; - unsigned char prev[EVP_MAX_MD_SIZE]; - size_t done_len = 0, dig_len = EVP_MD_size(evp_md); - size_t n = okm_len / dig_len; + if (okm_len % dig_len) n++; if (n > 255 || okm == NULL) - return NULL; + return 0; if ((hmac = HMAC_CTX_new()) == NULL) - return NULL; + return 0; if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL)) goto err; @@ -343,7 +317,7 @@ static unsigned char *HKDF_Expand(const EVP_MD *evp_md, done_len += copy_len; } - ret = okm; + ret = 1; err: OPENSSL_cleanse(prev, sizeof(prev)); diff --git a/crypto/kdf/kdf_err.c b/crypto/kdf/kdf_err.c index 92e6a0c7..b62c25ff 100644 --- a/crypto/kdf/kdf_err.c +++ b/crypto/kdf/kdf_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-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 @@ -14,6 +14,29 @@ #ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA KDF_str_functs[] = { + {ERR_PACK(ERR_LIB_KDF, KDF_F_HKDF_EXTRACT, 0), "HKDF_Extract"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_HKDF_DERIVE, 0), "kdf_hkdf_derive"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_HKDF_NEW, 0), "kdf_hkdf_new"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_HKDF_SIZE, 0), "kdf_hkdf_size"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_MD2CTRL, 0), "kdf_md2ctrl"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_PBKDF2_CTRL_STR, 0), + "kdf_pbkdf2_ctrl_str"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_PBKDF2_DERIVE, 0), "kdf_pbkdf2_derive"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_PBKDF2_NEW, 0), "kdf_pbkdf2_new"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_CTRL_STR, 0), + "kdf_scrypt_ctrl_str"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_CTRL_UINT32, 0), + "kdf_scrypt_ctrl_uint32"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_CTRL_UINT64, 0), + "kdf_scrypt_ctrl_uint64"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_DERIVE, 0), "kdf_scrypt_derive"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_NEW, 0), "kdf_scrypt_new"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_TLS1_PRF_CTRL_STR, 0), + "kdf_tls1_prf_ctrl_str"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_TLS1_PRF_DERIVE, 0), + "kdf_tls1_prf_derive"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_TLS1_PRF_NEW, 0), "kdf_tls1_prf_new"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_PBKDF2_SET_MEMBUF, 0), "pbkdf2_set_membuf"}, {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_CTRL_STR, 0), "pkey_hkdf_ctrl_str"}, {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_DERIVE, 0), "pkey_hkdf_derive"}, {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_INIT, 0), "pkey_hkdf_init"}, @@ -30,6 +53,7 @@ static const ERR_STRING_DATA KDF_str_functs[] = { {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_TLS1_PRF_DERIVE, 0), "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_TLS1_PRF_ALG, 0), "tls1_prf_alg"}, {0, NULL} }; @@ -50,6 +74,8 @@ static const ERR_STRING_DATA KDF_str_reasons[] = { "unknown parameter 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), + "wrong output buffer size"}, {0, NULL} }; diff --git a/crypto/kdf/kdf_local.h b/crypto/kdf/kdf_local.h new file mode 100644 index 00000000..4956dad9 --- /dev/null +++ b/crypto/kdf/kdf_local.h @@ -0,0 +1,22 @@ +/* + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2018, 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 + */ + +int call_ctrl(int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), + EVP_KDF_IMPL *impl, int cmd, ...); +int kdf_str2ctrl(EVP_KDF_IMPL *impl, + int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), + int cmd, const char *str); +int kdf_hex2ctrl(EVP_KDF_IMPL *impl, + int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), + int cmd, const char *hex); +int kdf_md2ctrl(EVP_KDF_IMPL *impl, + int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), + int cmd, const char *md_name); + diff --git a/crypto/kdf/kdf_util.c b/crypto/kdf/kdf_util.c new file mode 100644 index 00000000..8eb6d26b --- /dev/null +++ b/crypto/kdf/kdf_util.c @@ -0,0 +1,73 @@ +/* + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2018, 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 + */ + +#include +#include +#include +#include +#include "internal/cryptlib.h" +#include "internal/evp_int.h" +#include "internal/numbers.h" +#include "kdf_local.h" + +int call_ctrl(int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), + EVP_KDF_IMPL *impl, int cmd, ...) +{ + int ret; + va_list args; + + va_start(args, cmd); + ret = ctrl(impl, cmd, args); + va_end(args); + + return ret; +} + +/* Utility functions to send a string or hex string to a ctrl */ + +int kdf_str2ctrl(EVP_KDF_IMPL *impl, + int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), + int cmd, const char *str) +{ + return call_ctrl(ctrl, impl, cmd, (const unsigned char *)str, strlen(str)); +} + +int kdf_hex2ctrl(EVP_KDF_IMPL *impl, + int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), + int cmd, const char *hex) +{ + unsigned char *bin; + long binlen; + int ret = -1; + + bin = OPENSSL_hexstr2buf(hex, &binlen); + if (bin == NULL) + return 0; + + if (binlen <= INT_MAX) + ret = call_ctrl(ctrl, impl, cmd, bin, (size_t)binlen); + OPENSSL_free(bin); + return ret; +} + +/* Pass a message digest to a ctrl */ +int kdf_md2ctrl(EVP_KDF_IMPL *impl, + int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), + int cmd, const char *md_name) +{ + const EVP_MD *md; + + if (md_name == NULL || (md = EVP_get_digestbyname(md_name)) == NULL) { + KDFerr(KDF_F_KDF_MD2CTRL, KDF_R_INVALID_DIGEST); + return 0; + } + return call_ctrl(ctrl, impl, cmd, md); +} + diff --git a/crypto/kdf/pbkdf2.c b/crypto/kdf/pbkdf2.c new file mode 100644 index 00000000..bf1ac6d7 --- /dev/null +++ b/crypto/kdf/pbkdf2.c @@ -0,0 +1,264 @@ +/* + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include "internal/cryptlib.h" +#include "internal/evp_int.h" +#include "kdf_local.h" + +static void kdf_pbkdf2_reset(EVP_KDF_IMPL *impl); +static void kdf_pbkdf2_init(EVP_KDF_IMPL *impl); +static int pkcs5_pbkdf2_alg(const char *pass, size_t passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, unsigned char *key, + size_t keylen); + +struct evp_kdf_impl_st { + unsigned char *pass; + size_t pass_len; + unsigned char *salt; + size_t salt_len; + int iter; + const EVP_MD *md; +}; + +static EVP_KDF_IMPL *kdf_pbkdf2_new(void) +{ + EVP_KDF_IMPL *impl; + + impl = OPENSSL_zalloc(sizeof(*impl)); + if (impl == NULL) { + KDFerr(KDF_F_KDF_PBKDF2_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + kdf_pbkdf2_init(impl); + return impl; +} + +static void kdf_pbkdf2_free(EVP_KDF_IMPL *impl) +{ + kdf_pbkdf2_reset(impl); + OPENSSL_free(impl); +} + +static void kdf_pbkdf2_reset(EVP_KDF_IMPL *impl) +{ + OPENSSL_free(impl->salt); + OPENSSL_clear_free(impl->pass, impl->pass_len); + memset(impl, 0, sizeof(*impl)); + kdf_pbkdf2_init(impl); +} + +static void kdf_pbkdf2_init(EVP_KDF_IMPL *impl) +{ + impl->iter = PKCS5_DEFAULT_ITER; + impl->md = EVP_sha1(); +} + +static int pbkdf2_set_membuf(unsigned char **buffer, size_t *buflen, + const unsigned char *new_buffer, + size_t new_buflen) +{ + if (new_buffer == NULL) + return 1; + + OPENSSL_clear_free(*buffer, *buflen); + + if (new_buflen > 0) { + *buffer = OPENSSL_memdup(new_buffer, new_buflen); + } else { + *buffer = OPENSSL_malloc(1); + } + if (*buffer == NULL) { + KDFerr(KDF_F_PBKDF2_SET_MEMBUF, ERR_R_MALLOC_FAILURE); + return 0; + } + + *buflen = new_buflen; + return 1; +} + +static int kdf_pbkdf2_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args) +{ + int iter; + const unsigned char *p; + size_t len; + const EVP_MD *md; + + switch (cmd) { + case EVP_KDF_CTRL_SET_PASS: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + return pbkdf2_set_membuf(&impl->pass, &impl->pass_len, p, len); + + case EVP_KDF_CTRL_SET_SALT: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + return pbkdf2_set_membuf(&impl->salt, &impl->salt_len, p, len); + + case EVP_KDF_CTRL_SET_ITER: + iter = va_arg(args, int); + if (iter < 1) + return 0; + + impl->iter = iter; + return 1; + + case EVP_KDF_CTRL_SET_MD: + md = va_arg(args, const EVP_MD *); + if (md == NULL) + return 0; + + impl->md = md; + return 1; + + default: + return -2; + } +} + +static int kdf_pbkdf2_ctrl_str(EVP_KDF_IMPL *impl, const char *type, + const char *value) +{ + if (value == NULL) { + KDFerr(KDF_F_KDF_PBKDF2_CTRL_STR, KDF_R_VALUE_MISSING); + return 0; + } + + if (strcmp(type, "pass") == 0) + return kdf_str2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_PASS, + value); + + if (strcmp(type, "hexpass") == 0) + return kdf_hex2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_PASS, + value); + + if (strcmp(type, "salt") == 0) + return kdf_str2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_SALT, + value); + + if (strcmp(type, "hexsalt") == 0) + return kdf_hex2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_SALT, + value); + + if (strcmp(type, "iter") == 0) + return call_ctrl(kdf_pbkdf2_ctrl, impl, EVP_KDF_CTRL_SET_ITER, + atoi(value)); + + if (strcmp(type, "digest") == 0) + return kdf_md2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_MD, value); + + return -2; +} + +static int kdf_pbkdf2_derive(EVP_KDF_IMPL *impl, unsigned char *key, + size_t keylen) +{ + if (impl->pass == NULL) { + KDFerr(KDF_F_KDF_PBKDF2_DERIVE, KDF_R_MISSING_PASS); + return 0; + } + + if (impl->salt == NULL) { + KDFerr(KDF_F_KDF_PBKDF2_DERIVE, KDF_R_MISSING_SALT); + return 0; + } + + return pkcs5_pbkdf2_alg((char *)impl->pass, impl->pass_len, + impl->salt, impl->salt_len, impl->iter, + impl->md, key, keylen); +} + +const EVP_KDF_METHOD pbkdf2_kdf_meth = { + EVP_KDF_PBKDF2, + kdf_pbkdf2_new, + kdf_pbkdf2_free, + kdf_pbkdf2_reset, + kdf_pbkdf2_ctrl, + kdf_pbkdf2_ctrl_str, + NULL, + kdf_pbkdf2_derive +}; + +/* + * This is an implementation of PKCS#5 v2.0 password based encryption key + * derivation function PBKDF2. SHA1 version verified against test vectors + * posted by Peter Gutmann to the PKCS-TNG mailing list. + */ + +static int pkcs5_pbkdf2_alg(const char *pass, size_t passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, unsigned char *key, + size_t keylen) +{ + int ret = 0; + unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; + int cplen, j, k, tkeylen, mdlen; + unsigned long i = 1; + HMAC_CTX *hctx_tpl = NULL, *hctx = NULL; + + mdlen = EVP_MD_size(digest); + if (mdlen < 0) + return 0; + + hctx_tpl = HMAC_CTX_new(); + if (hctx_tpl == NULL) + return 0; + p = key; + tkeylen = keylen; + if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL)) + goto err; + hctx = HMAC_CTX_new(); + if (hctx == NULL) + goto err; + while (tkeylen) { + if (tkeylen > mdlen) + cplen = mdlen; + else + cplen = tkeylen; + /* + * We are unlikely to ever use more than 256 blocks (5120 bits!) but + * just in case... + */ + itmp[0] = (unsigned char)((i >> 24) & 0xff); + itmp[1] = (unsigned char)((i >> 16) & 0xff); + itmp[2] = (unsigned char)((i >> 8) & 0xff); + itmp[3] = (unsigned char)(i & 0xff); + if (!HMAC_CTX_copy(hctx, hctx_tpl)) + goto err; + if (!HMAC_Update(hctx, salt, saltlen) + || !HMAC_Update(hctx, itmp, 4) + || !HMAC_Final(hctx, digtmp, NULL)) + goto err; + memcpy(p, digtmp, cplen); + for (j = 1; j < iter; j++) { + if (!HMAC_CTX_copy(hctx, hctx_tpl)) + goto err; + if (!HMAC_Update(hctx, digtmp, mdlen) + || !HMAC_Final(hctx, digtmp, NULL)) + goto err; + for (k = 0; k < cplen; k++) + p[k] ^= digtmp[k]; + } + tkeylen -= cplen; + i++; + p += cplen; + } + ret = 1; + +err: + HMAC_CTX_free(hctx); + HMAC_CTX_free(hctx_tpl); + return ret; +} diff --git a/crypto/kdf/scrypt.c b/crypto/kdf/scrypt.c index 6b35b77f..ee77f1ef 100644 --- a/crypto/kdf/scrypt.c +++ b/crypto/kdf/scrypt.c @@ -8,25 +8,34 @@ */ #include +#include #include -#include -#include #include -#include "internal/cryptlib.h" +#include +#include #include "internal/evp_int.h" +#include "internal/numbers.h" +#include "kdf_local.h" #ifndef OPENSSL_NO_SCRYPT +static void kdf_scrypt_reset(EVP_KDF_IMPL *impl); +static void kdf_scrypt_init(EVP_KDF_IMPL *impl); static int atou64(const char *nptr, uint64_t *result); +static int scrypt_alg(const char *pass, size_t passlen, + const unsigned char *salt, size_t saltlen, + uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, + unsigned char *key, size_t keylen); -typedef struct { +struct evp_kdf_impl_st { unsigned char *pass; size_t pass_len; unsigned char *salt; size_t salt_len; - uint64_t N, r, p; + uint64_t N; + uint32_t r, p; uint64_t maxmem_bytes; -} SCRYPT_PKEY_CTX; +}; /* Custom uint64_t parser since we do not have strtoull */ static int atou64(const char *nptr, uint64_t *result) @@ -53,51 +62,53 @@ static int atou64(const char *nptr, uint64_t *result) return 1; } -static int pkey_scrypt_init(EVP_PKEY_CTX *ctx) +static EVP_KDF_IMPL *kdf_scrypt_new(void) { - SCRYPT_PKEY_CTX *kctx; + EVP_KDF_IMPL *impl; - kctx = OPENSSL_zalloc(sizeof(*kctx)); - if (kctx == NULL) { - KDFerr(KDF_F_PKEY_SCRYPT_INIT, ERR_R_MALLOC_FAILURE); - return 0; + impl = OPENSSL_zalloc(sizeof(*impl)); + if (impl == NULL) { + KDFerr(KDF_F_KDF_SCRYPT_NEW, ERR_R_MALLOC_FAILURE); + return NULL; } + kdf_scrypt_init(impl); + return impl; +} +static void kdf_scrypt_free(EVP_KDF_IMPL *impl) +{ + kdf_scrypt_reset(impl); + OPENSSL_free(impl); +} + +static void kdf_scrypt_reset(EVP_KDF_IMPL *impl) +{ + OPENSSL_free(impl->salt); + OPENSSL_clear_free(impl->pass, impl->pass_len); + memset(impl, 0, sizeof(*impl)); + kdf_scrypt_init(impl); +} + +static void kdf_scrypt_init(EVP_KDF_IMPL *impl) +{ /* Default values are the most conservative recommendation given in the * original paper of C. Percival. Derivation uses roughly 1 GiB of memory - * for this parameter choice (approx. 128 * r * (N + p) bytes). + * for this parameter choice (approx. 128 * r * N * p bytes). */ - kctx->N = 1 << 20; - kctx->r = 8; - kctx->p = 1; - kctx->maxmem_bytes = 1025 * 1024 * 1024; - - ctx->data = kctx; - - return 1; + impl->N = 1 << 20; + impl->r = 8; + impl->p = 1; + impl->maxmem_bytes = 1025 * 1024 * 1024; } -static void pkey_scrypt_cleanup(EVP_PKEY_CTX *ctx) -{ - SCRYPT_PKEY_CTX *kctx = ctx->data; - - OPENSSL_clear_free(kctx->salt, kctx->salt_len); - OPENSSL_clear_free(kctx->pass, kctx->pass_len); - OPENSSL_free(kctx); -} - -static int pkey_scrypt_set_membuf(unsigned char **buffer, size_t *buflen, - const unsigned char *new_buffer, - const int new_buflen) +static int scrypt_set_membuf(unsigned char **buffer, size_t *buflen, + const unsigned char *new_buffer, + size_t new_buflen) { if (new_buffer == NULL) return 1; - if (new_buflen < 0) - return 0; - - if (*buffer != NULL) - OPENSSL_clear_free(*buffer, *buflen); + OPENSSL_clear_free(*buffer, *buflen); if (new_buflen > 0) { *buffer = OPENSSL_memdup(new_buffer, new_buflen); @@ -105,7 +116,7 @@ static int pkey_scrypt_set_membuf(unsigned char **buffer, size_t *buflen, *buffer = OPENSSL_malloc(1); } if (*buffer == NULL) { - KDFerr(KDF_F_PKEY_SCRYPT_SET_MEMBUF, ERR_R_MALLOC_FAILURE); + KDFerr(KDF_F_SCRYPT_SET_MEMBUF, ERR_R_MALLOC_FAILURE); return 0; } @@ -118,149 +129,378 @@ static int is_power_of_two(uint64_t value) return (value != 0) && ((value & (value - 1)) == 0); } -static int pkey_scrypt_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +static int kdf_scrypt_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args) { - SCRYPT_PKEY_CTX *kctx = ctx->data; uint64_t u64_value; + uint32_t value; + const unsigned char *p; + size_t len; - switch (type) { - case EVP_PKEY_CTRL_PASS: - return pkey_scrypt_set_membuf(&kctx->pass, &kctx->pass_len, p2, p1); + switch (cmd) { + case EVP_KDF_CTRL_SET_PASS: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + return scrypt_set_membuf(&impl->pass, &impl->pass_len, p, len); - case EVP_PKEY_CTRL_SCRYPT_SALT: - return pkey_scrypt_set_membuf(&kctx->salt, &kctx->salt_len, p2, p1); + case EVP_KDF_CTRL_SET_SALT: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + return scrypt_set_membuf(&impl->salt, &impl->salt_len, p, len); - case EVP_PKEY_CTRL_SCRYPT_N: - u64_value = *((uint64_t *)p2); + case EVP_KDF_CTRL_SET_SCRYPT_N: + u64_value = va_arg(args, uint64_t); if ((u64_value <= 1) || !is_power_of_two(u64_value)) return 0; - kctx->N = u64_value; + + impl->N = u64_value; return 1; - case EVP_PKEY_CTRL_SCRYPT_R: - u64_value = *((uint64_t *)p2); - if (u64_value < 1) + case EVP_KDF_CTRL_SET_SCRYPT_R: + value = va_arg(args, uint32_t); + if (value < 1) return 0; - kctx->r = u64_value; + + impl->r = value; return 1; - case EVP_PKEY_CTRL_SCRYPT_P: - u64_value = *((uint64_t *)p2); - if (u64_value < 1) + case EVP_KDF_CTRL_SET_SCRYPT_P: + value = va_arg(args, uint32_t); + if (value < 1) return 0; - kctx->p = u64_value; + + impl->p = value; return 1; - case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES: - u64_value = *((uint64_t *)p2); + case EVP_KDF_CTRL_SET_MAXMEM_BYTES: + u64_value = va_arg(args, uint64_t); if (u64_value < 1) return 0; - kctx->maxmem_bytes = u64_value; + + impl->maxmem_bytes = u64_value; return 1; default: return -2; - } } -static int pkey_scrypt_ctrl_uint64(EVP_PKEY_CTX *ctx, int type, - const char *value) +static int kdf_scrypt_ctrl_uint32(EVP_KDF_IMPL *impl, int cmd, + const char *value) { - uint64_t int_value; + int int_value = atoi(value); - if (!atou64(value, &int_value)) { - KDFerr(KDF_F_PKEY_SCRYPT_CTRL_UINT64, KDF_R_VALUE_ERROR); + if (int_value < 0 || (uint64_t)int_value > UINT32_MAX) { + KDFerr(KDF_F_KDF_SCRYPT_CTRL_UINT32, KDF_R_VALUE_ERROR); return 0; } - return pkey_scrypt_ctrl(ctx, type, 0, &int_value); + return call_ctrl(kdf_scrypt_ctrl, impl, cmd, (uint32_t)int_value); } -static int pkey_scrypt_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, - const char *value) +static int kdf_scrypt_ctrl_uint64(EVP_KDF_IMPL *impl, int cmd, + const char *value) +{ + uint64_t u64_value; + + if (!atou64(value, &u64_value)) { + KDFerr(KDF_F_KDF_SCRYPT_CTRL_UINT64, KDF_R_VALUE_ERROR); + return 0; + } + return call_ctrl(kdf_scrypt_ctrl, impl, cmd, u64_value); +} + +static int kdf_scrypt_ctrl_str(EVP_KDF_IMPL *impl, const char *type, + const char *value) { if (value == NULL) { - KDFerr(KDF_F_PKEY_SCRYPT_CTRL_STR, KDF_R_VALUE_MISSING); + KDFerr(KDF_F_KDF_SCRYPT_CTRL_STR, KDF_R_VALUE_MISSING); return 0; } if (strcmp(type, "pass") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_PASS, value); + return kdf_str2ctrl(impl, kdf_scrypt_ctrl, EVP_KDF_CTRL_SET_PASS, + value); if (strcmp(type, "hexpass") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_PASS, value); + return kdf_hex2ctrl(impl, kdf_scrypt_ctrl, EVP_KDF_CTRL_SET_PASS, + value); if (strcmp(type, "salt") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SCRYPT_SALT, value); + return kdf_str2ctrl(impl, kdf_scrypt_ctrl, EVP_KDF_CTRL_SET_SALT, + value); if (strcmp(type, "hexsalt") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SCRYPT_SALT, value); + return kdf_hex2ctrl(impl, kdf_scrypt_ctrl, EVP_KDF_CTRL_SET_SALT, + value); if (strcmp(type, "N") == 0) - return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_N, value); + return kdf_scrypt_ctrl_uint64(impl, EVP_KDF_CTRL_SET_SCRYPT_N, value); if (strcmp(type, "r") == 0) - return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_R, value); + return kdf_scrypt_ctrl_uint32(impl, EVP_KDF_CTRL_SET_SCRYPT_R, value); if (strcmp(type, "p") == 0) - return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_P, value); + return kdf_scrypt_ctrl_uint32(impl, EVP_KDF_CTRL_SET_SCRYPT_P, value); if (strcmp(type, "maxmem_bytes") == 0) - return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES, - value); + return kdf_scrypt_ctrl_uint64(impl, EVP_KDF_CTRL_SET_MAXMEM_BYTES, + value); - KDFerr(KDF_F_PKEY_SCRYPT_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE); return -2; } -static int pkey_scrypt_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen) +static int kdf_scrypt_derive(EVP_KDF_IMPL *impl, unsigned char *key, + size_t keylen) { - SCRYPT_PKEY_CTX *kctx = ctx->data; - - if (kctx->pass == NULL) { - KDFerr(KDF_F_PKEY_SCRYPT_DERIVE, KDF_R_MISSING_PASS); + if (impl->pass == NULL) { + KDFerr(KDF_F_KDF_SCRYPT_DERIVE, KDF_R_MISSING_PASS); return 0; } - if (kctx->salt == NULL) { - KDFerr(KDF_F_PKEY_SCRYPT_DERIVE, KDF_R_MISSING_SALT); + if (impl->salt == NULL) { + KDFerr(KDF_F_KDF_SCRYPT_DERIVE, KDF_R_MISSING_SALT); return 0; } - return EVP_PBE_scrypt((char *)kctx->pass, kctx->pass_len, kctx->salt, - kctx->salt_len, kctx->N, kctx->r, kctx->p, - kctx->maxmem_bytes, key, *keylen); + return scrypt_alg((char *)impl->pass, impl->pass_len, impl->salt, + impl->salt_len, impl->N, impl->r, impl->p, + impl->maxmem_bytes, key, keylen); } -const EVP_PKEY_METHOD scrypt_pkey_meth = { - EVP_PKEY_SCRYPT, - 0, - pkey_scrypt_init, - 0, - pkey_scrypt_cleanup, - - 0, 0, - 0, 0, - - 0, - 0, - - 0, - 0, - - 0, 0, - - 0, 0, 0, 0, - - 0, 0, - - 0, 0, - - 0, - pkey_scrypt_derive, - pkey_scrypt_ctrl, - pkey_scrypt_ctrl_str +const EVP_KDF_METHOD scrypt_kdf_meth = { + EVP_KDF_SCRYPT, + kdf_scrypt_new, + kdf_scrypt_free, + kdf_scrypt_reset, + kdf_scrypt_ctrl, + kdf_scrypt_ctrl_str, + NULL, + kdf_scrypt_derive }; +#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) +static void salsa208_word_specification(uint32_t inout[16]) +{ + int i; + uint32_t x[16]; + + memcpy(x, inout, sizeof(x)); + for (i = 8; i > 0; i -= 2) { + x[4] ^= R(x[0] + x[12], 7); + x[8] ^= R(x[4] + x[0], 9); + x[12] ^= R(x[8] + x[4], 13); + x[0] ^= R(x[12] + x[8], 18); + x[9] ^= R(x[5] + x[1], 7); + x[13] ^= R(x[9] + x[5], 9); + x[1] ^= R(x[13] + x[9], 13); + x[5] ^= R(x[1] + x[13], 18); + x[14] ^= R(x[10] + x[6], 7); + x[2] ^= R(x[14] + x[10], 9); + x[6] ^= R(x[2] + x[14], 13); + x[10] ^= R(x[6] + x[2], 18); + x[3] ^= R(x[15] + x[11], 7); + x[7] ^= R(x[3] + x[15], 9); + x[11] ^= R(x[7] + x[3], 13); + x[15] ^= R(x[11] + x[7], 18); + x[1] ^= R(x[0] + x[3], 7); + x[2] ^= R(x[1] + x[0], 9); + x[3] ^= R(x[2] + x[1], 13); + x[0] ^= R(x[3] + x[2], 18); + x[6] ^= R(x[5] + x[4], 7); + x[7] ^= R(x[6] + x[5], 9); + x[4] ^= R(x[7] + x[6], 13); + x[5] ^= R(x[4] + x[7], 18); + x[11] ^= R(x[10] + x[9], 7); + x[8] ^= R(x[11] + x[10], 9); + x[9] ^= R(x[8] + x[11], 13); + x[10] ^= R(x[9] + x[8], 18); + x[12] ^= R(x[15] + x[14], 7); + x[13] ^= R(x[12] + x[15], 9); + x[14] ^= R(x[13] + x[12], 13); + x[15] ^= R(x[14] + x[13], 18); + } + for (i = 0; i < 16; ++i) + inout[i] += x[i]; + OPENSSL_cleanse(x, sizeof(x)); +} + +static void scryptBlockMix(uint32_t *B_, uint32_t *B, uint64_t r) +{ + uint64_t i, j; + uint32_t X[16], *pB; + + memcpy(X, B + (r * 2 - 1) * 16, sizeof(X)); + pB = B; + for (i = 0; i < r * 2; i++) { + for (j = 0; j < 16; j++) + X[j] ^= *pB++; + salsa208_word_specification(X); + memcpy(B_ + (i / 2 + (i & 1) * r) * 16, X, sizeof(X)); + } + OPENSSL_cleanse(X, sizeof(X)); +} + +static void scryptROMix(unsigned char *B, uint64_t r, uint64_t N, + uint32_t *X, uint32_t *T, uint32_t *V) +{ + unsigned char *pB; + uint32_t *pV; + uint64_t i, k; + + /* Convert from little endian input */ + for (pV = V, i = 0, pB = B; i < 32 * r; i++, pV++) { + *pV = *pB++; + *pV |= *pB++ << 8; + *pV |= *pB++ << 16; + *pV |= (uint32_t)*pB++ << 24; + } + + for (i = 1; i < N; i++, pV += 32 * r) + scryptBlockMix(pV, pV - 32 * r, r); + + scryptBlockMix(X, V + (N - 1) * 32 * r, r); + + for (i = 0; i < N; i++) { + uint32_t j; + j = X[16 * (2 * r - 1)] % N; + pV = V + 32 * r * j; + for (k = 0; k < 32 * r; k++) + T[k] = X[k] ^ *pV++; + scryptBlockMix(X, T, r); + } + /* Convert output to little endian */ + for (i = 0, pB = B; i < 32 * r; i++) { + uint32_t xtmp = X[i]; + *pB++ = xtmp & 0xff; + *pB++ = (xtmp >> 8) & 0xff; + *pB++ = (xtmp >> 16) & 0xff; + *pB++ = (xtmp >> 24) & 0xff; + } +} + +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t)-1) +#endif + +/* + * Maximum power of two that will fit in uint64_t: this should work on + * most (all?) platforms. + */ + +#define LOG2_UINT64_MAX (sizeof(uint64_t) * 8 - 1) + +/* + * Maximum value of p * r: + * p <= ((2^32-1) * hLen) / MFLen => + * p <= ((2^32-1) * 32) / (128 * r) => + * p * r <= (2^30-1) + */ + +#define SCRYPT_PR_MAX ((1 << 30) - 1) + +static int scrypt_alg(const char *pass, size_t passlen, + const unsigned char *salt, size_t saltlen, + uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, + unsigned char *key, size_t keylen) +{ + int rv = 0; + unsigned char *B; + uint32_t *X, *V, *T; + uint64_t i, Blen, Vlen; + + /* Sanity check parameters */ + /* initial check, r,p must be non zero, N >= 2 and a power of 2 */ + if (r == 0 || p == 0 || N < 2 || (N & (N - 1))) + return 0; + /* Check p * r < SCRYPT_PR_MAX avoiding overflow */ + if (p > SCRYPT_PR_MAX / r) { + EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED); + return 0; + } + + /* + * Need to check N: if 2^(128 * r / 8) overflows limit this is + * automatically satisfied since N <= UINT64_MAX. + */ + + if (16 * r <= LOG2_UINT64_MAX) { + if (N >= (((uint64_t)1) << (16 * r))) { + EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED); + return 0; + } + } + + /* Memory checks: check total allocated buffer size fits in uint64_t */ + + /* + * B size in section 5 step 1.S + * Note: we know p * 128 * r < UINT64_MAX because we already checked + * p * r < SCRYPT_PR_MAX + */ + Blen = p * 128 * r; + /* + * Yet we pass it as integer to PKCS5_PBKDF2_HMAC... [This would + * have to be revised when/if PKCS5_PBKDF2_HMAC accepts size_t.] + */ + if (Blen > INT_MAX) { + EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED); + return 0; + } + + /* + * Check 32 * r * (N + 2) * sizeof(uint32_t) fits in uint64_t + * This is combined size V, X and T (section 4) + */ + i = UINT64_MAX / (32 * sizeof(uint32_t)); + if (N + 2 > i / r) { + EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED); + return 0; + } + Vlen = 32 * r * (N + 2) * sizeof(uint32_t); + + /* check total allocated size fits in uint64_t */ + if (Blen > UINT64_MAX - Vlen) { + EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED); + return 0; + } + + /* Check that the maximum memory doesn't exceed a size_t limits */ + if (maxmem > SIZE_MAX) + maxmem = SIZE_MAX; + + if (Blen + Vlen > maxmem) { + EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED); + return 0; + } + + /* If no key return to indicate parameters are OK */ + if (key == NULL) + return 1; + + B = OPENSSL_malloc((size_t)(Blen + Vlen)); + if (B == NULL) { + EVPerr(EVP_F_SCRYPT_ALG, ERR_R_MALLOC_FAILURE); + return 0; + } + X = (uint32_t *)(B + Blen); + T = X + 32 * r; + V = T + 32 * r; + if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, EVP_sha256(), + (int)Blen, B) == 0) + goto err; + + for (i = 0; i < p; i++) + scryptROMix(B + 128 * r * i, r, N, X, T, V); + + if (PKCS5_PBKDF2_HMAC(pass, passlen, B, (int)Blen, 1, EVP_sha256(), + keylen, key) == 0) + goto err; + rv = 1; + err: + if (rv == 0) + EVPerr(EVP_F_SCRYPT_ALG, EVP_R_PBKDF2_ERROR); + + OPENSSL_clear_free(B, (size_t)(Blen + Vlen)); + return rv; +} + #endif diff --git a/crypto/kdf/tls1_prf.c b/crypto/kdf/tls1_prf.c index 24ad59b9..1f8374f6 100644 --- a/crypto/kdf/tls1_prf.c +++ b/crypto/kdf/tls1_prf.c @@ -8,11 +8,15 @@ */ #include +#include +#include #include "internal/cryptlib.h" -#include #include +#include #include "internal/evp_int.h" +#include "kdf_local.h" +static void kdf_tls1_prf_reset(EVP_KDF_IMPL *impl); static int tls1_prf_alg(const EVP_MD *md, const unsigned char *sec, size_t slen, const unsigned char *seed, size_t seed_len, @@ -20,9 +24,9 @@ static int tls1_prf_alg(const EVP_MD *md, #define TLS1_PRF_MAXBUF 1024 -/* TLS KDF pkey context structure */ +/* TLS KDF kdf context structure */ -typedef struct { +struct evp_kdf_impl_st { /* Digest to use for PRF */ const EVP_MD *md; /* Secret value to use for PRF */ @@ -31,145 +35,137 @@ typedef struct { /* Buffer of concatenated seed data */ unsigned char seed[TLS1_PRF_MAXBUF]; size_t seedlen; -} TLS1_PRF_PKEY_CTX; +}; -static int pkey_tls1_prf_init(EVP_PKEY_CTX *ctx) +static EVP_KDF_IMPL *kdf_tls1_prf_new(void) { - TLS1_PRF_PKEY_CTX *kctx; + EVP_KDF_IMPL *impl; - if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL) { - KDFerr(KDF_F_PKEY_TLS1_PRF_INIT, ERR_R_MALLOC_FAILURE); - return 0; - } - ctx->data = kctx; - - return 1; + if ((impl = OPENSSL_zalloc(sizeof(*impl))) == NULL) + KDFerr(KDF_F_KDF_TLS1_PRF_NEW, ERR_R_MALLOC_FAILURE); + return impl; } -static void pkey_tls1_prf_cleanup(EVP_PKEY_CTX *ctx) +static void kdf_tls1_prf_free(EVP_KDF_IMPL *impl) { - TLS1_PRF_PKEY_CTX *kctx = ctx->data; - OPENSSL_clear_free(kctx->sec, kctx->seclen); - OPENSSL_cleanse(kctx->seed, kctx->seedlen); - OPENSSL_free(kctx); + kdf_tls1_prf_reset(impl); + OPENSSL_free(impl); } -static int pkey_tls1_prf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +static void kdf_tls1_prf_reset(EVP_KDF_IMPL *impl) { - TLS1_PRF_PKEY_CTX *kctx = ctx->data; - switch (type) { - case EVP_PKEY_CTRL_TLS_MD: - kctx->md = p2; + OPENSSL_clear_free(impl->sec, impl->seclen); + OPENSSL_cleanse(impl->seed, impl->seedlen); + memset(impl, 0, sizeof(*impl)); +} + +static int kdf_tls1_prf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args) +{ + const unsigned char *p; + size_t len; + const EVP_MD *md; + + switch (cmd) { + 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_PKEY_CTRL_TLS_SECRET: - if (p1 < 0) + case EVP_KDF_CTRL_SET_TLS_SECRET: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + OPENSSL_clear_free(impl->sec, impl->seclen); + impl->sec = OPENSSL_memdup(p, len); + if (impl->sec == NULL) return 0; - if (kctx->sec != NULL) - OPENSSL_clear_free(kctx->sec, kctx->seclen); - OPENSSL_cleanse(kctx->seed, kctx->seedlen); - kctx->seedlen = 0; - kctx->sec = OPENSSL_memdup(p2, p1); - if (kctx->sec == NULL) - return 0; - kctx->seclen = p1; + + impl->seclen = len; return 1; - case EVP_PKEY_CTRL_TLS_SEED: - if (p1 == 0 || p2 == NULL) + case EVP_KDF_CTRL_RESET_TLS_SEED: + OPENSSL_cleanse(impl->seed, impl->seedlen); + impl->seedlen = 0; + return 1; + + case EVP_KDF_CTRL_ADD_TLS_SEED: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + if (len == 0 || p == NULL) return 1; - if (p1 < 0 || p1 > (int)(TLS1_PRF_MAXBUF - kctx->seedlen)) + + if (len > (TLS1_PRF_MAXBUF - impl->seedlen)) return 0; - memcpy(kctx->seed + kctx->seedlen, p2, p1); - kctx->seedlen += p1; + + memcpy(impl->seed + impl->seedlen, p, len); + impl->seedlen += len; return 1; default: return -2; - } } -static int pkey_tls1_prf_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) +static int kdf_tls1_prf_ctrl_str(EVP_KDF_IMPL *impl, + const char *type, const char *value) { if (value == NULL) { - KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_VALUE_MISSING); + KDFerr(KDF_F_KDF_TLS1_PRF_CTRL_STR, KDF_R_VALUE_MISSING); return 0; } - if (strcmp(type, "md") == 0) { - TLS1_PRF_PKEY_CTX *kctx = ctx->data; + if (strcmp(type, "digest") == 0) + return kdf_md2ctrl(impl, kdf_tls1_prf_ctrl, EVP_KDF_CTRL_SET_MD, value); - const EVP_MD *md = EVP_get_digestbyname(value); - if (md == NULL) { - KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_INVALID_DIGEST); - return 0; - } - kctx->md = md; - return 1; - } if (strcmp(type, "secret") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value); - if (strcmp(type, "hexsecret") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value); - if (strcmp(type, "seed") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value); - if (strcmp(type, "hexseed") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value); + return kdf_str2ctrl(impl, kdf_tls1_prf_ctrl, + EVP_KDF_CTRL_SET_TLS_SECRET, value); + + if (strcmp(type, "hexsecret") == 0) + return kdf_hex2ctrl(impl, kdf_tls1_prf_ctrl, + EVP_KDF_CTRL_SET_TLS_SECRET, value); + + if (strcmp(type, "seed") == 0) + return kdf_str2ctrl(impl, kdf_tls1_prf_ctrl, EVP_KDF_CTRL_ADD_TLS_SEED, + value); + + if (strcmp(type, "hexseed") == 0) + return kdf_hex2ctrl(impl, kdf_tls1_prf_ctrl, EVP_KDF_CTRL_ADD_TLS_SEED, + value); - KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE); return -2; } -static int pkey_tls1_prf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen) +static int kdf_tls1_prf_derive(EVP_KDF_IMPL *impl, unsigned char *key, + size_t keylen) { - TLS1_PRF_PKEY_CTX *kctx = ctx->data; - if (kctx->md == NULL) { - KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST); + if (impl->md == NULL) { + KDFerr(KDF_F_KDF_TLS1_PRF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST); return 0; } - if (kctx->sec == NULL) { - KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_SECRET); + if (impl->sec == NULL) { + KDFerr(KDF_F_KDF_TLS1_PRF_DERIVE, KDF_R_MISSING_SECRET); return 0; } - if (kctx->seedlen == 0) { - KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_SEED); + if (impl->seedlen == 0) { + KDFerr(KDF_F_KDF_TLS1_PRF_DERIVE, KDF_R_MISSING_SEED); return 0; } - return tls1_prf_alg(kctx->md, kctx->sec, kctx->seclen, - kctx->seed, kctx->seedlen, - key, *keylen); + return tls1_prf_alg(impl->md, impl->sec, impl->seclen, + impl->seed, impl->seedlen, + key, keylen); } -const EVP_PKEY_METHOD tls1_prf_pkey_meth = { - EVP_PKEY_TLS1_PRF, - 0, - pkey_tls1_prf_init, - 0, - pkey_tls1_prf_cleanup, - - 0, 0, - 0, 0, - - 0, - 0, - - 0, - 0, - - 0, 0, - - 0, 0, 0, 0, - - 0, 0, - - 0, 0, - - 0, - pkey_tls1_prf_derive, - pkey_tls1_prf_ctrl, - pkey_tls1_prf_ctrl_str +const EVP_KDF_METHOD tls1_prf_kdf_meth = { + EVP_KDF_TLS1_PRF, + kdf_tls1_prf_new, + kdf_tls1_prf_free, + kdf_tls1_prf_reset, + kdf_tls1_prf_ctrl, + kdf_tls1_prf_ctrl_str, + NULL, + kdf_tls1_prf_derive }; static int tls1_prf_P_hash(const EVP_MD *md, @@ -249,12 +245,11 @@ static int tls1_prf_alg(const EVP_MD *md, const unsigned char *seed, size_t seed_len, unsigned char *out, size_t olen) { - if (EVP_MD_type(md) == NID_md5_sha1) { size_t i; unsigned char *tmp; if (!tls1_prf_P_hash(EVP_md5(), sec, slen/2 + (slen & 1), - seed, seed_len, out, olen)) + seed, seed_len, out, olen)) return 0; if ((tmp = OPENSSL_malloc(olen)) == NULL) { @@ -262,7 +257,7 @@ static int tls1_prf_alg(const EVP_MD *md, return 0; } if (!tls1_prf_P_hash(EVP_sha1(), sec + slen/2, slen/2 + (slen & 1), - seed, seed_len, tmp, olen)) { + seed, seed_len, tmp, olen)) { OPENSSL_clear_free(tmp, olen); return 0; } diff --git a/crypto/lhash/lhash.c b/crypto/lhash/lhash.c index c8260398..aa0ca1c9 100644 --- a/crypto/lhash/lhash.c +++ b/crypto/lhash/lhash.c @@ -74,6 +74,16 @@ err: } void OPENSSL_LH_free(OPENSSL_LHASH *lh) +{ + if (lh == NULL) + return; + + OPENSSL_LH_flush(lh); + OPENSSL_free(lh->b); + OPENSSL_free(lh); +} + +void OPENSSL_LH_flush(OPENSSL_LHASH *lh) { unsigned int i; OPENSSL_LH_NODE *n, *nn; @@ -89,8 +99,6 @@ void OPENSSL_LH_free(OPENSSL_LHASH *lh) n = nn; } } - OPENSSL_free(lh->b); - OPENSSL_free(lh); } void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data) diff --git a/crypto/modes/asm/ghash-armv4.pl b/crypto/modes/asm/ghash-armv4.pl index 759d29c4..1391b1b6 100644 --- a/crypto/modes/asm/ghash-armv4.pl +++ b/crypto/modes/asm/ghash-armv4.pl @@ -142,7 +142,6 @@ ___ $code=<<___; #include "arm_arch.h" -.text #if defined(__thumb2__) || defined(__clang__) .syntax unified #define ldrplb ldrbpl @@ -154,6 +153,8 @@ $code=<<___; .code 32 #endif +.text + .type rem_4bit,%object .align 5 rem_4bit: diff --git a/crypto/modes/asm/ghash-x86_64.pl b/crypto/modes/asm/ghash-x86_64.pl index 8f8ab621..a5d216ab 100644 --- a/crypto/modes/asm/ghash-x86_64.pl +++ b/crypto/modes/asm/ghash-x86_64.pl @@ -529,6 +529,7 @@ $code.=<<___; .type gcm_init_clmul,\@abi-omnipotent .align 16 gcm_init_clmul: +.cfi_startproc .L_init_clmul: ___ $code.=<<___ if ($win64); @@ -598,6 +599,7 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .size gcm_init_clmul,.-gcm_init_clmul ___ } @@ -609,6 +611,7 @@ $code.=<<___; .type gcm_gmult_clmul,\@abi-omnipotent .align 16 gcm_gmult_clmul: +.cfi_startproc .L_gmult_clmul: movdqu ($Xip),$Xi movdqa .Lbswap_mask(%rip),$T3 @@ -645,6 +648,7 @@ $code.=<<___; pshufb $T3,$Xi movdqu $Xi,($Xip) ret +.cfi_endproc .size gcm_gmult_clmul,.-gcm_gmult_clmul ___ } @@ -658,6 +662,7 @@ $code.=<<___; .type gcm_ghash_clmul,\@abi-omnipotent .align 32 gcm_ghash_clmul: +.cfi_startproc .L_ghash_clmul: ___ $code.=<<___ if ($win64); @@ -1005,6 +1010,7 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .size gcm_ghash_clmul,.-gcm_ghash_clmul ___ } @@ -1014,6 +1020,7 @@ $code.=<<___; .type gcm_init_avx,\@abi-omnipotent .align 32 gcm_init_avx: +.cfi_startproc ___ if ($avx) { my ($Htbl,$Xip)=@_4args; @@ -1142,11 +1149,13 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .size gcm_init_avx,.-gcm_init_avx ___ } else { $code.=<<___; jmp .L_init_clmul +.cfi_endproc .size gcm_init_avx,.-gcm_init_avx ___ } @@ -1156,7 +1165,9 @@ $code.=<<___; .type gcm_gmult_avx,\@abi-omnipotent .align 32 gcm_gmult_avx: +.cfi_startproc jmp .L_gmult_clmul +.cfi_endproc .size gcm_gmult_avx,.-gcm_gmult_avx ___ @@ -1165,6 +1176,7 @@ $code.=<<___; .type gcm_ghash_avx,\@abi-omnipotent .align 32 gcm_ghash_avx: +.cfi_startproc ___ if ($avx) { my ($Xip,$Htbl,$inp,$len)=@_4args; @@ -1577,11 +1589,13 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .size gcm_ghash_avx,.-gcm_ghash_avx ___ } else { $code.=<<___; jmp .L_ghash_clmul +.cfi_endproc .size gcm_ghash_avx,.-gcm_ghash_avx ___ } diff --git a/crypto/modes/asm/ghashv8-armx.pl b/crypto/modes/asm/ghashv8-armx.pl index ea059503..e8915833 100644 --- a/crypto/modes/asm/ghashv8-armx.pl +++ b/crypto/modes/asm/ghashv8-armx.pl @@ -66,18 +66,26 @@ $inc="x12"; { my ($Xl,$Xm,$Xh,$IN)=map("q$_",(0..3)); my ($t0,$t1,$t2,$xC2,$H,$Hhl,$H2)=map("q$_",(8..14)); +my $_byte = ($flavour =~ /win/ ? "DCB" : ".byte"); $code=<<___; #include "arm_arch.h" #if __ARM_MAX_ARCH__>=7 -.text ___ -$code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/); -$code.=<<___ if ($flavour !~ /64/); +$code.=".arch armv8-a+crypto\n.text\n" if ($flavour =~ /64/); +$code.=<<___ if ($flavour !~ /64/); .fpu neon -.code 32 -#undef __thumb2__ +#ifdef __thumb2__ +.syntax unified +.thumb +# define INST(a,b,c,d) $_byte c,0xef,a,b +#else +.code 32 +# define INST(a,b,c,d) $_byte a,b,c,0xf2 +#endif + +.text ___ ################################################################################ @@ -752,7 +760,7 @@ if ($flavour =~ /64/) { ######## 64-bit code # since ARMv7 instructions are always encoded little-endian. # correct solution is to use .inst directive, but older # assemblers don't implement it:-( - sprintf ".byte\t0x%02x,0x%02x,0x%02x,0x%02x\t@ %s %s", + sprintf "INST(0x%02x,0x%02x,0x%02x,0x%02x)\t@ %s %s", $word&0xff,($word>>8)&0xff, ($word>>16)&0xff,($word>>24)&0xff, $mnemonic,$arg; @@ -767,13 +775,17 @@ if ($flavour =~ /64/) { ######## 64-bit code # fix up remaining new-style suffixes s/\],#[0-9]+/]!/o; - s/cclr\s+([^,]+),\s*([a-z]+)/mov$2 $1,#0/o or + s/cclr\s+([^,]+),\s*([a-z]+)/mov.$2 $1,#0/o or s/vdup\.32\s+(.*)/unvdup32($1)/geo or s/v?(pmull2?)\.p64\s+(.*)/unvpmullp64($1,$2)/geo or s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo or s/^(\s+)b\./$1b/o or s/^(\s+)ret/$1bx\tlr/o; + if (s/^(\s+)mov\.([a-z]+)/$1mov$2/) { + print " it $2\n"; + } + print $_,"\n"; } } diff --git a/crypto/perlasm/arm-xlate.pl b/crypto/perlasm/arm-xlate.pl index d78a8baa..af6f7d31 100755 --- a/crypto/perlasm/arm-xlate.pl +++ b/crypto/perlasm/arm-xlate.pl @@ -28,6 +28,13 @@ my $fpu = sub { if ($flavour =~ /linux/) { ".fpu\t".join(',',@_); } else { ""; } }; +my $rodata = sub { + SWITCH: for ($flavour) { + /linux/ && return ".section\t.rodata"; + /ios/ && return ".section\t__TEXT,__const"; + last; + } +}; my $hidden = sub { if ($flavour =~ /ios/) { ".private_extern\t".join(',',@_); } else { ".hidden\t".join(',',@_); } @@ -96,6 +103,12 @@ my $asciz = sub { { ""; } }; +my $adrp = sub { + my ($args,$comment) = split(m|\s*//|,shift); + "\tadrp\t$args\@PAGE"; +} if ($flavour =~ /ios64/); + + sub range { my ($r,$sfx,$start,$end) = @_; @@ -125,6 +138,10 @@ sub expand_line { $line =~ s/\b(\w+)/$GLOBALS{$1} or $1/ge; + if ($flavour =~ /ios64/) { + $line =~ s/#:lo12:(\w+)/$1\@PAGEOFF/; + } + return $line; } diff --git a/crypto/perlasm/x86_64-xlate.pl b/crypto/perlasm/x86_64-xlate.pl index 5e5d6cc0..4a7ec7a6 100755 --- a/crypto/perlasm/x86_64-xlate.pl +++ b/crypto/perlasm/x86_64-xlate.pl @@ -541,6 +541,7 @@ my %globals; ); my ($cfa_reg, $cfa_rsp); + my @cfa_stack; # [us]leb128 format is variable-length integer representation base # 2^128, with most significant bit of each byte being 0 denoting @@ -648,7 +649,13 @@ my %globals; # why it starts with -8. Recall that CFA is top of caller's # stack... /startproc/ && do { ($cfa_reg, $cfa_rsp) = ("%rsp", -8); last; }; - /endproc/ && do { ($cfa_reg, $cfa_rsp) = ("%rsp", 0); last; }; + /endproc/ && do { ($cfa_reg, $cfa_rsp) = ("%rsp", 0); + # .cfi_remember_state directives that are not + # matched with .cfi_restore_state are + # unnecessary. + die "unpaired .cfi_remember_state" if (@cfa_stack); + last; + }; /def_cfa_register/ && do { $cfa_reg = $$line; last; }; /def_cfa_offset/ @@ -688,6 +695,14 @@ my %globals; cfa_expression($$line))); last; }; + /remember_state/ + && do { push @cfa_stack, [$cfa_reg, $cfa_rsp]; + last; + }; + /restore_state/ + && do { ($cfa_reg, $cfa_rsp) = @{pop @cfa_stack}; + last; + }; } $self->{value} = ".cfi_$dir\t$$line" if ($dir); diff --git a/crypto/poly1305/asm/poly1305-armv4.pl b/crypto/poly1305/asm/poly1305-armv4.pl index 7003cc77..38622af1 100755 --- a/crypto/poly1305/asm/poly1305-armv4.pl +++ b/crypto/poly1305/asm/poly1305-armv4.pl @@ -48,7 +48,6 @@ if ($flavour && $flavour ne "void") { $code.=<<___; #include "arm_arch.h" -.text #if defined(__thumb2__) .syntax unified .thumb @@ -56,6 +55,8 @@ $code.=<<___; .code 32 #endif +.text + .globl poly1305_emit .globl poly1305_blocks .globl poly1305_init @@ -100,8 +101,10 @@ poly1305_init: and r4,r4,r10 #if __ARM_MAX_ARCH__>=7 +# if !defined(_WIN32) ldr r12,[r11,r12] @ OPENSSL_armcap_P -# ifdef __APPLE__ +# endif +# if defined(__APPLE__) || defined(_WIN32) ldr r12,[r12] # endif #endif @@ -116,31 +119,21 @@ poly1305_init: #if __ARM_MAX_ARCH__>=7 tst r12,#ARMV7_NEON @ check for NEON -# ifdef __APPLE__ - adr r9,poly1305_blocks_neon - adr r11,poly1305_blocks -# ifdef __thumb2__ - it ne -# endif - movne r11,r9 - adr r12,poly1305_emit - adr r10,poly1305_emit_neon -# ifdef __thumb2__ - it ne -# endif - movne r12,r10 -# else -# ifdef __thumb2__ - itete eq -# endif - addeq r12,r11,#(poly1305_emit-.Lpoly1305_init) - addne r12,r11,#(poly1305_emit_neon-.Lpoly1305_init) - addeq r11,r11,#(poly1305_blocks-.Lpoly1305_init) - addne r11,r11,#(poly1305_blocks_neon-.Lpoly1305_init) -# endif # ifdef __thumb2__ - orr r12,r12,#1 @ thumb-ify address - orr r11,r11,#1 + adr r9,.Lpoly1305_blocks_neon + adr r11,.Lpoly1305_blocks + adr r12,.Lpoly1305_emit + adr r10,.Lpoly1305_emit_neon + itt ne + movne r11,r9 + movne r12,r10 + orr r11,r11,#1 @ thumb-ify address + orr r12,r12,#1 +# else + addeq r12,r11,#(.Lpoly1305_emit-.Lpoly1305_init) + addne r12,r11,#(.Lpoly1305_emit_neon-.Lpoly1305_init) + addeq r11,r11,#(.Lpoly1305_blocks-.Lpoly1305_init) + addne r11,r11,#(.Lpoly1305_blocks_neon-.Lpoly1305_init) # endif #endif ldrb r9,[$inp,#11] @@ -352,6 +345,7 @@ $code.=<<___; .type poly1305_emit,%function .align 5 poly1305_emit: +.Lpoly1305_emit: stmdb sp!,{r4-r11} .Lpoly1305_emit_enter: @@ -671,6 +665,7 @@ poly1305_init_neon: .type poly1305_blocks_neon,%function .align 5 poly1305_blocks_neon: +.Lpoly1305_blocks_neon: ldr ip,[$ctx,#36] @ is_base2_26 ands $len,$len,#-16 beq .Lno_data_neon @@ -1157,6 +1152,7 @@ poly1305_blocks_neon: .type poly1305_emit_neon,%function .align 5 poly1305_emit_neon: +.Lpoly1305_emit_neon: ldr ip,[$ctx,#36] @ is_base2_26 stmdb sp!,{r4-r11} @@ -1229,7 +1225,11 @@ poly1305_emit_neon: .Lzeros: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .LOPENSSL_armcap: +# ifdef _WIN32 +.word OPENSSL_armcap_P +# else .word OPENSSL_armcap_P-.Lpoly1305_init +# endif #endif ___ } } diff --git a/crypto/poly1305/asm/poly1305-armv8.pl b/crypto/poly1305/asm/poly1305-armv8.pl index 31b3110a..b7aa7dc9 100755 --- a/crypto/poly1305/asm/poly1305-armv8.pl +++ b/crypto/poly1305/asm/poly1305-armv8.pl @@ -71,17 +71,12 @@ poly1305_init: csel x0,xzr,x0,eq b.eq .Lno_key -#ifdef __ILP32__ - ldrsw $t1,.LOPENSSL_armcap_P -#else - ldr $t1,.LOPENSSL_armcap_P -#endif - adr $t0,.LOPENSSL_armcap_P + adrp x17,OPENSSL_armcap_P + ldr w17,[x17,#:lo12:OPENSSL_armcap_P] ldp $r0,$r1,[$inp] // load key mov $s1,#0xfffffffc0fffffff movk $s1,#0x0fff,lsl#48 - ldr w17,[$t0,$t1] #ifdef __ARMEB__ rev $r0,$r0 // flip bytes rev $r1,$r1 @@ -93,10 +88,10 @@ poly1305_init: tst w17,#ARMV7_NEON - adr $d0,poly1305_blocks - adr $r0,poly1305_blocks_neon - adr $d1,poly1305_emit - adr $r1,poly1305_emit_neon + adr $d0,.Lpoly1305_blocks + adr $r0,.Lpoly1305_blocks_neon + adr $d1,.Lpoly1305_emit + adr $r1,.Lpoly1305_emit_neon csel $d0,$d0,$r0,eq csel $d1,$d1,$r1,eq @@ -115,6 +110,7 @@ poly1305_init: .type poly1305_blocks,%function .align 5 poly1305_blocks: +.Lpoly1305_blocks: ands $len,$len,#-16 b.eq .Lno_data @@ -179,6 +175,7 @@ poly1305_blocks: .type poly1305_emit,%function .align 5 poly1305_emit: +.Lpoly1305_emit: ldp $h0,$h1,[$ctx] // load hash base 2^64 ldr $h2,[$ctx,#16] ldp $t0,$t1,[$nonce] // load nonce @@ -285,12 +282,14 @@ poly1305_splat: .type poly1305_blocks_neon,%function .align 5 poly1305_blocks_neon: +.Lpoly1305_blocks_neon: ldr $is_base2_26,[$ctx,#24] cmp $len,#128 b.hs .Lblocks_neon - cbz $is_base2_26,poly1305_blocks + cbz $is_base2_26,.Lpoly1305_blocks .Lblocks_neon: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-80]! add x29,sp,#0 @@ -430,7 +429,7 @@ poly1305_blocks_neon: csel $in2,$zeros,$in2,lo mov x4,#1 - str x4,[$ctx,#-24] // set is_base2_26 + stur x4,[$ctx,#-24] // set is_base2_26 sub $ctx,$ctx,#48 // restore original $ctx b .Ldo_neon @@ -859,6 +858,7 @@ poly1305_blocks_neon: st1 {$ACC4}[0],[$ctx] .Lno_data_neon: + .inst 0xd50323bf // autiasp ldr x29,[sp],#80 ret .size poly1305_blocks_neon,.-poly1305_blocks_neon @@ -866,6 +866,7 @@ poly1305_blocks_neon: .type poly1305_emit_neon,%function .align 5 poly1305_emit_neon: +.Lpoly1305_emit_neon: ldr $is_base2_26,[$ctx,#24] cbz $is_base2_26,poly1305_emit @@ -918,12 +919,6 @@ poly1305_emit_neon: .align 5 .Lzeros: .long 0,0,0,0,0,0,0,0 -.LOPENSSL_armcap_P: -#ifdef __ILP32__ -.long OPENSSL_armcap_P-. -#else -.quad OPENSSL_armcap_P-. -#endif .asciz "Poly1305 for ARMv8, CRYPTOGAMS by " .align 2 ___ diff --git a/crypto/property/README b/crypto/property/README new file mode 100644 index 00000000..b3f56cfa --- /dev/null +++ b/crypto/property/README @@ -0,0 +1,87 @@ +Properties are associated with algorithms and are used to select between different implementations dynamically. + +This implementation is based on a number of assumptions: + +* Property definition is uncommon. I.e. providers will be loaded and + unloaded relatively infrequently, if at all. + +* The number of distinct property names will be small. + +* Providers will often give the same implementation properties to most or + all of their implemented algorithms. E.g. the FIPS property would be set + across an entire provider. Likewise for, hardware, accelerated, software, + HSM and, perhaps, constant_time. + +* There are a lot of algorithm implementations, therefore property + definitions should be space efficient. However... + +* ... property queries are very common. These must be fast. + +* Property queries come from a small set and are reused many times typically. + I.e. an application tends to use the same set of queries over and over, + rather than spanning a wide variety of queries. + +* Property queries can never add new property definitions. + + +Some consequences of these assumptions are: + +* That definition is uncommon and queries are very common, we can treat + the property definitions as almost immutable. Specifically, a query can + never change the state of the definitions. + +* That definition is uncommon and needs to be space efficient, it will + be feasible to use a hash table to contain the names (and possibly also + values) of all properties and to reference these instead of duplicating + strings. Moreover, such a data structure need not be garbage collected. + By converting strings to integers using a structure such as this, string + comparison degenerates to integer comparison. Additionally, lists of + properties can be sorted by the string index which makes comparisons linear + time rather than quadratic time - the O(n log n) sort cost being amortised. + +* A cache for property definitions is also viable, if only implementation + properties are used and not algorithm properties, or at least these are + maintained separately. This cache would be a hash table, indexed by + the property definition string, and algorithms with the same properties + would share their definition structure. Again, reducing space use. + +* A query cache is desirable. This would be a hash table keyed by the + algorithm identifier and the entire query string and it would map to + the chosen algorithm. When a provider is loaded or unloaded, this cache + must be invalidated. The cache will also be invalidated when the global + properties are changed as doing so removes the need to index on both the + global and requested property strings. + + +The implementation: + +* property_lock.c contains some wrapper functions to handle the global + lock more easily. The global lock is held for short periods of time with + per algorithm locking being used for longer intervals. + +* property_string.c contains the string cache which converts property + names and values to small integer indices. Names and values are stored in + separate hash tables. The two Boolean values, the strings "yes" and "no", + are populated as the first two members of the value table. All property + names reserved by OpenSSL are also populated here. No functions are + provided to convert from an index back to the original string (this can be + done by maintaining parallel stacks of strings if required). + +* property_parse.c contains the property definition and query parsers. + These convert ASCII strings into lists of properties. The resulting + lists are sorted by the name index. Some additional utility functions + for dealing with property lists are also included: comparison of a query + against a definition and merging two queries into a single larger query. + +* property.c contains the main APIs for defining and using properties. + Algorithms are discovered from their NID and a query string. + The results are cached. + + The caching of query results has to be efficient but it must also be robust + against a denial of service attack. The cache cannot be permitted to grow + without bounds and must garbage collect under-used entries. The garbage + collection does not have to be exact. + +* defn_cache.c contains a cache that maps property definition strings to + parsed properties. It is used by property.c to improve performance when + the same definition appears multiple times. diff --git a/crypto/property/build.info b/crypto/property/build.info new file mode 100644 index 00000000..3a86b6e1 --- /dev/null +++ b/crypto/property/build.info @@ -0,0 +1,3 @@ +LIBS=../../libcrypto +SOURCE[../../libcrypto]=property_string.c property_parse.c property.c \ + property_err.c defn_cache.c diff --git a/crypto/property/defn_cache.c b/crypto/property/defn_cache.c new file mode 100644 index 00000000..df87c19f --- /dev/null +++ b/crypto/property/defn_cache.c @@ -0,0 +1,105 @@ +/* + * 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 + */ + +#include +#include +#include +#include "internal/propertyerr.h" +#include "internal/property.h" +#include "property_lcl.h" + +/* + * Implement a property definition cache. + * These functions assume that they are called under a write lock. + * No attempt is made to clean out the cache, except when it is shut down. + */ + +typedef struct { + const char *prop; + OSSL_PROPERTY_LIST *defn; + char body[1]; +} PROPERTY_DEFN_ELEM; + +DEFINE_LHASH_OF(PROPERTY_DEFN_ELEM); + +static LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns = NULL; + +static unsigned long property_defn_hash(const PROPERTY_DEFN_ELEM *a) +{ + return OPENSSL_LH_strhash(a->prop); +} + +static int property_defn_cmp(const PROPERTY_DEFN_ELEM *a, + const PROPERTY_DEFN_ELEM *b) +{ + return strcmp(a->prop, b->prop); +} + +static void property_defn_free(PROPERTY_DEFN_ELEM *elem) +{ + ossl_property_free(elem->defn); + OPENSSL_free(elem); +} + +int ossl_prop_defn_init(void) +{ + property_defns = lh_PROPERTY_DEFN_ELEM_new(&property_defn_hash, + &property_defn_cmp); + return property_defns != NULL; +} + +void ossl_prop_defn_cleanup(void) +{ + if (property_defns != NULL) { + lh_PROPERTY_DEFN_ELEM_doall(property_defns, &property_defn_free); + lh_PROPERTY_DEFN_ELEM_free(property_defns); + property_defns = NULL; + } +} + +OSSL_PROPERTY_LIST *ossl_prop_defn_get(const char *prop) +{ + PROPERTY_DEFN_ELEM elem, *r; + + elem.prop = prop; + r = lh_PROPERTY_DEFN_ELEM_retrieve(property_defns, &elem); + return r != NULL ? r->defn : NULL; +} + +int ossl_prop_defn_set(const char *prop, OSSL_PROPERTY_LIST *pl) +{ + PROPERTY_DEFN_ELEM elem, *old, *p = NULL; + size_t len; + + if (prop == NULL) + return 1; + + if (pl == NULL) { + elem.prop = prop; + lh_PROPERTY_DEFN_ELEM_delete(property_defns, &elem); + return 1; + } + len = strlen(prop); + p = OPENSSL_malloc(sizeof(*p) + len); + if (p != NULL) { + p->prop = p->body; + p->defn = pl; + memcpy(p->body, prop, len + 1); + old = lh_PROPERTY_DEFN_ELEM_insert(property_defns, p); + if (old != NULL) { + property_defn_free(old); + return 1; + } + if (!lh_PROPERTY_DEFN_ELEM_error(property_defns)) + return 1; + } + OPENSSL_free(p); + return 0; +} diff --git a/crypto/property/properties.ebnf b/crypto/property/properties.ebnf new file mode 100644 index 00000000..9a6857f7 --- /dev/null +++ b/crypto/property/properties.ebnf @@ -0,0 +1,17 @@ +(* https://bottlecaps.de/rr/ui *) + +Definition + ::= PropertyName ( '=' Value )? ( ',' PropertyName ( '=' Value )? )* +Query ::= ( '-'? PropertyName | PropertyName ( '=' | '!=' ) Value ) + ( ',' ( '-'? PropertyName | PropertyName ( '=' | '!=' ) Value ) )* +Value ::= NumberLiteral + | StringLiteral +StringLiteral ::= QuotedString | UnquotedString +QuotedString ::= '"' [^"]* '"' + | "'" [^']* "'" +UnquotedString ::= [^{space},]+ +NumberLiteral + ::= '0' ( [0-7]* | 'x' [0-9A-Fa-f]+ ) + | '-'? [1-9] [0-9]+ +PropertyName + ::= [A-Z] [A-Z0-9_]* ( '.' [A-Z] [A-Z0-9_]* )* diff --git a/crypto/property/properties.xhtml b/crypto/property/properties.xhtml new file mode 100644 index 00000000..33827226 --- /dev/null +++ b/crypto/property/properties.xhtml @@ -0,0 +1,685 @@ + + + + + + + + + + + Definition: + + + + + + + + PropertyName + + = + + + Value + + , + + + + + +
         ::= PropertyName ( '=' Value )? ( ',' PropertyName ( '=' Value )? )*
+
+ no referencesQuery: + + + + + + + + - + + + PropertyName + + + PropertyName + + = + + + != + + + Value + + , + + + + +
Query    ::= ( '-'? PropertyName | PropertyName ( '=' | '!=' ) Value ) ( ',' ( '-'? PropertyName | PropertyName ( '=' | '!=' ) Value ) )*
+
+ no referencesValue: + + + + + + + + NumberLiteral + + + StringLiteral + + + +
Value    ::= NumberLiteral
+
           | StringLiteral
+
+ referenced by: + + Definition + Query + + StringLiteral: + + + + + + + + QuotedString + + + UnquotedString + + + + +
         ::= QuotedString
+
           | UnquotedString
+
+ referenced by: + + Value + + QuotedString: + + + + + + + + " + + + [^"] + + + " + + + ' + + + [^'] + + + ' + + + + + +
         ::= '"' [^"]* '"'
+
           | "'" [^']* "'"
+
+ referenced by: + + StringLiteral + + UnquotedString: + + + + + + + + [^{space},] + + + + + +
         ::= [^{space},]+
+
+ referenced by: + + StringLiteral + + NumberLiteral: + + + + + + + + 0 + + + [0-7] + + + x + + + [0-9] + + + [A-F] + + + [a-f] + + + - + + + [1-9] + + + [0-9] + + + + + +
         ::= '0' ( [0-7]* | 'x' [0-9A-Fa-f]+ )
+
           | '-'? [1-9] [0-9]+
+
+ referenced by: + + Value + + PropertyName: + + + + + + + + [A-Z] + + + [A-Z] + + + [0-9] + + + _ + + + . + + + + + +
         ::= [A-Z] [A-Z0-9_]* ( '.' [A-Z] [A-Z0-9_]* )*
+
+ referenced by: + + Definition + Query + + + + + +   + + ... generated by Railroad Diagram Generator + + + + + + + + R + R + + + + + + \ No newline at end of file diff --git a/crypto/property/property.c b/crypto/property/property.c new file mode 100644 index 00000000..dea0dfd6 --- /dev/null +++ b/crypto/property/property.c @@ -0,0 +1,507 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include "internal/property.h" +#include "internal/ctype.h" +#include +#include +#include "internal/thread_once.h" +#include "internal/lhash.h" +#include "internal/sparse_array.h" +#include "property_lcl.h" + +/* The number of elements in the query cache before we initiate a flush */ +#define IMPL_CACHE_FLUSH_THRESHOLD 500 + +typedef struct { + OSSL_PROPERTY_LIST *properties; + void *method; + void (*method_destruct)(void *); +} IMPLEMENTATION; + +DEFINE_STACK_OF(IMPLEMENTATION) + +typedef struct { + const char *query; + void *method; + char body[1]; +} QUERY; + +DEFINE_LHASH_OF(QUERY); + +typedef struct { + int nid; + STACK_OF(IMPLEMENTATION) *impls; + LHASH_OF(QUERY) *cache; +} ALGORITHM; + +struct ossl_method_store_st { + size_t nelem; + SPARSE_ARRAY_OF(ALGORITHM) *algs; + OSSL_PROPERTY_LIST *global_properties; + int need_flush; + unsigned int nbits; + unsigned char rand_bits[(IMPL_CACHE_FLUSH_THRESHOLD + 7) / 8]; + CRYPTO_RWLOCK *lock; +}; + +typedef struct { + OSSL_METHOD_STORE *store; + LHASH_OF(QUERY) *cache; + size_t nelem; +} IMPL_CACHE_FLUSH; + +DEFINE_SPARSE_ARRAY_OF(ALGORITHM); + +static void ossl_method_cache_flush(OSSL_METHOD_STORE *store, int nid); +static void ossl_method_cache_flush_all(OSSL_METHOD_STORE *c); + +int ossl_property_read_lock(OSSL_METHOD_STORE *p) +{ + return p != NULL ? CRYPTO_THREAD_read_lock(p->lock) : 0; +} + +int ossl_property_write_lock(OSSL_METHOD_STORE *p) +{ + return p != NULL ? CRYPTO_THREAD_write_lock(p->lock) : 0; +} + +int ossl_property_unlock(OSSL_METHOD_STORE *p) +{ + return p != 0 ? CRYPTO_THREAD_unlock(p->lock) : 0; +} + +int ossl_method_store_init(void) +{ + if (ossl_property_string_init() + && ossl_prop_defn_init() + && ossl_property_parse_init()) + return 1; + + ossl_method_store_cleanup(); + return 0; +} + +void ossl_method_store_cleanup(void) +{ + ossl_property_string_cleanup(); + ossl_prop_defn_cleanup(); +} + +static CRYPTO_ONCE method_store_init_flag = CRYPTO_ONCE_STATIC_INIT; +DEFINE_RUN_ONCE_STATIC(do_method_store_init) +{ + return OPENSSL_init_crypto(0, NULL) + && ossl_method_store_init() + && OPENSSL_atexit(&ossl_method_store_cleanup); +} + +static unsigned long query_hash(const QUERY *a) +{ + return OPENSSL_LH_strhash(a->query); +} + +static int query_cmp(const QUERY *a, const QUERY *b) +{ + return strcmp(a->query, b->query); +} + +static void impl_free(IMPLEMENTATION *impl) +{ + if (impl != NULL) { + if (impl->method_destruct) + impl->method_destruct(impl->method); + OPENSSL_free(impl); + } +} + +static void impl_cache_free(QUERY *elem) +{ + OPENSSL_free(elem); +} + +static void alg_cleanup(size_t idx, ALGORITHM *a) +{ + if (a != NULL) { + sk_IMPLEMENTATION_pop_free(a->impls, &impl_free); + lh_QUERY_doall(a->cache, &impl_cache_free); + lh_QUERY_free(a->cache); + OPENSSL_free(a); + } +} + +OSSL_METHOD_STORE *ossl_method_store_new(void) +{ + OSSL_METHOD_STORE *res = OPENSSL_zalloc(sizeof(*res)); + + if (!RUN_ONCE(&method_store_init_flag, do_method_store_init)) + return 0; + + if (res != NULL) { + if ((res->algs = ossl_sa_ALGORITHM_new()) == NULL) { + OPENSSL_free(res); + return NULL; + } + if ((res->lock = CRYPTO_THREAD_lock_new()) == NULL) { + OPENSSL_free(res->algs); + OPENSSL_free(res); + return NULL; + } + } + return res; +} + +void ossl_method_store_free(OSSL_METHOD_STORE *store) +{ + if (store != NULL) { + ossl_sa_ALGORITHM_doall(store->algs, &alg_cleanup); + ossl_sa_ALGORITHM_free(store->algs); + ossl_property_free(store->global_properties); + CRYPTO_THREAD_lock_free(store->lock); + OPENSSL_free(store); + } +} + +static ALGORITHM *ossl_method_store_retrieve(OSSL_METHOD_STORE *store, int nid) +{ + return ossl_sa_ALGORITHM_get(store->algs, nid); +} + +static int ossl_method_store_insert(OSSL_METHOD_STORE *store, ALGORITHM *alg) +{ + return ossl_sa_ALGORITHM_set(store->algs, alg->nid, alg); +} + +int ossl_method_store_add(OSSL_METHOD_STORE *store, + int nid, const char *properties, + void *method, void (*method_destruct)(void *)) +{ + ALGORITHM *alg = NULL; + IMPLEMENTATION *impl; + int ret = 0; + + if (nid <= 0 || method == NULL || store == NULL) + return 0; + if (properties == NULL) + properties = ""; + + /* Create new entry */ + impl = OPENSSL_malloc(sizeof(*impl)); + if (impl == NULL) + return 0; + impl->method = method; + impl->method_destruct = method_destruct; + + /* + * Insert into the hash table if required. + * + * A write lock is used unconditionally because we wend our way down to the + * property string code which isn't locking friendly. + */ + ossl_property_write_lock(store); + ossl_method_cache_flush(store, nid); + if ((impl->properties = ossl_prop_defn_get(properties)) == NULL) { + if ((impl->properties = ossl_parse_property(properties)) == NULL) + goto err; + ossl_prop_defn_set(properties, impl->properties); + } + + alg = ossl_method_store_retrieve(store, nid); + if (alg == NULL) { + if ((alg = OPENSSL_zalloc(sizeof(*alg))) == NULL + || (alg->impls = sk_IMPLEMENTATION_new_null()) == NULL + || (alg->cache = lh_QUERY_new(&query_hash, &query_cmp)) == NULL) + goto err; + alg->nid = nid; + if (!ossl_method_store_insert(store, alg)) + goto err; + } + + /* Push onto stack */ + if (sk_IMPLEMENTATION_push(alg->impls, impl)) + ret = 1; + ossl_property_unlock(store); + if (ret == 0) + impl_free(impl); + return ret; + +err: + ossl_property_unlock(store); + alg_cleanup(0, alg); + impl_free(impl); + return 0; +} + +int ossl_method_store_remove(OSSL_METHOD_STORE *store, int nid, + const void *method) +{ + ALGORITHM *alg = NULL; + int i; + + if (nid <= 0 || method == NULL || store == NULL) + return 0; + + ossl_property_write_lock(store); + ossl_method_cache_flush(store, nid); + alg = ossl_method_store_retrieve(store, nid); + if (alg == NULL) { + ossl_property_unlock(store); + return 0; + } + + /* + * A sorting find then a delete could be faster but these stacks should be + * relatively small, so we avoid the overhead. Sorting could also surprise + * users when result orderings change (even though they are not guaranteed). + */ + for (i = 0; i < sk_IMPLEMENTATION_num(alg->impls); i++) { + IMPLEMENTATION *impl = sk_IMPLEMENTATION_value(alg->impls, i); + + if (impl->method == method) { + sk_IMPLEMENTATION_delete(alg->impls, i); + ossl_property_unlock(store); + impl_free(impl); + return 1; + } + } + ossl_property_unlock(store); + return 0; +} + +int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid, + const char *prop_query, void **method) +{ + ALGORITHM *alg; + IMPLEMENTATION *impl; + OSSL_PROPERTY_LIST *pq = NULL, *p2; + int ret = 0; + int j; + + if (nid <= 0 || method == NULL || store == NULL) + return 0; + + /* + * This only needs to be a read lock, because queries never create property + * names or value and thus don't modify any of the property string layer. + */ + ossl_property_read_lock(store); + alg = ossl_method_store_retrieve(store, nid); + if (alg == NULL) { + ossl_property_unlock(store); + return 0; + } + + if (prop_query == NULL) { + if ((impl = sk_IMPLEMENTATION_value(alg->impls, 0)) != NULL) { + *method = impl->method; + ret = 1; + } + goto fin; + } + pq = ossl_parse_query(prop_query); + if (pq == NULL) + goto fin; + if (store->global_properties != NULL) { + p2 = ossl_property_merge(pq, store->global_properties); + if (p2 == NULL) + goto fin; + ossl_property_free(pq); + pq = p2; + } + for (j = 0; j < sk_IMPLEMENTATION_num(alg->impls); j++) { + impl = sk_IMPLEMENTATION_value(alg->impls, j); + + if (ossl_property_match(pq, impl->properties)) { + *method = impl->method; + ret = 1; + goto fin; + } + } +fin: + ossl_property_unlock(store); + ossl_property_free(pq); + return ret; +} + +int ossl_method_store_set_global_properties(OSSL_METHOD_STORE *store, + const char *prop_query) { + int ret = 0; + + if (store == NULL) + return 1; + + ossl_property_write_lock(store); + ossl_method_cache_flush_all(store); + if (prop_query == NULL) { + ossl_property_free(store->global_properties); + store->global_properties = NULL; + ossl_property_unlock(store); + return 1; + } + store->global_properties = ossl_parse_query(prop_query); + ret = store->global_properties != NULL; + ossl_property_unlock(store); + return ret; +} + +static void impl_cache_flush_alg(size_t idx, ALGORITHM *alg) +{ + lh_QUERY_doall(alg->cache, &impl_cache_free); + lh_QUERY_flush(alg->cache); +} + +static void ossl_method_cache_flush(OSSL_METHOD_STORE *store, int nid) +{ + ALGORITHM *alg = ossl_method_store_retrieve(store, nid); + + if (alg != NULL) { + store->nelem -= lh_QUERY_num_items(alg->cache); + impl_cache_flush_alg(0, alg); + } +} + +static void ossl_method_cache_flush_all(OSSL_METHOD_STORE *store) +{ + ossl_sa_ALGORITHM_doall(store->algs, &impl_cache_flush_alg); + store->nelem = 0; +} + +IMPLEMENT_LHASH_DOALL_ARG(QUERY, IMPL_CACHE_FLUSH); + +/* + * Flush an element from the query cache (perhaps). + * + * In order to avoid taking a write lock to keep accurate LRU information or + * using atomic operations to approximate similar, the procedure used here + * is to stochastically flush approximately half the cache. Since generating + * random numbers is relatively expensive, we produce them in blocks and + * consume them as we go, saving generated bits between generations of flushes. + * + * This procedure isn't ideal, LRU would be better. However, in normal + * operation, reaching a full cache would be quite unexpected. It means + * that no steady state of algorithm queries has been reached. I.e. it is most + * likely an attack of some form. A suboptimal clearance strategy that doesn't + * degrade performance of the normal case is preferable to a more refined + * approach that imposes a performance impact. + */ +static void impl_cache_flush_cache(QUERY *c, IMPL_CACHE_FLUSH *state) +{ + OSSL_METHOD_STORE *store = state->store; + unsigned int n; + + if (store->nbits == 0) { + if (!RAND_bytes(store->rand_bits, sizeof(store->rand_bits))) + return; + store->nbits = sizeof(store->rand_bits) * 8; + } + n = --store->nbits; + if ((store->rand_bits[n >> 3] & (1 << (n & 7))) != 0) + OPENSSL_free(lh_QUERY_delete(state->cache, c)); + else + state->nelem++; +} + +static void impl_cache_flush_one_alg(size_t idx, ALGORITHM *alg, void *v) +{ + IMPL_CACHE_FLUSH *state = (IMPL_CACHE_FLUSH *)v; + + state->cache = alg->cache; + lh_QUERY_doall_IMPL_CACHE_FLUSH(state->cache, &impl_cache_flush_cache, + state); +} + +static void ossl_method_cache_flush_some(OSSL_METHOD_STORE *store) +{ + IMPL_CACHE_FLUSH state; + + state.nelem = 0; + state.store = store; + ossl_sa_ALGORITHM_doall_arg(store->algs, &impl_cache_flush_one_alg, &state); + store->need_flush = 0; + store->nelem = state.nelem; +} + +int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, int nid, + const char *prop_query, void **method) +{ + ALGORITHM *alg; + QUERY elem, *r; + + if (nid <= 0 || store == NULL) + return 0; + + ossl_property_read_lock(store); + alg = ossl_method_store_retrieve(store, nid); + if (alg == NULL) { + ossl_property_unlock(store); + return 0; + } + + elem.query = prop_query; + r = lh_QUERY_retrieve(alg->cache, &elem); + if (r == NULL) { + ossl_property_unlock(store); + return 0; + } + *method = r->method; + ossl_property_unlock(store); + return 1; +} + +int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, int nid, + const char *prop_query, void *method) +{ + QUERY elem, *old, *p = NULL; + ALGORITHM *alg; + size_t len; + + if (nid <= 0 || store == NULL) + return 0; + if (prop_query == NULL) + return 1; + + ossl_property_write_lock(store); + if (store->need_flush) + ossl_method_cache_flush_some(store); + alg = ossl_method_store_retrieve(store, nid); + if (alg == NULL) { + ossl_property_unlock(store); + return 0; + } + + if (method == NULL) { + elem.query = prop_query; + lh_QUERY_delete(alg->cache, &elem); + ossl_property_unlock(store); + return 1; + } + p = OPENSSL_malloc(sizeof(*p) + (len = strlen(prop_query))); + if (p != NULL) { + p->query = p->body; + p->method = method; + memcpy((char *)p->query, prop_query, len + 1); + if ((old = lh_QUERY_insert(alg->cache, p)) != NULL) + OPENSSL_free(old); + if (old != NULL || !lh_QUERY_error(alg->cache)) { + store->nelem++; + if (store->nelem >= IMPL_CACHE_FLUSH_THRESHOLD) + store->need_flush = 1; + ossl_property_unlock(store); + return 1; + } + } + ossl_property_unlock(store); + OPENSSL_free(p); + return 0; +} diff --git a/crypto/property/property_err.c b/crypto/property/property_err.c new file mode 100644 index 00000000..619e5e7d --- /dev/null +++ b/crypto/property/property_err.c @@ -0,0 +1,61 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-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 +#include "internal/propertyerr.h" + +#ifndef OPENSSL_NO_ERR + +static const ERR_STRING_DATA PROP_str_functs[] = { + {ERR_PACK(ERR_LIB_PROP, PROP_F_OSSL_PARSE_PROPERTY, 0), + "ossl_parse_property"}, + {ERR_PACK(ERR_LIB_PROP, PROP_F_OSSL_PARSE_QUERY, 0), "ossl_parse_query"}, + {ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_HEX, 0), "parse_hex"}, + {ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_NAME, 0), "parse_name"}, + {ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_NUMBER, 0), "parse_number"}, + {ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_OCT, 0), "parse_oct"}, + {ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_STRING, 0), "parse_string"}, + {ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_UNQUOTED, 0), "parse_unquoted"}, + {0, NULL} +}; + +static const ERR_STRING_DATA PROP_str_reasons[] = { + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NAME_TOO_LONG), "name too long"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_ASCII_CHARACTER), + "not an ascii character"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_HEXADECIMAL_DIGIT), + "not an hexadecimal digit"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_IDENTIFIER), "not an identifier"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_OCTAL_DIGIT), + "not an octal digit"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_A_DECIMAL_DIGIT), + "not a decimal digit"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NO_MATCHING_STRING_DELIMETER), + "no matching string delimeter"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NO_VALUE), "no value"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_PARSE_FAILED), "parse failed"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_STRING_TOO_LONG), "string too long"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_TRAILING_CHARACTERS), + "trailing characters"}, + {0, NULL} +}; + +#endif + +int ERR_load_PROP_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(PROP_str_functs[0].error) == NULL) { + ERR_load_strings_const(PROP_str_functs); + ERR_load_strings_const(PROP_str_reasons); + } +#endif + return 1; +} diff --git a/crypto/property/property_lcl.h b/crypto/property/property_lcl.h new file mode 100644 index 00000000..faf3fe15 --- /dev/null +++ b/crypto/property/property_lcl.h @@ -0,0 +1,51 @@ +/* + * 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 + */ + +#include +#include "internal/property.h" + +typedef struct ossl_property_list_st OSSL_PROPERTY_LIST; +typedef int OSSL_PROPERTY_IDX; + +/* Initialisation and finalisation for subsystem */ +int ossl_method_store_init(void); +void ossl_method_store_cleanup(void); + +/* Property string functions */ +OSSL_PROPERTY_IDX ossl_property_name(const char *s, int create); +OSSL_PROPERTY_IDX ossl_property_value(const char *s, int create); +int ossl_property_string_init(void); +void ossl_property_string_cleanup(void); + +/* Property list functions */ +int ossl_property_parse_init(void); +void ossl_property_free(OSSL_PROPERTY_LIST *p); +int ossl_property_match(const OSSL_PROPERTY_LIST *query, + const OSSL_PROPERTY_LIST *defn); +OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a, + const OSSL_PROPERTY_LIST *b); + +/* Property definition functions */ +OSSL_PROPERTY_LIST *ossl_parse_property(const char *s); + +/* Property query functions */ +OSSL_PROPERTY_LIST *ossl_parse_query(const char *s); + +/* Property definition cache functions */ +int ossl_prop_defn_init(void); +void ossl_prop_defn_cleanup(void); +OSSL_PROPERTY_LIST *ossl_prop_defn_get(const char *prop); +int ossl_prop_defn_set(const char *prop, OSSL_PROPERTY_LIST *pl); + +/* Property cache lock / unlock */ +int ossl_property_write_lock(OSSL_METHOD_STORE *); +int ossl_property_read_lock(OSSL_METHOD_STORE *); +int ossl_property_unlock(OSSL_METHOD_STORE *); + diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c new file mode 100644 index 00000000..2094d38e --- /dev/null +++ b/crypto/property/property_parse.c @@ -0,0 +1,545 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include "internal/propertyerr.h" +#include "internal/property.h" +#include "internal/ctype.h" +#include "internal/nelem.h" +#include "property_lcl.h" +#include "e_os.h" + +typedef enum { + PROPERTY_TYPE_STRING, PROPERTY_TYPE_NUMBER, + PROPERTY_TYPE_VALUE_UNDEFINED +} PROPERTY_TYPE; + +typedef enum { + PROPERTY_OPER_EQ, PROPERTY_OPER_NE, PROPERTY_OVERRIDE +} PROPERTY_OPER; + +typedef struct { + OSSL_PROPERTY_IDX name_idx; + PROPERTY_TYPE type; + PROPERTY_OPER oper; + union { + int64_t int_val; /* Signed integer */ + OSSL_PROPERTY_IDX str_val; /* String */ + } v; +} PROPERTY_DEFINITION; + +struct ossl_property_list_st { + int n; + PROPERTY_DEFINITION properties[1]; +}; + +static OSSL_PROPERTY_IDX ossl_property_true, ossl_property_false; + +DEFINE_STACK_OF(PROPERTY_DEFINITION) + +static const char *skip_space(const char *s) +{ + while (ossl_isspace(*s)) + s++; + return s; +} + +static int match_ch(const char *t[], char m) +{ + const char *s = *t; + + if (*s == m) { + *t = skip_space(s + 1); + return 1; + } + return 0; +} + +#define MATCH(s, m) match(s, m, sizeof(m) - 1) + +static int match(const char *t[], const char m[], size_t m_len) +{ + const char *s = *t; + + if (strncasecmp(s, m, m_len) == 0) { + *t = skip_space(s + m_len); + return 1; + } + return 0; +} + +static int parse_name(const char *t[], int create, OSSL_PROPERTY_IDX *idx) +{ + char name[100]; + int err = 0; + size_t i = 0; + const char *s = *t; + int user_name = 0; + + for (;;) { + if (!ossl_isalpha(*s)) { + PROPerr(PROP_F_PARSE_NAME, PROP_R_NOT_AN_IDENTIFIER); + return 0; + } + do { + if (i < sizeof(name) - 1) + name[i++] = ossl_tolower(*s); + else + err = 1; + } while (*++s == '_' || ossl_isalnum(*s)); + if (*s != '.') + break; + user_name = 1; + if (i < sizeof(name) - 1) + name[i++] = *s; + else + err = 1; + s++; + } + name[i] = '\0'; + *t = skip_space(s); + if (!err) { + *idx = ossl_property_name(name, user_name && create); + return 1; + } + PROPerr(PROP_F_PARSE_NAME, PROP_R_NAME_TOO_LONG); + return 0; +} + +static int parse_number(const char *t[], PROPERTY_DEFINITION *res) +{ + const char *s = *t; + int64_t v = 0; + + if (!ossl_isdigit(*s)) + return 0; + do { + v = v * 10 + (*s++ - '0'); + } while (ossl_isdigit(*s)); + if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { + PROPerr(PROP_F_PARSE_NUMBER, PROP_R_NOT_A_DECIMAL_DIGIT); + return 0; + } + *t = skip_space(s); + res->type = PROPERTY_TYPE_NUMBER; + res->v.int_val = v; + return 1; +} + +static int parse_hex(const char *t[], PROPERTY_DEFINITION *res) +{ + const char *s = *t; + int64_t v = 0; + + if (!ossl_isxdigit(*s)) + return 0; + do { + v <<= 4; + if (ossl_isdigit(*s)) + v += *s - '0'; + else + v += ossl_tolower(*s) - 'a'; + } while (ossl_isxdigit(*++s)); + if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { + PROPerr(PROP_F_PARSE_HEX, PROP_R_NOT_AN_HEXADECIMAL_DIGIT); + return 0; + } + *t = skip_space(s); + res->type = PROPERTY_TYPE_NUMBER; + res->v.int_val = v; + return 1; +} + +static int parse_oct(const char *t[], PROPERTY_DEFINITION *res) +{ + const char *s = *t; + int64_t v = 0; + + if (*s == '9' || *s == '8' || !ossl_isdigit(*s)) + return 0; + do { + v = (v << 3) + (*s - '0'); + } while (ossl_isdigit(*++s) && *s != '9' && *s != '8'); + if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { + PROPerr(PROP_F_PARSE_OCT, PROP_R_NOT_AN_OCTAL_DIGIT); + return 0; + } + *t = skip_space(s); + res->type = PROPERTY_TYPE_NUMBER; + res->v.int_val = v; + return 1; +} + +static int parse_string(const char *t[], char delim, PROPERTY_DEFINITION *res, + const int create) +{ + char v[1000]; + const char *s = *t; + size_t i = 0; + int err = 0; + + while (*s != '\0' && *s != delim) { + if (i < sizeof(v) - 1) + v[i++] = *s; + else + err = 1; + s++; + } + if (*s == '\0') { + PROPerr(PROP_F_PARSE_STRING, + PROP_R_NO_MATCHING_STRING_DELIMETER); + return 0; + } + v[i] = '\0'; + *t = skip_space(s + 1); + if (err) + PROPerr(PROP_F_PARSE_STRING, PROP_R_STRING_TOO_LONG); + else + res->v.str_val = ossl_property_value(v, create); + res->type = PROPERTY_TYPE_STRING; + return !err; +} + +static int parse_unquoted(const char *t[], PROPERTY_DEFINITION *res, + const int create) +{ + char v[1000]; + const char *s = *t; + size_t i = 0; + int err = 0; + + if (*s == '\0' || *s == ',') + return 0; + while (ossl_isprint(*s) && !ossl_isspace(*s) && *s != ',') { + if (i < sizeof(v) - 1) + v[i++] = ossl_tolower(*s); + else + err = 1; + s++; + } + if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { + PROPerr(PROP_F_PARSE_UNQUOTED, PROP_R_NOT_AN_ASCII_CHARACTER); + return 0; + } + v[i] = 0; + *t = skip_space(s); + if (err) + PROPerr(PROP_F_PARSE_UNQUOTED, PROP_R_STRING_TOO_LONG); + else + res->v.str_val = ossl_property_value(v, create); + res->type = PROPERTY_TYPE_STRING; + return !err; +} + +static int parse_value(const char *t[], PROPERTY_DEFINITION *res, int create) +{ + const char *s = *t; + int r = 0; + + if (*s == '"' || *s == '\'') { + s++; + r = parse_string(&s, s[-1], res, create); + } else if (*s == '+') { + s++; + r = parse_number(&s, res); + } else if (*s == '-') { + s++; + r = parse_number(&s, res); + res->v.int_val = -res->v.int_val; + } else if (*s == '0' && s[1] == 'x') { + s += 2; + r = parse_hex(&s, res); + } else if (*s == '0' && ossl_isdigit(s[1])) { + s++; + r = parse_oct(&s, res); + } else if (ossl_isdigit(*s)) { + return parse_number(t, res); + } else if (ossl_isalpha(*s)) + return parse_unquoted(t, res, create); + if (r) + *t = s; + return r; +} + +static int pd_compare(const PROPERTY_DEFINITION *const *p1, + const PROPERTY_DEFINITION *const *p2) +{ + const PROPERTY_DEFINITION *pd1 = *p1; + const PROPERTY_DEFINITION *pd2 = *p2; + + if (pd1->name_idx < pd2->name_idx) + return -1; + if (pd1->name_idx > pd2->name_idx) + return 1; + return 0; +} + +static void pd_free(PROPERTY_DEFINITION *pd) +{ + OPENSSL_free(pd); +} + +/* + * Convert a stack of property definitions and queries into a fixed array. + * The items are sorted for efficient query. The stack is not freed. + */ +static OSSL_PROPERTY_LIST *stack_to_property_list(STACK_OF(PROPERTY_DEFINITION) + *sk) +{ + const int n = sk_PROPERTY_DEFINITION_num(sk); + OSSL_PROPERTY_LIST *r; + int i; + + r = OPENSSL_malloc(sizeof(*r) + + (n == 0 ? 0 : n - 1) * sizeof(r->properties[0])); + if (r != NULL) { + sk_PROPERTY_DEFINITION_sort(sk); + + for (i = 0; i < n; i++) + r->properties[i] = *sk_PROPERTY_DEFINITION_value(sk, i); + r->n = n; + } + return r; +} + +OSSL_PROPERTY_LIST *ossl_parse_property(const char *defn) +{ + PROPERTY_DEFINITION *prop = NULL; + OSSL_PROPERTY_LIST *res = NULL; + STACK_OF(PROPERTY_DEFINITION) *sk; + const char *s = defn; + int done; + + if (s == NULL || (sk = sk_PROPERTY_DEFINITION_new(&pd_compare)) == NULL) + return NULL; + + s = skip_space(s); + done = *s == '\0'; + while (!done) { + prop = OPENSSL_malloc(sizeof(*prop)); + if (prop == NULL) + goto err; + memset(&prop->v, 0, sizeof(prop->v)); + if (!parse_name(&s, 1, &prop->name_idx)) + goto err; + prop->oper = PROPERTY_OPER_EQ; + if (prop->name_idx == 0) { + PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_PARSE_FAILED); + goto err; + } + if (match_ch(&s, '=')) { + if (!parse_value(&s, prop, 1)) { + PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_NO_VALUE); + goto err; + } + } else { + /* A name alone means a true Boolean */ + prop->type = PROPERTY_TYPE_STRING; + prop->v.str_val = ossl_property_true; + } + + if (!sk_PROPERTY_DEFINITION_push(sk, prop)) + goto err; + prop = NULL; + done = !match_ch(&s, ','); + } + if (*s != '\0') { + PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_TRAILING_CHARACTERS); + goto err; + } + res = stack_to_property_list(sk); + +err: + OPENSSL_free(prop); + sk_PROPERTY_DEFINITION_pop_free(sk, &pd_free); + return res; +} + +OSSL_PROPERTY_LIST *ossl_parse_query(const char *s) +{ + STACK_OF(PROPERTY_DEFINITION) *sk; + OSSL_PROPERTY_LIST *res = NULL; + PROPERTY_DEFINITION *prop = NULL; + int done; + + if (s == NULL || (sk = sk_PROPERTY_DEFINITION_new(&pd_compare)) == NULL) + return NULL; + + s = skip_space(s); + done = *s == '\0'; + while (!done) { + prop = OPENSSL_malloc(sizeof(*prop)); + if (prop == NULL) + goto err; + memset(&prop->v, 0, sizeof(prop->v)); + + if (match_ch(&s, '-')) { + prop->oper = PROPERTY_OVERRIDE; + if (!parse_name(&s, 0, &prop->name_idx)) + goto err; + goto skip_value; + } + if (!parse_name(&s, 0, &prop->name_idx)) + goto err; + + if (match_ch(&s, '=')) { + prop->oper = PROPERTY_OPER_EQ; + } else if (MATCH(&s, "!=")) { + prop->oper = PROPERTY_OPER_NE; + } else { + /* A name alone is a Boolean comparison for true */ + prop->oper = PROPERTY_OPER_EQ; + prop->type = PROPERTY_TYPE_STRING; + prop->v.str_val = ossl_property_true; + goto skip_value; + } + if (!parse_value(&s, prop, 0)) + prop->type = PROPERTY_TYPE_VALUE_UNDEFINED; + +skip_value: + if (!sk_PROPERTY_DEFINITION_push(sk, prop)) + goto err; + prop = NULL; + done = !match_ch(&s, ','); + } + if (*s != '\0') { + PROPerr(PROP_F_OSSL_PARSE_QUERY, PROP_R_TRAILING_CHARACTERS); + goto err; + } + res = stack_to_property_list(sk); + +err: + OPENSSL_free(prop); + sk_PROPERTY_DEFINITION_pop_free(sk, &pd_free); + return res; +} + +int ossl_property_match(const OSSL_PROPERTY_LIST *query, + const OSSL_PROPERTY_LIST *defn) +{ + const PROPERTY_DEFINITION *const q = query->properties; + const PROPERTY_DEFINITION *const d = defn->properties; + int i = 0, j = 0; + PROPERTY_OPER oper; + + while (i < query->n) { + if ((oper = q[i].oper) == PROPERTY_OVERRIDE) { + i++; + continue; + } + if (j < defn->n) { + if (q[i].name_idx > d[j].name_idx) { /* skip defn, not in query */ + j++; + continue; + } + if (q[i].name_idx == d[j].name_idx) { /* both in defn and query */ + const int eq = q[i].type == d[j].type + && memcmp(&q[i].v, &d[j].v, sizeof(q[i].v)) == 0; + + if ((eq && oper != PROPERTY_OPER_EQ) + || (!eq && oper != PROPERTY_OPER_NE)) + return 0; + i++; + j++; + continue; + } + } + + /* + * Handle the cases of a missing value and a query with no corresponding + * definition. The former fails for any comparision except inequality, + * the latter is treated as a comparison against the Boolean false. + */ + if (q[i].type == PROPERTY_TYPE_VALUE_UNDEFINED) { + if (oper != PROPERTY_OPER_NE) + return 0; + } else if (q[i].type != PROPERTY_TYPE_STRING + || (oper == PROPERTY_OPER_EQ + && q[i].v.str_val != ossl_property_false) + || (oper == PROPERTY_OPER_NE + && q[i].v.str_val == ossl_property_false)) { + return 0; + } + i++; + } + return 1; +} + +void ossl_property_free(OSSL_PROPERTY_LIST *p) +{ + OPENSSL_free(p); +} + +/* + * Merge two property lists. + * If there is a common name, the one from the first list is used. + */ +OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a, + const OSSL_PROPERTY_LIST *b) +{ + const PROPERTY_DEFINITION *const ap = a->properties; + const PROPERTY_DEFINITION *const bp = b->properties; + const PROPERTY_DEFINITION *copy; + OSSL_PROPERTY_LIST *r; + int i, j, n; + const int t = a->n + b->n; + + r = OPENSSL_malloc(sizeof(*r) + + (t == 0 ? 0 : t - 1) * sizeof(r->properties[0])); + if (r == NULL) + return NULL; + + for (i = j = n = 0; i < a->n || j < b->n; n++) { + if (i >= a->n) { + copy = &bp[j++]; + } else if (j >= b->n) { + copy = &ap[i++]; + } else if (ap[i].name_idx <= bp[j].name_idx) { + if (ap[i].name_idx == bp[j].name_idx) + j++; + copy = &ap[i++]; + } else { + copy = &bp[j++]; + } + memcpy(r->properties + n, copy, sizeof(r->properties[0])); + } + r->n = n; + if (n != t) + r = OPENSSL_realloc(r, sizeof(*r) + (n - 1) * sizeof(r->properties[0])); + return r; +} + +int ossl_property_parse_init(void) +{ + static const char *const predefined_names[] = { + "default", /* Being provided by the default built-in provider */ + "provider", /* Name of provider (default, fips) */ + "version", /* Version number of this provider */ + "fips", /* FIPS supporting provider */ + "engine", /* An old style engine masquerading as a provider */ + }; + size_t i; + + for (i = 0; i < OSSL_NELEM(predefined_names); i++) + if (ossl_property_name(predefined_names[i], 1) == 0) + goto err; + + /* Pre-populate the two Boolean values */ + if ((ossl_property_true = ossl_property_value("yes", 1)) == 0 + || (ossl_property_false = ossl_property_value("no", 1)) == 0) + goto err; + + return 1; +err: + return 0; +} diff --git a/crypto/property/property_string.c b/crypto/property/property_string.c new file mode 100644 index 00000000..7f6e30ef --- /dev/null +++ b/crypto/property/property_string.c @@ -0,0 +1,137 @@ +/* + * 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 + */ + +#include +#include +#include +#include "internal/lhash.h" +#include "property_lcl.h" + +/* + * Property strings are a consolidation of all strings seen by the property + * subsystem. There are two name spaces to keep property names separate from + * property values (numeric values are not expected to be cached however). + * They allow a rapid conversion from a string to a unique index and any + * subsequent string comparison can be done via an integer compare. + * + * This implementation uses OpenSSL's standard hash table. There are more + * space and time efficient algorithms if this becomes a bottleneck. + */ + +typedef struct { + const char *s; + OSSL_PROPERTY_IDX idx; + char body[1]; +} PROPERTY_STRING; + +DEFINE_LHASH_OF(PROPERTY_STRING); +typedef LHASH_OF(PROPERTY_STRING) PROP_TABLE; + +static PROP_TABLE *prop_names; +static PROP_TABLE *prop_values; +static OSSL_PROPERTY_IDX prop_name_idx = 0; +static OSSL_PROPERTY_IDX prop_value_idx = 0; + +static unsigned long property_hash(const PROPERTY_STRING *a) +{ + return OPENSSL_LH_strhash(a->s); +} + +static int property_cmp(const PROPERTY_STRING *a, const PROPERTY_STRING *b) +{ + return strcmp(a->s, b->s); +} + +static void property_free(PROPERTY_STRING *ps) +{ + OPENSSL_free(ps); +} + +static void property_table_free(PROP_TABLE **pt) +{ + PROP_TABLE *t = *pt; + + if (t != NULL) { + lh_PROPERTY_STRING_doall(t, &property_free); + lh_PROPERTY_STRING_free(t); + *pt = NULL; + } +} + +static PROPERTY_STRING *new_property_string(const char *s, + OSSL_PROPERTY_IDX *pidx) +{ + const size_t l = strlen(s); + PROPERTY_STRING *ps = OPENSSL_malloc(sizeof(*ps) + l); + + if (ps != NULL) { + memcpy(ps->body, s, l + 1); + ps->s = ps->body; + ps->idx = ++*pidx; + if (ps->idx == 0) { + OPENSSL_free(ps); + return NULL; + } + } + return ps; +} + +static OSSL_PROPERTY_IDX ossl_property_string(PROP_TABLE *t, + OSSL_PROPERTY_IDX *pidx, + const char *s) +{ + PROPERTY_STRING p, *ps, *ps_new; + + p.s = s; + ps = lh_PROPERTY_STRING_retrieve(t, &p); + if (ps == NULL && pidx != NULL) + if ((ps_new = new_property_string(s, pidx)) != NULL) { + lh_PROPERTY_STRING_insert(t, ps_new); + if (lh_PROPERTY_STRING_error(t)) { + property_free(ps_new); + return 0; + } + ps = ps_new; + } + return ps != NULL ? ps->idx : 0; +} + +OSSL_PROPERTY_IDX ossl_property_name(const char *s, int create) +{ + return ossl_property_string(prop_names, create ? &prop_name_idx : NULL, s); +} + +OSSL_PROPERTY_IDX ossl_property_value(const char *s, int create) +{ + return ossl_property_string(prop_values, create ? &prop_value_idx : NULL, s); +} + +int ossl_property_string_init(void) +{ + prop_names = lh_PROPERTY_STRING_new(&property_hash, &property_cmp); + if (prop_names == NULL) + return 0; + + prop_values = lh_PROPERTY_STRING_new(&property_hash, &property_cmp); + if (prop_values == NULL) + goto err; + return 1; + +err: + ossl_property_string_cleanup(); + return 0; +} + +void ossl_property_string_cleanup(void) +{ + property_table_free(&prop_names); + property_table_free(&prop_values); + prop_name_idx = prop_value_idx = 0; +} diff --git a/crypto/sha/asm/keccak1600-armv4.pl b/crypto/sha/asm/keccak1600-armv4.pl index 44504fa8..be411ed7 100755 --- a/crypto/sha/asm/keccak1600-armv4.pl +++ b/crypto/sha/asm/keccak1600-armv4.pl @@ -113,8 +113,6 @@ my @T = map([ 8*$_, 8*($_+1), 8*($_+2), 8*($_+3), 8*($_+4) ], (30,35,40,45,50)); $code.=<<___; #include "arm_arch.h" -.text - #if defined(__thumb2__) .syntax unified .thumb @@ -122,6 +120,8 @@ $code.=<<___; .code 32 #endif +.text + .type iotas32, %object .align 5 iotas32: @@ -691,7 +691,14 @@ ___ $code.=<<___; blo .Lround2x +#if __ARM_ARCH__>=5 ldr pc,[sp,#440] +#else + ldr lr,[sp,#440] + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif .size KeccakF1600_int,.-KeccakF1600_int .type KeccakF1600, %function @@ -730,7 +737,14 @@ KeccakF1600: stmia @E[1], {@C[0]-@C[9]} add sp,sp,#440+20 +#if __ARM_ARCH__>=5 ldmia sp!,{r4-r11,pc} +#else + ldmia sp!,{r4-r11,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif .size KeccakF1600,.-KeccakF1600 ___ { my ($A_flat,$inp,$len,$bsz) = map("r$_",(10..12,14)); @@ -905,7 +919,14 @@ SHA3_absorb: .Labsorb_abort: add sp,sp,#456+32 mov r0,$len @ return value +#if __ARM_ARCH__>=5 ldmia sp!,{r4-r12,pc} +#else + ldmia sp!,{r4-r12,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif .size SHA3_absorb,.-SHA3_absorb ___ } @@ -1055,7 +1076,14 @@ SHA3_squeeze: .align 4 .Lsqueeze_done: add sp,sp,#24 +#if __ARM_ARCH__>=5 ldmia sp!,{r4-r10,pc} +#else + ldmia sp!,{r4-r10,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif .size SHA3_squeeze,.-SHA3_squeeze ___ } @@ -1265,7 +1293,7 @@ KeccakF1600_neon: subs r3, r3, #1 bne .Loop_neon - bx lr + ret .size KeccakF1600_neon,.-KeccakF1600_neon .global SHA3_absorb_neon diff --git a/crypto/sha/asm/keccak1600-armv8.pl b/crypto/sha/asm/keccak1600-armv8.pl index 7baf0468..bd15a52a 100755 --- a/crypto/sha/asm/keccak1600-armv8.pl +++ b/crypto/sha/asm/keccak1600-armv8.pl @@ -121,6 +121,7 @@ $code.=<<___; .align 5 KeccakF1600_int: adr $C[2],iotas + .inst 0xd503233f // paciasp stp $C[2],x30,[sp,#16] // 32 bytes on top are mine b .Loop .align 4 @@ -292,12 +293,14 @@ $code.=<<___; bne .Loop ldr x30,[sp,#24] + .inst 0xd50323bf // autiasp ret .size KeccakF1600_int,.-KeccakF1600_int .type KeccakF1600,%function .align 5 KeccakF1600: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-128]! add x29,sp,#0 stp x19,x20,[sp,#16] @@ -347,6 +350,7 @@ KeccakF1600: ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldp x29,x30,[sp],#128 + .inst 0xd50323bf // autiasp ret .size KeccakF1600,.-KeccakF1600 @@ -354,6 +358,7 @@ KeccakF1600: .type SHA3_absorb,%function .align 5 SHA3_absorb: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-128]! add x29,sp,#0 stp x19,x20,[sp,#16] @@ -451,6 +456,7 @@ $code.=<<___; ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldp x29,x30,[sp],#128 + .inst 0xd50323bf // autiasp ret .size SHA3_absorb,.-SHA3_absorb ___ @@ -461,6 +467,7 @@ $code.=<<___; .type SHA3_squeeze,%function .align 5 SHA3_squeeze: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-48]! add x29,sp,#0 stp x19,x20,[sp,#16] @@ -523,6 +530,7 @@ SHA3_squeeze: ldp x19,x20,[sp,#16] ldp x21,x22,[sp,#32] ldp x29,x30,[sp],#48 + .inst 0xd50323bf // autiasp ret .size SHA3_squeeze,.-SHA3_squeeze ___ @@ -641,6 +649,7 @@ KeccakF1600_ce: .type KeccakF1600_cext,%function .align 5 KeccakF1600_cext: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-80]! add x29,sp,#0 stp d8,d9,[sp,#16] // per ABI requirement @@ -673,6 +682,7 @@ $code.=<<___; ldp d12,d13,[sp,#48] ldp d14,d15,[sp,#64] ldr x29,[sp],#80 + .inst 0xd50323bf // autiasp ret .size KeccakF1600_cext,.-KeccakF1600_cext ___ @@ -685,6 +695,7 @@ $code.=<<___; .type SHA3_absorb_cext,%function .align 5 SHA3_absorb_cext: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-80]! add x29,sp,#0 stp d8,d9,[sp,#16] // per ABI requirement @@ -756,6 +767,7 @@ $code.=<<___; ldp d12,d13,[sp,#48] ldp d14,d15,[sp,#64] ldp x29,x30,[sp],#80 + .inst 0xd50323bf // autiasp ret .size SHA3_absorb_cext,.-SHA3_absorb_cext ___ @@ -767,6 +779,7 @@ $code.=<<___; .type SHA3_squeeze_cext,%function .align 5 SHA3_squeeze_cext: + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-16]! add x29,sp,#0 mov x9,$ctx @@ -822,6 +835,7 @@ SHA3_squeeze_cext: .Lsqueeze_done_ce: ldr x29,[sp],#16 + .inst 0xd50323bf // autiasp ret .size SHA3_squeeze_cext,.-SHA3_squeeze_cext ___ diff --git a/crypto/sha/asm/sha1-armv4-large.pl b/crypto/sha/asm/sha1-armv4-large.pl index cdacbd46..cd0b95ad 100644 --- a/crypto/sha/asm/sha1-armv4-large.pl +++ b/crypto/sha/asm/sha1-armv4-large.pl @@ -187,7 +187,6 @@ ___ $code=<<___; #include "arm_arch.h" -.text #if defined(__thumb2__) .syntax unified .thumb @@ -195,6 +194,8 @@ $code=<<___; .code 32 #endif +.text + .global sha1_block_data_order .type sha1_block_data_order,%function @@ -202,12 +203,14 @@ $code=<<___; sha1_block_data_order: #if __ARM_MAX_ARCH__>=7 .Lsha1_block: - adr r3,.Lsha1_block ldr r12,.LOPENSSL_armcap +# if !defined(_WIN32) + adr r3,.Lsha1_block ldr r12,[r3,r12] @ OPENSSL_armcap_P -#ifdef __APPLE__ +# endif +# if defined(__APPLE__) || defined(_WIN32) ldr r12,[r12] -#endif +# endif tst r12,#ARMV8_SHA1 bne .LARMv8 tst r12,#ARMV7_NEON @@ -311,7 +314,11 @@ $code.=<<___; .LK_60_79: .word 0xca62c1d6 #if __ARM_MAX_ARCH__>=7 .LOPENSSL_armcap: +# ifdef _WIN32 +.word OPENSSL_armcap_P +# else .word OPENSSL_armcap_P-.Lsha1_block +# endif #endif .asciz "SHA1 block transform for ARMv4/NEON/ARMv8, CRYPTOGAMS by " .align 5 @@ -613,14 +620,15 @@ my ($ABCD,$E,$E0,$E1)=map("q$_",(0..3)); my @MSG=map("q$_",(4..7)); my @Kxx=map("q$_",(8..11)); my ($W0,$W1,$ABCD_SAVE)=map("q$_",(12..14)); +my $_byte = ($flavour =~ /win/ ? "DCB" : ".byte"); $code.=<<___; #if __ARM_MAX_ARCH__>=7 # if defined(__thumb2__) -# define INST(a,b,c,d) .byte c,d|0xf,a,b +# define INST(a,b,c,d) $_byte c,d|0xf,a,b # else -# define INST(a,b,c,d) .byte a,b,c,d|0x10 +# define INST(a,b,c,d) $_byte a,b,c,d|0x10 # endif .type sha1_block_data_order_armv8,%function diff --git a/crypto/sha/asm/sha1-armv8.pl b/crypto/sha/asm/sha1-armv8.pl index a695b2c4..7a0cbf53 100644 --- a/crypto/sha/asm/sha1-armv8.pl +++ b/crypto/sha/asm/sha1-armv8.pl @@ -58,10 +58,10 @@ $code.=<<___ if ($i<15 && !($i&1)); lsr @Xx[$i+1],@Xx[$i],#32 ___ $code.=<<___ if ($i<14 && !($i&1)); - ldr @Xx[$i+2],[$inp,#`($i+2)*4-64`] + ldur @Xx[$i+2],[$inp,#`($i+2)*4-64`] ___ $code.=<<___ if ($i<14 && ($i&1)); -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror @Xx[$i+1],@Xx[$i+1],#32 #else rev32 @Xx[$i+1],@Xx[$i+1] @@ -171,23 +171,19 @@ ___ } $code.=<<___; -#include "arm_arch.h" +#ifndef __KERNEL__ +# include "arm_arch.h" +.extern OPENSSL_armcap_P +#endif .text -.extern OPENSSL_armcap_P .globl sha1_block_data_order .type sha1_block_data_order,%function .align 6 sha1_block_data_order: -#ifdef __ILP32__ - ldrsw x16,.LOPENSSL_armcap_P -#else - ldr x16,.LOPENSSL_armcap_P -#endif - adr x17,.LOPENSSL_armcap_P - add x16,x16,x17 - ldr w16,[x16] + adrp x16,OPENSSL_armcap_P + ldr w16,[x16,#:lo12:OPENSSL_armcap_P] tst w16,#ARMV8_SHA1 b.ne .Lv8_entry @@ -208,7 +204,7 @@ sha1_block_data_order: movz $K,#0x7999 sub $num,$num,#1 movk $K,#0x5a82,lsl#16 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror $Xx[0],@Xx[0],#32 #else rev32 @Xx[0],@Xx[0] @@ -321,15 +317,11 @@ $code.=<<___; .long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 //K_20_39 .long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc //K_40_59 .long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 //K_60_79 -.LOPENSSL_armcap_P: -#ifdef __ILP32__ -.long OPENSSL_armcap_P-. -#else -.quad OPENSSL_armcap_P-. -#endif .asciz "SHA1 block transform for ARMv8, CRYPTOGAMS by " .align 2 +#if !defined(__KERNELL__) && !defined(_WIN64) .comm OPENSSL_armcap_P,4,4 +#endif ___ }}} diff --git a/crypto/sha/asm/sha256-armv4.pl b/crypto/sha/asm/sha256-armv4.pl index e0512b4d..cd01fcb5 100644 --- a/crypto/sha/asm/sha256-armv4.pl +++ b/crypto/sha/asm/sha256-armv4.pl @@ -181,7 +181,6 @@ $code=<<___; # define __ARM_MAX_ARCH__ 7 #endif -.text #if defined(__thumb2__) .syntax unified .thumb @@ -189,6 +188,8 @@ $code=<<___; .code 32 #endif +.text + .type K256,%object .align 5 K256: @@ -212,7 +213,11 @@ K256: .word 0 @ terminator #if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) .LOPENSSL_armcap: +# ifdef _WIN32 +.word OPENSSL_armcap_P +# else .word OPENSSL_armcap_P-.Lsha256_block_data_order +# endif #endif .align 5 @@ -227,10 +232,12 @@ sha256_block_data_order: #endif #if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) ldr r12,.LOPENSSL_armcap +# if !defined(_WIN32) ldr r12,[r3,r12] @ OPENSSL_armcap_P -#ifdef __APPLE__ +# endif +# if defined(__APPLE__) || defined(_WIN32) ldr r12,[r12] -#endif +# endif tst r12,#ARMV8_SHA256 bne .LARMv8 tst r12,#ARMV7_NEON @@ -598,14 +605,15 @@ my ($ABCD,$EFGH,$abcd)=map("q$_",(0..2)); my @MSG=map("q$_",(8..11)); my ($W0,$W1,$ABCD_SAVE,$EFGH_SAVE)=map("q$_",(12..15)); my $Ktbl="r3"; +my $_byte = ($flavour =~ /win/ ? "DCB" : ".byte"); $code.=<<___; #if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) # if defined(__thumb2__) -# define INST(a,b,c,d) .byte c,d|0xc,a,b +# define INST(a,b,c,d) $_byte c,d|0xc,a,b # else -# define INST(a,b,c,d) .byte a,b,c,d +# define INST(a,b,c,d) $_byte a,b,c,d # endif .type sha256_block_data_order_armv8,%function diff --git a/crypto/sha/asm/sha512-armv4.pl b/crypto/sha/asm/sha512-armv4.pl index 795c4cbb..39c943b4 100644 --- a/crypto/sha/asm/sha512-armv4.pl +++ b/crypto/sha/asm/sha512-armv4.pl @@ -196,6 +196,9 @@ $code.=<<___; add $Ktbl,$Ktbl,#8 ___ } + +my $_word = ($flavour =~ /win/ ? "DCDU" : ".word"); + $code=<<___; #ifndef __KERNEL__ # include "arm_arch.h" @@ -211,14 +214,13 @@ $code=<<___; #ifdef __ARMEL__ # define LO 0 # define HI 4 -# define WORD64(hi0,lo0,hi1,lo1) .word lo0,hi0, lo1,hi1 +# define WORD64(hi0,lo0,hi1,lo1) $_word lo0,hi0, lo1,hi1 #else # define HI 0 # define LO 4 -# define WORD64(hi0,lo0,hi1,lo1) .word hi0,lo0, hi1,lo1 +# define WORD64(hi0,lo0,hi1,lo1) $_word hi0,lo0, hi1,lo1 #endif -.text #if defined(__thumb2__) .syntax unified .thumb @@ -227,6 +229,8 @@ $code=<<___; .code 32 #endif +.text + .type K512,%object .align 5 K512: @@ -273,7 +277,11 @@ WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817) .size K512,.-K512 #if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) .LOPENSSL_armcap: +# ifdef _WIN32 +.word OPENSSL_armcap_P +# else .word OPENSSL_armcap_P-.Lsha512_block_data_order +# endif .skip 32-4 #else .skip 32 @@ -290,10 +298,12 @@ sha512_block_data_order: #endif #if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) ldr r12,.LOPENSSL_armcap +# if !defined(_WIN32) ldr r12,[r3,r12] @ OPENSSL_armcap_P -#ifdef __APPLE__ +# endif +# if defined(__APPLE__) || defined(_WIN32) ldr r12,[r12] -#endif +# endif tst r12,#ARMV7_NEON bne .LNEON #endif diff --git a/crypto/sha/asm/sha512-armv8.pl b/crypto/sha/asm/sha512-armv8.pl index c787ea81..f7c67219 100644 --- a/crypto/sha/asm/sha512-armv8.pl +++ b/crypto/sha/asm/sha512-armv8.pl @@ -188,24 +188,18 @@ ___ $code.=<<___; #ifndef __KERNEL__ # include "arm_arch.h" +.extern OPENSSL_armcap_P #endif .text -.extern OPENSSL_armcap_P .globl $func .type $func,%function .align 6 $func: #ifndef __KERNEL__ -# ifdef __ILP32__ - ldrsw x16,.LOPENSSL_armcap_P -# else - ldr x16,.LOPENSSL_armcap_P -# endif - adr x17,.LOPENSSL_armcap_P - add x16,x16,x17 - ldr w16,[x16] + adrp x16,OPENSSL_armcap_P + ldr w16,[x16,#:lo12:OPENSSL_armcap_P] ___ $code.=<<___ if ($SZ==4); tst w16,#ARMV8_SHA256 @@ -219,6 +213,7 @@ $code.=<<___ if ($SZ==8); ___ $code.=<<___; #endif + .inst 0xd503233f // paciasp stp x29,x30,[sp,#-128]! add x29,sp,#0 @@ -280,6 +275,7 @@ $code.=<<___; ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldp x29,x30,[sp],#128 + .inst 0xd50323bf // autiasp ret .size $func,.-$func @@ -351,15 +347,6 @@ $code.=<<___ if ($SZ==4); ___ $code.=<<___; .size .LK$BITS,.-.LK$BITS -#ifndef __KERNEL__ -.align 3 -.LOPENSSL_armcap_P: -# ifdef __ILP32__ - .long OPENSSL_armcap_P-. -# else - .quad OPENSSL_armcap_P-. -# endif -#endif .asciz "SHA$BITS block transform for ARMv8, CRYPTOGAMS by " .align 2 ___ @@ -839,7 +826,7 @@ ___ } $code.=<<___; -#ifndef __KERNEL__ +#if !defined(__KERNEL__) && !defined(_WIN64) .comm OPENSSL_armcap_P,4,4 #endif ___ diff --git a/crypto/sha/keccak1600.c b/crypto/sha/keccak1600.c index c49c4b3a..7aa07552 100644 --- a/crypto/sha/keccak1600.c +++ b/crypto/sha/keccak1600.c @@ -25,7 +25,14 @@ void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r); # define KECCAK_2X /* default to KECCAK_2X variant */ #endif -#if defined(__i386) || defined(__i386__) || defined(_M_IX86) +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + (defined(__x86_64) && !defined(__BMI__)) || defined(_M_X64) || \ + defined(__mips) || defined(__riscv) || defined(__s390__) || \ + defined(__EMSCRIPTEN__) +/* + * These don't have "and with complement" instruction, so minimize amount + * of "not"-s. Implemented only in the [default] KECCAK_2X variant. + */ # define KECCAK_COMPLEMENTING_TRANSFORM #endif diff --git a/crypto/sparse_array.c b/crypto/sparse_array.c new file mode 100644 index 00000000..5bcdbc53 --- /dev/null +++ b/crypto/sparse_array.c @@ -0,0 +1,218 @@ +/* + * 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 + */ + +#include +#include +#include "internal/sparse_array.h" + +/* + * How many bits are used to index each level in the tree structre? + * This setting determines the number of pointers stored in each node of the + * tree used to represent the sparse array. Having more pointers reduces the + * depth of the tree but potentially wastes more memory. That is, this is a + * direct space versus time tradeoff. + * + * The large memory model uses twelve bits which means that the are 4096 + * pointers in each tree node. This is more than sufficient to hold the + * largest defined NID (as of Feb 2019). This means that using a NID to + * index a sparse array becomes a constant time single array look up. + * + * The small memory model uses four bits which means the tree nodes contain + * sixteen pointers. This reduces the amount of unused space significantly + * at a cost in time. + * + * The library builder is also permitted to define other sizes in the closed + * interval [2, sizeof(size_t) * 8]. + */ +#ifndef OPENSSL_SA_BLOCK_BITS +# ifdef OPENSSL_SMALL_FOOTPRINT +# define OPENSSL_SA_BLOCK_BITS 4 +# else +# define OPENSSL_SA_BLOCK_BITS 12 +# endif +#elif OPENSSL_SA_BLOCK_BITS < 2 || OPENSSL_SA_BLOCK_BITS > (BN_BITS2 - 1) +# error OPENSSL_SA_BLOCK_BITS is out of range +#endif + +/* + * From the number of bits, work out: + * the number of pointers in a tree node; + * a bit mask to quickly extract an index and + * the maximum depth of the tree structure. + */ +#define SA_BLOCK_MAX (1 << OPENSSL_SA_BLOCK_BITS) +#define SA_BLOCK_MASK (SA_BLOCK_MAX - 1) +#define SA_BLOCK_MAX_LEVELS (((int)sizeof(size_t) * 8 \ + + OPENSSL_SA_BLOCK_BITS - 1) \ + / OPENSSL_SA_BLOCK_BITS) + +struct sparse_array_st { + int levels; + size_t top; + size_t nelem; + void **nodes; +}; + +OPENSSL_SA *OPENSSL_SA_new(void) +{ + OPENSSL_SA *res = OPENSSL_zalloc(sizeof(*res)); + + return res; +} + +static void sa_doall(const OPENSSL_SA *sa, void (*node)(void **), + void (*leaf)(size_t, void *, void *), void *arg) +{ + int i[SA_BLOCK_MAX_LEVELS]; + void *nodes[SA_BLOCK_MAX_LEVELS]; + size_t idx = 0; + int l = 0; + + i[0] = 0; + nodes[0] = sa->nodes; + while (l >= 0) { + const int n = i[l]; + void ** const p = nodes[l]; + + if (n >= SA_BLOCK_MAX) { + if (p != NULL && node != NULL) + (*node)(p); + l--; + idx >>= OPENSSL_SA_BLOCK_BITS; + } else { + i[l] = n + 1; + if (p != NULL && p[n] != NULL) { + idx = (idx & ~SA_BLOCK_MASK) | n; + if (l < sa->levels - 1) { + i[++l] = 0; + nodes[l] = p[n]; + idx <<= OPENSSL_SA_BLOCK_BITS; + } else if (leaf != NULL) { + (*leaf)(idx, p[n], arg); + } + } + } + } +} + +static void sa_free_node(void **p) +{ + OPENSSL_free(p); +} + +static void sa_free_leaf(size_t n, void *p, void *arg) +{ + OPENSSL_free(p); +} + +void OPENSSL_SA_free(OPENSSL_SA *sa) +{ + sa_doall(sa, &sa_free_node, NULL, NULL); + OPENSSL_free(sa); +} + +void OPENSSL_SA_free_leaves(OPENSSL_SA *sa) +{ + sa_doall(sa, &sa_free_node, &sa_free_leaf, NULL); + OPENSSL_free(sa); +} + +/* Wrap this in a structure to avoid compiler warnings */ +struct trampoline_st { + void (*func)(size_t, void *); +}; + +static void trampoline(size_t n, void *l, void *arg) +{ + ((const struct trampoline_st *)arg)->func(n, l); +} + +void OPENSSL_SA_doall(const OPENSSL_SA *sa, void (*leaf)(size_t, void *)) +{ + struct trampoline_st tramp; + + tramp.func = leaf; + if (sa != NULL) + sa_doall(sa, NULL, &trampoline, &tramp); +} + +void OPENSSL_SA_doall_arg(const OPENSSL_SA *sa, + void (*leaf)(size_t, void *, void *), void *arg) +{ + if (sa != NULL) + sa_doall(sa, NULL, leaf, arg); +} + +size_t OPENSSL_SA_num(const OPENSSL_SA *sa) +{ + return sa == NULL ? 0 : sa->nelem; +} + +void *OPENSSL_SA_get(const OPENSSL_SA *sa, size_t n) +{ + int level; + void **p, *r = NULL; + + if (sa == NULL) + return NULL; + + if (n <= sa->top) { + p = sa->nodes; + for (level = sa->levels - 1; p != NULL && level > 0; level--) + p = (void **)p[(n >> (OPENSSL_SA_BLOCK_BITS * level)) + & SA_BLOCK_MASK]; + r = p == NULL ? NULL : p[n & SA_BLOCK_MASK]; + } + return r; +} + +static ossl_inline void **alloc_node(void) +{ + return OPENSSL_zalloc(SA_BLOCK_MAX * sizeof(void *)); +} + +int OPENSSL_SA_set(OPENSSL_SA *sa, size_t posn, void *val) +{ + int i, level = 1; + size_t n = posn; + void **p; + + if (sa == NULL) + return 0; + + for (level = 1; level < SA_BLOCK_MAX_LEVELS; level++) + if ((n >>= OPENSSL_SA_BLOCK_BITS) == 0) + break; + + for (;sa->levels < level; sa->levels++) { + p = alloc_node(); + if (p == NULL) + return 0; + p[0] = sa->nodes; + sa->nodes = p; + } + if (sa->top < posn) + sa->top = posn; + + p = sa->nodes; + for (level = sa->levels - 1; level > 0; level--) { + i = (posn >> (OPENSSL_SA_BLOCK_BITS * level)) & SA_BLOCK_MASK; + if (p[i] == NULL && (p[i] = alloc_node()) == NULL) + return 0; + p = p[i]; + } + p += posn & SA_BLOCK_MASK; + if (val == NULL && *p != NULL) + sa->nelem--; + else if (val != NULL && *p == NULL) + sa->nelem++; + *p = val; + return 1; +} diff --git a/doc/internal/man3/DEFINE_SPARSE_ARRAY_OF.pod b/doc/internal/man3/DEFINE_SPARSE_ARRAY_OF.pod new file mode 100644 index 00000000..c36472aa --- /dev/null +++ b/doc/internal/man3/DEFINE_SPARSE_ARRAY_OF.pod @@ -0,0 +1,120 @@ +=pod + +=head1 NAME + +DEFINE_SPARSE_ARRAY_OF, ossl_sa_TYPE_new, ossl_sa_TYPE_free, +ossl_sa_TYPE_free_leaves, ossl_sa_TYPE_num, ossl_sa_TYPE_doall, +ossl_sa_TYPE_doall_arg, ossl_sa_TYPE_get, ossl_sa_TYPE_set +- sparse array container + +=head1 SYNOPSIS + +=for comment generic + + #include "internal/sparse_array.h" + + typedef struct sparse_array_st OPENSSL_SA; + + SPARSE_ARRAY_OF(TYPE) + DEFINE_SPARSE_ARRAY_OF(TYPE) + + SPARSE_ARRAY_OF(TYPE) *ossl_sa_TYPE_new(void); + void ossl_sa_TYPE_free(const SPARSE_ARRAY_OF(TYPE) *sa); + void ossl_sa_TYPE_free_leaves(const SPARSE_ARRAY_OF(TYPE) *sa); + int ossl_sa_TYPE_num(const SPARSE_ARRAY_OF(TYPE) *sa); + void ossl_sa_TYPE_doall(const OPENSSL_SA *sa, void (*leaf)(size_t, void *)); + void ossl_sa_TYPE_doall_arg(const OPENSSL_SA *sa, + void (*leaf)(size_t, void *, void *), void *arg); + TYPE *ossl_sa_TYPE_get(const SPARSE_ARRAY_OF(TYPE) *sa, size_t idx); + int ossl_sa_TYPE_set(SPARSE_ARRAY_OF(TYPE) *sa, size_t idx, TYPE *value); + +=head1 DESCRIPTION + +SPARSE_ARRAY_OF() returns the name for a sparse array of the specified +B. DEFINE_STACK_OF() creates set of functions for a sparse array of +B. This will mean that a pointer to type B is stored in each +element of a sparse array, the type is referenced by SPARSE_ARRAY_OF(TYPE) and +each function name begins with I. For example: + + TYPE *ossl_sa_TYPE_get(SPARSE_ARRAY_OF(TYPE) *sa, size_t idx); + +ossl_sa_TYPE_num() returns the number of elements in B or 0 if B is +B. + +ossl_sa_TYPE_get() returns element B in B, where B starts at +zero. If B refers to a value that has not been set then B is +returned. + +ossl_sa_TYPE_set() sets element B in B to B, where B +starts at zero. The sparse array will be resized as required. + +ossl_sa_TYPE_new() allocates a new empty sparse array. + +ossl_sa_TYPE_free() frees up the B structure. It does B free up any +elements of B. After this call B is no longer valid. + +ossl_sa_TYPE_free_leaves() frees up the B structure and all of its +elements. After this call B is no longer valid. + +ossl_sa_TYPE_doall() calls the function B for each element in B +in ascending index order. The index position, within the sparse array, +of each item is passed as the first argument to the leaf function and a +pointer to the associated value is is passed as the second argument. + +ossl_sa_TYPE_doall_arg() calls the function B for each element in +B in ascending index order. The index position, within the sparse +array, of each item is passed as the first argument to the leaf function, +a pointer to the associated value is passed as the second argument and +the third argument is the user supplied B. + + +=head1 NOTES + +Sparse arrays are an internal data structure and should B be used by user +applications. + +Care should be taken when accessing sparse arrays in multi-threaded +environments. The ossl_sa_TYPE_set operation can cause the internal structure +of the sparse array to change which causes race conditions if the sparse array +is accessed in a different thread. + +SPARSE_ARRAY_OF() and DEFINE_SPARSE_ARRAY_OF() are implemented as macros. + +The underlying utility B API should not be used directly. It +defines these functions: OPENSSL_SA_doall, OPENSSL_SA_doall_arg, +OPENSSL_SA_free, OPENSSL_SA_free_leaves, OPENSSL_SA_get, OPENSSL_SA_new, +OPENSSL_SA_num and OPENSSL_SA_set. + +=head1 RETURN VALUES + +ossl_sa_TYPE_num() returns the number of elements in the sparse array or B<0> +if the passed sparse array is B. + +ossl_sa_TYPE_get() returns a pointer to a sparse array element or B if +the element has not be set. + +ossl_sa_TYPE_set() return B<1> on success and B<0> on error. In the latter +case, the elements of the sparse array remain unchanged, although the internal +structures might have. + +ossl_sa_TYPE_new() returns an empty sparse array or B if an error +occurs. + +ossl_sa_TYPE_doall, ossl_sa_TYPE_doall_arg, ossl_sa_TYPE_free() and +ossl_sa_TYPE_free_leaves() do not return values. + +=head1 HISTORY + +This functionality was added to OpenSSL 3.0.0. + +=head1 COPYRIGHT + +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 +L. + +=cut diff --git a/doc/internal/man3/OSSL_METHOD_STORE.pod b/doc/internal/man3/OSSL_METHOD_STORE.pod new file mode 100644 index 00000000..25cf56e0 --- /dev/null +++ b/doc/internal/man3/OSSL_METHOD_STORE.pod @@ -0,0 +1,116 @@ +=pod + +=head1 NAME + +OSSL_METHOD_STORE, ossl_method_store_new, ossl_method_store_free, +ossl_method_store_init, ossl_method_store_cleanup, +ossl_method_store_add, ossl_method_store_remove, ossl_method_store_fetch, +ossl_method_store_set_global_properties, +ossl_method_store_cache_get, ossl_method_store_cache_set +- implementation method store and query + +=head1 SYNOPSIS + + #include "internal/property.h" + + typedef struct ossl_method_store_st OSSL_METHOD_STORE; + + OSSL_METHOD_STORE *ossl_method_store_new(void); + void ossl_method_store_free(OSSL_METHOD_STORE *store); + int ossl_method_store_init(void); + void ossl_method_store_cleanup(void); + int ossl_method_store_add(OSSL_METHOD_STORE *store, + int nid, const char *properties, + void *method, void (*method_destruct)(void *)); + int ossl_method_store_remove(OSSL_METHOD_STORE *store, + int nid, const void *method); + int ossl_method_store_fetch(OSSL_METHOD_STORE *store, + int nid, const char *properties, + void **method); + int ossl_method_store_set_global_properties(OSSL_METHOD_STORE *store, + const char *prop_query); + int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, int nid, + const char *prop_query, void **method); + int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, int nid, + const char *prop_query, void *method); + +=head1 DESCRIPTION + +OSSL_METHOD_STORE stores methods that can be queried using properties and a +numeric identity (nid). + +Methods are expected to be library internal structures. +It's left to the caller to define the exact contents. + +Numeric identities are expected to be an algorithm identity for the methods. +It's left to the caller to define exactly what an algorithm is, and to allocate +these numeric identities accordingly. + +The B also holds an internal query cache, which is accessed +separately (see L below). + +=head2 Store Functions + +ossl_method_store_init() initialises the method store subsystem. + +ossl_method_store_cleanup() cleans up and shuts down the implementation method +store subsystem. + +ossl_method_store_new() create a new empty method store. + +ossl_method_store_free() frees resources allocated to B. + +ossl_method_store_add() adds the B to the B as an instance of an +algorithm indicated by B and the property definition B. +The optional B function is called when B is being +released from B. + +ossl_method_store_remove() removes the B identified by B from the +B. + +ossl_method_store_fetch() queries B for an method identified by B +that matches the property query B. +The result, if any, is returned in B. + +ossl_method_store_set_global_properties() sets method B wide query +properties to B. +All subsequent fetches will need to meet both these global query properties +and the ones passed to the ossl_method_store_free(). + +=head2 Cache Functions + +ossl_method_store_cache_get() queries the cache associated with the B +for an method identified by B that matches the property query +B. +The result, if any, is returned in B. + +ossl_method_store_cache_set() sets a cache entry identified by B with the +property query B in the B. +Future cache gets will return the specified B. + +=head1 RETURN VALUES + +ossl_method_store_new() a new method store object or B on failure. + +ossl_method_store_free(), ossl_method_store_add(), +ossl_method_store_remove(), ossl_method_store_fetch(), +ossl_method_store_set_global_properties(), ossl_method_store_cache_get() +and ossl_method_store_cache_set() return B<1> on success and B<0> on error. + +ossl_method_store_free() and ossl_method_store_cleanup() do not return values. + +=head1 HISTORY + +This functionality was added to OpenSSL 3.0.0. + +=head1 COPYRIGHT + +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 +L. + +=cut diff --git a/doc/internal/man3/openssl_ctx_get_data.pod b/doc/internal/man3/openssl_ctx_get_data.pod new file mode 100644 index 00000000..ee98dc27 --- /dev/null +++ b/doc/internal/man3/openssl_ctx_get_data.pod @@ -0,0 +1,112 @@ +=pod + +=head1 NAME + +openssl_ctx_new_index, openssl_ctx_get_data - internal OPENSSL_CTX routines + +=head1 SYNOPSIS + + #include + #include "internal/cryptlib.h" + + typedef struct openssl_ctx_method { + void *(*new_func)(void); + void (*free_func)(void *); + } OPENSSL_CTX_METHOD; + + int openssl_ctx_new_index(const OPENSSL_CTX_METHOD *meth); + void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index); + +=head1 DESCRIPTION + +Internally, the OpenSSL library context C is implemented +as a C, which allows data from diverse parts of the +library to be added and removed dynamically. +Each such data item must have a corresponding CRYPTO_EX_DATA index +associated with it. +See the example further down to see how that's done. + +openssl_ctx_new_index() allocates a new library context index, and +associates it with the functions given through C. +The functions given through that method are used to create or free +items that are stored at that index whenever a library context is +created or freed, meaning that the code that use a data item of that +index doesn't have to worry about that, just use the data available. + +Deallocation of an index happens automatically when the library +context is freed. + +openssl_ctx_get_data() is used to retrieve a pointer to the data in +the library context C associated with the given C. + +=head1 EXAMPLES + +=head2 Initialization + +For a type C that should end up in the OpenSSL library context, a +small bit of initialization is needed, i.e. to associate a constructor +and a destructor to a new index. + + /* The index will always be entirely global, and dynamically allocated */ + static int foo_index = -1; + + typedef struct foo_st { + int i; + void *data; + } FOO; + + static void *foo_new(void) + { + FOO *ptr = OPENSSL_zalloc(sizeof(*foo)); + if (ptr != NULL) + ptr->i = 42; + return ptr; + } + static void foo_free(void *ptr) + { + OPENSSL_free(ptr); + } + static const OPENSSL_CTX_METHOD foo_method = { + foo_new, + foo_free + }; + + static int foo_init(void) + { + foo_index = openssl_ctx_new_index(foo_method); + + return foo_index != -1; + } + +=head2 Usage + +To get and use the data stored in the library context, simply do this: + + /* + * ctx is received from a caller, + * foo_index comes from the example above + */ + FOO *data = openssl_ctx_get_data(ctx, foo_index); + +=head1 RETURN VALUES + +openssl_ctx_new_index() returns -1 on error, otherwise the allocated +index number. + +openssl_ctx_get_data() returns a pointer on success, or C on +failure. + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +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 +L. + +=cut diff --git a/doc/man1/ciphers.pod b/doc/man1/ciphers.pod index 7d795c39..b5bca974 100644 --- a/doc/man1/ciphers.pod +++ b/doc/man1/ciphers.pod @@ -411,7 +411,7 @@ based on client preferences. An equal-preference is specified with square brackets, combining multiple selectors separated by |. For example: [ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256] - + Once an equal-preference group is used, future directives must be opcode-less. diff --git a/doc/man1/dgst.pod b/doc/man1/dgst.pod index 993c92bb..c745cfa9 100644 --- a/doc/man1/dgst.pod +++ b/doc/man1/dgst.pod @@ -230,8 +230,8 @@ prior to verification. =head1 HISTORY -The default digest was changed from MD5 to SHA256 in OpenSSL 1.1.0 -The FIPS-related options were removed in OpenSSL 1.1.0 +The default digest was changed from MD5 to SHA256 in OpenSSL 1.1.0. +The FIPS-related options were removed in OpenSSL 1.1.0. =head1 COPYRIGHT diff --git a/doc/man1/s_client.pod b/doc/man1/s_client.pod index e16450b5..c4a98435 100644 --- a/doc/man1/s_client.pod +++ b/doc/man1/s_client.pod @@ -208,14 +208,17 @@ Use IPv6 only. =item B<-servername name> Set the TLS SNI (Server Name Indication) extension in the ClientHello message to -the given value. If both this option and the B<-noservername> are not given, the -TLS SNI extension is still set to the hostname provided to the B<-connect> option, -or "localhost" if B<-connect> has not been supplied. This is default since OpenSSL -1.1.1. +the given value. +If B<-servername> is not provided, the TLS SNI extension will be populated with +the name given to B<-connect> if it follows a DNS name format. If B<-connect> is +not provided either, the SNI is set to "localhost". +This is the default since OpenSSL 1.1.1. -Even though SNI name should normally be a DNS name and not an IP address, this -option will not make the distinction when parsing B<-connect> and will send -IP address if one passed. +Even though SNI should normally be a DNS name and not an IP address, if +B<-servername> is provided then that name will be sent, regardless of whether +it is a DNS name or not. + +This option cannot be used in conjuction with B<-noservername>. =item B<-noservername> diff --git a/doc/man3/CRYPTO_get_ex_new_index.pod b/doc/man3/CRYPTO_get_ex_new_index.pod index a2b39d92..44bab624 100644 --- a/doc/man3/CRYPTO_get_ex_new_index.pod +++ b/doc/man3/CRYPTO_get_ex_new_index.pod @@ -3,8 +3,9 @@ =head1 NAME CRYPTO_EX_new, CRYPTO_EX_free, CRYPTO_EX_dup, -CRYPTO_free_ex_index, CRYPTO_get_ex_new_index, CRYPTO_set_ex_data, -CRYPTO_get_ex_data, CRYPTO_free_ex_data, CRYPTO_new_ex_data +CRYPTO_free_ex_index, CRYPTO_get_ex_new_index, +CRYPTO_alloc_ex_data, CRYPTO_set_ex_data, CRYPTO_get_ex_data, +CRYPTO_free_ex_data, CRYPTO_new_ex_data - functions supporting application-specific data =head1 SYNOPSIS @@ -26,6 +27,9 @@ CRYPTO_get_ex_data, CRYPTO_free_ex_data, CRYPTO_new_ex_data int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) + int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad, + int idx); + int CRYPTO_set_ex_data(CRYPTO_EX_DATA *r, int idx, void *arg); void *CRYPTO_get_ex_data(CRYPTO_EX_DATA *r, int idx); @@ -114,7 +118,8 @@ new_func() is called for every defined index. There is no requirement that the entire parent, or containing, structure has been set up. The new_func() is typically used only to allocate memory to store the exdata, and perhaps an "initialized" flag within that memory. -The exdata value should be set by calling CRYPTO_set_ex_data(). +The exdata value may be allocated later on with CRYPTO_alloc_ex_data(), +or may be set by calling CRYPTO_set_ex_data(). When a structure is free'd (such as SSL_CTX_free()) then the free_func() is called for every defined index. Again, the state of the @@ -147,14 +152,18 @@ will fail. CRYPTO_get_ex_new_index() returns a new index or -1 on failure. -CRYPTO_free_ex_index() and -CRYPTO_set_ex_data() return 1 on success or 0 on failure. +CRYPTO_free_ex_index(), CRYPTO_alloc_ex_data() and CRYPTO_set_ex_data() +return 1 on success or 0 on failure. CRYPTO_get_ex_data() returns the application data or NULL on failure; note that NULL may be a valid value. dup_func() should return 0 for failure and 1 for success. +=head1 HISTORY + +CRYPTO_alloc_ex_data() was added in OpenSSL 3.0.0. + =head1 COPYRIGHT Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/EC_GROUP_copy.pod b/doc/man3/EC_GROUP_copy.pod index 453825a7..3f7108d0 100644 --- a/doc/man3/EC_GROUP_copy.pod +++ b/doc/man3/EC_GROUP_copy.pod @@ -11,7 +11,7 @@ EC_GROUP_get_point_conversion_form, EC_GROUP_get0_seed, EC_GROUP_get_seed_len, EC_GROUP_set_seed, EC_GROUP_get_degree, EC_GROUP_check, EC_GROUP_check_discriminant, EC_GROUP_cmp, EC_GROUP_get_basis_type, EC_GROUP_get_trinomial_basis, -EC_GROUP_get_pentanomial_basis +EC_GROUP_get_pentanomial_basis, EC_GROUP_get0_field - Functions for manipulating EC_GROUP objects =head1 SYNOPSIS @@ -32,6 +32,7 @@ EC_GROUP_get_pentanomial_basis int EC_GROUP_order_bits(const EC_GROUP *group); int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx); const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group); + const BIGNUM *EC_GROUP_get0_field(const EC_GROUP *group); void EC_GROUP_set_curve_name(EC_GROUP *group, int nid); int EC_GROUP_get_curve_name(const EC_GROUP *group); @@ -177,6 +178,8 @@ specified curve respectively. If there is no curve name associated with a curve EC_GROUP_get0_order() returns an internal pointer to the group order. EC_GROUP_order_bits() returns the number of bits in the group order. EC_GROUP_get0_cofactor() returns an internal pointer to the group cofactor. +EC_GROUP_get0_field() returns an internal pointer to the group field. For curves over GF(p), this is the modulus; for curves +over GF(2^m), this is the irreducible polynomial defining the field. EC_GROUP_get0_seed returns a pointer to the seed that was used to generate the parameter b, or NULL if the seed is not specified. EC_GROUP_get_seed_len returns the length of the seed or 0 if the seed is not specified. diff --git a/doc/man3/EVP_KDF_CTX.pod b/doc/man3/EVP_KDF_CTX.pod new file mode 100644 index 00000000..b01c719c --- /dev/null +++ b/doc/man3/EVP_KDF_CTX.pod @@ -0,0 +1,217 @@ +=pod + +=head1 NAME + +EVP_KDF_CTX, EVP_KDF_CTX_new_id, EVP_KDF_CTX_free, EVP_KDF_reset, +EVP_KDF_ctrl, EVP_KDF_vctrl, EVP_KDF_ctrl_str, EVP_KDF_size, +EVP_KDF_derive - EVP KDF routines + +=head1 SYNOPSIS + + #include + + typedef struct evp_kdf_ctx_st EVP_KDF_CTX; + + EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id); + void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx); + void EVP_KDF_reset(EVP_KDF_CTX *ctx); + int EVP_KDF_ctrl(EVP_KDF_CTX *ctx, int cmd, ...); + int EVP_KDF_vctrl(EVP_KDF_CTX *ctx, int cmd, va_list args); + int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value); + size_t EVP_KDF_size(EVP_KDF_CTX *ctx); + int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen); + +=head1 DESCRIPTION + +The EVP KDF routines are a high level interface to Key Derivation Function +algorithms and should be used instead of algorithm-specific functions. + +After creating a C for the required algorithm using +EVP_KDF_CTX_new_id(), inputs to the algorithm are supplied using calls to +EVP_KDF_ctrl(), EVP_KDF_vctrl() or EVP_KDF_ctrl_str() before calling +EVP_KDF_derive() to derive the key. + +=head2 Types + +B is a context type that holds the algorithm inputs. + +=head2 Context manipulation functions + +EVP_KDF_CTX_new_id() creates a KDF context for the algorithm identified by the +specified NID. + +EVP_KDF_CTX_free() frees up the context C. If C is C, nothing +is done. + +=head2 Computing functions + +EVP_KDF_reset() resets the context to the default state as if the context +had just been created. + +EVP_KDF_ctrl() is used to provide inputs to the KDF algorithm prior to +EVP_KDF_derive() being called. The inputs that may be provided will vary +depending on the KDF algorithm or its implementation. This functions takes +variable arguments, the exact expected arguments depend on C. +See L below for a description of standard controls. + +EVP_KDF_vctrl() is the variant of EVP_KDF_ctrl() that takes a C +argument instead of variadic arguments. + +EVP_KDF_ctrl_str() allows an application to send an algorithm specific control +operation to a context C in string form. This is intended to be used for +options specified on the command line or in text files. + +EVP_KDF_size() returns the output size if the algorithm produces a fixed amount +of output and C otherwise. If an error occurs then 0 is returned. +For some algorithms an error may result if input parameters necessary to +calculate a fixed output size have not yet been supplied. + +EVP_KDF_derive() derives C bytes of key material and places it in the +C buffer. If the algorithm produces a fixed amount of output then an +error will occur unless the C parameter is equal to that output size, +as returned by EVP_KDF_size(). + +=head1 CONTROLS + +The standard controls are: + +=over 4 + +=item B + +This control expects two arguments: C, C + +Some KDF implementations require a password. For those KDF implementations +that support it, this control sets the password. + +EVP_KDF_ctrl_str() takes two type strings for this control: + +=over 4 + +=item "pass" + +The value string is used as is. + +=item "hexpass" + +The value string is expected to be a hexadecimal number, which will be +decoded before being passed on as the control value. + +=back + +=item B + +This control expects two arguments: C, C + +Some KDF implementations can take a salt. For those KDF implementations that +support it, this control sets the salt. + +The default value, if any, is implementation dependent. + +EVP_KDF_ctrl_str() takes two type strings for this control: + +=over 4 + +=item "salt" + +The value string is used as is. + +=item "hexsalt" + +The value string is expected to be a hexadecimal number, which will be +decoded before being passed on as the control value. + +=back + +=item B + +This control expects one argument: C + +Some KDF implementations require an iteration count. For those KDF implementations that support it, this control sets the iteration count. + +The default value, if any, is implementation dependent. + +EVP_KDF_ctrl_str() type string: "iter" + +The value string is expected to be a decimal number. + +=item B + +This control expects one argument: C + +For MAC implementations that use a message digest as an underlying computation +algorithm, this control set what the digest algorithm should be. + +EVP_KDF_ctrl_str() type string: "md" + +The value string is expected to be the name of a digest. + +=item B + +This control expects two arguments: C, C + +Some KDF implementations require a key. For those KDF implementations that +support it, this control sets the key. + +EVP_KDF_ctrl_str() takes two type strings for this control: + +=over 4 + +=item "key" + +The value string is used as is. + +=item "hexkey" + +The value string is expected to be a hexadecimal number, which will be +decoded before being passed on as the control value. + +=back + +=item B + +This control expects one argument: C + +Memory-hard password-based KDF algorithms, such as scrypt, use an amount of +memory that depends on the load factors provided as input. For those KDF +implementations that support it, this control sets an upper limit on the amount +of memory that may be consumed while performing a key derivation. If this +memory usage limit is exceeded because the load factors are chosen too high, +the key derivation will fail. + +The default value is implementation dependent. + +EVP_KDF_ctrl_str() type string: "maxmem_bytes" + +The value string is expected to be a decimal number. + +=back + +=head1 RETURN VALUES + +EVP_KDF_CTX_new_id() returns either the newly allocated C +structure or C if an error occurred. + +EVP_KDF_CTX_free() and EVP_KDF_reset() do not return a value. + +EVP_KDF_size() returns the output size. C is returned to indicate +that the algorithm produces a variable amount of output; 0 to indicate failure. + +The remaining functions return 1 for success and 0 or a negative value for +failure. In particular, a return value of -2 indicates the operation is not +supported by the KDF algorithm. + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/OPENSSL_CTX.pod b/doc/man3/OPENSSL_CTX.pod new file mode 100644 index 00000000..53483671 --- /dev/null +++ b/doc/man3/OPENSSL_CTX.pod @@ -0,0 +1,48 @@ +=pod + +=head1 NAME + +OPENSSL_CTX, OPENSSL_CTX_new, OPENSSL_CTX_free - OpenSSL library context + +=head1 SYNOPSIS + + #include + + typedef struct openssl_ctx_st OPENSSL_CTX; + + OPENSSL_CTX *OPENSSL_CTX_new(void); + void OPENSSL_CTX_free(OPENSSL_CTX *ctx); + +=head1 DESCRIPTION + +C is an internal OpenSSL library context type. +Applications may allocate their own, but may also use C to use +the internal default context with functions that take a C +argument. + +OPENSSL_CTX_new() creates a new OpenSSL library context. + +OPENSSL_CTX_free() frees the given C. + +=head1 RETURN VALUES + +OPENSSL_CTX_new() return a library context pointer on success, or +C on error. + +OPENSSL_CTX_free() doesn't return any value. + +=head1 HISTORY + +OPENSSL_CTX, OPENSSL_CTX_new() and OPENSSL_CTX_free() +were added in OpenSSL 3.0.0. + +=head1 COPYRIGHT + +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 +L. + +=cut diff --git a/doc/man3/OPENSSL_LH_COMPFUNC.pod b/doc/man3/OPENSSL_LH_COMPFUNC.pod index 7caf9b36..9a927f88 100644 --- a/doc/man3/OPENSSL_LH_COMPFUNC.pod +++ b/doc/man3/OPENSSL_LH_COMPFUNC.pod @@ -6,7 +6,7 @@ LHASH, DECLARE_LHASH_OF, OPENSSL_LH_COMPFUNC, OPENSSL_LH_HASHFUNC, OPENSSL_LH_DOALL_FUNC, LHASH_DOALL_ARG_FN_TYPE, IMPLEMENT_LHASH_HASH_FN, IMPLEMENT_LHASH_COMP_FN, -lh_TYPE_new, lh_TYPE_free, +lh_TYPE_new, lh_TYPE_free, lh_TYPE_flush, lh_TYPE_insert, lh_TYPE_delete, lh_TYPE_retrieve, lh_TYPE_doall, lh_TYPE_doall_arg, lh_TYPE_error - dynamic hash table @@ -20,6 +20,7 @@ lh_TYPE_doall, lh_TYPE_doall_arg, lh_TYPE_error - dynamic hash table LHASH *lh_TYPE_new(OPENSSL_LH_HASHFUNC hash, OPENSSL_LH_COMPFUNC compare); void lh_TYPE_free(LHASH_OF(TYPE) *table); + void lh_TYPE_flush(LHASH_OF(TYPE) *table); TYPE *lh_TYPE_insert(LHASH_OF(TYPE) *table, TYPE *data); TYPE *lh_TYPE_delete(LHASH_OF(TYPE) *table, TYPE *data); @@ -95,6 +96,11 @@ B. Allocated hash table entries will not be freed; consider using lh_TYPE_doall() to deallocate any remaining entries in the hash table (see below). +lh_TYPE_flush() empties the B structure B
. New +entries can be added to the flushed table. Allocated hash table entries +will not be freed; consider using lh_TYPE_doall() to deallocate any +remaining entries in the hash table (see below). + lh_TYPE_insert() inserts the structure pointed to by B into B
. If there already is an entry with the same key, the old value is replaced. Note that lh_TYPE_insert() stores pointers, the @@ -173,7 +179,8 @@ B otherwise. lh_TYPE_error() returns 1 if an error occurred in the last operation, 0 otherwise. It's meaningful only after non-retrieve operations. -lh_TYPE_free(), lh_TYPE_doall() and lh_TYPE_doall_arg() return no values. +lh_TYPE_free(), lh_TYPE_flush, lh_TYPE_doall() and lh_TYPE_doall_arg() +return no values. =head1 NOTE diff --git a/doc/man3/RIPEMD160_Init.pod b/doc/man3/RIPEMD160_Init.pod index aec64419..27ff3779 100644 --- a/doc/man3/RIPEMD160_Init.pod +++ b/doc/man3/RIPEMD160_Init.pod @@ -13,7 +13,7 @@ RIPEMD-160 hash function unsigned char *md); int RIPEMD160_Init(RIPEMD160_CTX *c); - int RIPEMD160_Update(RIPEMD_CTX *c, const void *data, unsigned long len); + int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, unsigned long len); int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c); =head1 DESCRIPTION diff --git a/doc/man3/SSL_CONF_cmd.pod b/doc/man3/SSL_CONF_cmd.pod index 0a51e9ed..5759c7f1 100644 --- a/doc/man3/SSL_CONF_cmd.pod +++ b/doc/man3/SSL_CONF_cmd.pod @@ -308,11 +308,6 @@ Attempts to pad TLSv1.3 records so that they are a multiple of B in length on send. A B of 0 or 1 turns off padding. Otherwise, the B must be >1 or <=16384. -=item B - -Disables all attempts at renegotiation in TLSv1.2 and earlier, same as setting -B. - =item B This sets the supported signature algorithms for TLSv1.2 and TLSv1.3. @@ -456,6 +451,9 @@ Only used by servers. B: set B flag. Only used by servers. +B: disables all attempts at renegotiation in TLSv1.2 and +earlier, same as setting B. + B: permits the use of unsafe legacy renegotiation. Equivalent to B. @@ -486,6 +484,10 @@ specification. Some applications may be able to mitigate the replay risks in other ways and in such cases the built-in OpenSSL functionality is not required. Disabling anti-replay is equivalent to setting B. +B: use extended master secret extension, enabled by +default. Inverse of B: that is, +B<-ExtendedMasterSecret> is the same as setting B. + =item B The B argument is a comma separated list of flags to set. diff --git a/doc/man3/SSL_CTX_set_info_callback.pod b/doc/man3/SSL_CTX_set_info_callback.pod index cb8f9965..3248e10c 100644 --- a/doc/man3/SSL_CTX_set_info_callback.pod +++ b/doc/man3/SSL_CTX_set_info_callback.pod @@ -92,17 +92,13 @@ Callback has been called due to an alert being sent or received. =item SSL_CB_HANDSHAKE_START -Callback has been called because a new handshake is started. In TLSv1.3 this is -also used for the start of post-handshake message exchanges such as for the -exchange of session tickets, or for key updates. It also occurs when resuming a -handshake following a pause to handle early data. +Callback has been called because a new handshake is started. It also occurs when +resuming a handshake following a pause to handle early data. -=item SSL_CB_HANDSHAKE_DONE 0x20 +=item SSL_CB_HANDSHAKE_DONE -Callback has been called because a handshake is finished. In TLSv1.3 this is -also used at the end of an exchange of post-handshake messages such as for -session tickets or key updates. It also occurs if the handshake is paused to -allow the exchange of early data. +Callback has been called because a handshake is finished. It also occurs if the +handshake is paused to allow the exchange of early data. =back diff --git a/doc/man3/SSL_CTX_set_options.pod b/doc/man3/SSL_CTX_set_options.pod index 63d3aae9..7626bd33 100644 --- a/doc/man3/SSL_CTX_set_options.pod +++ b/doc/man3/SSL_CTX_set_options.pod @@ -198,6 +198,14 @@ RFC7366 Encrypt-then-MAC option on TLS and DTLS connection. If this option is set, Encrypt-then-MAC is disabled. Clients will not propose, and servers will not accept the extension. +=item SSL_OP_NO_EXTENDED_MASTER_SECRET + +Normally clients and servers will transparently attempt to negotiate the +RFC7627 Extended Master Secret option on TLS and DTLS connection. + +If this option is set, Extended Master Secret is disabled. Clients will +not propose, and servers will not accept the extension. + =item SSL_OP_NO_RENEGOTIATION Disable all renegotiation in TLSv1.2 and earlier. Do not send HelloRequest @@ -366,9 +374,11 @@ OpenSSL 0.9.8m. The B and B options were added in OpenSSL 1.1.1. +The B option was added in OpenSSL 3.0.0. + =head1 COPYRIGHT -Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2001-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 diff --git a/doc/man7/EVP_KDF_HKDF.pod b/doc/man7/EVP_KDF_HKDF.pod new file mode 100644 index 00000000..2188b136 --- /dev/null +++ b/doc/man7/EVP_KDF_HKDF.pod @@ -0,0 +1,180 @@ +=pod + +=head1 NAME + +EVP_KDF_HKDF - The HKDF EVP_KDF implementation + +=head1 DESCRIPTION + +Support for computing the B KDF through the B API. + +The EVP_KDF_HKDF algorithm implements the HKDF key derivation function. +HKDF follows the "extract-then-expand" paradigm, where the KDF logically +consists of two modules. The first stage takes the input keying material +and "extracts" from it a fixed-length pseudorandom key K. The second stage +"expands" the key K into several additional pseudorandom keys (the output +of the KDF). + +=head2 Numeric identity + +B is the numeric identity for this implementation; it +can be used with the EVP_KDF_CTX_new_id() function. + +=head2 Supported controls + +The supported controls are: + +=over 4 + +=item B + +=item B + +=item B + +These controls work as described in L. + +=item B + +This control does not expect any arguments. + +Resets the context info buffer to zero length. + +=item B + +This control expects two arguments: C, C + +Sets the info value to the first B bytes of the buffer B. If a +value is already set, the contents of the buffer are appended to the existing +value. + +The total length of the context info buffer cannot exceed 1024 bytes; +this should be more than enough for any normal use of HKDF. + +EVP_KDF_ctrl_str() takes two type strings for this control: + +=over 4 + +=item "info" + +The value string is used as is. + +=item "hexinfo" + +The value string is expected to be a hexadecimal number, which will be +decoded before being passed on as the control value. + +=back + +=item B + +This control expects one argument: C + +Sets the mode for the HKDF operation. There are three modes that are currently +defined: + +=over 4 + +=item EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND + +This is the default mode. Calling L on an EVP_KDF_CTX set +up for HKDF will perform an extract followed by an expand operation in one go. +The derived key returned will be the result after the expand operation. The +intermediate fixed-length pseudorandom key K is not returned. + +In this mode the digest, key, salt and info values must be set before a key is +derived otherwise an error will occur. + +=item EVP_KDF_HKDF_MODE_EXTRACT_ONLY + +In this mode calling L will just perform the extract +operation. The value returned will be the intermediate fixed-length pseudorandom +key K. The C parameter must match the size of K, which can be looked +up by calling EVP_KDF_size() after setting the mode and digest. + +The digest, key and salt values must be set before a key is derived otherwise +an error will occur. + +=item EVP_KDF_HKDF_MODE_EXPAND_ONLY + +In this mode calling L will just perform the expand +operation. The input key should be set to the intermediate fixed-length +pseudorandom key K returned from a previous extract operation. + +The digest, key and info values must be set before a key is derived otherwise +an error will occur. + +=back + +EVP_KDF_ctrl_str() type string: "mode" + +The value string is expected to be one of: "EXTRACT_AND_EXPAND", "EXTRACT_ONLY" +or "EXPAND_ONLY". + +=back + +=head1 NOTES + +A context for HKDF can be obtained by calling: + + EVP_KDF_CTX *kctx = EVP_KDF_CTX_new_id(EVP_KDF_HKDF); + +The output length of an HKDF expand operation is specified via the C +parameter to the L function. When using +EVP_KDF_HKDF_MODE_EXTRACT_ONLY the C parameter must equal the size of +the intermediate fixed-length pseudorandom key otherwise an error will occur. +For that mode, the fixed output size can be looked up by calling EVP_KDF_size() +after setting the mode and digest on the C. + +=head1 EXAMPLE + +This example derives 10 bytes using SHA-256 with the secret key "secret", +salt value "salt" and info value "label": + + EVP_KDF_CTX *kctx; + unsigned char out[10]; + + kctx = EVP_KDF_CTX_new_id(EVP_KDF_HKDF); + + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) { + error("EVP_KDF_CTRL_SET_MD"); + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "salt", (size_t)4) <= 0) { + error("EVP_KDF_CTRL_SET_SALT"); + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, "secret", (size_t)6) <= 0) { + error("EVP_KDF_CTRL_SET_KEY"); + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_ADD_HKDF_INFO, "label", (size_t)5) <= 0) { + error("EVP_KDF_CTRL_ADD_HKDF_INFO"); + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + error("EVP_KDF_derive"); + } + + EVP_KDF_CTX_free(kctx); + +=head1 CONFORMING TO + +RFC 5869 + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L + +=head1 COPYRIGHT + +Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/EVP_KDF_PBKDF2.pod b/doc/man7/EVP_KDF_PBKDF2.pod new file mode 100644 index 00000000..ba322d40 --- /dev/null +++ b/doc/man7/EVP_KDF_PBKDF2.pod @@ -0,0 +1,78 @@ +=pod + +=head1 NAME + +EVP_KDF_PBKDF2 - The PBKDF2 EVP_KDF implementation + +=head1 DESCRIPTION + +Support for computing the B password-based KDF through the B +API. + +The EVP_KDF_PBKDF2 algorithm implements the PBKDF2 password-based key +derivation function, as described in RFC 2898; it derives a key from a password +using a salt and iteration count. + +=head2 Numeric identity + +B is the numeric identity for this implementation; it +can be used with the EVP_KDF_CTX_new_id() function. + +=head2 Supported controls + +The supported controls are: + +=over 4 + +=item B + +=item B + +=item B + +=item B + +These controls work as described in L. + +B is the iteration count and its value should be greater than or equal to +1. RFC 2898 suggests an iteration count of at least 1000. The default value is +2048. Any B less than 1 is treated as a single iteration. + +=back + +=head1 NOTES + +A typical application of this algorithm is to derive keying material for an +encryption algorithm from a password in the B, a salt in B, +and an iteration count. + +Increasing the B parameter slows down the algorithm which makes it +harder for an attacker to perform a brute force attack using a large number +of candidate passwords. + +No assumption is made regarding the given password; it is simply treated as a +byte sequence. + +=head1 CONFORMING TO + +RFC 2898 + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=head1 COPYRIGHT + +Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/scrypt.pod b/doc/man7/EVP_KDF_SCRYPT.pod similarity index 53% rename from doc/man7/scrypt.pod rename to doc/man7/EVP_KDF_SCRYPT.pod index eabad5b7..a44dc63d 100644 --- a/doc/man7/scrypt.pod +++ b/doc/man7/EVP_KDF_SCRYPT.pod @@ -2,11 +2,14 @@ =head1 NAME -scrypt - EVP_PKEY scrypt KDF support +EVP_KDF_SCRYPT - The scrypt EVP_KDF implementation =head1 DESCRIPTION -The EVP_PKEY_SCRYPT algorithm implements the scrypt password based key +Support for computing the B password-based KDF through the B +API. + +The EVP_KDF_SCRYPT algorithm implements the scrypt password-based key derivation function, as described in RFC 7914. It is memory-hard in the sense that it deliberately requires a significant amount of RAM for efficient computation. The intention of this is to render brute forcing of passwords on @@ -26,49 +29,82 @@ computation time of less than 5 seconds on a 2.5 GHz Intel Core 2 Duo are N = 2^20 = 1048576, r = 8, p = 1. Consequently, the required amount of memory for this computation is roughly 1 GiB. On a more recent CPU (Intel i7-5930K at 3.5 GHz), this computation takes about 3 seconds. When N, r or p are not specified, -they default to 1048576, 8, and 1, respectively. The default amount of RAM that +they default to 1048576, 8, and 1, respectively. The maximum amount of RAM that may be used by scrypt defaults to 1025 MiB. +=head2 Numeric identity + +B is the numeric identity for this implementation; it +can be used with the EVP_KDF_CTX_new_id() function. + +=head2 Supported controls + +The supported controls are: + +=over 4 + +=item B + +=item B + +These controls work as described in L. + +=item B + +=item B + +=item B + +B expects one argument: C + +B expects one argument: C + +B expects one argument: C + +These controls configure the scrypt work factors N, r and p. + +EVP_KDF_ctrl_str() type strings: "N", "r" and "p", respectively. + +The corresponding value strings are expected to be decimal numbers. + +=back + =head1 NOTES A context for scrypt can be obtained by calling: - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SCRYPT, NULL); + EVP_KDF_CTX *kctx = EVP_KDF_CTX_new_id(EVP_KDF_SCRYPT); The output length of an scrypt key derivation is specified via the -length parameter to the L function. +B parameter to the L function. =head1 EXAMPLE -This example derives a 64-byte long test vector using scrypt using the password +This example derives a 64-byte long test vector using scrypt with the password "password", salt "NaCl" and N = 1024, r = 8, p = 16. - EVP_PKEY_CTX *pctx; + EVP_KDF_CTX *kctx; unsigned char out[64]; - size_t outlen = sizeof(out); - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SCRYPT, NULL); + kctx = EVP_KDF_CTX_new_id(EVP_KDF_SCRYPT); - if (EVP_PKEY_derive_init(pctx) <= 0) { - error("EVP_PKEY_derive_init"); + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, "password", (size_t)8) <= 0) { + error("EVP_KDF_CTRL_SET_PASS"); } - if (EVP_PKEY_CTX_set1_pbe_pass(pctx, "password", 8) <= 0) { - error("EVP_PKEY_CTX_set1_pbe_pass"); + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "NaCl", (size_t)4) <= 0) { + error("EVP_KDF_CTRL_SET_SALT"); } - if (EVP_PKEY_CTX_set1_scrypt_salt(pctx, "NaCl", 4) <= 0) { - error("EVP_PKEY_CTX_set1_scrypt_salt"); + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_N, (uint64_t)1024) <= 0) { + error("EVP_KDF_CTRL_SET_SCRYPT_N"); } - if (EVP_PKEY_CTX_set_scrypt_N(pctx, 1024) <= 0) { - error("EVP_PKEY_CTX_set_scrypt_N"); + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_R, (uint32_t)8) <= 0) { + error("EVP_KDF_CTRL_SET_SCRYPT_R"); } - if (EVP_PKEY_CTX_set_scrypt_r(pctx, 8) <= 0) { - error("EVP_PKEY_CTX_set_scrypt_r"); + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_P, (uint32_t)16) <= 0) { + error("EVP_KDF_CTRL_SET_SCRYPT_P"); } - if (EVP_PKEY_CTX_set_scrypt_p(pctx, 16) <= 0) { - error("EVP_PKEY_CTX_set_scrypt_p"); - } - if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) { - error("EVP_PKEY_derive"); + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + error("EVP_KDF_derive"); } { @@ -86,7 +122,7 @@ This example derives a 64-byte long test vector using scrypt using the password assert(!memcmp(out, expected, sizeof(out))); } - EVP_PKEY_CTX_free(pctx); + EVP_KDF_CTX_free(kctx); =head1 CONFORMING TO @@ -94,14 +130,12 @@ RFC 7914 =head1 SEE ALSO -L, -L, -L, -L, -L, -L, -L, -L +L, +L, +L, +L, +L, +L =head1 COPYRIGHT diff --git a/doc/man7/EVP_KDF_TLS1_PRF.pod b/doc/man7/EVP_KDF_TLS1_PRF.pod new file mode 100644 index 00000000..e6cbe099 --- /dev/null +++ b/doc/man7/EVP_KDF_TLS1_PRF.pod @@ -0,0 +1,142 @@ +=pod + +=head1 NAME + +EVP_KDF_TLS1_PRF - The TLS1 PRF EVP_KDF implementation + +=head1 DESCRIPTION + +Support for computing the B PRF through the B API. + +The EVP_KDF_TLS1_PRF algorithm implements the PRF used by TLS versions up to +and including TLS 1.2. + +=head2 Numeric identity + +B is the numeric identity for this implementation; it +can be used with the EVP_KDF_CTX_new_id() function. + +=head2 Supported controls + +The supported controls are: + +=over 4 + +=item B + +This control works as described in L. + +The C control is used to set the message digest associated +with the TLS PRF. EVP_md5_sha1() is treated as a special case which uses the +PRF algorithm using both B and B as used in TLS 1.0 and 1.1. + +=item B + +This control expects two arguments: C, C + +Sets the secret value of the TLS PRF to B bytes of the buffer B. +Any existing secret value is replaced. + +EVP_KDF_ctrl_str() takes two type strings for this control: + +=over 4 + +=item "secret" + +The value string is used as is. + +=item "hexsecret" + +The value string is expected to be a hexadecimal number, which will be +decoded before being passed on as the control value. + +=back + +=item B + +This control does not expect any arguments. + +Resets the context seed buffer to zero length. + +=item B + +This control expects two arguments: C, C + +Sets the seed to B bytes of B. If a seed is already set it is +appended to the existing value. + +The total length of the context seed buffer cannot exceed 1024 bytes; +this should be more than enough for any normal use of the TLS PRF. + +EVP_KDF_ctrl_str() takes two type strings for this control: + +=over 4 + +=item "seed" + +The value string is used as is. + +=item "hexseed" + +The value string is expected to be a hexadecimal number, which will be +decoded before being passed on as the control value. + +=back + +=back + +=head1 NOTES + +A context for the TLS PRF can be obtained by calling: + + EVP_KDF_CTX *kctx = EVP_KDF_CTX_new_id(EVP_KDF_TLS1_PRF, NULL); + +The digest, secret value and seed must be set before a key is derived otherwise +an error will occur. + +The output length of the PRF is specified by the C parameter to the +EVP_KDF_derive() function. + +=head1 EXAMPLE + +This example derives 10 bytes using SHA-256 with the secret key "secret" +and seed value "seed": + + EVP_KDF_CTX *kctx; + unsigned char out[10]; + + kctx = EVP_KDF_CTX_new_id(EVP_KDF_TLS1_PRF); + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) { + error("EVP_KDF_CTRL_SET_MD"); + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_TLS_SECRET, + "secret", (size_t)6) <= 0) { + error("EVP_KDF_CTRL_SET_TLS_SECRET"); + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_ADD_TLS_SEED, "seed", (size_t)4) <= 0) { + error("EVP_KDF_CTRL_ADD_TLS_SEED"); + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + error("EVP_KDF_derive"); + } + EVP_KDF_CTX_free(kctx); + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=head1 COPYRIGHT + +Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/openssl_user_macros.pod.in b/doc/man7/openssl_user_macros.pod.in index 30b8121e..17c2d2e1 100644 --- a/doc/man7/openssl_user_macros.pod.in +++ b/doc/man7/openssl_user_macros.pod.in @@ -19,7 +19,7 @@ user defined macros. =head2 The macros -=over +=over 4 =item B @@ -30,7 +30,7 @@ be declared. The version number assigned to this macro can take one of two forms: -=over +=over 4 =item C<0xMNNFF000L> @@ -43,7 +43,7 @@ Any version number may be given, but these numbers are the current known major deprecation points, making them the most meaningful: -=over +=over 4 =item C<0x00908000L> (version 0.9.8) @@ -63,7 +63,7 @@ This form is a simple number that represents the major version number and is supported for version 3.0.0 and up. For extra convenience, these numbers are also available: -=over +=over 4 =item Z<>0 (C<0x00908000L>, i.e. version 0.9.8) diff --git a/engines/build.info b/engines/build.info index 27f1cecf..e493ceda 100644 --- a/engines/build.info +++ b/engines/build.info @@ -10,6 +10,9 @@ IF[{- !$disabled{"engine"} -}] IF[{- !$disabled{afalgeng} -}] SOURCE[../libcrypto]=e_afalg.c ENDIF + IF[{- !$disabled{"devcryptoeng"} -}] + SOURCE[../libcrypto]=e_devcrypto.c + ENDIF ELSE MODULES{engine}=padlock SOURCE[padlock]=e_padlock.c {- $target{padlock_asm_src} -} @@ -39,6 +42,16 @@ IF[{- !$disabled{"engine"} -}] GENERATE[afalg.ld]=../util/engines.num ENDIF ENDIF + IF[{- !$disabled{"devcryptoeng"} -}] + MODULES=devcrypto + SOURCE[devcrypto]=e_devcrypto.c + DEPEND[devcrypto]=../libcrypto + INCLUDE[devcrypto]=../include + IF[{- defined $target{shared_defflag} -}] + SHARED_SOURCE[devcrypto]=devcrypto.ld + GENERATE[devcrypto.ld]=../util/engines.num + ENDIF + ENDIF MODULES{noinst,engine}=ossltest dasync SOURCE[dasync]=e_dasync.c diff --git a/engines/e_dasync.c b/engines/e_dasync.c index 3d80610b..f8a52e9d 100644 --- a/engines/e_dasync.c +++ b/engines/e_dasync.c @@ -138,7 +138,6 @@ struct dasync_pipeline_ctx { unsigned char **inbufs; unsigned char **outbufs; size_t *lens; - int enc; unsigned char tlsaad[SSL_MAX_PIPELINES][EVP_AEAD_TLS1_AAD_LEN]; unsigned int aadctr; }; @@ -617,7 +616,7 @@ static int dasync_cipher_ctrl_helper(EVP_CIPHER_CTX *ctx, int type, int arg, len = p[arg - 2] << 8 | p[arg - 1]; - if (pipe_ctx->enc) { + if (EVP_CIPHER_CTX_encrypting(ctx)) { if ((p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) { if (len < AES_BLOCK_SIZE) return 0; diff --git a/crypto/engine/eng_devcrypto.c b/engines/e_devcrypto.c similarity index 93% rename from crypto/engine/eng_devcrypto.c rename to engines/e_devcrypto.c index ec6337de..77f0e48f 100644 --- a/crypto/engine/eng_devcrypto.c +++ b/engines/e_devcrypto.c @@ -7,7 +7,7 @@ * https://www.openssl.org/source/license.html */ -#include "e_os.h" +#include "../e_os.h" #include #include #include @@ -23,26 +23,26 @@ #include #include -#include "internal/engine.h" - /* #define ENGINE_DEVCRYPTO_DEBUG */ #ifdef CRYPTO_ALGORITHM_MIN # define CHECK_BSD_STYLE_MACROS #endif +#define engine_devcrypto_id "devcrypto" + /* * ONE global file descriptor for all sessions. This allows operations * such as digest session data copying (see digest_copy()), but is also * saner... why re-open /dev/crypto for every session? */ -static int cfd; +static int cfd = -1; #define DEVCRYPTO_REQUIRE_ACCELERATED 0 /* require confirmation of acceleration */ #define DEVCRYPTO_USE_SOFTWARE 1 /* allow software drivers */ #define DEVCRYPTO_REJECT_SOFTWARE 2 /* only disallow confirmed software drivers */ -#define DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS DEVCRYPTO_REJECT_SOFTWARE -static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS; +#define DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS DEVCRYPTO_REJECT_SOFTWARE +static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS; /* * cipher/digest status & acceleration definitions @@ -66,6 +66,10 @@ struct driver_info_st { char *driver_name; }; +#ifdef OPENSSL_NO_DYNAMIC_ENGINE +void engine_load_devcrypto_int(void); +#endif + /****************************************************************************** * * Ciphers @@ -182,8 +186,13 @@ static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); const struct cipher_data_st *cipher_d = get_cipher_data(EVP_CIPHER_CTX_nid(ctx)); + int sess = cipher_ctx->sess.ses; + + /* close a previous open session */ + if (cipher_ctx->sess.ses != 0 && + ioctl(cfd, CIOCFSESSION, &cipher_ctx->sess.ses) <0) + SYSerr(SYS_F_IOCTL, errno); - memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess)); cipher_ctx->sess.cipher = cipher_d->devcryptoid; cipher_ctx->sess.keylen = cipher_d->keylen; cipher_ctx->sess.key = (void *)key; @@ -325,10 +334,17 @@ static int cipher_ctrl(EVP_CIPHER_CTX *ctx, int type, int p1, void* p2) EVP_CIPHER_CTX *to_ctx = (EVP_CIPHER_CTX *)p2; struct cipher_ctx *cipher_ctx; - if (type == EVP_CTRL_COPY) { - /* when copying the context, a new session needs to be initialized */ + if (type == EVP_CTRL_COPY || type == EVP_CTRL_INIT) { cipher_ctx = (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); - return (cipher_ctx == NULL) + + if (cipher_ctx == NULL) /* OK for copy, error for init */ + return (type == EVP_CTRL_COPY); + + /* both COPY & INIT need a clean context */ + memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess)); + + /* when copying the context, a new session needs to be open as well */ + return (type == EVP_CTRL_INIT) || cipher_init(to_ctx, cipher_ctx->sess.key, EVP_CIPHER_CTX_iv(ctx), (cipher_ctx->op == COP_ENCRYPT)); } @@ -345,6 +361,7 @@ static int cipher_cleanup(EVP_CIPHER_CTX *ctx) SYSerr(SYS_F_IOCTL, errno); return 0; } + memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess)); return 1; } @@ -414,6 +431,7 @@ static void prepare_cipher_methods(void) || !EVP_CIPHER_meth_set_flags(known_cipher_methods[i], cipher_data[i].flags | EVP_CIPH_CUSTOM_COPY + | EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1) || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init) || !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i], @@ -1030,7 +1048,7 @@ static const ENGINE_CMD_DEFN devcrypto_cmds[] = { OPENSSL_MSTR(DEVCRYPTO_USE_SOFTWARE) "=allow all drivers, " OPENSSL_MSTR(DEVCRYPTO_REJECT_SOFTWARE) "=use if acceleration can't be determined) [default=" - OPENSSL_MSTR(DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS) "]", + OPENSSL_MSTR(DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS) "]", ENGINE_CMD_FLAG_NUMERIC}, #endif @@ -1138,6 +1156,37 @@ static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) * *****/ +/* + * Opens /dev/crypto + */ +static int open_devcrypto(void) +{ + if (cfd >= 0) + return 1; + + if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0) { +#ifndef ENGINE_DEVCRYPTO_DEBUG + if (errno != ENOENT) +#endif + fprintf(stderr, "Could not open /dev/crypto: %s\n", strerror(errno)); + return 0; + } + + return 1; +} + +static int close_devcrypto(void) +{ + if (cfd < 0) + return 1; + cfd = -1; + if (close(cfd) == 0) { + fprintf(stderr, "Error closing /dev/crypto: %s\n", strerror(errno)); + return 0; + } + return 1; +} + static int devcrypto_unload(ENGINE *e) { destroy_all_cipher_methods(); @@ -1145,48 +1194,29 @@ static int devcrypto_unload(ENGINE *e) destroy_all_digest_methods(); #endif - close(cfd); + close_devcrypto(); return 1; } -/* - * This engine is always built into libcrypto, so it doesn't offer any - * ability to be dynamically loadable. - */ -void engine_load_devcrypto_int() -{ - ENGINE *e = NULL; - if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0) { -#ifndef ENGINE_DEVCRYPTO_DEBUG - if (errno != ENOENT) -#endif - fprintf(stderr, "Could not open /dev/crypto: %s\n", strerror(errno)); - return; - } +static int bind_devcrypto(ENGINE *e) { - if ((e = ENGINE_new()) == NULL - || !ENGINE_set_destroy_function(e, devcrypto_unload)) { - ENGINE_free(e); - /* - * We know that devcrypto_unload() won't be called when one of the - * above two calls have failed, so we close cfd explicitly here to - * avoid leaking resources. - */ - close(cfd); - return; - } + if (!ENGINE_set_id(e, engine_devcrypto_id) + || !ENGINE_set_name(e, "/dev/crypto engine") + || !ENGINE_set_destroy_function(e, devcrypto_unload) + || !ENGINE_set_cmd_defns(e, devcrypto_cmds) + || !ENGINE_set_ctrl_function(e, devcrypto_ctrl)) + return 0; prepare_cipher_methods(); #ifdef IMPLEMENT_DIGEST prepare_digest_methods(); #endif - if (!ENGINE_set_id(e, "devcrypto") - || !ENGINE_set_name(e, "/dev/crypto engine") - || !ENGINE_set_cmd_defns(e, devcrypto_cmds) - || !ENGINE_set_ctrl_function(e, devcrypto_ctrl) - + return (ENGINE_set_ciphers(e, devcrypto_ciphers) +#ifdef IMPLEMENT_DIGEST + && ENGINE_set_digests(e, devcrypto_digests) +#endif /* * Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD * implementations, it seems to only exist in FreeBSD, and regarding the @@ -1209,23 +1239,36 @@ void engine_load_devcrypto_int() */ #if 0 # ifndef OPENSSL_NO_RSA - || !ENGINE_set_RSA(e, devcrypto_rsa) + && ENGINE_set_RSA(e, devcrypto_rsa) # endif # ifndef OPENSSL_NO_DSA - || !ENGINE_set_DSA(e, devcrypto_dsa) + && ENGINE_set_DSA(e, devcrypto_dsa) # endif # ifndef OPENSSL_NO_DH - || !ENGINE_set_DH(e, devcrypto_dh) + && ENGINE_set_DH(e, devcrypto_dh) # endif # ifndef OPENSSL_NO_EC - || !ENGINE_set_EC(e, devcrypto_ec) + && ENGINE_set_EC(e, devcrypto_ec) # endif #endif - || !ENGINE_set_ciphers(e, devcrypto_ciphers) -#ifdef IMPLEMENT_DIGEST - || !ENGINE_set_digests(e, devcrypto_digests) -#endif - ) { + ); +} + +#ifdef OPENSSL_NO_DYNAMIC_ENGINE +/* + * In case this engine is built into libcrypto, then it doesn't offer any + * ability to be dynamically loadable. + */ +void engine_load_devcrypto_int(void) +{ + ENGINE *e = NULL; + + if (!open_devcrypto()) + return; + + if ((e = ENGINE_new()) == NULL + || !bind_devcrypto(e)) { + close_devcrypto(); ENGINE_free(e); return; } @@ -1234,3 +1277,22 @@ void engine_load_devcrypto_int() ENGINE_free(e); /* Loose our local reference */ ERR_clear_error(); } + +#else + +static int bind_helper(ENGINE *e, const char *id) +{ + if ((id && (strcmp(id, engine_devcrypto_id) != 0)) + || !open_devcrypto()) + return 0; + if (!bind_devcrypto(e)) { + close_devcrypto(); + return 0; + } + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) + +#endif diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h index 9bf3c316..28fd96e2 100644 --- a/include/internal/cryptlib.h +++ b/include/internal/cryptlib.h @@ -95,4 +95,13 @@ uint32_t OPENSSL_rdtsc(void); size_t OPENSSL_instrument_bus(unsigned int *, size_t); size_t OPENSSL_instrument_bus2(unsigned int *, size_t, size_t); +typedef struct openssl_ctx_method { + void *(*new_func)(void); + void (*free_func)(void *); +} OPENSSL_CTX_METHOD; +/* For each type of data to store in the context, an index must be created */ +int openssl_ctx_new_index(const OPENSSL_CTX_METHOD *); +/* Functions to retrieve pointers to data by index */ +void *openssl_ctx_get_data(OPENSSL_CTX *, int /* index */); + #endif diff --git a/include/internal/property.h b/include/internal/property.h new file mode 100644 index 00000000..82b3a338 --- /dev/null +++ b/include/internal/property.h @@ -0,0 +1,35 @@ +/* + * 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 + */ + +#ifndef HEADER_PROPERTY_H +# define HEADER_PROPERTY_H + +typedef struct ossl_method_store_st OSSL_METHOD_STORE; + +/* Implementation store functions */ +OSSL_METHOD_STORE *ossl_method_store_new(void); +void ossl_method_store_free(OSSL_METHOD_STORE *store); +int ossl_method_store_add(OSSL_METHOD_STORE *store, int nid, + const char *properties, void *implementation, + void (*implementation_destruct)(void *)); +int ossl_method_store_remove(OSSL_METHOD_STORE *store, + int nid, const void *implementation); +int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid, + const char *prop_query, void **result); +int ossl_method_store_set_global_properties(OSSL_METHOD_STORE *store, + const char *prop_query); + +/* proeprty query cache functions */ +int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, int nid, + const char *prop_query, void **result); +int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, int nid, + const char *prop_query, void *result); + +#endif diff --git a/include/internal/propertyerr.h b/include/internal/propertyerr.h new file mode 100644 index 00000000..908c9109 --- /dev/null +++ b/include/internal/propertyerr.h @@ -0,0 +1,46 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-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 + */ + +#ifndef HEADER_PROPERR_H +# define HEADER_PROPERR_H + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_PROP_strings(void); + +/* + * PROP function codes. + */ +# define PROP_F_OSSL_PARSE_PROPERTY 100 +# define PROP_F_OSSL_PARSE_QUERY 101 +# define PROP_F_PARSE_HEX 102 +# define PROP_F_PARSE_NAME 103 +# define PROP_F_PARSE_NUMBER 104 +# define PROP_F_PARSE_OCT 105 +# define PROP_F_PARSE_STRING 106 +# define PROP_F_PARSE_UNQUOTED 107 + +/* + * PROP reason codes. + */ +# define PROP_R_NAME_TOO_LONG 100 +# define PROP_R_NOT_AN_ASCII_CHARACTER 101 +# define PROP_R_NOT_AN_HEXADECIMAL_DIGIT 102 +# define PROP_R_NOT_AN_IDENTIFIER 103 +# define PROP_R_NOT_AN_OCTAL_DIGIT 104 +# define PROP_R_NOT_A_DECIMAL_DIGIT 105 +# define PROP_R_NO_MATCHING_STRING_DELIMETER 106 +# define PROP_R_NO_VALUE 107 +# define PROP_R_PARSE_FAILED 108 +# define PROP_R_STRING_TOO_LONG 109 +# define PROP_R_TRAILING_CHARACTERS 110 + +#endif diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index cbde3d5e..deb369ee 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -107,7 +107,8 @@ DEFINE_STACK_OF(void) # define CRYPTO_EX_INDEX_APP 13 # define CRYPTO_EX_INDEX_UI_METHOD 14 # define CRYPTO_EX_INDEX_DRBG 15 -# define CRYPTO_EX_INDEX__COUNT 16 +# define CRYPTO_EX_INDEX_OPENSSL_CTX 16 +# define CRYPTO_EX_INDEX__COUNT 17 /* No longer needed, so this is a no-op */ #define OPENSSL_malloc_init() while(0) continue @@ -187,6 +188,10 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +/* Allocate a single item in the CRYPTO_EX_DATA variable */ +int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad, + int idx); + /* * Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular * index (relative to the class type involved) @@ -446,6 +451,8 @@ int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key); CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void); int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b); +OPENSSL_CTX *OPENSSL_CTX_new(void); +void OPENSSL_CTX_free(OPENSSL_CTX *); # ifdef __cplusplus } diff --git a/include/openssl/e_os2.h b/include/openssl/e_os2.h index 002cea3b..b88abc17 100644 --- a/include/openssl/e_os2.h +++ b/include/openssl/e_os2.h @@ -287,6 +287,13 @@ typedef unsigned __int64 uint64_t; # define ossl_noreturn # endif +/* ossl_unused: portable unused attribute for use in public headers */ +# if defined(__GNUC__) +# define ossl_unused __attribute__((unused)) +# else +# define ossl_unused +# endif + #ifdef __cplusplus } #endif diff --git a/include/openssl/ec.h b/include/openssl/ec.h index 4afaad45..7c153684 100644 --- a/include/openssl/ec.h +++ b/include/openssl/ec.h @@ -212,6 +212,12 @@ void EC_GROUP_set_curve_name(EC_GROUP *group, int nid); */ int EC_GROUP_get_curve_name(const EC_GROUP *group); +/** Gets the field of an EC_GROUP + * \param group EC_GROUP object + * \return the group field + */ +const BIGNUM *EC_GROUP_get0_field(const EC_GROUP *group); + void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); int EC_GROUP_get_asn1_flag(const EC_GROUP *group); diff --git a/include/openssl/ecerr.h b/include/openssl/ecerr.h index 1cbd3a38..80744815 100644 --- a/include/openssl/ecerr.h +++ b/include/openssl/ecerr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-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 @@ -62,6 +62,7 @@ int ERR_load_EC_strings(void); # define EC_F_EC_ASN1_GROUP2CURVE 153 # define EC_F_EC_ASN1_GROUP2FIELDID 154 # define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208 +# define EC_F_EC_GF2M_SIMPLE_FIELD_INV 296 # define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159 # define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195 # define EC_F_EC_GF2M_SIMPLE_LADDER_POST 285 @@ -74,6 +75,7 @@ int ERR_load_EC_strings(void); # define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164 # define EC_F_EC_GFP_MONT_FIELD_DECODE 133 # define EC_F_EC_GFP_MONT_FIELD_ENCODE 134 +# define EC_F_EC_GFP_MONT_FIELD_INV 297 # define EC_F_EC_GFP_MONT_FIELD_MUL 131 # define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209 # define EC_F_EC_GFP_MONT_FIELD_SQR 132 @@ -91,6 +93,7 @@ int ERR_load_EC_strings(void); # define EC_F_EC_GFP_NIST_FIELD_SQR 201 # define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202 # define EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES 287 +# define EC_F_EC_GFP_SIMPLE_FIELD_INV 298 # define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165 # define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166 # define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102 @@ -202,6 +205,7 @@ int ERR_load_EC_strings(void); # define EC_R_BAD_SIGNATURE 156 # define EC_R_BIGNUM_OUT_OF_RANGE 144 # define EC_R_BUFFER_TOO_SMALL 100 +# define EC_R_CANNOT_INVERT 165 # define EC_R_COORDINATES_OUT_OF_RANGE 146 # define EC_R_CURVE_DOES_NOT_SUPPORT_ECDH 160 # define EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING 159 diff --git a/include/openssl/err.h b/include/openssl/err.h index ed3a2f06..0d6956cf 100644 --- a/include/openssl/err.h +++ b/include/openssl/err.h @@ -95,6 +95,7 @@ typedef struct err_state_st { # define ERR_LIB_KDF 52 # define ERR_LIB_SM2 53 # define ERR_LIB_ESS 54 +# define ERR_LIB_PROP 55 # define ERR_LIB_USER 128 @@ -135,6 +136,7 @@ typedef struct err_state_st { # define KDFerr(f,r) ERR_PUT_error(ERR_LIB_KDF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) # define SM2err(f,r) ERR_PUT_error(ERR_LIB_SM2,(f),(r),OPENSSL_FILE,OPENSSL_LINE) # define ESSerr(f,r) ERR_PUT_error(ERR_LIB_ESS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define PROPerr(f,r) ERR_PUT_error(ERR_LIB_PROP,(f),(r),OPENSSL_FILE,OPENSSL_LINE) # define ERR_PACK(l,f,r) ( \ (((unsigned int)(l) & 0x0FF) << 24L) | \ diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h index d3ed5b5a..7da602d9 100644 --- a/include/openssl/evperr.h +++ b/include/openssl/evperr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-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 @@ -55,6 +55,9 @@ int ERR_load_EVP_strings(void); # define EVP_F_EVP_ENCRYPTDECRYPTUPDATE 219 # define EVP_F_EVP_ENCRYPTFINAL_EX 127 # define EVP_F_EVP_ENCRYPTUPDATE 167 +# define EVP_F_EVP_KDF_CTRL 224 +# define EVP_F_EVP_KDF_CTRL_STR 225 +# define EVP_F_EVP_KDF_CTX_NEW_ID 226 # define EVP_F_EVP_MAC_CTRL 209 # define EVP_F_EVP_MAC_CTRL_STR 210 # define EVP_F_EVP_MAC_CTX_COPY 211 @@ -125,6 +128,7 @@ int ERR_load_EVP_strings(void); # define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118 # define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN 164 # define EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN 180 +# define EVP_F_PKEY_KDF_CTRL 227 # define EVP_F_PKEY_MAC_INIT 214 # define EVP_F_PKEY_SET_TYPE 158 # define EVP_F_POLY1305_CTRL 216 @@ -132,6 +136,7 @@ int ERR_load_EVP_strings(void); # define EVP_F_RC5_CTRL 125 # define EVP_F_S390X_AES_GCM_CTRL 201 # define EVP_F_S390X_AES_GCM_TLS_CIPHER 208 +# define EVP_F_SCRYPT_ALG 228 # define EVP_F_UPDATE 173 /* @@ -188,6 +193,7 @@ int ERR_load_EVP_strings(void); # define EVP_R_ONLY_ONESHOT_SUPPORTED 177 # define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150 # define EVP_R_OPERATON_NOT_INITIALIZED 151 +# define EVP_R_PARAMETER_TOO_LARGE 187 # define EVP_R_PARTIALLY_OVERLAPPING 162 # define EVP_R_PBKDF2_ERROR 181 # define EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED 179 diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h index b9e7824e..663ba90a 100644 --- a/include/openssl/kdf.h +++ b/include/openssl/kdf.h @@ -10,10 +10,52 @@ #ifndef HEADER_KDF_H # define HEADER_KDF_H +# include +# include +# include # include -#ifdef __cplusplus +# ifdef __cplusplus extern "C" { -#endif +# endif + +# define EVP_KDF_PBKDF2 NID_id_pbkdf2 +# define EVP_KDF_SCRYPT NID_id_scrypt +# define EVP_KDF_TLS1_PRF NID_tls1_prf +# define EVP_KDF_HKDF NID_hkdf + +EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id); +void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx); + +void EVP_KDF_reset(EVP_KDF_CTX *ctx); +int EVP_KDF_ctrl(EVP_KDF_CTX *ctx, int cmd, ...); +int EVP_KDF_vctrl(EVP_KDF_CTX *ctx, int cmd, va_list args); +int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value); +size_t EVP_KDF_size(EVP_KDF_CTX *ctx); +int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen); + + +# define EVP_KDF_CTRL_SET_PASS 0x01 /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_SET_SALT 0x02 /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_SET_ITER 0x03 /* int */ +# define EVP_KDF_CTRL_SET_MD 0x04 /* EVP_MD * */ +# define EVP_KDF_CTRL_SET_KEY 0x05 /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_SET_MAXMEM_BYTES 0x06 /* uint64_t */ +# define EVP_KDF_CTRL_SET_TLS_SECRET 0x07 /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_RESET_TLS_SEED 0x08 +# define EVP_KDF_CTRL_ADD_TLS_SEED 0x09 /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_RESET_HKDF_INFO 0x0a +# define EVP_KDF_CTRL_ADD_HKDF_INFO 0x0b /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_SET_HKDF_MODE 0x0c /* int */ +# define EVP_KDF_CTRL_SET_SCRYPT_N 0x0d /* uint64_t */ +# define EVP_KDF_CTRL_SET_SCRYPT_R 0x0e /* uint32_t */ +# define EVP_KDF_CTRL_SET_SCRYPT_P 0x0f /* uint32_t */ + +# define EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND 0 +# define EVP_KDF_HKDF_MODE_EXTRACT_ONLY 1 +# define EVP_KDF_HKDF_MODE_EXPAND_ONLY 2 + + +/**** The legacy PKEY-based KDF API follows. ****/ # define EVP_PKEY_CTRL_TLS_MD (EVP_PKEY_ALG_CTRL) # define EVP_PKEY_CTRL_TLS_SECRET (EVP_PKEY_ALG_CTRL + 1) @@ -30,9 +72,12 @@ extern "C" { # define EVP_PKEY_CTRL_SCRYPT_P (EVP_PKEY_ALG_CTRL + 12) # define EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES (EVP_PKEY_ALG_CTRL + 13) -# define EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND 0 -# define EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY 1 -# define EVP_PKEY_HKDEF_MODE_EXPAND_ONLY 2 +# define EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND \ + EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND +# define EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY \ + EVP_KDF_HKDF_MODE_EXTRACT_ONLY +# define EVP_PKEY_HKDEF_MODE_EXPAND_ONLY \ + EVP_KDF_HKDF_MODE_EXPAND_ONLY # define EVP_PKEY_CTX_set_tls1_prf_md(pctx, md) \ EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ @@ -91,7 +136,7 @@ extern "C" { EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES, maxmem_bytes) -# ifdef __cplusplus +# ifdef __cplusplus } # endif #endif diff --git a/include/openssl/kdferr.h b/include/openssl/kdferr.h index 0fddea0e..a143959b 100644 --- a/include/openssl/kdferr.h +++ b/include/openssl/kdferr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-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,23 @@ int ERR_load_KDF_strings(void); /* * KDF function codes. */ +# define KDF_F_HKDF_EXTRACT 112 +# define KDF_F_KDF_HKDF_DERIVE 113 +# define KDF_F_KDF_HKDF_NEW 114 +# define KDF_F_KDF_HKDF_SIZE 115 +# define KDF_F_KDF_MD2CTRL 116 +# define KDF_F_KDF_PBKDF2_CTRL_STR 117 +# define KDF_F_KDF_PBKDF2_DERIVE 118 +# define KDF_F_KDF_PBKDF2_NEW 119 +# define KDF_F_KDF_SCRYPT_CTRL_STR 120 +# define KDF_F_KDF_SCRYPT_CTRL_UINT32 121 +# define KDF_F_KDF_SCRYPT_CTRL_UINT64 122 +# define KDF_F_KDF_SCRYPT_DERIVE 123 +# define KDF_F_KDF_SCRYPT_NEW 124 +# define KDF_F_KDF_TLS1_PRF_CTRL_STR 125 +# define KDF_F_KDF_TLS1_PRF_DERIVE 126 +# define KDF_F_KDF_TLS1_PRF_NEW 127 +# define KDF_F_PBKDF2_SET_MEMBUF 128 # define KDF_F_PKEY_HKDF_CTRL_STR 103 # define KDF_F_PKEY_HKDF_DERIVE 102 # define KDF_F_PKEY_HKDF_INIT 108 @@ -30,6 +47,7 @@ int ERR_load_KDF_strings(void); # define KDF_F_PKEY_TLS1_PRF_CTRL_STR 100 # define KDF_F_PKEY_TLS1_PRF_DERIVE 101 # define KDF_F_PKEY_TLS1_PRF_INIT 110 +# define KDF_F_SCRYPT_SET_MEMBUF 129 # define KDF_F_TLS1_PRF_ALG 111 /* @@ -47,5 +65,6 @@ int ERR_load_KDF_strings(void); # define KDF_R_UNKNOWN_PARAMETER_TYPE 103 # define KDF_R_VALUE_ERROR 108 # define KDF_R_VALUE_MISSING 102 +# define KDF_R_WRONG_OUTPUT_BUFFER_SIZE 112 #endif diff --git a/include/openssl/lhash.h b/include/openssl/lhash.h index 672841d2..6144fddc 100644 --- a/include/openssl/lhash.h +++ b/include/openssl/lhash.h @@ -72,6 +72,7 @@ typedef struct lhash_st OPENSSL_LHASH; int OPENSSL_LH_error(OPENSSL_LHASH *lh); OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c); void OPENSSL_LH_free(OPENSSL_LHASH *lh); +void OPENSSL_LH_flush(OPENSSL_LHASH *lh); void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data); void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data); void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data); @@ -127,52 +128,56 @@ void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out); return (LHASH_OF(type) *) \ OPENSSL_LH_new((OPENSSL_LH_HASHFUNC)hfn, (OPENSSL_LH_COMPFUNC)cfn); \ } \ - static ossl_inline void lh_##type##_free(LHASH_OF(type) *lh) \ + static ossl_unused ossl_inline void lh_##type##_free(LHASH_OF(type) *lh) \ { \ OPENSSL_LH_free((OPENSSL_LHASH *)lh); \ } \ - static ossl_inline type *lh_##type##_insert(LHASH_OF(type) *lh, type *d) \ + static ossl_unused ossl_inline void lh_##type##_flush(LHASH_OF(type) *lh) \ + { \ + OPENSSL_LH_flush((OPENSSL_LHASH *)lh); \ + } \ + static ossl_unused ossl_inline type *lh_##type##_insert(LHASH_OF(type) *lh, type *d) \ { \ return (type *)OPENSSL_LH_insert((OPENSSL_LHASH *)lh, d); \ } \ - static ossl_inline type *lh_##type##_delete(LHASH_OF(type) *lh, const type *d) \ + static ossl_unused ossl_inline type *lh_##type##_delete(LHASH_OF(type) *lh, const type *d) \ { \ return (type *)OPENSSL_LH_delete((OPENSSL_LHASH *)lh, d); \ } \ - static ossl_inline type *lh_##type##_retrieve(LHASH_OF(type) *lh, const type *d) \ + static ossl_unused ossl_inline type *lh_##type##_retrieve(LHASH_OF(type) *lh, const type *d) \ { \ return (type *)OPENSSL_LH_retrieve((OPENSSL_LHASH *)lh, d); \ } \ - static ossl_inline int lh_##type##_error(LHASH_OF(type) *lh) \ + static ossl_unused ossl_inline int lh_##type##_error(LHASH_OF(type) *lh) \ { \ return OPENSSL_LH_error((OPENSSL_LHASH *)lh); \ } \ - static ossl_inline unsigned long lh_##type##_num_items(LHASH_OF(type) *lh) \ + static ossl_unused ossl_inline unsigned long lh_##type##_num_items(LHASH_OF(type) *lh) \ { \ return OPENSSL_LH_num_items((OPENSSL_LHASH *)lh); \ } \ - static ossl_inline void lh_##type##_node_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ + static ossl_unused ossl_inline void lh_##type##_node_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ { \ OPENSSL_LH_node_stats_bio((const OPENSSL_LHASH *)lh, out); \ } \ - static ossl_inline void lh_##type##_node_usage_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ + static ossl_unused ossl_inline void lh_##type##_node_usage_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ { \ OPENSSL_LH_node_usage_stats_bio((const OPENSSL_LHASH *)lh, out); \ } \ - static ossl_inline void lh_##type##_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ + static ossl_unused ossl_inline void lh_##type##_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ { \ OPENSSL_LH_stats_bio((const OPENSSL_LHASH *)lh, out); \ } \ - static ossl_inline unsigned long lh_##type##_get_down_load(LHASH_OF(type) *lh) \ + static ossl_unused ossl_inline unsigned long lh_##type##_get_down_load(LHASH_OF(type) *lh) \ { \ return OPENSSL_LH_get_down_load((OPENSSL_LHASH *)lh); \ } \ - static ossl_inline void lh_##type##_set_down_load(LHASH_OF(type) *lh, unsigned long dl) \ + static ossl_unused ossl_inline void lh_##type##_set_down_load(LHASH_OF(type) *lh, unsigned long dl) \ { \ OPENSSL_LH_set_down_load((OPENSSL_LHASH *)lh, dl); \ } \ - static ossl_inline void lh_##type##_doall(LHASH_OF(type) *lh, \ - void (*doall)(type *)) \ + static ossl_unused ossl_inline void lh_##type##_doall(LHASH_OF(type) *lh, \ + void (*doall)(type *)) \ { \ OPENSSL_LH_doall((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNC)doall); \ } \ @@ -185,7 +190,7 @@ void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out); int_implement_lhash_doall(type, argtype, type) #define int_implement_lhash_doall(type, argtype, cbargtype) \ - static ossl_inline void \ + static ossl_unused ossl_inline void \ lh_##type##_doall_##argtype(LHASH_OF(type) *lh, \ void (*fn)(cbargtype *, argtype *), \ argtype *arg) \ diff --git a/include/openssl/ossl_typ.h b/include/openssl/ossl_typ.h index 51171d5a..44ddfaaf 100644 --- a/include/openssl/ossl_typ.h +++ b/include/openssl/ossl_typ.h @@ -99,6 +99,8 @@ typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; typedef struct evp_pkey_method_st EVP_PKEY_METHOD; typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; +typedef struct evp_kdf_ctx_st EVP_KDF_CTX; + typedef struct evp_Encode_Ctx_st EVP_ENCODE_CTX; typedef struct hmac_ctx_st HMAC_CTX; @@ -177,6 +179,8 @@ typedef struct ct_policy_eval_ctx_st CT_POLICY_EVAL_CTX; typedef struct ossl_store_info_st OSSL_STORE_INFO; typedef struct ossl_store_search_st OSSL_STORE_SEARCH; +typedef struct openssl_ctx_st OPENSSL_CTX; + #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \ defined(INTMAX_MAX) && defined(UINTMAX_MAX) typedef intmax_t ossl_intmax_t; diff --git a/include/openssl/safestack.h b/include/openssl/safestack.h index ba38ff7e..1fbe6cbd 100644 --- a/include/openssl/safestack.h +++ b/include/openssl/safestack.h @@ -24,96 +24,96 @@ extern "C" { typedef int (*sk_##t1##_compfunc)(const t3 * const *a, const t3 *const *b); \ typedef void (*sk_##t1##_freefunc)(t3 *a); \ typedef t3 * (*sk_##t1##_copyfunc)(const t3 *a); \ - static ossl_inline int sk_##t1##_num(const STACK_OF(t1) *sk) \ + static ossl_unused ossl_inline int sk_##t1##_num(const STACK_OF(t1) *sk) \ { \ return OPENSSL_sk_num((const OPENSSL_STACK *)sk); \ } \ - static ossl_inline t2 *sk_##t1##_value(const STACK_OF(t1) *sk, int idx) \ + static ossl_unused ossl_inline t2 *sk_##t1##_value(const STACK_OF(t1) *sk, int idx) \ { \ return (t2 *)OPENSSL_sk_value((const OPENSSL_STACK *)sk, idx); \ } \ - static ossl_inline STACK_OF(t1) *sk_##t1##_new(sk_##t1##_compfunc compare) \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_new(sk_##t1##_compfunc compare) \ { \ return (STACK_OF(t1) *)OPENSSL_sk_new((OPENSSL_sk_compfunc)compare); \ } \ - static ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \ { \ return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \ } \ - static ossl_inline STACK_OF(t1) *sk_##t1##_new_reserve(sk_##t1##_compfunc compare, int n) \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_new_reserve(sk_##t1##_compfunc compare, int n) \ { \ return (STACK_OF(t1) *)OPENSSL_sk_new_reserve((OPENSSL_sk_compfunc)compare, n); \ } \ - static ossl_inline int sk_##t1##_reserve(STACK_OF(t1) *sk, int n) \ + static ossl_unused ossl_inline int sk_##t1##_reserve(STACK_OF(t1) *sk, int n) \ { \ return OPENSSL_sk_reserve((OPENSSL_STACK *)sk, n); \ } \ - static ossl_inline void sk_##t1##_free(STACK_OF(t1) *sk) \ + static ossl_unused ossl_inline void sk_##t1##_free(STACK_OF(t1) *sk) \ { \ OPENSSL_sk_free((OPENSSL_STACK *)sk); \ } \ - static ossl_inline void sk_##t1##_zero(STACK_OF(t1) *sk) \ + static ossl_unused ossl_inline void sk_##t1##_zero(STACK_OF(t1) *sk) \ { \ OPENSSL_sk_zero((OPENSSL_STACK *)sk); \ } \ - static ossl_inline t2 *sk_##t1##_delete(STACK_OF(t1) *sk, int i) \ + static ossl_unused ossl_inline t2 *sk_##t1##_delete(STACK_OF(t1) *sk, int i) \ { \ return (t2 *)OPENSSL_sk_delete((OPENSSL_STACK *)sk, i); \ } \ - static ossl_inline t2 *sk_##t1##_delete_ptr(STACK_OF(t1) *sk, t2 *ptr) \ + static ossl_unused ossl_inline t2 *sk_##t1##_delete_ptr(STACK_OF(t1) *sk, t2 *ptr) \ { \ return (t2 *)OPENSSL_sk_delete_ptr((OPENSSL_STACK *)sk, \ (const void *)ptr); \ } \ - static ossl_inline int sk_##t1##_push(STACK_OF(t1) *sk, t2 *ptr) \ + static ossl_unused ossl_inline int sk_##t1##_push(STACK_OF(t1) *sk, t2 *ptr) \ { \ return OPENSSL_sk_push((OPENSSL_STACK *)sk, (const void *)ptr); \ } \ - static ossl_inline int sk_##t1##_unshift(STACK_OF(t1) *sk, t2 *ptr) \ + static ossl_unused ossl_inline int sk_##t1##_unshift(STACK_OF(t1) *sk, t2 *ptr) \ { \ return OPENSSL_sk_unshift((OPENSSL_STACK *)sk, (const void *)ptr); \ } \ - static ossl_inline t2 *sk_##t1##_pop(STACK_OF(t1) *sk) \ + static ossl_unused ossl_inline t2 *sk_##t1##_pop(STACK_OF(t1) *sk) \ { \ return (t2 *)OPENSSL_sk_pop((OPENSSL_STACK *)sk); \ } \ - static ossl_inline t2 *sk_##t1##_shift(STACK_OF(t1) *sk) \ + static ossl_unused ossl_inline t2 *sk_##t1##_shift(STACK_OF(t1) *sk) \ { \ return (t2 *)OPENSSL_sk_shift((OPENSSL_STACK *)sk); \ } \ - static ossl_inline void sk_##t1##_pop_free(STACK_OF(t1) *sk, sk_##t1##_freefunc freefunc) \ + static ossl_unused ossl_inline void sk_##t1##_pop_free(STACK_OF(t1) *sk, sk_##t1##_freefunc freefunc) \ { \ OPENSSL_sk_pop_free((OPENSSL_STACK *)sk, (OPENSSL_sk_freefunc)freefunc); \ } \ - static ossl_inline int sk_##t1##_insert(STACK_OF(t1) *sk, t2 *ptr, int idx) \ + static ossl_unused ossl_inline int sk_##t1##_insert(STACK_OF(t1) *sk, t2 *ptr, int idx) \ { \ return OPENSSL_sk_insert((OPENSSL_STACK *)sk, (const void *)ptr, idx); \ } \ - static ossl_inline t2 *sk_##t1##_set(STACK_OF(t1) *sk, int idx, t2 *ptr) \ + static ossl_unused ossl_inline t2 *sk_##t1##_set(STACK_OF(t1) *sk, int idx, t2 *ptr) \ { \ return (t2 *)OPENSSL_sk_set((OPENSSL_STACK *)sk, idx, (const void *)ptr); \ } \ - static ossl_inline int sk_##t1##_find(STACK_OF(t1) *sk, t2 *ptr) \ + static ossl_unused ossl_inline int sk_##t1##_find(STACK_OF(t1) *sk, t2 *ptr) \ { \ return OPENSSL_sk_find((OPENSSL_STACK *)sk, (const void *)ptr); \ } \ - static ossl_inline int sk_##t1##_find_ex(STACK_OF(t1) *sk, t2 *ptr) \ + static ossl_unused ossl_inline int sk_##t1##_find_ex(STACK_OF(t1) *sk, t2 *ptr) \ { \ return OPENSSL_sk_find_ex((OPENSSL_STACK *)sk, (const void *)ptr); \ } \ - static ossl_inline void sk_##t1##_sort(STACK_OF(t1) *sk) \ + static ossl_unused ossl_inline void sk_##t1##_sort(STACK_OF(t1) *sk) \ { \ OPENSSL_sk_sort((OPENSSL_STACK *)sk); \ } \ - static ossl_inline int sk_##t1##_is_sorted(const STACK_OF(t1) *sk) \ + static ossl_unused ossl_inline int sk_##t1##_is_sorted(const STACK_OF(t1) *sk) \ { \ return OPENSSL_sk_is_sorted((const OPENSSL_STACK *)sk); \ } \ - static ossl_inline STACK_OF(t1) * sk_##t1##_dup(const STACK_OF(t1) *sk) \ + static ossl_unused ossl_inline STACK_OF(t1) * sk_##t1##_dup(const STACK_OF(t1) *sk) \ { \ return (STACK_OF(t1) *)OPENSSL_sk_dup((const OPENSSL_STACK *)sk); \ } \ - static ossl_inline STACK_OF(t1) *sk_##t1##_deep_copy(const STACK_OF(t1) *sk, \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_deep_copy(const STACK_OF(t1) *sk, \ sk_##t1##_copyfunc copyfunc, \ sk_##t1##_freefunc freefunc) \ { \ @@ -121,7 +121,7 @@ extern "C" { (OPENSSL_sk_copyfunc)copyfunc, \ (OPENSSL_sk_freefunc)freefunc); \ } \ - static ossl_inline sk_##t1##_compfunc sk_##t1##_set_cmp_func(STACK_OF(t1) *sk, sk_##t1##_compfunc compare) \ + static ossl_unused ossl_inline sk_##t1##_compfunc sk_##t1##_set_cmp_func(STACK_OF(t1) *sk, sk_##t1##_compfunc compare) \ { \ return (sk_##t1##_compfunc)OPENSSL_sk_set_cmp_func((OPENSSL_STACK *)sk, (OPENSSL_sk_compfunc)compare); \ } diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index c2bce682..5692cfab 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -298,23 +298,26 @@ typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx); typedef int (*SSL_async_callback_fn)(SSL *s, void *arg); /* - * Some values are reserved until OpenSSL 1.2.0 because they were previously + * Some values are reserved until OpenSSL 3.0.0 because they were previously * included in SSL_OP_ALL in a 1.1.x release. - * - * Reserved value (until OpenSSL 1.2.0) 0x00000001U - * Reserved value (until OpenSSL 1.2.0) 0x00000002U */ + +/* Disable Extended master secret */ +# define SSL_OP_NO_EXTENDED_MASTER_SECRET 0x00000001U + +/* Reserved value (until OpenSSL 3.0.0) 0x00000002U */ + /* Allow initial connection to servers that don't support RI */ # define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004U -/* Reserved value (until OpenSSL 1.2.0) 0x00000008U */ +/* Reserved value (until OpenSSL 3.0.0) 0x00000008U */ # define SSL_OP_TLSEXT_PADDING 0x00000010U -/* Reserved value (until OpenSSL 1.2.0) 0x00000020U */ +/* Reserved value (until OpenSSL 3.0.0) 0x00000020U */ # define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x00000040U /* - * Reserved value (until OpenSSL 1.2.0) 0x00000080U - * Reserved value (until OpenSSL 1.2.0) 0x00000100U - * Reserved value (until OpenSSL 1.2.0) 0x00000200U + * Reserved value (until OpenSSL 3.0.0) 0x00000080U + * Reserved value (until OpenSSL 3.0.0) 0x00000100U + * Reserved value (until OpenSSL 3.0.0) 0x00000200U */ /* In TLSv1.3 allow a non-(ec)dhe based kex_mode */ diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h index dc608dfb..97ccb41d 100644 --- a/include/openssl/sslerr.h +++ b/include/openssl/sslerr.h @@ -596,8 +596,9 @@ int ERR_load_SSL_strings(void); # define SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION 209 # define SSL_R_MISSING_TMP_DH_KEY 171 # define SSL_R_MISSING_TMP_ECDH_KEY 311 -# define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 293 -# define SSL_R_NESTED_GROUP 294 +# define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 101 +# define SSL_R_NESTED_GROUP 108 +# define SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA 293 # define SSL_R_NOT_ON_RECORD_BOUNDARY 182 # define SSL_R_NOT_REPLACING_CERTIFICATE 289 # define SSL_R_NOT_SERVER 284 @@ -728,11 +729,11 @@ int ERR_load_SSL_strings(void); # define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239 # define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 242 # define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES 243 +# define SSL_R_UNEXPECTED_GROUP_CLOSE 109 # define SSL_R_UNEXPECTED_CCS_MESSAGE 262 # define SSL_R_UNEXPECTED_END_OF_EARLY_DATA 178 -# define SSL_R_UNEXPECTED_GROUP_CLOSE 295 # define SSL_R_UNEXPECTED_MESSAGE 244 -# define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 296 +# define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 110 # define SSL_R_UNEXPECTED_RECORD 245 # define SSL_R_UNINITIALIZED 276 # define SSL_R_UNKNOWN_ALERT_TYPE 246 diff --git a/include/openssl/stack.h b/include/openssl/stack.h index 16cb94b6..638b3afc 100644 --- a/include/openssl/stack.h +++ b/include/openssl/stack.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-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 diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index 2f5987b0..feca76eb 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -1363,6 +1363,14 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, } while (num_recs == 0); rr = &rr[curr_rec]; + if (s->rlayer.handshake_fragment_len > 0 + && SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE + && SSL_IS_TLS13(s)) { + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_READ_BYTES, + SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA); + return -1; + } + /* * Reset the count of consecutive warning alerts if we've got a non-empty * record that isn't an alert. diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c index 6d4c69df..f0bec364 100644 --- a/ssl/ssl_conf.c +++ b/ssl/ssl_conf.c @@ -380,7 +380,8 @@ static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) SSL_FLAG_TBL("AllowNoDHEKEX", SSL_OP_ALLOW_NO_DHE_KEX), SSL_FLAG_TBL("PrioritizeChaCha", SSL_OP_PRIORITIZE_CHACHA), SSL_FLAG_TBL("MiddleboxCompat", SSL_OP_ENABLE_MIDDLEBOX_COMPAT), - SSL_FLAG_TBL_INV("AntiReplay", SSL_OP_NO_ANTI_REPLAY) + SSL_FLAG_TBL_INV("AntiReplay", SSL_OP_NO_ANTI_REPLAY), + SSL_FLAG_TBL_INV("ExtendedMasterSecret", SSL_OP_NO_EXTENDED_MASTER_SECRET) }; if (value == NULL) return -3; diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 05a99d50..46521b71 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -968,6 +968,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS), "mixed special operator with groups"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NESTED_GROUP), "nested group"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA), + "mixed handshake and non handshake data"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_ON_RECORD_BOUNDARY), "not on record boundary"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_REPLACING_CERTIFICATE), @@ -1202,12 +1204,11 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "unable to load ssl3 md5 routines"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES), "unable to load ssl3 sha1 routines"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_GROUP_CLOSE), "unexpected group close"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_CCS_MESSAGE), "unexpected ccs message"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_END_OF_EARLY_DATA), "unexpected end of early data"}, - {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_GROUP_CLOSE), - "unexpected group close"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_MESSAGE), "unexpected message"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_OPERATOR_IN_GROUP), "unexpected operator in group"}, diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index e12f0c3d..ac33c355 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -2645,6 +2645,26 @@ STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx) return NULL; } +/* + * Distinguish between ciphers controlled by set_ciphersuite() and + * set_cipher_list() when counting. + */ +static int cipher_list_tls12_num(STACK_OF(SSL_CIPHER) *sk) +{ + int i, num = 0; + const SSL_CIPHER *c; + + if (sk == NULL) + return 0; + for (i = 0; i < sk_SSL_CIPHER_num(sk); ++i) { + c = sk_SSL_CIPHER_value(sk, i); + if (c->min_tls >= TLS1_3_VERSION) + continue; + num++; + } + return num; +} + /** specify the ciphers to be used by default by the SSL_CTX */ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) { @@ -2662,7 +2682,7 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) */ if (sk == NULL) return 0; - else if (sk_SSL_CIPHER_num(sk) == 0) { + else if (cipher_list_tls12_num(sk) == 0) { SSLerr(SSL_F_SSL_CTX_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH); return 0; } @@ -2680,7 +2700,7 @@ int SSL_set_cipher_list(SSL *s, const char *str) /* see comment in SSL_CTX_set_cipher_list */ if (sk == NULL) return 0; - else if (sk_SSL_CIPHER_num(sk) == 0) { + else if (cipher_list_tls12_num(sk) == 0) { SSLerr(SSL_F_SSL_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH); return 0; } diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 773309a1..60d4da04 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -1169,8 +1169,7 @@ static int init_etm(SSL *s, unsigned int context) static int init_ems(SSL *s, unsigned int context) { - if (!s->server) - s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS; + s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS; return 1; } diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 6e133e02..f01e9eef 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -494,6 +494,9 @@ EXT_RETURN tls_construct_ctos_sct(SSL *s, WPACKET *pkt, unsigned int context, EXT_RETURN tls_construct_ctos_ems(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { + if (s->options & SSL_OP_NO_EXTENDED_MASTER_SECRET) + return EXT_RETURN_NOT_SENT; + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret) || !WPACKET_put_bytes_u16(pkt, 0)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_EMS, @@ -1743,6 +1746,8 @@ int tls_parse_stoc_etm(SSL *s, PACKET *pkt, unsigned int context, X509 *x, int tls_parse_stoc_ems(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { + if (s->options & SSL_OP_NO_EXTENDED_MASTER_SECRET) + return 1; s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS; if (!s->hit) s->session->flags |= SSL_SESS_FLAG_EXTMS; diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 6545f572..73ceadc3 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -989,6 +989,9 @@ int tls_parse_ctos_ems(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 0; } + if (s->options & SSL_OP_NO_EXTENDED_MASTER_SECRET) + return 1; + s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS; return 1; diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c index ebe471b6..24c7e94e 100644 --- a/ssl/statem/statem.c +++ b/ssl/statem/statem.c @@ -342,8 +342,10 @@ static int state_machine(SSL *s, int server) } s->server = server; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); + if (cb != NULL) { + if (SSL_IS_FIRST_HANDSHAKE(s) || !SSL_IS_TLS13(s)) + cb(s, SSL_CB_HANDSHAKE_START, 1); + } /* * Fatal errors in this block don't send an alert because we have diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 2f78a3f6..8a7ada8f 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -1030,6 +1030,7 @@ unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop) { void (*cb) (const SSL *ssl, int type, int val) = NULL; + int cleanuphand = s->statem.cleanuphand; if (clearbufs) { if (!SSL_IS_DTLS(s)) { @@ -1056,7 +1057,7 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop) * Only set if there was a Finished message and this isn't after a TLSv1.3 * post handshake exchange */ - if (s->statem.cleanuphand) { + if (cleanuphand) { /* skipped if we just sent a HelloRequest */ s->renegotiate = 0; s->new_session = 0; @@ -1116,8 +1117,12 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop) /* The callback may expect us to not be in init at handshake done */ ossl_statem_set_in_init(s, 0); - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_DONE, 1); + if (cb != NULL) { + if (cleanuphand + || !SSL_IS_TLS13(s) + || SSL_IS_FIRST_HANDSHAKE(s)) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + } if (!stop) { /* If we've got more work to do we go back into init */ diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 69c515c9..ebb6224b 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -4041,7 +4041,6 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) uint64_t nonce; static const unsigned char nonce_label[] = "resumption"; const EVP_MD *md = ssl_handshake_md(s); - void (*cb) (const SSL *ssl, int type, int val) = NULL; int hashleni = EVP_MD_size(md); /* Ensure cast to size_t is safe */ @@ -4053,24 +4052,6 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) } hashlen = (size_t)hashleni; - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - if (cb != NULL) { - /* - * We don't start and stop the handshake in between each ticket when - * sending more than one - but it should appear that way to the info - * callback. - */ - if (s->sent_tickets != 0) { - ossl_statem_set_in_init(s, 0); - cb(s, SSL_CB_HANDSHAKE_DONE, 1); - ossl_statem_set_in_init(s, 1); - } - cb(s, SSL_CB_HANDSHAKE_START, 1); - } /* * If we already sent one NewSessionTicket, or we resumed then * s->session may already be in a cache and so we must not modify it. diff --git a/test/bntest.c b/test/bntest.c index e4b71e26..8c8acb66 100644 --- a/test/bntest.c +++ b/test/bntest.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-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 @@ -123,7 +123,7 @@ static int getint(STANZA *s, int *out, const char *attribute) *out = (int)word; st = 1; -err: + err: BN_free(ret); return st; } @@ -138,7 +138,6 @@ static int equalBN(const char *op, const BIGNUM *expected, const BIGNUM *actual) return 0; } - /* * Return a "random" flag for if a BN should be negated. */ @@ -150,7 +149,6 @@ static int rand_neg(void) return sign[(neg++) % 8]; } - static int test_swap(void) { BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL; @@ -166,7 +164,7 @@ static int test_swap(void) BN_bntest_rand(b, 1024, 1, 0); BN_copy(c, a); BN_copy(d, b); - top = BN_num_bits(a)/BN_BITS2; + top = BN_num_bits(a) / BN_BITS2; /* regular swap */ BN_swap(a, b); @@ -252,14 +250,13 @@ static int test_sub(void) goto err; } st = 1; -err: + err: BN_free(a); BN_free(b); BN_free(c); return st; } - static int test_div_recip(void) { BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL; @@ -293,7 +290,7 @@ static int test_div_recip(void) goto err; } st = 1; -err: + err: BN_free(a); BN_free(b); BN_free(c); @@ -303,7 +300,6 @@ err: return st; } - static int test_mod(void) { BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL; @@ -328,7 +324,7 @@ static int test_mod(void) goto err; } st = 1; -err: + err: BN_free(a); BN_free(b); BN_free(c); @@ -573,7 +569,7 @@ static int test_modexp_mont5(void) st = 1; -err: + err: BN_MONT_CTX_free(mont); BN_free(a); BN_free(p); @@ -1141,7 +1137,7 @@ static int file_sum(STANZA *s) } st = 1; -err: + err: BN_free(a); BN_free(b); BN_free(sum); @@ -1190,7 +1186,7 @@ static int file_lshift1(STANZA *s) goto err; st = 1; -err: + err: BN_free(a); BN_free(lshift1); BN_free(zero); @@ -1219,7 +1215,7 @@ static int file_lshift(STANZA *s) goto err; st = 1; -err: + err: BN_free(a); BN_free(lshift); BN_free(ret); @@ -1249,7 +1245,7 @@ static int file_rshift(STANZA *s) } st = 1; -err: + err: BN_free(a); BN_free(rshift); BN_free(ret); @@ -1306,7 +1302,7 @@ static int file_square(STANZA *s) #endif st = 1; -err: + err: BN_free(a); BN_free(square); BN_free(zero); @@ -1343,7 +1339,7 @@ static int file_product(STANZA *s) goto err; st = 1; -err: + err: BN_free(a); BN_free(b); BN_free(product); @@ -1426,7 +1422,7 @@ static int file_quotient(STANZA *s) } st = 1; -err: + err: BN_free(a); BN_free(b); BN_free(quotient); @@ -1480,7 +1476,7 @@ static int file_modmul(STANZA *s) } st = 1; -err: + err: BN_free(a); BN_free(b); BN_free(m); @@ -1532,7 +1528,7 @@ static int file_modexp(STANZA *s) goto err; st = 1; -err: + err: BN_free(a); BN_free(b); BN_free(c); @@ -1560,7 +1556,7 @@ static int file_exp(STANZA *s) goto err; st = 1; -err: + err: BN_free(a); BN_free(e); BN_free(exp); @@ -1591,7 +1587,7 @@ static int file_modsqrt(STANZA *s) goto err; st = 1; -err: + err: BN_free(a); BN_free(p); BN_free(mod_sqrt); @@ -1621,8 +1617,8 @@ static int test_bn2padded(void) /* Test a random numbers at various byte lengths. */ for (size_t bytes = 128 - 7; bytes <= 128; bytes++) { -#define TOP_BIT_ON 0 -#define BOTTOM_BIT_NOTOUCH 0 +# define TOP_BIT_ON 0 +# define BOTTOM_BIT_NOTOUCH 0 if (!TEST_true(BN_rand(n, bytes * 8, TOP_BIT_ON, BOTTOM_BIT_NOTOUCH))) goto err; if (!TEST_int_eq(BN_num_bytes(n),A) bytes @@ -1653,7 +1649,7 @@ static int test_bn2padded(void) } st = 1; -err: + err: BN_free(n); return st; #else @@ -1725,7 +1721,7 @@ static int test_dec2bn(void) goto err; st = 1; -err: + err: BN_free(bn); return st; } @@ -1791,7 +1787,7 @@ static int test_hex2bn(void) goto err; st = 1; -err: + err: BN_free(bn); return st; } @@ -1845,7 +1841,7 @@ static int test_asc2bn(void) goto err; st = 1; -err: + err: BN_free(bn); return st; } @@ -1889,7 +1885,7 @@ static int test_mpi(int i) BN_free(bn2); st = 1; -err: + err: BN_free(bn); return st; } @@ -1915,7 +1911,7 @@ static int test_rand(void) goto err; st = 1; -err: + err: BN_free(bn); return st; } @@ -1979,7 +1975,7 @@ static int test_negzero(void) goto err; st = 1; -err: + err: BN_free(a); BN_free(b); BN_free(c); @@ -2020,7 +2016,7 @@ static int test_badmod(void) ERR_clear_error(); if (!TEST_false(BN_mod_exp_mont_consttime(a, BN_value_one(), BN_value_one(), - zero, ctx, NULL))) + zero, ctx, NULL))) goto err; ERR_clear_error(); @@ -2042,12 +2038,12 @@ static int test_badmod(void) ERR_clear_error(); if (!TEST_false(BN_mod_exp_mont_consttime(a, BN_value_one(), BN_value_one(), - b, ctx, NULL))) + b, ctx, NULL))) goto err; ERR_clear_error(); st = 1; -err: + err: BN_free(a); BN_free(b); BN_free(zero); @@ -2081,7 +2077,7 @@ static int test_expmodzero(void) goto err; st = 1; -err: + err: BN_free(zero); BN_free(a); BN_free(r); @@ -2127,7 +2123,7 @@ static int test_expmodone(void) } ret = 1; -err: + err: BN_free(r); BN_free(a); BN_free(p); @@ -2148,7 +2144,7 @@ static int test_smallprime(void) goto err; st = 1; -err: + err: BN_free(r); return st; } @@ -2172,7 +2168,7 @@ static int test_is_prime(int i) } ret = 1; -err: + err: BN_free(r); return ret; } @@ -2195,11 +2191,97 @@ static int test_not_prime(int i) } ret = 1; -err: + err: BN_free(r); return ret; } +static int test_ctx_set_ct_flag(BN_CTX *c) +{ + int st = 0; + size_t i; + BIGNUM *b[15]; + + BN_CTX_start(c); + for (i = 0; i < OSSL_NELEM(b); i++) { + if (!TEST_ptr(b[i] = BN_CTX_get(c))) + goto err; + if (i % 2 == 1) + BN_set_flags(b[i], BN_FLG_CONSTTIME); + } + + st = 1; + err: + BN_CTX_end(c); + return st; +} + +static int test_ctx_check_ct_flag(BN_CTX *c) +{ + int st = 0; + size_t i; + BIGNUM *b[30]; + + BN_CTX_start(c); + for (i = 0; i < OSSL_NELEM(b); i++) { + if (!TEST_ptr(b[i] = BN_CTX_get(c))) + goto err; + if (!TEST_false(BN_get_flags(b[i], BN_FLG_CONSTTIME))) + goto err; + } + + st = 1; + err: + BN_CTX_end(c); + return st; +} + +static int test_ctx_consttime_flag(void) +{ + /*- + * The constant-time flag should not "leak" among BN_CTX frames: + * + * - test_ctx_set_ct_flag() starts a frame in the given BN_CTX and + * sets the BN_FLG_CONSTTIME flag on some of the BIGNUMs obtained + * from the frame before ending it. + * - test_ctx_check_ct_flag() then starts a new frame and gets a + * number of BIGNUMs from it. In absence of leaks, none of the + * BIGNUMs in the new frame should have BN_FLG_CONSTTIME set. + * + * In actual BN_CTX usage inside libcrypto the leak could happen at + * any depth level in the BN_CTX stack, with varying results + * depending on the patterns of sibling trees of nested function + * calls sharing the same BN_CTX object, and the effect of + * unintended BN_FLG_CONSTTIME on the called BN_* functions. + * + * This simple unit test abstracts away this complexity and verifies + * that the leak does not happen between two sibling functions + * sharing the same BN_CTX object at the same level of nesting. + * + */ + BN_CTX *nctx = NULL; + BN_CTX *sctx = NULL; + size_t i = 0; + int st = 0; + + if (!TEST_ptr(nctx = BN_CTX_new()) + || !TEST_ptr(sctx = BN_CTX_secure_new())) + goto err; + + for (i = 0; i < 2; i++) { + BN_CTX *c = i == 0 ? nctx : sctx; + if (!TEST_true(test_ctx_set_ct_flag(c)) + || !TEST_true(test_ctx_check_ct_flag(c))) + goto err; + } + + st = 1; + err: + BN_CTX_free(nctx); + BN_CTX_free(sctx); + return st; +} + static int file_test_run(STANZA *s) { static const FILETEST filetests[] = { @@ -2298,6 +2380,7 @@ int setup_tests(void) ADD_TEST(test_expmodone); ADD_TEST(test_smallprime); ADD_TEST(test_swap); + ADD_TEST(test_ctx_consttime_flag); #ifndef OPENSSL_NO_EC2M ADD_TEST(test_gf2m_add); ADD_TEST(test_gf2m_mod); diff --git a/test/build.info b/test/build.info index 4c29beb2..db4e1a7b 100644 --- a/test/build.info +++ b/test/build.info @@ -15,7 +15,7 @@ IF[{- !$disabled{tests} -}] testutil/format_output.c testutil/tap_bio.c \ testutil/test_cleanup.c testutil/main.c testutil/init.c \ testutil/options.c testutil/test_options.c ../apps/opt.c - INCLUDE[libtestutil.a]=../include .. + INCLUDE[libtestutil.a]=../include ../apps/include .. DEPEND[libtestutil.a]=../libcrypto PROGRAMS{noinst}=\ @@ -30,7 +30,7 @@ IF[{- !$disabled{tests} -}] dhtest enginetest casttest \ bftest ssltest_old dsatest dsa_no_digest_size_test exptest rsa_test \ evp_test evp_extra_test igetest v3nametest v3ext \ - crltest danetest bad_dtls_test lhash_test \ + crltest danetest bad_dtls_test lhash_test sparse_array_test \ conf_include_test \ constant_time_test verify_extra_test clienthellotest \ packettest asynctest secmemtest srptest memleaktest stack_test \ @@ -38,244 +38,246 @@ IF[{- !$disabled{tests} -}] ssl_test_ctx_test ssl_test x509aux cipherlist_test asynciotest \ bio_callback_test bio_memleak_test \ bioprinttest sslapitest dtlstest sslcorrupttest bio_enc_test \ - pkey_meth_test pkey_meth_kdf_test uitest cipherbytes_test \ + pkey_meth_test pkey_meth_kdf_test evp_kdf_test uitest \ + cipherbytes_test \ asn1_encode_test asn1_decode_test asn1_string_table_test \ x509_time_test x509_dup_cert_test x509_check_cert_pkey_test \ recordlentest drbgtest sslbuffertest \ recordlentest drbgtest drbg_cavs_test sslbuffertest \ time_offset_test pemtest ssl_cert_table_internal_test ciphername_test \ servername_test ocspapitest rsa_mp_test fatalerrtest tls13ccstest \ - sysdefaulttest errtest gosttest + sysdefaulttest errtest gosttest \ + context_internal_test SOURCE[versions]=versions.c - INCLUDE[versions]=../include + INCLUDE[versions]=../include ../apps/include DEPEND[versions]=../libcrypto SOURCE[aborttest]=aborttest.c - INCLUDE[aborttest]=../include + INCLUDE[aborttest]=../include ../apps/include DEPEND[aborttest]=../libcrypto SOURCE[sanitytest]=sanitytest.c - INCLUDE[sanitytest]=../include + INCLUDE[sanitytest]=../include ../apps/include DEPEND[sanitytest]=../libcrypto libtestutil.a SOURCE[rsa_complex]=rsa_complex.c - INCLUDE[rsa_complex]=../include + INCLUDE[rsa_complex]=../include ../apps/include SOURCE[test_test]=test_test.c - INCLUDE[test_test]=../include + INCLUDE[test_test]=../include ../apps/include DEPEND[test_test]=../libcrypto libtestutil.a SOURCE[exdatatest]=exdatatest.c - INCLUDE[exdatatest]=../include + INCLUDE[exdatatest]=../include ../apps/include DEPEND[exdatatest]=../libcrypto libtestutil.a SOURCE[bntest]=bntest.c - INCLUDE[bntest]=../include + INCLUDE[bntest]=../include ../apps/include DEPEND[bntest]=../libcrypto libtestutil.a SOURCE[ectest]=ectest.c - INCLUDE[ectest]=../include + INCLUDE[ectest]=../include ../apps/include DEPEND[ectest]=../libcrypto libtestutil.a SOURCE[ecstresstest]=ecstresstest.c - INCLUDE[ecstresstest]=../include + INCLUDE[ecstresstest]=../include ../apps/include DEPEND[ecstresstest]=../libcrypto libtestutil.a SOURCE[ecdsatest]=ecdsatest.c - INCLUDE[ecdsatest]=../include + INCLUDE[ecdsatest]=../include ../apps/include DEPEND[ecdsatest]=../libcrypto libtestutil.a SOURCE[gmdifftest]=gmdifftest.c - INCLUDE[gmdifftest]=../include + INCLUDE[gmdifftest]=../include ../apps/include DEPEND[gmdifftest]=../libcrypto libtestutil.a SOURCE[pbelutest]=pbelutest.c - INCLUDE[pbelutest]=../include + INCLUDE[pbelutest]=../include ../apps/include DEPEND[pbelutest]=../libcrypto libtestutil.a SOURCE[ideatest]=ideatest.c - INCLUDE[ideatest]=../include + INCLUDE[ideatest]=../include ../apps/include DEPEND[ideatest]=../libcrypto libtestutil.a SOURCE[md2test]=md2test.c - INCLUDE[md2test]=../include + INCLUDE[md2test]=../include ../apps/include DEPEND[md2test]=../libcrypto libtestutil.a SOURCE[hmactest]=hmactest.c - INCLUDE[hmactest]=../include + INCLUDE[hmactest]=../include ../apps/include DEPEND[hmactest]=../libcrypto libtestutil.a SOURCE[rc2test]=rc2test.c - INCLUDE[rc2test]=../include + INCLUDE[rc2test]=../include ../apps/include DEPEND[rc2test]=../libcrypto libtestutil.a SOURCE[rc4test]=rc4test.c - INCLUDE[rc4test]=../include + INCLUDE[rc4test]=../include ../apps/include DEPEND[rc4test]=../libcrypto libtestutil.a SOURCE[rc5test]=rc5test.c - INCLUDE[rc5test]=../include + INCLUDE[rc5test]=../include ../apps/include DEPEND[rc5test]=../libcrypto libtestutil.a SOURCE[destest]=destest.c - INCLUDE[destest]=../include + INCLUDE[destest]=../include ../apps/include DEPEND[destest]=../libcrypto libtestutil.a SOURCE[mdc2test]=mdc2test.c - INCLUDE[mdc2test]=../include + INCLUDE[mdc2test]=../include ../apps/include DEPEND[mdc2test]=../libcrypto libtestutil.a SOURCE[dhtest]=dhtest.c - INCLUDE[dhtest]=../include + INCLUDE[dhtest]=../include ../apps/include DEPEND[dhtest]=../libcrypto libtestutil.a SOURCE[enginetest]=enginetest.c - INCLUDE[enginetest]=../include + INCLUDE[enginetest]=../include ../apps/include DEPEND[enginetest]=../libcrypto libtestutil.a SOURCE[casttest]=casttest.c - INCLUDE[casttest]=../include + INCLUDE[casttest]=../include ../apps/include DEPEND[casttest]=../libcrypto libtestutil.a SOURCE[bftest]=bftest.c - INCLUDE[bftest]=../include + INCLUDE[bftest]=../include ../apps/include DEPEND[bftest]=../libcrypto libtestutil.a SOURCE[ssltest_old]=ssltest_old.c - INCLUDE[ssltest_old]=.. ../include + INCLUDE[ssltest_old]=.. ../include ../apps/include DEPEND[ssltest_old]=../libcrypto ../libssl SOURCE[dsatest]=dsatest.c - INCLUDE[dsatest]=../include + INCLUDE[dsatest]=../include ../apps/include DEPEND[dsatest]=../libcrypto libtestutil.a SOURCE[dsa_no_digest_size_test]=dsa_no_digest_size_test.c - INCLUDE[dsa_no_digest_size_test]=../include + INCLUDE[dsa_no_digest_size_test]=../include ../apps/include DEPEND[dsa_no_digest_size_test]=../libcrypto libtestutil.a SOURCE[exptest]=exptest.c - INCLUDE[exptest]=../include + INCLUDE[exptest]=../include ../apps/include DEPEND[exptest]=../libcrypto libtestutil.a SOURCE[rsa_test]=rsa_test.c - INCLUDE[rsa_test]=../include + INCLUDE[rsa_test]=../include ../apps/include DEPEND[rsa_test]=../libcrypto libtestutil.a SOURCE[rsa_mp_test]=rsa_mp_test.c - INCLUDE[rsa_mp_test]=../include + INCLUDE[rsa_mp_test]=../include ../apps/include DEPEND[rsa_mp_test]=../libcrypto libtestutil.a SOURCE[fatalerrtest]=fatalerrtest.c ssltestlib.c - INCLUDE[fatalerrtest]=../include + INCLUDE[fatalerrtest]=../include ../apps/include DEPEND[fatalerrtest]=../libcrypto ../libssl libtestutil.a SOURCE[tls13ccstest]=tls13ccstest.c ssltestlib.c - INCLUDE[tls13ccstest]=../include + INCLUDE[tls13ccstest]=../include ../apps/include DEPEND[tls13ccstest]=../libcrypto ../libssl libtestutil.a SOURCE[evp_test]=evp_test.c - INCLUDE[evp_test]=../include + INCLUDE[evp_test]=../include ../apps/include DEPEND[evp_test]=../libcrypto libtestutil.a SOURCE[evp_extra_test]=evp_extra_test.c - INCLUDE[evp_extra_test]=../include ../crypto/include + INCLUDE[evp_extra_test]=../include ../apps/include ../crypto/include DEPEND[evp_extra_test]=../libcrypto libtestutil.a SOURCE[igetest]=igetest.c - INCLUDE[igetest]=../include + INCLUDE[igetest]=../include ../apps/include DEPEND[igetest]=../libcrypto libtestutil.a SOURCE[v3nametest]=v3nametest.c - INCLUDE[v3nametest]=../include + INCLUDE[v3nametest]=../include ../apps/include DEPEND[v3nametest]=../libcrypto libtestutil.a SOURCE[crltest]=crltest.c - INCLUDE[crltest]=../include + INCLUDE[crltest]=../include ../apps/include DEPEND[crltest]=../libcrypto libtestutil.a SOURCE[v3ext]=v3ext.c - INCLUDE[v3ext]=../include + INCLUDE[v3ext]=../include ../apps/include DEPEND[v3ext]=../libcrypto libtestutil.a SOURCE[danetest]=danetest.c - INCLUDE[danetest]=../include + INCLUDE[danetest]=../include ../apps/include DEPEND[danetest]=../libcrypto ../libssl libtestutil.a SOURCE[constant_time_test]=constant_time_test.c - INCLUDE[constant_time_test]=../include + INCLUDE[constant_time_test]=../include ../apps/include DEPEND[constant_time_test]=../libcrypto libtestutil.a SOURCE[verify_extra_test]=verify_extra_test.c - INCLUDE[verify_extra_test]=../include + INCLUDE[verify_extra_test]=../include ../apps/include DEPEND[verify_extra_test]=../libcrypto libtestutil.a SOURCE[clienthellotest]=clienthellotest.c - INCLUDE[clienthellotest]=../include + INCLUDE[clienthellotest]=../include ../apps/include DEPEND[clienthellotest]=../libcrypto ../libssl libtestutil.a SOURCE[bad_dtls_test]=bad_dtls_test.c - INCLUDE[bad_dtls_test]=../include + INCLUDE[bad_dtls_test]=../include ../apps/include DEPEND[bad_dtls_test]=../libcrypto ../libssl libtestutil.a SOURCE[packettest]=packettest.c - INCLUDE[packettest]=../include + INCLUDE[packettest]=../include ../apps/include DEPEND[packettest]=../libcrypto libtestutil.a SOURCE[asynctest]=asynctest.c - INCLUDE[asynctest]=../include + INCLUDE[asynctest]=../include ../apps/include DEPEND[asynctest]=../libcrypto SOURCE[secmemtest]=secmemtest.c - INCLUDE[secmemtest]=../include + INCLUDE[secmemtest]=../include ../apps/include DEPEND[secmemtest]=../libcrypto libtestutil.a SOURCE[srptest]=srptest.c - INCLUDE[srptest]=../include + INCLUDE[srptest]=../include ../apps/include DEPEND[srptest]=../libcrypto libtestutil.a SOURCE[memleaktest]=memleaktest.c - INCLUDE[memleaktest]=../include + INCLUDE[memleaktest]=../include ../apps/include DEPEND[memleaktest]=../libcrypto libtestutil.a SOURCE[stack_test]=stack_test.c - INCLUDE[stack_test]=../include + INCLUDE[stack_test]=../include ../apps/include DEPEND[stack_test]=../libcrypto libtestutil.a SOURCE[lhash_test]=lhash_test.c - INCLUDE[lhash_test]=../include + INCLUDE[lhash_test]=../include ../apps/include DEPEND[lhash_test]=../libcrypto libtestutil.a SOURCE[dtlsv1listentest]=dtlsv1listentest.c - INCLUDE[dtlsv1listentest]=../include + INCLUDE[dtlsv1listentest]=../include ../apps/include DEPEND[dtlsv1listentest]=../libssl libtestutil.a SOURCE[ct_test]=ct_test.c - INCLUDE[ct_test]=../include + INCLUDE[ct_test]=../include ../apps/include DEPEND[ct_test]=../libcrypto libtestutil.a SOURCE[threadstest]=threadstest.c - INCLUDE[threadstest]=../include + INCLUDE[threadstest]=../include ../apps/include DEPEND[threadstest]=../libcrypto libtestutil.a SOURCE[afalgtest]=afalgtest.c - INCLUDE[afalgtest]=../include + INCLUDE[afalgtest]=../include ../apps/include DEPEND[afalgtest]=../libcrypto libtestutil.a SOURCE[d2i_test]=d2i_test.c - INCLUDE[d2i_test]=../include + INCLUDE[d2i_test]=../include ../apps/include DEPEND[d2i_test]=../libcrypto libtestutil.a SOURCE[ssl_test_ctx_test]=ssl_test_ctx_test.c ssl_test_ctx.c - INCLUDE[ssl_test_ctx_test]=../include + INCLUDE[ssl_test_ctx_test]=../include ../apps/include DEPEND[ssl_test_ctx_test]=../libcrypto ../libssl libtestutil.a SOURCE[ssl_test]=ssl_test.c ssl_test_ctx.c handshake_helper.c - INCLUDE[ssl_test]=../include + INCLUDE[ssl_test]=../include ../apps/include DEPEND[ssl_test]=../libcrypto ../libssl libtestutil.a SOURCE[cipherlist_test]=cipherlist_test.c - INCLUDE[cipherlist_test]=../include + INCLUDE[cipherlist_test]=../include ../apps/include DEPEND[cipherlist_test]=../libcrypto ../libssl libtestutil.a INCLUDE[ssl_test_ctx.o]=../include @@ -283,148 +285,152 @@ IF[{- !$disabled{tests} -}] INCLUDE[ssltestlib.o]=.. ../include SOURCE[x509aux]=x509aux.c - INCLUDE[x509aux]=../include + INCLUDE[x509aux]=../include ../apps/include DEPEND[x509aux]=../libcrypto libtestutil.a SOURCE[asynciotest]=asynciotest.c ssltestlib.c - INCLUDE[asynciotest]=../include + INCLUDE[asynciotest]=../include ../apps/include DEPEND[asynciotest]=../libcrypto ../libssl libtestutil.a SOURCE[bio_callback_test]=bio_callback_test.c - INCLUDE[bio_callback_test]=../include + INCLUDE[bio_callback_test]=../include ../apps/include DEPEND[bio_callback_test]=../libcrypto libtestutil.a SOURCE[bio_memleak_test]=bio_memleak_test.c - INCLUDE[bio_memleak_test]=../include + INCLUDE[bio_memleak_test]=../include ../apps/include DEPEND[bio_memleak_test]=../libcrypto libtestutil.a SOURCE[bioprinttest]=bioprinttest.c - INCLUDE[bioprinttest]=../include + INCLUDE[bioprinttest]=../include ../apps/include DEPEND[bioprinttest]=../libcrypto libtestutil.a SOURCE[sslapitest]=sslapitest.c ssltestlib.c - INCLUDE[sslapitest]=../include .. + INCLUDE[sslapitest]=../include ../apps/include .. DEPEND[sslapitest]=../libcrypto ../libssl libtestutil.a SOURCE[ocspapitest]=ocspapitest.c - INCLUDE[ocspapitest]=../include + INCLUDE[ocspapitest]=../include ../apps/include DEPEND[ocspapitest]=../libcrypto libtestutil.a SOURCE[dtlstest]=dtlstest.c ssltestlib.c - INCLUDE[dtlstest]=../include + INCLUDE[dtlstest]=../include ../apps/include DEPEND[dtlstest]=../libcrypto ../libssl libtestutil.a SOURCE[sslcorrupttest]=sslcorrupttest.c ssltestlib.c - INCLUDE[sslcorrupttest]=../include + INCLUDE[sslcorrupttest]=../include ../apps/include DEPEND[sslcorrupttest]=../libcrypto ../libssl libtestutil.a SOURCE[bio_enc_test]=bio_enc_test.c - INCLUDE[bio_enc_test]=../include + INCLUDE[bio_enc_test]=../include ../apps/include DEPEND[bio_enc_test]=../libcrypto libtestutil.a SOURCE[pkey_meth_test]=pkey_meth_test.c - INCLUDE[pkey_meth_test]=../include + INCLUDE[pkey_meth_test]=../include ../apps/include DEPEND[pkey_meth_test]=../libcrypto libtestutil.a SOURCE[pkey_meth_kdf_test]=pkey_meth_kdf_test.c - INCLUDE[pkey_meth_kdf_test]=../include + INCLUDE[pkey_meth_kdf_test]=../include ../apps/include DEPEND[pkey_meth_kdf_test]=../libcrypto libtestutil.a + SOURCE[evp_kdf_test]=evp_kdf_test.c + INCLUDE[evp_kdf_test]=../include ../apps/include + DEPEND[evp_kdf_test]=../libcrypto libtestutil.a + SOURCE[x509_time_test]=x509_time_test.c - INCLUDE[x509_time_test]=../include + INCLUDE[x509_time_test]=../include ../apps/include DEPEND[x509_time_test]=../libcrypto libtestutil.a SOURCE[recordlentest]=recordlentest.c ssltestlib.c - INCLUDE[recordlentest]=../include + INCLUDE[recordlentest]=../include ../apps/include DEPEND[recordlentest]=../libcrypto ../libssl libtestutil.a SOURCE[drbgtest]=drbgtest.c - INCLUDE[drbgtest]=../include + INCLUDE[drbgtest]=../include ../apps/include DEPEND[drbgtest]=../libcrypto.a libtestutil.a SOURCE[drbg_cavs_test]=drbg_cavs_test.c drbg_cavs_data_ctr.c \ drbg_cavs_data_hash.c drbg_cavs_data_hmac.c - INCLUDE[drbg_cavs_test]=../include . .. + INCLUDE[drbg_cavs_test]=../include ../apps/include . .. DEPEND[drbg_cavs_test]=../libcrypto libtestutil.a SOURCE[x509_dup_cert_test]=x509_dup_cert_test.c - INCLUDE[x509_dup_cert_test]=../include + INCLUDE[x509_dup_cert_test]=../include ../apps/include DEPEND[x509_dup_cert_test]=../libcrypto libtestutil.a SOURCE[x509_check_cert_pkey_test]=x509_check_cert_pkey_test.c - INCLUDE[x509_check_cert_pkey_test]=../include + INCLUDE[x509_check_cert_pkey_test]=../include ../apps/include DEPEND[x509_check_cert_pkey_test]=../libcrypto libtestutil.a SOURCE[pemtest]=pemtest.c - INCLUDE[pemtest]=../include + INCLUDE[pemtest]=../include ../apps/include DEPEND[pemtest]=../libcrypto libtestutil.a SOURCE[ssl_cert_table_internal_test]=ssl_cert_table_internal_test.c - INCLUDE[ssl_cert_table_internal_test]=.. ../include + INCLUDE[ssl_cert_table_internal_test]=.. ../include ../apps/include DEPEND[ssl_cert_table_internal_test]=../libcrypto libtestutil.a SOURCE[ciphername_test]=ciphername_test.c - INCLUDE[ciphername_test]=../include + INCLUDE[ciphername_test]=../include ../apps/include DEPEND[ciphername_test]=../libcrypto ../libssl libtestutil.a SOURCE[servername_test]=servername_test.c ssltestlib.c - INCLUDE[servername_test]=../include + INCLUDE[servername_test]=../include ../apps/include DEPEND[servername_test]=../libcrypto ../libssl libtestutil.a IF[{- !$disabled{cms} -}] PROGRAMS{noinst}=cmsapitest SOURCE[cmsapitest]=cmsapitest.c - INCLUDE[cmsapitest]=../include + INCLUDE[cmsapitest]=../include ../apps/include DEPEND[cmsapitest]=../libcrypto libtestutil.a ENDIF IF[{- !$disabled{psk} -}] PROGRAMS{noinst}=dtls_mtu_test SOURCE[dtls_mtu_test]=dtls_mtu_test.c ssltestlib.c - INCLUDE[dtls_mtu_test]=.. ../include + INCLUDE[dtls_mtu_test]=.. ../include ../apps/include DEPEND[dtls_mtu_test]=../libcrypto ../libssl libtestutil.a ENDIF IF[{- !$disabled{shared} -}] PROGRAMS{noinst}=shlibloadtest SOURCE[shlibloadtest]=shlibloadtest.c - INCLUDE[shlibloadtest]=../include ../crypto/include + INCLUDE[shlibloadtest]=../include ../apps/include ../crypto/include ENDIF IF[{- $disabled{shared} -}] PROGRAMS{noinst}=cipher_overhead_test SOURCE[cipher_overhead_test]=cipher_overhead_test.c - INCLUDE[cipher_overhead_test]=.. ../include + INCLUDE[cipher_overhead_test]=.. ../include ../apps/include DEPEND[cipher_overhead_test]=../libcrypto ../libssl libtestutil.a ENDIF SOURCE[uitest]=uitest.c ../apps/apps_ui.c - INCLUDE[uitest]=.. ../include ../apps + INCLUDE[uitest]=.. ../include ../apps/include DEPEND[uitest]=../libcrypto ../libssl libtestutil.a SOURCE[cipherbytes_test]=cipherbytes_test.c - INCLUDE[cipherbytes_test]=../include + INCLUDE[cipherbytes_test]=../include ../apps/include DEPEND[cipherbytes_test]=../libcrypto ../libssl libtestutil.a SOURCE[asn1_encode_test]=asn1_encode_test.c - INCLUDE[asn1_encode_test]=../include + INCLUDE[asn1_encode_test]=../include ../apps/include DEPEND[asn1_encode_test]=../libcrypto libtestutil.a SOURCE[asn1_decode_test]=asn1_decode_test.c - INCLUDE[asn1_decode_test]=../include + INCLUDE[asn1_decode_test]=../include ../apps/include DEPEND[asn1_decode_test]=../libcrypto libtestutil.a SOURCE[asn1_string_table_test]=asn1_string_table_test.c - INCLUDE[asn1_string_table_test]=../include + INCLUDE[asn1_string_table_test]=../include ../apps/include DEPEND[asn1_string_table_test]=../libcrypto libtestutil.a SOURCE[time_offset_test]=time_offset_test.c - INCLUDE[time_offset_test]=../include + INCLUDE[time_offset_test]=../include ../apps/include DEPEND[time_offset_test]=../libcrypto libtestutil.a SOURCE[conf_include_test]=conf_include_test.c - INCLUDE[conf_include_test]=../include + INCLUDE[conf_include_test]=../include ../apps/include DEPEND[conf_include_test]=../libcrypto libtestutil.a # Internal test programs. These are essentially a collection of internal @@ -436,7 +442,7 @@ IF[{- !$disabled{tests} -}] IF[1] PROGRAMS{noinst}=asn1_internal_test modes_internal_test x509_internal_test \ tls13encryptiontest wpackettest ctype_internal_test \ - rdrand_sanitytest + rdrand_sanitytest property_test IF[{- !$disabled{poly1305} -}] PROGRAMS{noinst}=poly1305_internal_test ENDIF @@ -453,59 +459,71 @@ IF[{- !$disabled{tests} -}] PROGRAMS{noinst}=sm4_internal_test ENDIF IF[{- !$disabled{ec} -}] - PROGRAMS{noinst}=curve448_internal_test + PROGRAMS{noinst}=ec_internal_test curve448_internal_test ENDIF SOURCE[poly1305_internal_test]=poly1305_internal_test.c - INCLUDE[poly1305_internal_test]=.. ../include ../crypto/include + INCLUDE[poly1305_internal_test]=.. ../include ../apps/include ../crypto/include DEPEND[poly1305_internal_test]=../libcrypto.a libtestutil.a SOURCE[chacha_internal_test]=chacha_internal_test.c - INCLUDE[chacha_internal_test]=.. ../include ../crypto/include + INCLUDE[chacha_internal_test]=.. ../include ../apps/include ../crypto/include DEPEND[chacha_internal_test]=../libcrypto.a libtestutil.a SOURCE[asn1_internal_test]=asn1_internal_test.c - INCLUDE[asn1_internal_test]=.. ../include ../crypto/include + INCLUDE[asn1_internal_test]=.. ../include ../apps/include ../crypto/include DEPEND[asn1_internal_test]=../libcrypto.a libtestutil.a SOURCE[modes_internal_test]=modes_internal_test.c - INCLUDE[modes_internal_test]=.. ../include + INCLUDE[modes_internal_test]=.. ../include ../apps/include DEPEND[modes_internal_test]=../libcrypto.a libtestutil.a SOURCE[x509_internal_test]=x509_internal_test.c - INCLUDE[x509_internal_test]=.. ../include + INCLUDE[x509_internal_test]=.. ../include ../apps/include DEPEND[x509_internal_test]=../libcrypto.a libtestutil.a SOURCE[tls13encryptiontest]=tls13encryptiontest.c - INCLUDE[tls13encryptiontest]=.. ../include + INCLUDE[tls13encryptiontest]=.. ../include ../apps/include DEPEND[tls13encryptiontest]=../libcrypto ../libssl.a libtestutil.a SOURCE[wpackettest]=wpackettest.c - INCLUDE[wpackettest]=../include + INCLUDE[wpackettest]=../include ../apps/include DEPEND[wpackettest]=../libcrypto ../libssl.a libtestutil.a + SOURCE[property_test]=property_test.c + INCLUDE[property_test]=../include ../apps/include + DEPEND[property_test]=../libcrypto.a libtestutil.a + SOURCE[ctype_internal_test]=ctype_internal_test.c - INCLUDE[ctype_internal_test]=.. ../crypto/include ../include + INCLUDE[ctype_internal_test]=.. ../crypto/include ../include ../apps/include DEPEND[ctype_internal_test]=../libcrypto.a libtestutil.a + SOURCE[sparse_array_test]=sparse_array_test.c + INCLUDE[sparse_array_test]=../crypto/include ../include ../apps/include + DEPEND[sparse_array_test]=../libcrypto.a libtestutil.a + SOURCE[siphash_internal_test]=siphash_internal_test.c - INCLUDE[siphash_internal_test]=.. ../include ../crypto/include + INCLUDE[siphash_internal_test]=.. ../include ../apps/include ../crypto/include DEPEND[siphash_internal_test]=../libcrypto.a libtestutil.a SOURCE[sm2_internal_test]=sm2_internal_test.c - INCLUDE[sm2_internal_test]=../include ../crypto/include + INCLUDE[sm2_internal_test]=../include ../apps/include ../crypto/include DEPEND[sm2_internal_test]=../libcrypto.a libtestutil.a SOURCE[sm4_internal_test]=sm4_internal_test.c - INCLUDE[sm4_internal_test]=.. ../include ../crypto/include + INCLUDE[sm4_internal_test]=.. ../include ../apps/include ../crypto/include DEPEND[sm4_internal_test]=../libcrypto.a libtestutil.a + SOURCE[ec_internal_test]=ec_internal_test.c + INCLUDE[ec_internal_test]=../include ../crypto/ec ../apps/include ../crypto/include + DEPEND[ec_internal_test]=../libcrypto.a libtestutil.a + SOURCE[curve448_internal_test]=curve448_internal_test.c - INCLUDE[curve448_internal_test]=.. ../include ../crypto/ec/curve448 + INCLUDE[curve448_internal_test]=.. ../include ../apps/include ../crypto/ec/curve448 DEPEND[curve448_internal_test]=../libcrypto.a libtestutil.a SOURCE[rdrand_sanitytest]=rdrand_sanitytest.c - INCLUDE[rdrand_sanitytest]=../include + INCLUDE[rdrand_sanitytest]=../include ../apps/include DEPEND[rdrand_sanitytest]=../libcrypto.a libtestutil.a ENDIF @@ -514,12 +532,12 @@ IF[{- !$disabled{tests} -}] ENDIF SOURCE[mdc2_internal_test]=mdc2_internal_test.c - INCLUDE[mdc2_internal_test]=.. ../include + INCLUDE[mdc2_internal_test]=.. ../include ../apps/include DEPEND[mdc2_internal_test]=../libcrypto libtestutil.a PROGRAMS{noinst}=asn1_time_test SOURCE[asn1_time_test]=asn1_time_test.c - INCLUDE[asn1_time_test]=../include + INCLUDE[asn1_time_test]=../include ../apps/include DEPEND[asn1_time_test]=../libcrypto libtestutil.a # We disable this test completely in a shared build because it deliberately @@ -529,25 +547,30 @@ IF[{- !$disabled{tests} -}] PROGRAMS{noinst}=tls13secretstest SOURCE[tls13secretstest]=tls13secretstest.c SOURCE[tls13secretstest]= ../ssl/tls13_enc.c ../ssl/packet.c - INCLUDE[tls13secretstest]=.. ../include + INCLUDE[tls13secretstest]=.. ../include ../apps/include DEPEND[tls13secretstest]=../libcrypto ../libssl libtestutil.a ENDIF SOURCE[sslbuffertest]=sslbuffertest.c ssltestlib.c - INCLUDE[sslbuffertest]=../include + INCLUDE[sslbuffertest]=../include ../apps/include DEPEND[sslbuffertest]=../libcrypto ../libssl libtestutil.a SOURCE[sysdefaulttest]=sysdefaulttest.c - INCLUDE[sysdefaulttest]=../include + INCLUDE[sysdefaulttest]=../include ../apps/include DEPEND[sysdefaulttest]=../libcrypto ../libssl libtestutil.a SOURCE[errtest]=errtest.c - INCLUDE[errtest]=../include + INCLUDE[errtest]=../include ../apps/include DEPEND[errtest]=../libcrypto libtestutil.a SOURCE[gosttest]=gosttest.c ssltestlib.c - INCLUDE[gosttest]=../include .. + INCLUDE[gosttest]=../include ../apps/include .. DEPEND[gosttest]=../libcrypto ../libssl libtestutil.a + + PROGRAMS{noinst}=context_internal_test + SOURCE[context_internal_test]=context_internal_test.c + INCLUDE[context_internal_test]=.. ../include ../apps/include + DEPEND[context_internal_test]=../libcrypto.a libtestutil.a ENDIF {- diff --git a/test/cipherlist_test.c b/test/cipherlist_test.c index 89ef1b15..b950411c 100644 --- a/test/cipherlist_test.c +++ b/test/cipherlist_test.c @@ -215,9 +215,44 @@ static int test_default_cipherlist_explicit(void) return result; } +/* SSL_CTX_set_cipher_list() should fail if it clears all TLSv1.2 ciphers. */ +static int test_default_cipherlist_clear(void) +{ + SETUP_CIPHERLIST_TEST_FIXTURE(); + SSL *s = NULL; + + if (fixture == NULL) + return 0; + + if (!TEST_int_eq(SSL_CTX_set_cipher_list(fixture->server, "no-such"), 0)) + goto end; + + if (!TEST_int_eq(ERR_GET_REASON(ERR_get_error()), SSL_R_NO_CIPHER_MATCH)) + goto end; + + s = SSL_new(fixture->client); + + if (!TEST_ptr(s)) + goto end; + + if (!TEST_int_eq(SSL_set_cipher_list(s, "no-such"), 0)) + goto end; + + if (!TEST_int_eq(ERR_GET_REASON(ERR_get_error()), + SSL_R_NO_CIPHER_MATCH)) + goto end; + + result = 1; +end: + SSL_free(s); + tear_down(fixture); + return result; +} + int setup_tests(void) { ADD_TEST(test_default_cipherlist_implicit); ADD_TEST(test_default_cipherlist_explicit); + ADD_TEST(test_default_cipherlist_clear); return 1; } diff --git a/test/clienthellotest.c b/test/clienthellotest.c index 2c1110b1..7fdb5bc6 100644 --- a/test/clienthellotest.c +++ b/test/clienthellotest.c @@ -99,8 +99,9 @@ static int test_client_hello(int currtest) * ClientHello is already going to be quite long. To avoid getting one * that is too long for this test we use a restricted ciphersuite list */ - if (!TEST_true(SSL_CTX_set_cipher_list(ctx, ""))) + if (!TEST_false(SSL_CTX_set_cipher_list(ctx, ""))) goto end; + ERR_clear_error(); /* Fall through */ case TEST_ADD_PADDING: case TEST_PADDING_NOT_NEEDED: diff --git a/test/context_internal_test.c b/test/context_internal_test.c new file mode 100644 index 00000000..aca3db31 --- /dev/null +++ b/test/context_internal_test.c @@ -0,0 +1,95 @@ +/* + * 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 + */ + +/* Internal tests for the OpenSSL library context */ + +#include "internal/cryptlib.h" +#include "testutil.h" + +/* + * Everything between BEGIN EXAMPLE and END EXAMPLE is copied from + * doc/internal/man3/openssl_ctx_get_data.pod + */ + +/* + * ====================================================================== + * BEGIN EXAMPLE + */ + +/* The index will always be entirely global, and dynamically allocated */ +static int foo_index = -1; + +typedef struct foo_st { + int i; + void *data; +} FOO; + +static void *foo_new(void) +{ + FOO *ptr = OPENSSL_zalloc(sizeof(*ptr)); + if (ptr != NULL) + ptr->i = 42; + return ptr; +} +static void foo_free(void *ptr) +{ + OPENSSL_free(ptr); +} +static const OPENSSL_CTX_METHOD foo_method = { + foo_new, + foo_free +}; + +static int foo_init(void) +{ + if (foo_index == -1) + foo_index = openssl_ctx_new_index(&foo_method); + + return foo_index != -1; +} + +/* + * END EXAMPLE + * ====================================================================== + */ + +static int test_context(OPENSSL_CTX *ctx) +{ + FOO *data = NULL; + + return + TEST_true(foo_init()) + && TEST_ptr(data = openssl_ctx_get_data(ctx, foo_index)) + /* OPENSSL_zalloc in foo_new() initialized it to zero */ + && TEST_int_eq(data->i, 42); +} + +static int test_app_context(void) +{ + OPENSSL_CTX *ctx = NULL; + int result = + TEST_true(foo_init()) + && TEST_ptr(ctx = OPENSSL_CTX_new()) + && test_context(ctx); + + OPENSSL_CTX_free(ctx); + return result; +} + +static int test_def_context(void) +{ + return test_context(NULL); +} + +int setup_tests(void) +{ + ADD_TEST(test_app_context); + ADD_TEST(test_def_context); + return 1; +} diff --git a/test/ec_internal_test.c b/test/ec_internal_test.c new file mode 100644 index 00000000..8d3a4fdd --- /dev/null +++ b/test/ec_internal_test.c @@ -0,0 +1,205 @@ +/* + * 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 "internal/nelem.h" +#include "testutil.h" +#include +#include "ec_lcl.h" +#include + +static size_t crv_len = 0; +static EC_builtin_curve *curves = NULL; + +/* sanity checks field_inv function pointer in EC_METHOD */ +static int group_field_tests(const EC_GROUP *group, BN_CTX *ctx) +{ + BIGNUM *a = NULL, *b = NULL, *c = NULL; + int ret = 0; + + if (group->meth->field_inv == NULL || group->meth->field_mul == NULL) + return 1; + + BN_CTX_start(ctx); + a = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + if (!TEST_ptr(c = BN_CTX_get(ctx)) + /* 1/1 = 1 */ + || !TEST_true(group->meth->field_inv(group, b, BN_value_one(), ctx)) + || !TEST_true(BN_is_one(b)) + /* (1/a)*a = 1 */ + || !TEST_true(BN_pseudo_rand(a, BN_num_bits(group->field) - 1, + BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) + || !TEST_true(group->meth->field_inv(group, b, a, ctx)) + || (group->meth->field_encode && + !TEST_true(group->meth->field_encode(group, a, a, ctx))) + || (group->meth->field_encode && + !TEST_true(group->meth->field_encode(group, b, b, ctx))) + || !TEST_true(group->meth->field_mul(group, c, a, b, ctx)) + || (group->meth->field_decode && + !TEST_true(group->meth->field_decode(group, c, c, ctx))) + || !TEST_true(BN_is_one(c))) + goto err; + + /* 1/0 = error */ + BN_zero(a); + if (!TEST_false(group->meth->field_inv(group, b, a, ctx)) + || !TEST_true(ERR_GET_LIB(ERR_peek_last_error()) == ERR_LIB_EC) + || !TEST_true(ERR_GET_REASON(ERR_peek_last_error()) == + EC_R_CANNOT_INVERT) + /* 1/p = error */ + || !TEST_false(group->meth->field_inv(group, b, group->field, ctx)) + || !TEST_true(ERR_GET_LIB(ERR_peek_last_error()) == ERR_LIB_EC) + || !TEST_true(ERR_GET_REASON(ERR_peek_last_error()) == + EC_R_CANNOT_INVERT)) + goto err; + + ERR_clear_error(); + ret = 1; + err: + BN_CTX_end(ctx); + return ret; +} + +/* wrapper for group_field_tests for explicit curve params and EC_METHOD */ +static int field_tests(const EC_METHOD *meth, const unsigned char *params, + int len) +{ + BN_CTX *ctx = NULL; + BIGNUM *p = NULL, *a = NULL, *b = NULL; + EC_GROUP *group = NULL; + int ret = 0; + + if (!TEST_ptr(ctx = BN_CTX_new())) + return 0; + + BN_CTX_start(ctx); + p = BN_CTX_get(ctx); + a = BN_CTX_get(ctx); + if (!TEST_ptr(b = BN_CTX_get(ctx)) + || !TEST_ptr(group = EC_GROUP_new(meth)) + || !TEST_true(BN_bin2bn(params, len, p)) + || !TEST_true(BN_bin2bn(params + len, len, a)) + || !TEST_true(BN_bin2bn(params + 2 * len, len, b)) + || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx)) + || !group_field_tests(group, ctx)) + goto err; + ret = 1; + + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + if (group != NULL) + EC_GROUP_free(group); + return ret; +} + +/* NIST prime curve P-256 */ +static const unsigned char params_p256[] = { + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, + 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, + 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B +}; + +#ifndef OPENSSL_NO_EC2M +/* NIST binary curve B-283 */ +static const unsigned char params_b283[] = { + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* b */ + 0x02, 0x7B, 0x68, 0x0A, 0xC8, 0xB8, 0x59, 0x6D, 0xA5, 0xA4, 0xAF, 0x8A, + 0x19, 0xA0, 0x30, 0x3F, 0xCA, 0x97, 0xFD, 0x76, 0x45, 0x30, 0x9F, 0xA2, + 0xA5, 0x81, 0x48, 0x5A, 0xF6, 0x26, 0x3E, 0x31, 0x3B, 0x79, 0xA2, 0xF5 +}; +#endif + +/* test EC_GFp_simple_method directly */ +static int field_tests_ecp_simple(void) +{ + TEST_info("Testing EC_GFp_simple_method()\n"); + return field_tests(EC_GFp_simple_method(), params_p256, + sizeof(params_p256) / 3); +} + +/* test EC_GFp_mont_method directly */ +static int field_tests_ecp_mont(void) +{ + TEST_info("Testing EC_GFp_mont_method()\n"); + return field_tests(EC_GFp_mont_method(), params_p256, + sizeof(params_p256) / 3); +} + +#ifndef OPENSSL_NO_EC2M +/* test EC_GF2m_simple_method directly */ +static int field_tests_ec2_simple(void) +{ + TEST_info("Testing EC_GF2m_simple_method()\n"); + return field_tests(EC_GF2m_simple_method(), params_b283, + sizeof(params_b283) / 3); +} +#endif + +/* test default method for a named curve */ +static int field_tests_default(int n) +{ + BN_CTX *ctx = NULL; + EC_GROUP *group = NULL; + int nid = curves[n].nid; + int ret = 0; + + TEST_info("Testing curve %s\n", OBJ_nid2sn(nid)); + + if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)) + || !TEST_ptr(ctx = BN_CTX_new()) + || !group_field_tests(group, ctx)) + goto err; + + ret = 1; + err: + if (group != NULL) + EC_GROUP_free(group); + if (ctx != NULL) + BN_CTX_free(ctx); + return ret; +} + +int setup_tests(void) +{ + crv_len = EC_get_builtin_curves(NULL, 0); + if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len)) + || !TEST_true(EC_get_builtin_curves(curves, crv_len))) + return 0; + + ADD_TEST(field_tests_ecp_simple); + ADD_TEST(field_tests_ecp_mont); +#ifndef OPENSSL_NO_EC2M + ADD_TEST(field_tests_ec2_simple); +#endif + ADD_ALL_TESTS(field_tests_default, crv_len); + return 1; +} + +void cleanup_tests(void) +{ + OPENSSL_free(curves); +} diff --git a/test/ecdsatest.c b/test/ecdsatest.c index 004f39eb..bc3adc00 100644 --- a/test/ecdsatest.c +++ b/test/ecdsatest.c @@ -223,7 +223,7 @@ static int test_builtin(void) const BIGNUM *sig_r, *sig_s; BIGNUM *modified_r = NULL, *modified_s = NULL; BIGNUM *unmodified_r = NULL, *unmodified_s = NULL; - unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len; + unsigned int sig_len, order, r_len, s_len, bn_len, buf_len; int nid, ret = 0; /* fill digest values with some random data */ @@ -251,7 +251,7 @@ static int test_builtin(void) || !TEST_true(EC_KEY_set_group(eckey, group))) goto builtin_err; EC_GROUP_free(group); - degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey)); + order = EC_GROUP_order_bits(EC_KEY_get0_group(eckey)); TEST_info("testing %s", OBJ_nid2sn(nid)); @@ -316,7 +316,7 @@ static int test_builtin(void) /* Store the two BIGNUMs in raw_buf. */ r_len = BN_num_bytes(sig_r); s_len = BN_num_bytes(sig_s); - bn_len = (degree + 7) / 8; + bn_len = (order + 7) / 8; if (!TEST_false(r_len > bn_len) || !TEST_false(s_len > bn_len)) goto builtin_err; diff --git a/test/ectest.c b/test/ectest.c index cdfaeb69..0f425979 100644 --- a/test/ectest.c +++ b/test/ectest.c @@ -1159,6 +1159,43 @@ static int internal_curve_test_method(int n) return r; } +static int group_field_test(void) +{ + int r = 1; + BIGNUM *secp521r1_field = NULL; + BIGNUM *sect163r2_field = NULL; + EC_GROUP *secp521r1_group = NULL; + EC_GROUP *sect163r2_group = NULL; + + BN_hex2bn(&secp521r1_field, + "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFF"); + + + BN_hex2bn(§163r2_field, + "08000000000000000000000000000000" + "00000000C9"); + + secp521r1_group = EC_GROUP_new_by_curve_name(NID_secp521r1); + if (BN_cmp(secp521r1_field, EC_GROUP_get0_field(secp521r1_group))) + r = 0; + + # ifndef OPENSSL_NO_EC2M + sect163r2_group = EC_GROUP_new_by_curve_name(NID_sect163r2); + if (BN_cmp(sect163r2_field, EC_GROUP_get0_field(sect163r2_group))) + r = 0; + # endif + + EC_GROUP_free(secp521r1_group); + EC_GROUP_free(sect163r2_group); + BN_free(secp521r1_field); + BN_free(sect163r2_field); + return r; +} + # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 /* * nistp_test_params contains magic numbers for testing our optimized @@ -1513,6 +1550,7 @@ int setup_tests(void) # endif ADD_ALL_TESTS(internal_curve_test, crv_len); ADD_ALL_TESTS(internal_curve_test_method, crv_len); + ADD_TEST(group_field_test); #endif return 1; } diff --git a/test/evp_kdf_test.c b/test/evp_kdf_test.c new file mode 100644 index 00000000..923e9aef --- /dev/null +++ b/test/evp_kdf_test.c @@ -0,0 +1,237 @@ +/* + * Copyright 2018-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2018-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 + */ + +/* Tests of the EVP_KDF_CTX APIs */ + +#include +#include + +#include +#include +#include "testutil.h" + +static int test_kdf_tls1_prf(void) +{ + int ret = 0; + EVP_KDF_CTX *kctx; + unsigned char out[16]; + + if ((kctx = EVP_KDF_CTX_new_id(EVP_KDF_TLS1_PRF)) == NULL) { + TEST_error("EVP_KDF_TLS1_PRF"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_MD"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_TLS_SECRET, + "secret", (size_t)6) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_TLS_SECRET"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_ADD_TLS_SEED, "seed", (size_t)4) <= 0) { + TEST_error("EVP_KDF_CTRL_ADD_TLS_SEED"); + goto err; + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + TEST_error("EVP_KDF_derive"); + goto err; + } + + { + const unsigned char expected[sizeof(out)] = { + 0x8e, 0x4d, 0x93, 0x25, 0x30, 0xd7, 0x65, 0xa0, + 0xaa, 0xe9, 0x74, 0xc3, 0x04, 0x73, 0x5e, 0xcc + }; + if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) { + goto err; + } + } + ret = 1; +err: + EVP_KDF_CTX_free(kctx); + return ret; +} + +static int test_kdf_hkdf(void) +{ + int ret = 0; + EVP_KDF_CTX *kctx; + unsigned char out[10]; + + if ((kctx = EVP_KDF_CTX_new_id(EVP_KDF_HKDF)) == NULL) { + TEST_error("EVP_KDF_HKDF"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_MD"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "salt", (size_t)4) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_SALT"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, "secret", (size_t)6) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_KEY"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_ADD_HKDF_INFO, + "label", (size_t)5) <= 0) { + TEST_error("EVP_KDF_CTRL_ADD_HKDF_INFO"); + goto err; + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + TEST_error("EVP_KDF_derive"); + goto err; + } + + { + const unsigned char expected[sizeof(out)] = { + 0x2a, 0xc4, 0x36, 0x9f, 0x52, 0x59, 0x96, 0xf8, 0xde, 0x13 + }; + if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) { + goto err; + } + } + ret = 1; +err: + EVP_KDF_CTX_free(kctx); + return ret; +} + +static int test_kdf_pbkdf2(void) +{ + int ret = 0; + EVP_KDF_CTX *kctx; + unsigned char out[32]; + + if ((kctx = EVP_KDF_CTX_new_id(EVP_KDF_PBKDF2)) == NULL) { + TEST_error("EVP_KDF_PBKDF2"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, "password", (size_t)8) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_PASS"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "salt", (size_t)4) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_SALT"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, 2) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_ITER"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_MD"); + goto err; + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + TEST_error("EVP_KDF_derive"); + goto err; + } + + { + const unsigned char expected[sizeof(out)] = { + 0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3, + 0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0, + 0x2a, 0x30, 0x3f, 0x8e, 0xf3, 0xc2, 0x51, 0xdf, + 0xd6, 0xe2, 0xd8, 0x5a, 0x95, 0x47, 0x4c, 0x43 + }; + if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) { + goto err; + } + } + ret = 1; +err: + EVP_KDF_CTX_free(kctx); + return ret; +} + +#ifndef OPENSSL_NO_SCRYPT +static int test_kdf_scrypt(void) +{ + int ret = 0; + EVP_KDF_CTX *kctx; + unsigned char out[64]; + + if ((kctx = EVP_KDF_CTX_new_id(EVP_KDF_SCRYPT)) == NULL) { + TEST_error("EVP_KDF_SCRYPT"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, "password", (size_t)8) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_PASS"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "NaCl", (size_t)4) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_SALT"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_N, (uint64_t)1024) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_SCRYPT_N"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_R, (uint32_t)8) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_SCRYPT_R"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_P, (uint32_t)16) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_SCRYPT_P"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAXMEM_BYTES, (uint64_t)16) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_MAXMEM_BYTES"); + goto err; + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) > 0) { + TEST_error("EVP_KDF_derive should have failed"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAXMEM_BYTES, + (uint64_t)(10 * 1024 * 1024)) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_MAXMEM_BYTES"); + goto err; + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + TEST_error("EVP_KDF_derive"); + goto err; + } + + { + const unsigned char expected[sizeof(out)] = { + 0xfd, 0xba, 0xbe, 0x1c, 0x9d, 0x34, 0x72, 0x00, + 0x78, 0x56, 0xe7, 0x19, 0x0d, 0x01, 0xe9, 0xfe, + 0x7c, 0x6a, 0xd7, 0xcb, 0xc8, 0x23, 0x78, 0x30, + 0xe7, 0x73, 0x76, 0x63, 0x4b, 0x37, 0x31, 0x62, + 0x2e, 0xaf, 0x30, 0xd9, 0x2e, 0x22, 0xa3, 0x88, + 0x6f, 0xf1, 0x09, 0x27, 0x9d, 0x98, 0x30, 0xda, + 0xc7, 0x27, 0xaf, 0xb9, 0x4a, 0x83, 0xee, 0x6d, + 0x83, 0x60, 0xcb, 0xdf, 0xa2, 0xcc, 0x06, 0x40 + }; + if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) { + goto err; + } + } + ret = 1; +err: + EVP_KDF_CTX_free(kctx); + return ret; +} +#endif + +int setup_tests(void) +{ + ADD_TEST(test_kdf_tls1_prf); + ADD_TEST(test_kdf_hkdf); + ADD_TEST(test_kdf_pbkdf2); +#ifndef OPENSSL_NO_SCRYPT + ADD_TEST(test_kdf_scrypt); +#endif + return 1; +} diff --git a/test/evp_test.c b/test/evp_test.c index 49d254dc..cad580e1 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -1892,13 +1892,14 @@ static const EVP_TEST_METHOD encode_test_method = { encode_test_run, }; + /** *** KDF TESTS **/ typedef struct kdf_data_st { /* Context for this operation */ - EVP_PKEY_CTX *ctx; + EVP_KDF_CTX *ctx; /* Expected output */ unsigned char *output; size_t output_len; @@ -1913,6 +1914,137 @@ static int kdf_test_init(EVP_TEST *t, const char *name) KDF_DATA *kdata; int kdf_nid = OBJ_sn2nid(name); +#ifdef OPENSSL_NO_SCRYPT + if (strcmp(name, "scrypt") == 0) { + t->skip = 1; + return 1; + } +#endif + + if (kdf_nid == NID_undef) + kdf_nid = OBJ_ln2nid(name); + + if (!TEST_ptr(kdata = OPENSSL_zalloc(sizeof(*kdata)))) + return 0; + kdata->ctx = EVP_KDF_CTX_new_id(kdf_nid); + if (kdata->ctx == NULL) { + OPENSSL_free(kdata); + return 0; + } + t->data = kdata; + return 1; +} + +static void kdf_test_cleanup(EVP_TEST *t) +{ + KDF_DATA *kdata = t->data; + OPENSSL_free(kdata->output); + EVP_KDF_CTX_free(kdata->ctx); +} + +static int kdf_test_ctrl(EVP_TEST *t, EVP_KDF_CTX *kctx, + const char *value) +{ + int rv; + char *p, *tmpval; + + if (!TEST_ptr(tmpval = OPENSSL_strdup(value))) + return 0; + p = strchr(tmpval, ':'); + if (p != NULL) + *p++ = '\0'; + rv = EVP_KDF_ctrl_str(kctx, tmpval, p); + if (rv == -2) { + t->err = "KDF_CTRL_INVALID"; + rv = 1; + } else if (p != NULL && rv <= 0) { + /* If p has an OID and lookup fails assume disabled algorithm */ + int nid = OBJ_sn2nid(p); + + if (nid == NID_undef) + nid = OBJ_ln2nid(p); + if (nid != NID_undef + && EVP_get_digestbynid(nid) == NULL + && EVP_get_cipherbynid(nid) == NULL) { + t->skip = 1; + rv = 1; + } else { + t->err = "KDF_CTRL_ERROR"; + rv = 1; + } + } + OPENSSL_free(tmpval); + return rv > 0; +} + +static int kdf_test_parse(EVP_TEST *t, + const char *keyword, const char *value) +{ + KDF_DATA *kdata = t->data; + + if (strcmp(keyword, "Output") == 0) + return parse_bin(value, &kdata->output, &kdata->output_len); + if (strncmp(keyword, "Ctrl", 4) == 0) + return kdf_test_ctrl(t, kdata->ctx, value); + return 0; +} + +static int kdf_test_run(EVP_TEST *t) +{ + KDF_DATA *expected = t->data; + unsigned char *got = NULL; + size_t got_len = expected->output_len; + + if (!TEST_ptr(got = OPENSSL_malloc(got_len))) { + t->err = "INTERNAL_ERROR"; + goto err; + } + if (EVP_KDF_derive(expected->ctx, got, got_len) <= 0) { + t->err = "KDF_DERIVE_ERROR"; + goto err; + } + if (!memory_err_compare(t, "KDF_MISMATCH", + expected->output, expected->output_len, + got, got_len)) + goto err; + + t->err = NULL; + + err: + OPENSSL_free(got); + return 1; +} + +static const EVP_TEST_METHOD kdf_test_method = { + "KDF", + kdf_test_init, + kdf_test_cleanup, + kdf_test_parse, + kdf_test_run +}; + + +/** +*** PKEY KDF TESTS +**/ + +typedef struct pkey_kdf_data_st { + /* Context for this operation */ + EVP_PKEY_CTX *ctx; + /* Expected output */ + unsigned char *output; + size_t output_len; +} PKEY_KDF_DATA; + +/* + * Perform public key operation setup: lookup key, allocated ctx and call + * the appropriate initialisation function + */ +static int pkey_kdf_test_init(EVP_TEST *t, const char *name) +{ + PKEY_KDF_DATA *kdata; + int kdf_nid = OBJ_sn2nid(name); + #ifdef OPENSSL_NO_SCRYPT if (strcmp(name, "scrypt") == 0) { t->skip = 1; @@ -1939,17 +2071,17 @@ static int kdf_test_init(EVP_TEST *t, const char *name) return 1; } -static void kdf_test_cleanup(EVP_TEST *t) +static void pkey_kdf_test_cleanup(EVP_TEST *t) { - KDF_DATA *kdata = t->data; + PKEY_KDF_DATA *kdata = t->data; OPENSSL_free(kdata->output); EVP_PKEY_CTX_free(kdata->ctx); } -static int kdf_test_parse(EVP_TEST *t, - const char *keyword, const char *value) +static int pkey_kdf_test_parse(EVP_TEST *t, + const char *keyword, const char *value) { - KDF_DATA *kdata = t->data; + PKEY_KDF_DATA *kdata = t->data; if (strcmp(keyword, "Output") == 0) return parse_bin(value, &kdata->output, &kdata->output_len); @@ -1958,9 +2090,9 @@ static int kdf_test_parse(EVP_TEST *t, return 0; } -static int kdf_test_run(EVP_TEST *t) +static int pkey_kdf_test_run(EVP_TEST *t) { - KDF_DATA *expected = t->data; + PKEY_KDF_DATA *expected = t->data; unsigned char *got = NULL; size_t got_len = expected->output_len; @@ -1972,11 +2104,10 @@ static int kdf_test_run(EVP_TEST *t) t->err = "KDF_DERIVE_ERROR"; goto err; } - if (!memory_err_compare(t, "KDF_MISMATCH", - expected->output, expected->output_len, - got, got_len)) + if (!TEST_mem_eq(expected->output, expected->output_len, got, got_len)) { + t->err = "KDF_MISMATCH"; goto err; - + } t->err = NULL; err: @@ -1984,12 +2115,12 @@ static int kdf_test_run(EVP_TEST *t) return 1; } -static const EVP_TEST_METHOD kdf_test_method = { - "KDF", - kdf_test_init, - kdf_test_cleanup, - kdf_test_parse, - kdf_test_run +static const EVP_TEST_METHOD pkey_kdf_test_method = { + "PKEYKDF", + pkey_kdf_test_init, + pkey_kdf_test_cleanup, + pkey_kdf_test_parse, + pkey_kdf_test_run }; @@ -2497,6 +2628,7 @@ static const EVP_TEST_METHOD *evp_test_list[] = { &digestverify_test_method, &encode_test_method, &kdf_test_method, + &pkey_kdf_test_method, &keypair_test_method, &keygen_test_method, &mac_test_method, diff --git a/test/exdatatest.c b/test/exdatatest.c index db4e0ff0..3ce6d33c 100644 --- a/test/exdatatest.c +++ b/test/exdatatest.c @@ -18,6 +18,7 @@ static long saved_argl; static void *saved_argp; static int saved_idx; static int saved_idx2; +static int saved_idx3; static int gbl_result; /* @@ -71,12 +72,13 @@ static void exnew2(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp) { MYOBJ_EX_DATA *ex_data = OPENSSL_zalloc(sizeof(*ex_data)); - if (!TEST_int_eq(idx, saved_idx2) + + if (!TEST_true(idx == saved_idx2 || idx == saved_idx3) || !TEST_long_eq(argl, saved_argl) || !TEST_ptr_eq(argp, saved_argp) || !TEST_ptr_null(ptr) || !TEST_ptr(ex_data) - || !TEST_true(CRYPTO_set_ex_data(ad, saved_idx2, ex_data))) { + || !TEST_true(CRYPTO_set_ex_data(ad, idx, ex_data))) { gbl_result = 0; OPENSSL_free(ex_data); } else { @@ -88,13 +90,14 @@ static int exdup2(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, void *from_d, int idx, long argl, void *argp) { MYOBJ_EX_DATA **update_ex_data = (MYOBJ_EX_DATA**)from_d; - MYOBJ_EX_DATA *ex_data = CRYPTO_get_ex_data(to, saved_idx2); - if (!TEST_int_eq(idx, saved_idx2) + MYOBJ_EX_DATA *ex_data = NULL; + + if (!TEST_true(idx == saved_idx2 || idx == saved_idx3) || !TEST_long_eq(argl, saved_argl) || !TEST_ptr_eq(argp, saved_argp) || !TEST_ptr(from_d) || !TEST_ptr(*update_ex_data) - || !TEST_ptr(ex_data) + || !TEST_ptr(ex_data = CRYPTO_get_ex_data(to, idx)) || !TEST_true(ex_data->new)) { gbl_result = 0; } else { @@ -111,14 +114,14 @@ static int exdup2(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, static void exfree2(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp) { - MYOBJ_EX_DATA *ex_data = CRYPTO_get_ex_data(ad, saved_idx2); - OPENSSL_free(ex_data); - if (!TEST_int_eq(idx, saved_idx2) + MYOBJ_EX_DATA *ex_data = CRYPTO_get_ex_data(ad, idx); + + if (!TEST_true(idx == saved_idx2 || idx == saved_idx3) || !TEST_long_eq(argl, saved_argl) || !TEST_ptr_eq(argp, saved_argp) - || !TEST_ptr(ex_data) - || !TEST_true(CRYPTO_set_ex_data(ad, saved_idx2, NULL))) + || !TEST_true(CRYPTO_set_ex_data(ad, idx, NULL))) gbl_result = 0; + OPENSSL_free(ex_data); } typedef struct myobj_st { @@ -152,6 +155,7 @@ static char *MYOBJ_gethello(MYOBJ *obj) static void MYOBJ_sethello2(MYOBJ *obj, char *cp) { MYOBJ_EX_DATA* ex_data = CRYPTO_get_ex_data(&obj->ex_data, saved_idx2); + if (TEST_ptr(ex_data)) ex_data->hello = cp; else @@ -161,6 +165,31 @@ static void MYOBJ_sethello2(MYOBJ *obj, char *cp) static char *MYOBJ_gethello2(MYOBJ *obj) { MYOBJ_EX_DATA* ex_data = CRYPTO_get_ex_data(&obj->ex_data, saved_idx2); + + if (TEST_ptr(ex_data)) + return ex_data->hello; + + obj->st = gbl_result = 0; + return NULL; +} + +static void MYOBJ_allochello3(MYOBJ *obj, char *cp) +{ + MYOBJ_EX_DATA* ex_data = NULL; + + if (TEST_ptr_null(ex_data = CRYPTO_get_ex_data(&obj->ex_data, saved_idx3)) + && TEST_true(CRYPTO_alloc_ex_data(CRYPTO_EX_INDEX_APP, obj, + &obj->ex_data, saved_idx3)) + && TEST_ptr(ex_data = CRYPTO_get_ex_data(&obj->ex_data, saved_idx3))) + ex_data->hello = cp; + else + obj->st = gbl_result = 0; +} + +static char *MYOBJ_gethello3(MYOBJ *obj) +{ + MYOBJ_EX_DATA* ex_data = CRYPTO_get_ex_data(&obj->ex_data, saved_idx3); + if (TEST_ptr(ex_data)) return ex_data->hello; @@ -207,7 +236,15 @@ static int test_exdata(void) return 0; if (!TEST_ptr(CRYPTO_get_ex_data(&t1->ex_data, saved_idx2))) return 0; - if (!TEST_ptr(CRYPTO_get_ex_data(&t2->ex_data, saved_idx2))) + + /* + * saved_idx3 differs from other indexes by being created after the exdata + * was initialized. + */ + saved_idx3 = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_APP, + saved_argl, saved_argp, + exnew2, exdup2, exfree2); + if (!TEST_ptr_null(CRYPTO_get_ex_data(&t1->ex_data, saved_idx3))) return 0; MYOBJ_sethello(t1, p); @@ -220,6 +257,11 @@ static int test_exdata(void) if (!TEST_ptr_eq(cp, p)) return 0; + MYOBJ_allochello3(t1, p); + cp = MYOBJ_gethello3(t1); + if (!TEST_ptr_eq(cp, p)) + return 0; + cp = MYOBJ_gethello(t2); if (!TEST_ptr_null(cp)) return 0; @@ -246,6 +288,10 @@ static int test_exdata(void) if (!TEST_ptr_eq(cp, p)) return 0; + cp = MYOBJ_gethello3(t3); + if (!TEST_ptr_eq(cp, p)) + return 0; + MYOBJ_free(t1); MYOBJ_free(t2); MYOBJ_free(t3); diff --git a/test/pkey_meth_kdf_test.c b/test/pkey_meth_kdf_test.c index ad754253..cdc3d9f6 100644 --- a/test/pkey_meth_kdf_test.c +++ b/test/pkey_meth_kdf_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-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 @@ -18,30 +18,34 @@ static int test_kdf_tls1_prf(void) { + int ret = 0; EVP_PKEY_CTX *pctx; unsigned char out[16]; size_t outlen = sizeof(out); - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL); + if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL)) == NULL) { + TEST_error("EVP_PKEY_TLS1_PRF"); + goto err; + } if (EVP_PKEY_derive_init(pctx) <= 0) { TEST_error("EVP_PKEY_derive_init"); - return 0; + goto err; } if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_sha256()) <= 0) { TEST_error("EVP_PKEY_CTX_set_tls1_prf_md"); - return 0; + goto err; } if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, "secret", 6) <= 0) { TEST_error("EVP_PKEY_CTX_set1_tls1_prf_secret"); - return 0; + goto err; } if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, "seed", 4) <= 0) { TEST_error("EVP_PKEY_CTX_add1_tls1_prf_seed"); - return 0; + goto err; } if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) { TEST_error("EVP_PKEY_derive"); - return 0; + goto err; } { @@ -50,43 +54,49 @@ static int test_kdf_tls1_prf(void) 0xaa, 0xe9, 0x74, 0xc3, 0x04, 0x73, 0x5e, 0xcc }; if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) { - return 0; + goto err; } } + ret = 1; +err: EVP_PKEY_CTX_free(pctx); - return 1; + return ret; } static int test_kdf_hkdf(void) { + int ret = 0; EVP_PKEY_CTX *pctx; unsigned char out[10]; size_t outlen = sizeof(out); - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); + if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL)) == NULL) { + TEST_error("EVP_PKEY_HKDF"); + goto err; + } if (EVP_PKEY_derive_init(pctx) <= 0) { TEST_error("EVP_PKEY_derive_init"); - return 0; + goto err; } if (EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()) <= 0) { TEST_error("EVP_PKEY_CTX_set_hkdf_md"); - return 0; + goto err; } if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, "salt", 4) <= 0) { TEST_error("EVP_PKEY_CTX_set1_hkdf_salt"); - return 0; + goto err; } if (EVP_PKEY_CTX_set1_hkdf_key(pctx, "secret", 6) <= 0) { TEST_error("EVP_PKEY_CTX_set1_hkdf_key"); - return 0; + goto err; } if (EVP_PKEY_CTX_add1_hkdf_info(pctx, "label", 5) <= 0) { TEST_error("EVP_PKEY_CTX_set1_hkdf_info"); - return 0; + goto err; } if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) { TEST_error("EVP_PKEY_derive"); - return 0; + goto err; } { @@ -94,60 +104,66 @@ static int test_kdf_hkdf(void) 0x2a, 0xc4, 0x36, 0x9f, 0x52, 0x59, 0x96, 0xf8, 0xde, 0x13 }; if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) { - return 0; + goto err; } } + ret = 1; +err: EVP_PKEY_CTX_free(pctx); - return 1; + return ret; } #ifndef OPENSSL_NO_SCRYPT static int test_kdf_scrypt(void) { + int ret = 0; EVP_PKEY_CTX *pctx; unsigned char out[64]; size_t outlen = sizeof(out); - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SCRYPT, NULL); + if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SCRYPT, NULL)) == NULL) { + TEST_error("EVP_PKEY_SCRYPT"); + goto err; + } if (EVP_PKEY_derive_init(pctx) <= 0) { TEST_error("EVP_PKEY_derive_init"); - return 0; + goto err; } if (EVP_PKEY_CTX_set1_pbe_pass(pctx, "password", 8) <= 0) { TEST_error("EVP_PKEY_CTX_set1_pbe_pass"); - return 0; + goto err; } if (EVP_PKEY_CTX_set1_scrypt_salt(pctx, "NaCl", 4) <= 0) { TEST_error("EVP_PKEY_CTX_set1_scrypt_salt"); - return 0; + goto err; } if (EVP_PKEY_CTX_set_scrypt_N(pctx, 1024) <= 0) { TEST_error("EVP_PKEY_CTX_set_scrypt_N"); - return 0; + goto err; } if (EVP_PKEY_CTX_set_scrypt_r(pctx, 8) <= 0) { TEST_error("EVP_PKEY_CTX_set_scrypt_r"); - return 0; + goto err; } if (EVP_PKEY_CTX_set_scrypt_p(pctx, 16) <= 0) { TEST_error("EVP_PKEY_CTX_set_scrypt_p"); - return 0; + goto err; } if (EVP_PKEY_CTX_set_scrypt_maxmem_bytes(pctx, 16) <= 0) { TEST_error("EVP_PKEY_CTX_set_maxmem_bytes"); - return 0; + goto err; } if (EVP_PKEY_derive(pctx, out, &outlen) > 0) { TEST_error("EVP_PKEY_derive should have failed"); - return 0; + goto err; } if (EVP_PKEY_CTX_set_scrypt_maxmem_bytes(pctx, 10 * 1024 * 1024) <= 0) { TEST_error("EVP_PKEY_CTX_set_maxmem_bytes"); - return 0; + goto err; } if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) { TEST_error("EVP_PKEY_derive"); - return 0; + goto err; } { @@ -162,11 +178,13 @@ static int test_kdf_scrypt(void) 0x83, 0x60, 0xcb, 0xdf, 0xa2, 0xcc, 0x06, 0x40 }; if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) { - return 0; + goto err; } } + ret = 1; +err: EVP_PKEY_CTX_free(pctx); - return 1; + return ret; } #endif diff --git a/test/property_test.c b/test/property_test.c new file mode 100644 index 00000000..722de05d --- /dev/null +++ b/test/property_test.c @@ -0,0 +1,374 @@ +/* + * 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 + */ + +#include +#include "testutil.h" +#include "internal/nelem.h" +#include "internal/property.h" +#include "../crypto/property/property_lcl.h" + +static int add_property_names(const char *n, ...) +{ + va_list args; + int res = 1; + + va_start(args, n); + do { + if (!TEST_int_ne(ossl_property_name(n, 1), 0)) + res = 0; + } while ((n = va_arg(args, const char *)) != NULL); + va_end(args); + return res; +} + +static int test_property_string(void) +{ + OSSL_METHOD_STORE *store; + int res = 0; + OSSL_PROPERTY_IDX i, j; + + if (TEST_ptr(store = ossl_method_store_new()) + && TEST_int_eq(ossl_property_name("fnord", 0), 0) + && TEST_int_ne(ossl_property_name("fnord", 1), 0) + && TEST_int_ne(ossl_property_name("name", 1), 0) + /* Property value checks */ + && TEST_int_eq(ossl_property_value("fnord", 0), 0) + && TEST_int_ne(i = ossl_property_value("no", 0), 0) + && TEST_int_ne(j = ossl_property_value("yes", 0), 0) + && TEST_int_ne(i, j) + && TEST_int_eq(ossl_property_value("yes", 1), j) + && TEST_int_eq(ossl_property_value("no", 1), i) + && TEST_int_ne(i = ossl_property_value("illuminati", 1), 0) + && TEST_int_eq(j = ossl_property_value("fnord", 1), i + 1) + && TEST_int_eq(ossl_property_value("fnord", 1), j) + /* Check name and values are distinct */ + && TEST_int_eq(ossl_property_value("cold", 0), 0) + && TEST_int_ne(ossl_property_name("fnord", 0), + ossl_property_value("fnord", 0))) + res = 1; + ossl_method_store_free(store); + return res; +} + +static const struct { + const char *defn; + const char *query; + int e; +} parser_tests[] = { + { "", "sky=blue", 0 }, + { "", "sky!=blue", 1 }, + { "groan", "", 1 }, + { "cold=yes", "cold=yes", 1 }, + { "cold=yes", "cold", 1 }, + { "cold=yes", "cold!=no", 1 }, + { "groan", "groan=yes", 1 }, + { "groan", "groan=no", 0 }, + { "groan", "groan!=yes", 0 }, + { "cold=no", "cold", 0 }, + { "cold=no", "cold=no", 1 }, + { "groan", "cold", 0 }, + { "groan", "cold=no", 1 }, + { "groan", "cold!=yes", 1 }, + { "groan=blue", "groan=yellow", 0 }, + { "groan=blue", "groan!=yellow", 1 }, + { "today=monday, tomorrow=3", "today!=2", 1 }, + { "today=monday, tomorrow=3", "today!='monday'", 0 }, + { "today=monday, tomorrow=3", "tomorrow=3", 1 }, + { "n=0x3", "n=3", 1 }, + { "n=0x3", "n=-3", 0 }, + { "n=0x33", "n=51", 1 }, + { "n=033", "n=27", 1 }, + { "n=0", "n=00", 1 }, + { "n=0x0", "n=0", 1 }, +}; + +static int test_property_parse(int n) +{ + OSSL_METHOD_STORE *store; + OSSL_PROPERTY_LIST *p = NULL, *q = NULL; + int r = 0; + + if (TEST_ptr(store = ossl_method_store_new()) + && add_property_names("sky", "groan", "cold", "today", "tomorrow", "n", + NULL) + && TEST_ptr(p = ossl_parse_property(parser_tests[n].defn)) + && TEST_ptr(q = ossl_parse_query(parser_tests[n].query)) + && TEST_int_eq(ossl_property_match(q, p), parser_tests[n].e)) + r = 1; + ossl_property_free(p); + ossl_property_free(q); + ossl_method_store_free(store); + return r; +} + +static const struct { + const char *q_global; + const char *q_local; + const char *prop; +} merge_tests[] = { + { "", "colour=blue", "colour=blue" }, + { "colour=blue", "", "colour=blue" }, + { "colour=red", "colour=blue", "colour=blue" }, + { "clouds=pink, urn=red", "urn=blue, colour=green", + "urn=blue, colour=green, clouds=pink" }, + { "pot=gold", "urn=blue", "pot=gold, urn=blue" }, + { "night", "day", "day=yes, night=yes" }, + { "day", "night", "day=yes, night=yes" }, + { "", "", "" }, + /* + * The following four leave 'day' unspecified in the query, and will match + * any definition + */ + { "day=yes", "-day", "day=no" }, + { "day=yes", "-day", "day=yes" }, + { "day=yes", "-day", "day=arglebargle" }, + { "day=yes", "-day", "pot=sesquioxidizing" }, + { "day, night", "-night, day", "day=yes, night=no" }, + { "-day", "day=yes", "day=yes" }, +}; + +static int test_property_merge(int n) +{ + OSSL_METHOD_STORE *store; + OSSL_PROPERTY_LIST *q_global = NULL, *q_local = NULL; + OSSL_PROPERTY_LIST *q_combined = NULL, *prop = NULL; + int r = 0; + + if (TEST_ptr(store = ossl_method_store_new()) + && add_property_names("colour", "urn", "clouds", "pot", "day", "night", + NULL) + && TEST_ptr(prop = ossl_parse_property(merge_tests[n].prop)) + && TEST_ptr(q_global = ossl_parse_query(merge_tests[n].q_global)) + && TEST_ptr(q_local = ossl_parse_query(merge_tests[n].q_local)) + && TEST_ptr(q_combined = ossl_property_merge(q_local, q_global)) + && TEST_true(ossl_property_match(q_combined, prop))) + r = 1; + ossl_property_free(q_global); + ossl_property_free(q_local); + ossl_property_free(q_combined); + ossl_property_free(prop); + ossl_method_store_free(store); + return r; +} + +static int test_property_defn_cache(void) +{ + OSSL_METHOD_STORE *store; + OSSL_PROPERTY_LIST *red, *blue; + int r = 0; + + if (TEST_ptr(store = ossl_method_store_new()) + && add_property_names("red", "blue", NULL) + && TEST_ptr(red = ossl_parse_property("red")) + && TEST_ptr(blue = ossl_parse_property("blue")) + && TEST_ptr_ne(red, blue) + && TEST_true(ossl_prop_defn_set("red", red)) + && TEST_true(ossl_prop_defn_set("blue", blue)) + && TEST_ptr_eq(ossl_prop_defn_get("red"), red) + && TEST_ptr_eq(ossl_prop_defn_get("blue"), blue)) + r = 1; + ossl_method_store_free(store); + return r; +} + +static const struct { + const char *defn; + const char *query; + int e; +} definition_tests[] = { + { "alpha", "alpha=yes", 1 }, + { "alpha=no", "alpha", 0 }, + { "alpha=1", "alpha=1", 1 }, + { "alpha=2", "alpha=1", 0 }, + { "alpha", "omega", 0 } +}; + +static int test_definition_compares(int n) +{ + OSSL_METHOD_STORE *store; + OSSL_PROPERTY_LIST *d = NULL, *q = NULL; + int r; + + r = TEST_ptr(store = ossl_method_store_new()) + && add_property_names("alpha", "omega", NULL) + && TEST_ptr(d = ossl_parse_property(definition_tests[n].defn)) + && TEST_ptr(q = ossl_parse_query(definition_tests[n].query)) + && TEST_int_eq(ossl_property_match(q, d), definition_tests[n].e); + + ossl_property_free(d); + ossl_property_free(q); + ossl_method_store_free(store); + return r; +} + +static int test_register_deregister(void) +{ + static const struct { + int nid; + const char *prop; + char *impl; + } impls[] = { + { 6, "position=1", "a" }, + { 6, "position=2", "b" }, + { 6, "position=3", "c" }, + { 6, "position=4", "d" }, + }; + size_t i; + int ret = 0; + OSSL_METHOD_STORE *store; + + if (!TEST_ptr(store = ossl_method_store_new()) + || !add_property_names("position", NULL)) + goto err; + + for (i = 0; i < OSSL_NELEM(impls); i++) + if (!TEST_true(ossl_method_store_add(store, impls[i].nid, impls[i].prop, + impls[i].impl, NULL))) { + TEST_note("iteration %zd", i + 1); + goto err; + } + + /* Deregister in a different order to registration */ + for (i = 0; i < OSSL_NELEM(impls); i++) { + const size_t j = (1 + i * 3) % OSSL_NELEM(impls); + int nid = impls[j].nid; + void *impl = impls[j].impl; + + if (!TEST_true(ossl_method_store_remove(store, nid, impl)) + || !TEST_false(ossl_method_store_remove(store, nid, impl))) { + TEST_note("iteration %zd, position %zd", i + 1, j + 1); + goto err; + } + } + + if (TEST_false(ossl_method_store_remove(store, impls[0].nid, impls[0].impl))) + ret = 1; +err: + ossl_method_store_free(store); + return ret; +} + +static int test_property(void) +{ + static const struct { + int nid; + const char *prop; + char *impl; + } impls[] = { + { 1, "fast=no, colour=green", "a" }, + { 1, "fast, colour=blue", "b" }, + { 1, "", "-" }, + { 9, "sky=blue, furry", "c" }, + { 3, NULL, "d" }, + { 6, "sky.colour=blue, sky=green, old.data", "e" }, + }; + static struct { + int nid; + const char *prop; + char *expected; + } queries[] = { + { 1, "fast", "b" }, + { 1, "fast=yes", "b" }, + { 1, "fast=no, colour=green", "a" }, + { 1, "colour=blue, fast", "b" }, + { 1, "colour=blue", "b" }, + { 9, "furry", "c" }, + { 6, "sky.colour=blue", "e" }, + { 6, "old.data", "e" }, + { 9, "furry=yes, sky=blue", "c" }, + { 1, "", "a" }, + { 3, "", "d" }, + }; + OSSL_METHOD_STORE *store; + size_t i; + int ret = 0; + void *result; + + if (!TEST_ptr(store = ossl_method_store_new()) + || !add_property_names("fast", "colour", "sky", "furry", NULL)) + goto err; + + for (i = 0; i < OSSL_NELEM(impls); i++) + if (!TEST_true(ossl_method_store_add(store, impls[i].nid, impls[i].prop, + impls[i].impl, NULL))) { + TEST_note("iteration %zd", i + 1); + goto err; + } + for (i = 0; i < OSSL_NELEM(queries); i++) { + OSSL_PROPERTY_LIST *pq = NULL; + + if (!TEST_true(ossl_property_read_lock(store)) + || !TEST_true(ossl_method_store_fetch(store, queries[i].nid, + queries[i].prop, &result)) + || !TEST_true(ossl_property_unlock(store)) + || !TEST_str_eq((char *)result, queries[i].expected)) { + TEST_note("iteration %zd", i + 1); + ossl_property_free(pq); + goto err; + } + ossl_property_free(pq); + } + ret = 1; +err: + ossl_method_store_free(store); + return ret; +} + +static int test_query_cache_stochastic(void) +{ + const int max = 10000, tail = 10; + OSSL_METHOD_STORE *store; + int i, res = 0; + char buf[50]; + void *result; + int errors = 0; + int v[10001]; + + if (!TEST_ptr(store = ossl_method_store_new()) + || !add_property_names("n", NULL)) + goto err; + + for (i = 1; i <= max; i++) { + v[i] = 2 * i; + BIO_snprintf(buf, sizeof(buf), "n=%d\n", i); + if (!TEST_true(ossl_method_store_add(store, i, buf, "abc", NULL)) + || !TEST_true(ossl_method_store_cache_set(store, i, buf, v + i)) + || !TEST_true(ossl_method_store_cache_set(store, i, "n=1234", + "miss"))) { + TEST_note("iteration %d", i); + goto err; + } + } + for (i = 1; i <= max; i++) { + BIO_snprintf(buf, sizeof(buf), "n=%d\n", i); + if (!ossl_method_store_cache_get(store, i, buf, &result) + || result != v + i) + errors++; + } + /* There is a tiny probability that this will fail when it shouldn't */ + res = TEST_int_gt(errors, tail) && TEST_int_lt(errors, max - tail); + +err: + ossl_method_store_free(store); + return res; +} + +int setup_tests(void) +{ + ADD_TEST(test_property_string); + ADD_ALL_TESTS(test_property_parse, OSSL_NELEM(parser_tests)); + ADD_ALL_TESTS(test_property_merge, OSSL_NELEM(merge_tests)); + ADD_TEST(test_property_defn_cache); + ADD_ALL_TESTS(test_definition_compares, OSSL_NELEM(definition_tests)); + ADD_TEST(test_register_deregister); + ADD_TEST(test_property); + ADD_TEST(test_query_cache_stochastic); + return 1; +} diff --git a/test/recipes/02-test_internal_context.t b/test/recipes/02-test_internal_context.t new file mode 100644 index 00000000..c4c99043 --- /dev/null +++ b/test/recipes/02-test_internal_context.t @@ -0,0 +1,16 @@ +#! /usr/bin/env perl +# 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 + +use strict; +use OpenSSL::Test; # get 'plan' +use OpenSSL::Test::Simple; +use OpenSSL::Test::Utils; + +setup("test_internal_context"); + +simple_test("test_internal_context", "context_internal_test"); diff --git a/test/recipes/02-test_sparse_array.t b/test/recipes/02-test_sparse_array.t new file mode 100644 index 00000000..ee4a63e9 --- /dev/null +++ b/test/recipes/02-test_sparse_array.t @@ -0,0 +1,12 @@ +#! /usr/bin/env perl +# 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 + +use OpenSSL::Test::Simple; + +simple_test("test_sparse_array", "sparse_array_test"); diff --git a/test/recipes/03-test_internal_ec.t b/test/recipes/03-test_internal_ec.t new file mode 100644 index 00000000..0d31d0ac --- /dev/null +++ b/test/recipes/03-test_internal_ec.t @@ -0,0 +1,19 @@ +#! /usr/bin/env perl +# 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 + +use strict; +use OpenSSL::Test; # get 'plan' +use OpenSSL::Test::Simple; +use OpenSSL::Test::Utils; + +setup("test_internal_ec"); + +plan skip_all => "This test is unsupported in a no-ec build" + if disabled("ec"); + +simple_test("test_internal_ec", "ec_internal_test"); diff --git a/test/recipes/03-test_property.t b/test/recipes/03-test_property.t new file mode 100644 index 00000000..26542156 --- /dev/null +++ b/test/recipes/03-test_property.t @@ -0,0 +1,12 @@ +#! /usr/bin/env perl +# 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 + +use OpenSSL::Test::Simple; + +simple_test("test_property", "property_test"); diff --git a/test/recipes/30-test_evp.t b/test/recipes/30-test_evp.t index c2079bd6..24aa3a38 100644 --- a/test/recipes/30-test_evp.t +++ b/test/recipes/30-test_evp.t @@ -15,8 +15,8 @@ use OpenSSL::Test qw/:DEFAULT data_file/; setup("test_evp"); my @files = ( "evpciph.txt", "evpdigest.txt", "evpencod.txt", "evpkdf.txt", - "evpmac.txt", "evppbe.txt", "evppkey.txt", "evppkey_ecc.txt", - "evpcase.txt", "evpaessiv.txt" ); + "evppkey_kdf.txt", "evpmac.txt", "evppbe.txt", "evppkey.txt", + "evppkey_ecc.txt", "evpcase.txt", "evpaessiv.txt" ); plan tests => scalar(@files); diff --git a/test/recipes/30-test_evp_data/evpkdf.txt b/test/recipes/30-test_evp_data/evpkdf.txt index 16f439f9..6e34d38b 100644 --- a/test/recipes/30-test_evp_data/evpkdf.txt +++ b/test/recipes/30-test_evp_data/evpkdf.txt @@ -1,5 +1,5 @@ # -# Copyright 2001-2017 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -15,7 +15,7 @@ Title = TLS1 PRF tests (from NIST test vectors) KDF=TLS1-PRF -Ctrl.md = md:MD5-SHA1 +Ctrl.digest = digest:MD5-SHA1 Ctrl.Secret = hexsecret:bded7fa5c1699c010be23dd06ada3a48349f21e5f86263d512c0c5cc379f0e780ec55d9844b2f1db02a96453513568d0 Ctrl.label = seed:master secret Ctrl.client_random = hexseed:e5acaf549cd25c22d964c0d930fa4b5261d2507fad84c33715b7b9a864020693 @@ -23,7 +23,7 @@ Ctrl.server_random = hexseed:135e4d557fdf3aa6406d82975d5c606a9734c9334b42136e969 Output = 2f6962dfbc744c4b2138bb6b3d33054c5ecc14f24851d9896395a44ab3964efc2090c5bf51a0891209f46c1e1e998f62 KDF=TLS1-PRF -Ctrl.md = md:MD5-SHA1 +Ctrl.digest = digest:MD5-SHA1 Ctrl.Secret = hexsecret:2f6962dfbc744c4b2138bb6b3d33054c5ecc14f24851d9896395a44ab3964efc2090c5bf51a0891209f46c1e1e998f62 Ctrl.label = seed:key expansion Ctrl.server_random = hexseed:67267e650eb32444119d222a368c191af3082888dc35afe8368e638c828874be @@ -31,7 +31,7 @@ Ctrl.client_random = hexseed:d58a7b1cd4fedaa232159df652ce188f9d997e061b9bf48e83b Output = 3088825988e77fce68d19f756e18e43eb7fe672433504feaf99b3c503d9091b164f166db301d70c9fc0870b4a94563907bee1a61fb786cb717576890bcc51cb9ead97e01d0a2fea99c953377b195205ff07b369589178796edc963fd80fdbe518a2fc1c35c18ae8d KDF=TLS1-PRF -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.Secret = hexsecret:f8938ecc9edebc5030c0c6a441e213cd24e6f770a50dda07876f8d55da062bcadb386b411fd4fe4313a604fce6c17fbc Ctrl.label = seed:master secret Ctrl.client_random = hexseed:36c129d01a3200894b9179faac589d9835d58775f9b5ea3587cb8fd0364cae8c @@ -39,7 +39,7 @@ Ctrl.server_random = hexseed:f6c9575ed7ddd73e1f7d16eca115415812a43c2b747daaaae04 Output = 202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf KDF=TLS1-PRF -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.Secret = hexsecret:202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf Ctrl.label = seed:key expansion Ctrl.server_random = hexseed:ae6c806f8ad4d80784549dff28a4b58fd837681a51d928c3e30ee5ff14f39868 @@ -48,7 +48,7 @@ Output = d06139889fffac1e3a71865f504aa5d0d2a2e89506c6f2279b670c3e1b74f531016a253 # As above but use long name for KDF KDF=tls1-prf -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.Secret = hexsecret:202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf Ctrl.label = seed:key expansion Ctrl.server_random = hexseed:ae6c806f8ad4d80784549dff28a4b58fd837681a51d928c3e30ee5ff14f39868 @@ -64,7 +64,7 @@ Result = KDF_DERIVE_ERROR # Missing secret. KDF=TLS1-PRF -Ctrl.md = md:MD5-SHA1 +Ctrl.digest = digest:MD5-SHA1 Ctrl.Seed = hexseed:02 Output = 03 Result = KDF_DERIVE_ERROR @@ -72,7 +72,7 @@ Result = KDF_DERIVE_ERROR Title = HKDF tests (from RFC5869 test vectors) KDF = HKDF -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b Ctrl.salt = hexsalt:000102030405060708090a0b0c Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9 @@ -80,20 +80,20 @@ Output = 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf3400720 KDF = HKDF Ctrl.mode = mode:EXTRACT_ONLY -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b Ctrl.salt = hexsalt:000102030405060708090a0b0c Output = 077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5 KDF = HKDF Ctrl.mode = mode:EXPAND_ONLY -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5 Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9 Output = 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865 KDF = HKDF -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f Ctrl.salt = hexsalt:606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff @@ -101,20 +101,20 @@ Output = b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a9 KDF = HKDF Ctrl.mode = mode:EXTRACT_ONLY -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f Ctrl.salt = hexsalt:606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf Output = 06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244 KDF = HKDF Ctrl.mode = mode:EXPAND_ONLY -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244 Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff Output = b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87 KDF = HKDF -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b Ctrl.salt = salt: Ctrl.info = info: @@ -122,7 +122,7 @@ Output = 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d20139 KDF = HKDF Ctrl.mode = mode:EXTRACT_ONLY -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b Ctrl.salt = salt: Ctrl.info = info: @@ -130,13 +130,13 @@ Output = 19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04 KDF = HKDF Ctrl.mode = mode:EXPAND_ONLY -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04 Ctrl.info = info: Output = 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8 KDF = HKDF -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b Ctrl.salt = hexsalt:000102030405060708090a0b0c Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9 @@ -144,20 +144,20 @@ Output = 085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422 KDF = HKDF Ctrl.mode = mode:EXTRACT_ONLY -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b Ctrl.salt = hexsalt:000102030405060708090a0b0c Output = 9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243 KDF = HKDF Ctrl.mode = mode:EXPAND_ONLY -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243 Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9 Output = 085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896 KDF = HKDF -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f Ctrl.salt = hexsalt:606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff @@ -165,20 +165,20 @@ Output = 0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a KDF = HKDF Ctrl.mode = mode:EXTRACT_ONLY -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f Ctrl.salt = hexsalt:606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf Output = 8adae09a2a307059478d309b26c4115a224cfaf6 KDF = HKDF Ctrl.mode = mode:EXPAND_ONLY -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:8adae09a2a307059478d309b26c4115a224cfaf6 Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff Output = 0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4 KDF = HKDF -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b Ctrl.salt = salt: Ctrl.info = info: @@ -186,20 +186,20 @@ Output = 0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033 KDF = HKDF Ctrl.mode = mode:EXTRACT_ONLY -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b Ctrl.salt = salt: Output = da8c8a73c7fa77288ec6f5e7c297786aa0d32d01 KDF = HKDF Ctrl.mode = mode:EXPAND_ONLY -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:da8c8a73c7fa77288ec6f5e7c297786aa0d32d01 Ctrl.info = info: Output = 0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918 KDF = HKDF -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c Ctrl.salt = salt: Ctrl.info = info: @@ -207,14 +207,14 @@ Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081 KDF = HKDF Ctrl.mode = mode:EXTRACT_ONLY -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c Ctrl.salt = salt: Output = 2adccada18779e7c2077ad2eb19d3f3e731385dd KDF = HKDF Ctrl.mode = mode:EXPAND_ONLY -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:2adccada18779e7c2077ad2eb19d3f3e731385dd Ctrl.info = info: Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 @@ -227,27 +227,27 @@ Output = 00 Result = KDF_DERIVE_ERROR KDF = HKDF -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.salt = salt: Ctrl.info = info: Output = 00 Result = KDF_DERIVE_ERROR KDF = HKDF -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c Ctrl.info = info: Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 KDF = HKDF -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c Ctrl.salt = salt: Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 KDF = HKDF Ctrl.mode = mode:EXTRACT_AND_EXPAND -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c Ctrl.salt = salt: Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 @@ -303,3 +303,133 @@ Ctrl.r = r:8 Ctrl.p = p:1 Result = INTERNAL_ERROR +Title = PBKDF2 tests + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:1 +Ctrl.digest = digest:sha1 +Output = 0c60c80f961f0e71f3a9b524af6012062fe037a6 + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:1 +Ctrl.digest = digest:sha256 +Output = 120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:1 +Ctrl.digest = digest:sha512 +Output = 867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d470a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:2 +Ctrl.digest = digest:sha1 +Output = ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957 + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:2 +Ctrl.digest = digest:sha256 +Output = ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43 + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:2 +Ctrl.digest = digest:sha512 +Output = e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha1 +Output = 4b007901b765489abead49d926f721d065a429c1 + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha256 +Output = c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha512 +Output = d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f87f6902e072f457b5143f30602641b3d55cd335988cb36b84376060ecd532e039b742a239434af2d5 + +KDF = PBKDF2 +Ctrl.pass = pass:passwordPASSWORDpassword +Ctrl.salt = salt:saltSALTsaltSALTsaltSALTsaltSALTsalt +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha1 +Output = 3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038 + +KDF = PBKDF2 +Ctrl.pass = pass:passwordPASSWORDpassword +Ctrl.salt = salt:saltSALTsaltSALTsaltSALTsaltSALTsalt +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha256 +Output = 348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1c635518c7dac47e9 + +KDF = PBKDF2 +Ctrl.pass = pass:passwordPASSWORDpassword +Ctrl.salt = salt:saltSALTsaltSALTsaltSALTsaltSALTsalt +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha512 +Output = 8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30225c583a186cd82bd4daea9724a3d3b8 + +KDF = PBKDF2 +Ctrl.hexpass = hexpass:7061737300776f7264 +Ctrl.hexsalt = hexsalt:7361006c74 +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha1 +Output = 56fa6aa75548099dcc37d7f03425e0c3 + +KDF = PBKDF2 +Ctrl.hexpass = hexpass:7061737300776f7264 +Ctrl.hexsalt = hexsalt:7361006c74 +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha256 +Output = 89b69d0516f829893c696226650a8687 + +KDF = PBKDF2 +Ctrl.hexpass = hexpass:7061737300776f7264 +Ctrl.hexsalt = hexsalt:7361006c74 +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha512 +Output = 9d9e9c4cd21fe4be24d5b8244c759665 + +Title = PBKDF2 tests for empty inputs + +KDF = PBKDF2 +Ctrl.pass = pass: +Ctrl.salt = salt:salt +Ctrl.iter = iter:1 +Ctrl.digest = digest:sha1 +Output = a33dddc30478185515311f8752895d36ea4363a2 + +KDF = PBKDF2 +Ctrl.pass = pass: +Ctrl.salt = salt:salt +Ctrl.iter = iter:1 +Ctrl.digest = digest:sha256 +Output = f135c27993baf98773c5cdb40a5706ce6a345cde + +KDF = PBKDF2 +Ctrl.pass = pass: +Ctrl.salt = salt:salt +Ctrl.iter = iter:1 +Ctrl.digest = digest:sha512 +Output = 00ef42cdbfc98d29db20976608e455567fdddf14 + diff --git a/test/recipes/30-test_evp_data/evppkey_kdf.txt b/test/recipes/30-test_evp_data/evppkey_kdf.txt new file mode 100644 index 00000000..c619efdc --- /dev/null +++ b/test/recipes/30-test_evp_data/evppkey_kdf.txt @@ -0,0 +1,305 @@ +# +# Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# Tests start with one of these keywords +# Cipher Decrypt Derive Digest Encoding KDF PKEYKDF MAC PBE +# PrivPubKeyPair Sign Verify VerifyRecover +# and continue until a blank line. Lines starting with a pound sign, +# like this prolog, are ignored. + +Title = TLS1 PRF tests (from NIST test vectors) + +PKEYKDF=TLS1-PRF +Ctrl.md = md:MD5-SHA1 +Ctrl.Secret = hexsecret:bded7fa5c1699c010be23dd06ada3a48349f21e5f86263d512c0c5cc379f0e780ec55d9844b2f1db02a96453513568d0 +Ctrl.label = seed:master secret +Ctrl.client_random = hexseed:e5acaf549cd25c22d964c0d930fa4b5261d2507fad84c33715b7b9a864020693 +Ctrl.server_random = hexseed:135e4d557fdf3aa6406d82975d5c606a9734c9334b42136e96990fbd5358cdb2 +Output = 2f6962dfbc744c4b2138bb6b3d33054c5ecc14f24851d9896395a44ab3964efc2090c5bf51a0891209f46c1e1e998f62 + +PKEYKDF=TLS1-PRF +Ctrl.md = md:MD5-SHA1 +Ctrl.Secret = hexsecret:2f6962dfbc744c4b2138bb6b3d33054c5ecc14f24851d9896395a44ab3964efc2090c5bf51a0891209f46c1e1e998f62 +Ctrl.label = seed:key expansion +Ctrl.server_random = hexseed:67267e650eb32444119d222a368c191af3082888dc35afe8368e638c828874be +Ctrl.client_random = hexseed:d58a7b1cd4fedaa232159df652ce188f9d997e061b9bf48e83b62990440931f6 +Output = 3088825988e77fce68d19f756e18e43eb7fe672433504feaf99b3c503d9091b164f166db301d70c9fc0870b4a94563907bee1a61fb786cb717576890bcc51cb9ead97e01d0a2fea99c953377b195205ff07b369589178796edc963fd80fdbe518a2fc1c35c18ae8d + +PKEYKDF=TLS1-PRF +Ctrl.md = md:SHA256 +Ctrl.Secret = hexsecret:f8938ecc9edebc5030c0c6a441e213cd24e6f770a50dda07876f8d55da062bcadb386b411fd4fe4313a604fce6c17fbc +Ctrl.label = seed:master secret +Ctrl.client_random = hexseed:36c129d01a3200894b9179faac589d9835d58775f9b5ea3587cb8fd0364cae8c +Ctrl.server_random = hexseed:f6c9575ed7ddd73e1f7d16eca115415812a43c2b747daaaae043abfb50053fce +Output = 202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf + +PKEYKDF=TLS1-PRF +Ctrl.md = md:SHA256 +Ctrl.Secret = hexsecret:202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf +Ctrl.label = seed:key expansion +Ctrl.server_random = hexseed:ae6c806f8ad4d80784549dff28a4b58fd837681a51d928c3e30ee5ff14f39868 +Ctrl.client_random = hexseed:62e1fd91f23f558a605f28478c58cf72637b89784d959df7e946d3f07bd1b616 +Output = d06139889fffac1e3a71865f504aa5d0d2a2e89506c6f2279b670c3e1b74f531016a2530c51a3a0f7e1d6590d0f0566b2f387f8d11fd4f731cdd572d2eae927f6f2f81410b25e6960be68985add6c38445ad9f8c64bf8068bf9a6679485d966f1ad6f68b43495b10a683755ea2b858d70ccac7ec8b053c6bd41ca299d4e51928 + +# As above but use long name for KDF +PKEYKDF=tls1-prf +Ctrl.md = md:SHA256 +Ctrl.Secret = hexsecret:202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf +Ctrl.label = seed:key expansion +Ctrl.server_random = hexseed:ae6c806f8ad4d80784549dff28a4b58fd837681a51d928c3e30ee5ff14f39868 +Ctrl.client_random = hexseed:62e1fd91f23f558a605f28478c58cf72637b89784d959df7e946d3f07bd1b616 +Output = d06139889fffac1e3a71865f504aa5d0d2a2e89506c6f2279b670c3e1b74f531016a2530c51a3a0f7e1d6590d0f0566b2f387f8d11fd4f731cdd572d2eae927f6f2f81410b25e6960be68985add6c38445ad9f8c64bf8068bf9a6679485d966f1ad6f68b43495b10a683755ea2b858d70ccac7ec8b053c6bd41ca299d4e51928 + +# Missing digest. +PKEYKDF=TLS1-PRF +Ctrl.Secret = hexsecret:01 +Ctrl.Seed = hexseed:02 +Output = 03 +Result = KDF_DERIVE_ERROR + +# Missing secret. +PKEYKDF=TLS1-PRF +Ctrl.md = md:MD5-SHA1 +Ctrl.Seed = hexseed:02 +Output = 03 +Result = KDF_DERIVE_ERROR + +Title = HKDF tests (from RFC5869 test vectors) + +PKEYKDF = HKDF +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b +Ctrl.salt = hexsalt:000102030405060708090a0b0c +Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9 +Output = 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXTRACT_ONLY +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b +Ctrl.salt = hexsalt:000102030405060708090a0b0c +Output = 077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXPAND_ONLY +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5 +Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9 +Output = 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865 + +PKEYKDF = HKDF +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f +Ctrl.salt = hexsalt:606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf +Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff +Output = b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXTRACT_ONLY +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f +Ctrl.salt = hexsalt:606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf +Output = 06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXPAND_ONLY +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244 +Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff +Output = b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87 + +PKEYKDF = HKDF +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b +Ctrl.salt = salt: +Ctrl.info = info: +Output = 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXTRACT_ONLY +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b +Ctrl.salt = salt: +Ctrl.info = info: +Output = 19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXPAND_ONLY +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04 +Ctrl.info = info: +Output = 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8 + +PKEYKDF = HKDF +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b +Ctrl.salt = hexsalt:000102030405060708090a0b0c +Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9 +Output = 085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXTRACT_ONLY +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b +Ctrl.salt = hexsalt:000102030405060708090a0b0c +Output = 9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXPAND_ONLY +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243 +Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9 +Output = 085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896 + +PKEYKDF = HKDF +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f +Ctrl.salt = hexsalt:606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf +Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff +Output = 0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXTRACT_ONLY +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f +Ctrl.salt = hexsalt:606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf +Output = 8adae09a2a307059478d309b26c4115a224cfaf6 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXPAND_ONLY +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:8adae09a2a307059478d309b26c4115a224cfaf6 +Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff +Output = 0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4 + +PKEYKDF = HKDF +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b +Ctrl.salt = salt: +Ctrl.info = info: +Output = 0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXTRACT_ONLY +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b +Ctrl.salt = salt: +Output = da8c8a73c7fa77288ec6f5e7c297786aa0d32d01 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXPAND_ONLY +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:da8c8a73c7fa77288ec6f5e7c297786aa0d32d01 +Ctrl.info = info: +Output = 0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918 + +PKEYKDF = HKDF +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c +Ctrl.salt = salt: +Ctrl.info = info: +Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXTRACT_ONLY +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c +Ctrl.salt = salt: +Output = 2adccada18779e7c2077ad2eb19d3f3e731385dd + +PKEYKDF = HKDF +Ctrl.mode = mode:EXPAND_ONLY +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:2adccada18779e7c2077ad2eb19d3f3e731385dd +Ctrl.info = info: +Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 + +PKEYKDF = HKDF +Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c +Ctrl.salt = salt: +Ctrl.info = info: +Output = 00 +Result = KDF_DERIVE_ERROR + +PKEYKDF = HKDF +Ctrl.md = md:SHA1 +Ctrl.salt = salt: +Ctrl.info = info: +Output = 00 +Result = KDF_DERIVE_ERROR + +PKEYKDF = HKDF +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c +Ctrl.info = info: +Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 + +PKEYKDF = HKDF +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c +Ctrl.salt = salt: +Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXTRACT_AND_EXPAND +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c +Ctrl.salt = salt: +Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 + +Title = id-scrypt tests (from draft-josefsson-id-scrypt-kdf-03 and others) + +PKEYKDF = scrypt +Ctrl.pass = pass: +Ctrl.salt = salt: +Ctrl.N = N:16 +Ctrl.r = r:1 +Ctrl.p = p:1 +Output = 77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906 + +PKEYKDF = scrypt +Ctrl.pass = pass:password +Ctrl.salt = salt:NaCl +Ctrl.N = N:1024 +Ctrl.r = r:8 +Ctrl.p = p:16 +Output = fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640 + +PKEYKDF = scrypt +Ctrl.hexpass = hexpass:70617373776f7264 +Ctrl.salt = salt:NaCl +Ctrl.N = N:1024 +Ctrl.r = r:8 +Ctrl.p = p:16 +Output = fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640 + +PKEYKDF = scrypt +Ctrl.pass = pass:password +Ctrl.hexsalt = hexsalt:4e61436c +Ctrl.N = N:1024 +Ctrl.r = r:8 +Ctrl.p = p:16 +Output = fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640 + +PKEYKDF = scrypt +Ctrl.pass = pass:pleaseletmein +Ctrl.salt = salt:SodiumChloride +Ctrl.N = N:16384 +Ctrl.r = r:8 +Ctrl.p = p:1 +Output = 7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887 + +# Out of memory +PKEYKDF = scrypt +Ctrl.pass = pass:pleaseletmein +Ctrl.salt = salt:SodiumChloride +Ctrl.N = N:1048576 +Ctrl.r = r:8 +Ctrl.p = p:1 +Result = INTERNAL_ERROR + diff --git a/test/recipes/30-test_evp_kdf.t b/test/recipes/30-test_evp_kdf.t new file mode 100644 index 00000000..9e43d6d2 --- /dev/null +++ b/test/recipes/30-test_evp_kdf.t @@ -0,0 +1,13 @@ +#! /usr/bin/env perl +# Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. +# Copyright (c) 2018, 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 + + +use OpenSSL::Test::Simple; + +simple_test("test_evp_kdf", "evp_kdf_test"); diff --git a/test/recipes/70-test_sslrecords.t b/test/recipes/70-test_sslrecords.t index 0e38308f..b0ad0261 100644 --- a/test/recipes/70-test_sslrecords.t +++ b/test/recipes/70-test_sslrecords.t @@ -44,7 +44,7 @@ my $content_type = TLSProxy::Record::RT_APPLICATION_DATA; my $inject_recs_num = 1; $proxy->serverflags("-tls1_2"); $proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 18; +plan tests => 20; ok($fatal_alert, "Out of context empty records test"); #Test 2: Injecting in context empty records should succeed @@ -155,7 +155,7 @@ ok($fatal_alert, "Changed record version in TLS1.2"); #TLS1.3 specific tests SKIP: { - skip "TLSv1.3 disabled", 6 if disabled("tls1_3"); + skip "TLSv1.3 disabled", 8 if disabled("tls1_3"); #Test 13: Sending a different record version in TLS1.3 should fail $proxy->clear(); @@ -181,7 +181,9 @@ SKIP: { use constant { DATA_AFTER_SERVER_HELLO => 0, DATA_AFTER_FINISHED => 1, - DATA_AFTER_KEY_UPDATE => 2 + DATA_AFTER_KEY_UPDATE => 2, + DATA_BETWEEN_KEY_UPDATE => 3, + NO_DATA_BETWEEN_KEY_UPDATE => 4, }; #Test 16: Sending a ServerHello which doesn't end on a record boundary @@ -198,7 +200,6 @@ SKIP: { $fatal_alert = 0; $proxy->clear(); $boundary_test_type = DATA_AFTER_FINISHED; - $proxy->filter(\¬_on_record_boundary); $proxy->start(); ok($fatal_alert, "Record not on boundary in TLS1.3 (Finished)"); @@ -207,9 +208,24 @@ SKIP: { $fatal_alert = 0; $proxy->clear(); $boundary_test_type = DATA_AFTER_KEY_UPDATE; - $proxy->filter(\¬_on_record_boundary); $proxy->start(); ok($fatal_alert, "Record not on boundary in TLS1.3 (KeyUpdate)"); + + #Test 19: Sending application data in the middle of a fragmented KeyUpdate + # should fail. Strictly speaking this is not a record boundary test + # but we use the same filter. + $fatal_alert = 0; + $proxy->clear(); + $boundary_test_type = DATA_BETWEEN_KEY_UPDATE; + $proxy->start(); + ok($fatal_alert, "Data between KeyUpdate"); + + #Test 20: Fragmented KeyUpdate. This should succeed. Strictly speaking this + # is not a record boundary test but we use the same filter. + $proxy->clear(); + $boundary_test_type = NO_DATA_BETWEEN_KEY_UPDATE; + $proxy->start(); + ok(TLSProxy::Message->success(), "No data between KeyUpdate"); } @@ -573,7 +589,7 @@ sub not_on_record_boundary #Update the record $last_record->data($data); $last_record->len(length $data); - } else { + } elsif ($boundary_test_type == DATA_AFTER_KEY_UPDATE) { return if @{$proxy->{message_list}}[-1]->{mt} != TLSProxy::Message::MT_FINISHED; @@ -605,5 +621,79 @@ sub not_on_record_boundary $record->data($data); $record->len(length $data); push @{$records}, $record; + } else { + return if @{$proxy->{message_list}}[-1]->{mt} + != TLSProxy::Message::MT_FINISHED; + + my $record = TLSProxy::Record->new( + 1, + TLSProxy::Record::RT_APPLICATION_DATA, + TLSProxy::Record::VERS_TLS_1_2, + 0, + 0, + 0, + 0, + "", + "" + ); + + #Add a partial KeyUpdate message into the record + $data = pack "C1", + 0x18; # KeyUpdate message type. Omit the rest of the message header + + #Add content type and tag + $data .= pack("C", TLSProxy::Record::RT_HANDSHAKE).("\0"x16); + + $record->data($data); + $record->len(length $data); + push @{$records}, $record; + + if ($boundary_test_type == DATA_BETWEEN_KEY_UPDATE) { + #Now add an app data record + $record = TLSProxy::Record->new( + 1, + TLSProxy::Record::RT_APPLICATION_DATA, + TLSProxy::Record::VERS_TLS_1_2, + 0, + 0, + 0, + 0, + "", + "" + ); + + #Add an empty app data record (just content type and tag) + $data = pack("C", TLSProxy::Record::RT_APPLICATION_DATA).("\0"x16); + + $record->data($data); + $record->len(length $data); + push @{$records}, $record; + } + + #Now add the rest of the KeyUpdate message + $record = TLSProxy::Record->new( + 1, + TLSProxy::Record::RT_APPLICATION_DATA, + TLSProxy::Record::VERS_TLS_1_2, + 0, + 0, + 0, + 0, + "", + "" + ); + + #Add the last 4 bytes of the KeyUpdate record + $data = pack "C4", + 0x00, 0x00, 0x01, # Message length + 0x00; # Update not requested + + #Add content type and tag + $data .= pack("C", TLSProxy::Record::RT_HANDSHAKE).("\0"x16); + + $record->data($data); + $record->len(length $data); + push @{$records}, $record; + } } diff --git a/test/recipes/80-test_ssl_new.t b/test/recipes/80-test_ssl_new.t index fa98f24b..31c4399d 100644 --- a/test/recipes/80-test_ssl_new.t +++ b/test/recipes/80-test_ssl_new.t @@ -28,7 +28,7 @@ map { s/\^// } @conf_files if $^O eq "VMS"; # We hard-code the number of tests to double-check that the globbing above # finds all files as expected. -plan tests => 29; # = scalar @conf_srcs +plan tests => 30; # = scalar @conf_srcs # Some test results depend on the configuration of enabled protocols. We only # verify generated sources in the default configuration. @@ -70,6 +70,7 @@ my %conf_dependent_tests = ( "25-cipher.conf" => disabled("poly1305") || disabled("chacha"), "27-ticket-appdata.conf" => !$is_default_tls, "28-seclevel.conf" => disabled("tls1_2") || $no_ec, + "30-extended-master-secret.conf" => disabled("tls1_2"), ); # Add your test here if it should be skipped for some compile-time diff --git a/test/sparse_array_test.c b/test/sparse_array_test.c new file mode 100644 index 00000000..02ce0d1e --- /dev/null +++ b/test/sparse_array_test.c @@ -0,0 +1,198 @@ +/* + * 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 + */ + +#include +#include +#include + +#include +#include + +#include "internal/sparse_array.h" +#include "testutil.h" + +/* The macros below generate unused functions which error out one of the clang + * builds. We disable this check here. + */ +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wunused-function" +#endif + +DEFINE_SPARSE_ARRAY_OF(char); + +static int test_sparse_array(void) +{ + static const struct { + size_t n; + char *v; + } cases[] = { + { 22, "a" }, { 0, "z" }, { 1, "b" }, { 290, "c" }, + { INT_MAX, "m" }, { 6666666, "d" }, { (size_t)-1, "H" }, + { 99, "e" } + }; + SPARSE_ARRAY_OF(char) *sa; + size_t i, j; + int res = 0; + + if (!TEST_ptr(sa = ossl_sa_char_new()) + || !TEST_ptr_null(ossl_sa_char_get(sa, 3)) + || !TEST_ptr_null(ossl_sa_char_get(sa, 0)) + || !TEST_ptr_null(ossl_sa_char_get(sa, UINT_MAX))) + goto err; + + for (i = 0; i < OSSL_NELEM(cases); i++) { + if (!TEST_true(ossl_sa_char_set(sa, cases[i].n, cases[i].v))) { + TEST_note("iteration %zu", i + 1); + goto err; + } + for (j = 0; j <= i; j++) + if (!TEST_str_eq(ossl_sa_char_get(sa, cases[j].n), cases[j].v)) { + TEST_note("iteration %zu / %zu", i + 1, j + 1); + goto err; + } + } + + res = 1; +err: + ossl_sa_char_free(sa); + return res; +} + +static int test_sparse_array_num(void) +{ + static const struct { + size_t num; + size_t n; + char *v; + } cases[] = { + { 1, 22, "a" }, { 2, 1021, "b" }, { 3, 3, "c" }, { 2, 22, NULL }, + { 2, 3, "d" }, { 3, 22, "e" }, { 3, 666, NULL }, { 4, 666, "f" }, + { 3, 3, NULL }, { 2, 22, NULL }, { 1, 666, NULL }, { 2, 64000, "g" }, + { 1, 1021, NULL }, { 0, 64000, NULL }, { 1, 23, "h" }, { 0, 23, NULL } + }; + SPARSE_ARRAY_OF(char) *sa = NULL; + size_t i; + int res = 0; + + if (!TEST_size_t_eq(ossl_sa_char_num(NULL), 0) + || !TEST_ptr(sa = ossl_sa_char_new()) + || !TEST_size_t_eq(ossl_sa_char_num(sa), 0)) + goto err; + for (i = 0; i < OSSL_NELEM(cases); i++) + if (!TEST_true(ossl_sa_char_set(sa, cases[i].n, cases[i].v)) + || !TEST_size_t_eq(ossl_sa_char_num(sa), cases[i].num)) + goto err; + res = 1; +err: + ossl_sa_char_free(sa); + return res; +} + +struct index_cases_st { + size_t n; + char *v; + int del; +}; + +struct doall_st { + SPARSE_ARRAY_OF(char) *sa; + size_t num_cases; + const struct index_cases_st *cases; + int res; + int all; +}; + +static void leaf_check_all(size_t n, char *value, void *arg) +{ + struct doall_st *doall_data = (struct doall_st *)arg; + const struct index_cases_st *cases = doall_data->cases; + size_t i; + + doall_data->res = 0; + for (i = 0; i < doall_data->num_cases; i++) + if ((doall_data->all || !cases[i].del) + && n == cases[i].n && strcmp(value, cases[i].v) == 0) { + doall_data->res = 1; + return; + } + TEST_error("Index %zu with value %s not found", n, value); +} + +static void leaf_delete(size_t n, char *value, void *arg) +{ + struct doall_st *doall_data = (struct doall_st *)arg; + const struct index_cases_st *cases = doall_data->cases; + size_t i; + + doall_data->res = 0; + for (i = 0; i < doall_data->num_cases; i++) + if (n == cases[i].n && strcmp(value, cases[i].v) == 0) { + doall_data->res = 1; + ossl_sa_char_set(doall_data->sa, n, NULL); + return; + } + TEST_error("Index %zu with value %s not found", n, value); +} + +static int test_sparse_array_doall(void) +{ + static const struct index_cases_st cases[] = { + { 22, "A", 1 }, { 1021, "b", 0 }, { 3, "c", 0 }, { INT_MAX, "d", 1 }, + { (size_t)-1, "H", 0 }, { (size_t)-2, "i", 1 }, { 666666666, "s", 1 }, + { 1234567890, "t", 0 }, + }; + struct doall_st doall_data; + size_t i; + SPARSE_ARRAY_OF(char) *sa = NULL; + int res = 0; + + if (!TEST_ptr(sa = ossl_sa_char_new())) + goto err; + doall_data.num_cases = OSSL_NELEM(cases); + doall_data.cases = cases; + doall_data.all = 1; + doall_data.sa = NULL; + for (i = 0; i < OSSL_NELEM(cases); i++) + if (!TEST_true(ossl_sa_char_set(sa, cases[i].n, cases[i].v))) { + TEST_note("failed at iteration %zu", i + 1); + goto err; + } + + ossl_sa_char_doall_arg(sa, &leaf_check_all, &doall_data); + if (doall_data.res == 0) { + TEST_info("while checking all elements"); + goto err; + } + doall_data.all = 0; + doall_data.sa = sa; + ossl_sa_char_doall_arg(sa, &leaf_delete, &doall_data); + if (doall_data.res == 0) { + TEST_info("while deleting selected elements"); + goto err; + } + ossl_sa_char_doall_arg(sa, &leaf_check_all, &doall_data); + if (doall_data.res == 0) { + TEST_info("while checking for deleted elements"); + goto err; + } + res = 1; + +err: + ossl_sa_char_free(sa); + return res; +} + +int setup_tests(void) +{ + ADD_TEST(test_sparse_array); + ADD_TEST(test_sparse_array_num); + ADD_TEST(test_sparse_array_doall); + return 1; +} diff --git a/test/ssl-tests/16-certstatus.conf b/test/ssl-tests/16-certstatus.conf deleted file mode 100644 index e69de29b..00000000 diff --git a/test/ssl-tests/30-extended-master-secret.conf b/test/ssl-tests/30-extended-master-secret.conf new file mode 100644 index 00000000..9dae431d --- /dev/null +++ b/test/ssl-tests/30-extended-master-secret.conf @@ -0,0 +1,203 @@ +# Generated with generate_ssl_tests.pl + +num_tests = 7 + +test-0 = 0-disable-extended-master-secret-server-sha +test-1 = 1-disable-extended-master-secret-client-sha +test-2 = 2-disable-extended-master-secret-both-sha +test-3 = 3-disable-extended-master-secret-both-resume +test-4 = 4-disable-extended-master-secret-server-sha2 +test-5 = 5-disable-extended-master-secret-client-sha2 +test-6 = 6-disable-extended-master-secret-both-sha2 +# =========================================================== + +[0-disable-extended-master-secret-server-sha] +ssl_conf = 0-disable-extended-master-secret-server-sha-ssl + +[0-disable-extended-master-secret-server-sha-ssl] +server = 0-disable-extended-master-secret-server-sha-server +client = 0-disable-extended-master-secret-server-sha-client + +[0-disable-extended-master-secret-server-sha-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +Options = -ExtendedMasterSecret +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[0-disable-extended-master-secret-server-sha-client] +CipherString = AES128-SHA +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-0] +ExpectedResult = Success + + +# =========================================================== + +[1-disable-extended-master-secret-client-sha] +ssl_conf = 1-disable-extended-master-secret-client-sha-ssl + +[1-disable-extended-master-secret-client-sha-ssl] +server = 1-disable-extended-master-secret-client-sha-server +client = 1-disable-extended-master-secret-client-sha-client + +[1-disable-extended-master-secret-client-sha-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[1-disable-extended-master-secret-client-sha-client] +CipherString = AES128-SHA +MaxProtocol = TLSv1.2 +Options = -ExtendedMasterSecret +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-1] +ExpectedResult = Success + + +# =========================================================== + +[2-disable-extended-master-secret-both-sha] +ssl_conf = 2-disable-extended-master-secret-both-sha-ssl + +[2-disable-extended-master-secret-both-sha-ssl] +server = 2-disable-extended-master-secret-both-sha-server +client = 2-disable-extended-master-secret-both-sha-client + +[2-disable-extended-master-secret-both-sha-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +Options = -ExtendedMasterSecret +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[2-disable-extended-master-secret-both-sha-client] +CipherString = AES128-SHA +MaxProtocol = TLSv1.2 +Options = -ExtendedMasterSecret +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-2] +ExpectedResult = Success + + +# =========================================================== + +[3-disable-extended-master-secret-both-resume] +ssl_conf = 3-disable-extended-master-secret-both-resume-ssl + +[3-disable-extended-master-secret-both-resume-ssl] +server = 3-disable-extended-master-secret-both-resume-server +client = 3-disable-extended-master-secret-both-resume-client +resume-server = 3-disable-extended-master-secret-both-resume-resume-server +resume-client = 3-disable-extended-master-secret-both-resume-resume-client + +[3-disable-extended-master-secret-both-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +Options = -ExtendedMasterSecret +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[3-disable-extended-master-secret-both-resume-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[3-disable-extended-master-secret-both-resume-client] +CipherString = AES128-SHA +MaxProtocol = TLSv1.2 +Options = -ExtendedMasterSecret +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[3-disable-extended-master-secret-both-resume-resume-client] +CipherString = AES128-SHA +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-3] +ExpectedResult = Success +HandshakeMode = Resume + + +# =========================================================== + +[4-disable-extended-master-secret-server-sha2] +ssl_conf = 4-disable-extended-master-secret-server-sha2-ssl + +[4-disable-extended-master-secret-server-sha2-ssl] +server = 4-disable-extended-master-secret-server-sha2-server +client = 4-disable-extended-master-secret-server-sha2-client + +[4-disable-extended-master-secret-server-sha2-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +Options = -ExtendedMasterSecret +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[4-disable-extended-master-secret-server-sha2-client] +CipherString = AES128-SHA256 +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-4] +ExpectedResult = Success + + +# =========================================================== + +[5-disable-extended-master-secret-client-sha2] +ssl_conf = 5-disable-extended-master-secret-client-sha2-ssl + +[5-disable-extended-master-secret-client-sha2-ssl] +server = 5-disable-extended-master-secret-client-sha2-server +client = 5-disable-extended-master-secret-client-sha2-client + +[5-disable-extended-master-secret-client-sha2-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[5-disable-extended-master-secret-client-sha2-client] +CipherString = AES128-SHA256 +MaxProtocol = TLSv1.2 +Options = -ExtendedMasterSecret +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-5] +ExpectedResult = Success + + +# =========================================================== + +[6-disable-extended-master-secret-both-sha2] +ssl_conf = 6-disable-extended-master-secret-both-sha2-ssl + +[6-disable-extended-master-secret-both-sha2-ssl] +server = 6-disable-extended-master-secret-both-sha2-server +client = 6-disable-extended-master-secret-both-sha2-client + +[6-disable-extended-master-secret-both-sha2-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +Options = -ExtendedMasterSecret +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[6-disable-extended-master-secret-both-sha2-client] +CipherString = AES128-SHA256 +MaxProtocol = TLSv1.2 +Options = -ExtendedMasterSecret +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-6] +ExpectedResult = Success + + diff --git a/test/ssl-tests/30-extended-master-secret.conf.in b/test/ssl-tests/30-extended-master-secret.conf.in new file mode 100644 index 00000000..2386c98a --- /dev/null +++ b/test/ssl-tests/30-extended-master-secret.conf.in @@ -0,0 +1,122 @@ +# -*- mode: perl; -*- +# Copyright 2016-2016 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the OpenSSL license (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + + +## SSL test configurations + +package ssltests; + +use OpenSSL::Test::Utils; + +our @tests = (); + +my @tests_tls1_2 = ( + { + name => "disable-extended-master-secret-server-sha", + server => { + "Options" => "-ExtendedMasterSecret", + }, + client => { + "CipherString" => "AES128-SHA", + "MaxProtocol" => "TLSv1.2" + }, + test => { + "ExpectedResult" => "Success", + }, + }, + { + name => "disable-extended-master-secret-client-sha", + server => { + }, + client => { + "CipherString" => "AES128-SHA", + "Options" => "-ExtendedMasterSecret", + "MaxProtocol" => "TLSv1.2" + }, + test => { + "ExpectedResult" => "Success", + }, + }, + { + name => "disable-extended-master-secret-both-sha", + server => { + "Options" => "-ExtendedMasterSecret", + }, + client => { + "CipherString" => "AES128-SHA", + "Options" => "-ExtendedMasterSecret", + "MaxProtocol" => "TLSv1.2" + }, + test => { + "ExpectedResult" => "Success", + }, + }, + { + name => "disable-extended-master-secret-both-resume", + server => { + "Options" => "-ExtendedMasterSecret", + }, + resume_server => { + }, + client => { + "CipherString" => "AES128-SHA", + "Options" => "-ExtendedMasterSecret", + "MaxProtocol" => "TLSv1.2" + }, + resume_client => { + "CipherString" => "AES128-SHA", + "MaxProtocol" => "TLSv1.2" + }, + test => { + "HandshakeMode" => "Resume", + "ExpectedResult" => "Success", + }, + }, + { + name => "disable-extended-master-secret-server-sha2", + server => { + "Options" => "-ExtendedMasterSecret", + }, + client => { + "CipherString" => "AES128-SHA256", + "MaxProtocol" => "TLSv1.2" + }, + test => { + "ExpectedResult" => "Success", + }, + }, + { + name => "disable-extended-master-secret-client-sha2", + server => { + }, + client => { + "CipherString" => "AES128-SHA256", + "Options" => "-ExtendedMasterSecret", + "MaxProtocol" => "TLSv1.2" + }, + test => { + "ExpectedResult" => "Success", + }, + }, + { + name => "disable-extended-master-secret-both-sha2", + server => { + "Options" => "-ExtendedMasterSecret", + }, + client => { + "CipherString" => "AES128-SHA256", + "Options" => "-ExtendedMasterSecret", + "MaxProtocol" => "TLSv1.2" + }, + test => { + "ExpectedResult" => "Success", + }, + }, +); + +push @tests, @tests_tls1_2 unless disabled("tls1_2"); diff --git a/test/sslapitest.c b/test/sslapitest.c index 6b44c160..788ac460 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -571,6 +571,51 @@ static int test_client_hello_cb(void) testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} + +static int test_no_ems(void) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + + if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), + TLS1_VERSION, TLS1_2_VERSION, + &sctx, &cctx, cert, privkey)) { + printf("Unable to create SSL_CTX pair\n"); + goto end; + } + + SSL_CTX_set_options(sctx, SSL_OP_NO_EXTENDED_MASTER_SECRET); + + if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) { + printf("Unable to create SSL objects\n"); + goto end; + } + + if (!create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)) { + printf("Creating SSL connection failed\n"); + goto end; + } + + if (SSL_get_extms_support(serverssl)) { + printf("Server reports Extended Master Secret support\n"); + goto end; + } + + if (SSL_get_extms_support(clientssl)) { + printf("Client reports Extended Master Secret support\n"); + goto end; + } + testresult = 1; + end: SSL_free(serverssl); SSL_free(clientssl); @@ -4919,18 +4964,14 @@ static struct info_cb_states_st { {SSL_CB_LOOP, "TWCCS"}, {SSL_CB_LOOP, "TWEE"}, {SSL_CB_LOOP, "TWSC"}, {SSL_CB_LOOP, "TRSCV"}, {SSL_CB_LOOP, "TWFIN"}, {SSL_CB_LOOP, "TED"}, {SSL_CB_EXIT, NULL}, {SSL_CB_LOOP, "TED"}, {SSL_CB_LOOP, "TRFIN"}, - {SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_HANDSHAKE_START, NULL}, - {SSL_CB_LOOP, "TWST"}, {SSL_CB_HANDSHAKE_DONE, NULL}, - {SSL_CB_HANDSHAKE_START, NULL}, {SSL_CB_LOOP, "TWST"}, - {SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_EXIT, NULL}, - {SSL_CB_ALERT, NULL}, {SSL_CB_HANDSHAKE_START, NULL}, - {SSL_CB_LOOP, "PINIT "}, {SSL_CB_LOOP, "PINIT "}, {SSL_CB_LOOP, "TRCH"}, - {SSL_CB_LOOP, "TWSH"}, {SSL_CB_LOOP, "TWCCS"}, {SSL_CB_LOOP, "TWEE"}, - {SSL_CB_LOOP, "TWFIN"}, {SSL_CB_LOOP, "TED"}, {SSL_CB_EXIT, NULL}, - {SSL_CB_LOOP, "TED"}, {SSL_CB_LOOP, "TRFIN"}, - {SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_HANDSHAKE_START, NULL}, - {SSL_CB_LOOP, "TWST"}, {SSL_CB_HANDSHAKE_DONE, NULL}, - {SSL_CB_EXIT, NULL}, {0, NULL}, + {SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_LOOP, "TWST"}, + {SSL_CB_LOOP, "TWST"}, {SSL_CB_EXIT, NULL}, {SSL_CB_ALERT, NULL}, + {SSL_CB_HANDSHAKE_START, NULL}, {SSL_CB_LOOP, "PINIT "}, + {SSL_CB_LOOP, "PINIT "}, {SSL_CB_LOOP, "TRCH"}, {SSL_CB_LOOP, "TWSH"}, + {SSL_CB_LOOP, "TWCCS"}, {SSL_CB_LOOP, "TWEE"}, {SSL_CB_LOOP, "TWFIN"}, + {SSL_CB_LOOP, "TED"}, {SSL_CB_EXIT, NULL}, {SSL_CB_LOOP, "TED"}, + {SSL_CB_LOOP, "TRFIN"}, {SSL_CB_HANDSHAKE_DONE, NULL}, + {SSL_CB_LOOP, "TWST"}, {SSL_CB_EXIT, NULL}, {0, NULL}, }, { /* TLSv1.3 client followed by resumption */ {SSL_CB_HANDSHAKE_START, NULL}, {SSL_CB_LOOP, "PINIT "}, @@ -4938,20 +4979,16 @@ static struct info_cb_states_st { {SSL_CB_LOOP, "TRSH"}, {SSL_CB_LOOP, "TREE"}, {SSL_CB_LOOP, "TRSC"}, {SSL_CB_LOOP, "TRSCV"}, {SSL_CB_LOOP, "TRFIN"}, {SSL_CB_LOOP, "TWCCS"}, {SSL_CB_LOOP, "TWFIN"}, {SSL_CB_HANDSHAKE_DONE, NULL}, - {SSL_CB_EXIT, NULL}, {SSL_CB_HANDSHAKE_START, NULL}, - {SSL_CB_LOOP, "SSLOK "}, {SSL_CB_LOOP, "SSLOK "}, {SSL_CB_LOOP, "TRST"}, - {SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_EXIT, NULL}, - {SSL_CB_HANDSHAKE_START, NULL}, {SSL_CB_LOOP, "SSLOK "}, - {SSL_CB_LOOP, "SSLOK "}, {SSL_CB_LOOP, "TRST"}, - {SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_EXIT, NULL}, + {SSL_CB_EXIT, NULL}, {SSL_CB_LOOP, "SSLOK "}, {SSL_CB_LOOP, "SSLOK "}, + {SSL_CB_LOOP, "TRST"}, {SSL_CB_EXIT, NULL}, {SSL_CB_LOOP, "SSLOK "}, + {SSL_CB_LOOP, "SSLOK "}, {SSL_CB_LOOP, "TRST"}, {SSL_CB_EXIT, NULL}, {SSL_CB_ALERT, NULL}, {SSL_CB_HANDSHAKE_START, NULL}, {SSL_CB_LOOP, "PINIT "}, {SSL_CB_LOOP, "TWCH"}, {SSL_CB_EXIT, NULL}, {SSL_CB_LOOP, "TWCH"}, {SSL_CB_LOOP, "TRSH"}, {SSL_CB_LOOP, "TREE"}, {SSL_CB_LOOP, "TRFIN"}, {SSL_CB_LOOP, "TWCCS"}, {SSL_CB_LOOP, "TWFIN"}, {SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_EXIT, NULL}, - {SSL_CB_HANDSHAKE_START, NULL}, {SSL_CB_LOOP, "SSLOK "}, - {SSL_CB_LOOP, "SSLOK "}, {SSL_CB_LOOP, "TRST"}, - {SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_EXIT, NULL}, {0, NULL}, + {SSL_CB_LOOP, "SSLOK "}, {SSL_CB_LOOP, "SSLOK "}, {SSL_CB_LOOP, "TRST"}, + {SSL_CB_EXIT, NULL}, {0, NULL}, }, { /* TLSv1.3 server, early_data */ {SSL_CB_HANDSHAKE_START, NULL}, {SSL_CB_LOOP, "PINIT "}, @@ -4960,8 +4997,7 @@ static struct info_cb_states_st { {SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_EXIT, NULL}, {SSL_CB_HANDSHAKE_START, NULL}, {SSL_CB_LOOP, "TED"}, {SSL_CB_LOOP, "TED"}, {SSL_CB_LOOP, "TWEOED"}, {SSL_CB_LOOP, "TRFIN"}, - {SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_HANDSHAKE_START, NULL}, - {SSL_CB_LOOP, "TWST"}, {SSL_CB_HANDSHAKE_DONE, NULL}, + {SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_LOOP, "TWST"}, {SSL_CB_EXIT, NULL}, {0, NULL}, }, { /* TLSv1.3 client, early_data */ @@ -4972,9 +5008,8 @@ static struct info_cb_states_st { {SSL_CB_LOOP, "TED"}, {SSL_CB_LOOP, "TRSH"}, {SSL_CB_LOOP, "TREE"}, {SSL_CB_LOOP, "TRFIN"}, {SSL_CB_LOOP, "TPEDE"}, {SSL_CB_LOOP, "TWEOED"}, {SSL_CB_LOOP, "TWFIN"}, {SSL_CB_HANDSHAKE_DONE, NULL}, - {SSL_CB_EXIT, NULL}, {SSL_CB_HANDSHAKE_START, NULL}, - {SSL_CB_LOOP, "SSLOK "}, {SSL_CB_LOOP, "SSLOK "}, {SSL_CB_LOOP, "TRST"}, - {SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_EXIT, NULL}, {0, NULL}, + {SSL_CB_EXIT, NULL}, {SSL_CB_LOOP, "SSLOK "}, {SSL_CB_LOOP, "SSLOK "}, + {SSL_CB_LOOP, "TRST"}, {SSL_CB_EXIT, NULL}, {0, NULL}, }, { {0, NULL}, } @@ -5013,8 +5048,11 @@ static void sslapi_info_callback(const SSL *s, int where, int ret) return; } - /* Check that, if we've got SSL_CB_HANDSHAKE_DONE we are not in init */ - if ((where & SSL_CB_HANDSHAKE_DONE) && SSL_in_init((SSL *)s) != 0) { + /* + * Check that, if we've got SSL_CB_HANDSHAKE_DONE we are not in init + */ + if ((where & SSL_CB_HANDSHAKE_DONE) + && SSL_in_init((SSL *)s) != 0) { info_cb_failed = 1; return; } @@ -6094,6 +6132,7 @@ int setup_tests(void) #endif #ifndef OPENSSL_NO_TLS1_2 ADD_TEST(test_client_hello_cb); + ADD_TEST(test_no_ems); #endif #ifndef OPENSSL_NO_TLS1_3 ADD_ALL_TESTS(test_early_data_read_write, 3); diff --git a/test/ssltest_old.c b/test/ssltest_old.c index f26bf851..390ca88b 100644 --- a/test/ssltest_old.c +++ b/test/ssltest_old.c @@ -1382,11 +1382,52 @@ int main(int argc, char *argv[]) goto end; if (cipher != NULL) { - if (!SSL_CTX_set_cipher_list(c_ctx, cipher) - || !SSL_CTX_set_cipher_list(s_ctx, cipher) - || !SSL_CTX_set_cipher_list(s_ctx2, cipher)) { - ERR_print_errors(bio_err); - goto end; + if (strcmp(cipher, "") == 0) { + if (!SSL_CTX_set_cipher_list(c_ctx, cipher)) { + if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_NO_CIPHER_MATCH) { + ERR_clear_error(); + } else { + ERR_print_errors(bio_err); + goto end; + } + } else { + /* Should have failed when clearing all TLSv1.2 ciphers. */ + fprintf(stderr, "CLEARING ALL TLSv1.2 CIPHERS SHOULD FAIL\n"); + goto end; + } + + if (!SSL_CTX_set_cipher_list(s_ctx, cipher)) { + if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_NO_CIPHER_MATCH) { + ERR_clear_error(); + } else { + ERR_print_errors(bio_err); + goto end; + } + } else { + /* Should have failed when clearing all TLSv1.2 ciphers. */ + fprintf(stderr, "CLEARING ALL TLSv1.2 CIPHERS SHOULD FAIL\n"); + goto end; + } + + if (!SSL_CTX_set_cipher_list(s_ctx2, cipher)) { + if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_NO_CIPHER_MATCH) { + ERR_clear_error(); + } else { + ERR_print_errors(bio_err); + goto end; + } + } else { + /* Should have failed when clearing all TLSv1.2 ciphers. */ + fprintf(stderr, "CLEARING ALL TLSv1.2 CIPHERS SHOULD FAIL\n"); + goto end; + } + } else { + if (!SSL_CTX_set_cipher_list(c_ctx, cipher) + || !SSL_CTX_set_cipher_list(s_ctx, cipher) + || !SSL_CTX_set_cipher_list(s_ctx2, cipher)) { + ERR_print_errors(bio_err); + goto end; + } } } if (ciphersuites != NULL) { diff --git a/test/testutil.h b/test/testutil.h index 9e08a42e..ec2f532c 100644 --- a/test/testutil.h +++ b/test/testutil.h @@ -15,7 +15,7 @@ #include #include #include -#include "../apps/opt.h" +#include "opt.h" /*- * Simple unit tests should implement setup_tests(). diff --git a/util/find-doc-nits b/util/find-doc-nits index d722d3ca..a8cea9c5 100755 --- a/util/find-doc-nits +++ b/util/find-doc-nits @@ -68,7 +68,6 @@ sub name_synopsis() $tmp =~ s/ -.*//g; $tmp =~ s/ */ /g; print "$id missing comma in NAME\n" if $tmp =~ /[^,] /; - $tmp =~ s/,//g; my $dirname = dirname($filename); my $simplename = basename($filename); @@ -76,7 +75,11 @@ sub name_synopsis() my $foundfilename = 0; my %foundfilenames = (); my %names; - foreach my $n ( split ' ', $tmp ) { + foreach my $n ( split ',', $tmp ) { + $n =~ s/^\s+//; + $n =~ s/\s+$//; + print "$id the name '$n' contains white-space\n" + if $n =~ /\s/; $names{$n} = 1; $foundfilename++ if $n eq $simplename; $foundfilenames{$n} = 1 @@ -99,6 +102,7 @@ sub name_synopsis() next unless $line =~ /^\s/; my $sym; $line =~ s/STACK_OF\([^)]+\)/int/g; + $line =~ s/SPARSE_ARRAY_OF\([^)]+\)/int/g; $line =~ s/__declspec\([^)]+\)//; if ( $line =~ /env (\S*)=/ ) { # environment variable env NAME=... @@ -247,7 +251,7 @@ sub parsenum() return sort @apis; } -sub getdocced() +sub getdocced { my $dir = shift; my %return; @@ -349,13 +353,16 @@ sub collectnames { $tmp =~ tr/\n/ /; $tmp =~ s/-.*//g; - my @names = map { s/\s+//g; $_ } split(/,/, $tmp); + my @names = map { s/^\s+//g; s/\s+$//g; $_ } split(/,/, $tmp); unless (grep { $simplename eq $_ } @names) { print "$id missing $simplename\n"; push @names, $simplename; } foreach my $name (@names) { next if $name eq ""; + if ($name =~ /\s/) { + print "$id '$name' contains white space\n"; + } my $name_sec = "$name($section)"; if (! exists $name_collection{$name_sec}) { $name_collection{$name_sec} = $filename; @@ -524,7 +531,8 @@ if ( $opt_c ) { } if ( $opt_l ) { - foreach (@ARGV ? @ARGV : glob('doc/*/*.pod')) { + foreach (@ARGV ? @ARGV : (glob('doc/*/*.pod'), + glob('doc/internal/*/*.pod'))) { collectnames($_); } checklinks(); @@ -535,10 +543,16 @@ if ( $opt_n ) { foreach (@ARGV ? @ARGV : glob('doc/*/*.pod')) { &check($_); } + { + local $opt_p = undef; + foreach (@ARGV ? @ARGV : glob('doc/internal/*/*.pod')) { + &check($_); + } + } } if ( $opt_u ) { - my %temp = &getdocced('doc/man3'); + my %temp = getdocced('doc/man3'); foreach ( keys %temp ) { $docced{$_} = $temp{$_}; } diff --git a/util/libcrypto.num b/util/libcrypto.num index dd86f3d9..b9bc3703 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4631,4 +4631,17 @@ CMS_add1_signing_cert_v2 4586 3_0_0 EXIST::FUNCTION:CMS ESS_SIGNING_CERT_new_init 4587 3_0_0 EXIST::FUNCTION: ESS_SIGNING_CERT_V2_new_init 4588 3_0_0 EXIST::FUNCTION: ERR_load_ESS_strings 4589 3_0_0 EXIST::FUNCTION: -EVP_chacha20_poly1305_draft 4590 3_0_0 EXIST::FUNCTION:CHACHA,POLY1305 +EVP_KDF_CTX_new_id 4590 3_0_0 EXIST::FUNCTION: +EVP_KDF_CTX_free 4591 3_0_0 EXIST::FUNCTION: +EVP_KDF_reset 4592 3_0_0 EXIST::FUNCTION: +EVP_KDF_ctrl 4593 3_0_0 EXIST::FUNCTION: +EVP_KDF_vctrl 4594 3_0_0 EXIST::FUNCTION: +EVP_KDF_ctrl_str 4595 3_0_0 EXIST::FUNCTION: +EVP_KDF_size 4596 3_0_0 EXIST::FUNCTION: +EVP_KDF_derive 4597 3_0_0 EXIST::FUNCTION: +EC_GROUP_get0_field 4598 3_0_0 EXIST::FUNCTION:EC +CRYPTO_alloc_ex_data 4599 3_0_0 EXIST::FUNCTION: +OPENSSL_CTX_new 4600 3_0_0 EXIST::FUNCTION: +OPENSSL_CTX_free 4601 3_0_0 EXIST::FUNCTION: +OPENSSL_LH_flush 4602 3_0_0 EXIST::FUNCTION: +EVP_chacha20_poly1305_draft 4603 3_0_0 EXIST::FUNCTION:CHACHA,POLY1305 diff --git a/util/private.num b/util/private.num index 6fe43925..c4a27934 100644 --- a/util/private.num +++ b/util/private.num @@ -22,6 +22,7 @@ CRYPTO_EX_dup datatype CRYPTO_EX_free datatype CRYPTO_EX_new datatype DTLS_timer_cb datatype +EVP_KDF_CTX datatype EVP_MAC datatype EVP_MAC_CTX datatype EVP_PKEY_gen_cb datatype @@ -29,6 +30,7 @@ EVP_PKEY_METHOD datatype EVP_PKEY_ASN1_METHOD datatype GEN_SESSION_CB datatype OPENSSL_Applink external +OPENSSL_CTX datatype NAMING_AUTHORITY datatype OSSL_STORE_CTX datatype OSSL_STORE_INFO datatype