From: Ruben Kerkhof Date: Sat, 11 Oct 2014 12:24:13 +0000 (+0200) Subject: Upgrade to polarssl 1.3.8 X-Git-Tag: auth-3.4.2~15^2~40 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d5cb6176aa40ddd2fd3d3eb5c3fcabbe68c23100;p=pdns Upgrade to polarssl 1.3.8 Upstream commit 1910aa78a367 --- diff --git a/pdns/dist-recursor b/pdns/dist-recursor index e3b81d915..b9a614136 100755 --- a/pdns/dist-recursor +++ b/pdns/dist-recursor @@ -60,7 +60,7 @@ mkdir -p $DIRNAME/ext/rapidjson/include/rapidjson/internal cp -a ext/rapidjson/include/rapidjson/*.h $DIRNAME/ext/rapidjson/include/rapidjson/ cp -a ext/rapidjson/include/rapidjson/internal/*.h $DIRNAME/ext/rapidjson/include/rapidjson/internal mkdir -p $DIRNAME/ext/polarssl/include/polarssl -cp -a ext/polarssl/include/polarssl/config.h ext/polarssl/include/polarssl/aes.h ext/polarssl/include/polarssl/padlock.h $DIRNAME/ext/polarssl/include/polarssl +cp -a ext/polarssl/include/polarssl/config.h ext/polarssl/include/polarssl/check_config.h ext/polarssl/include/polarssl/aes.h ext/polarssl/include/polarssl/padlock.h $DIRNAME/ext/polarssl/include/polarssl mkdir -p $DIRNAME/ext/polarssl/library cp -a ext/polarssl/library/aes.c ext/polarssl/library/padlock.c $DIRNAME/ext/polarssl/library cp -a ext/yahttp/ $DIRNAME/ext/yahttp diff --git a/pdns/ext/polarssl/CMakeLists.txt b/pdns/ext/polarssl/CMakeLists.txt index 08cb9b51c..86439ada4 100644 --- a/pdns/ext/polarssl/CMakeLists.txt +++ b/pdns/ext/polarssl/CMakeLists.txt @@ -1,23 +1,49 @@ cmake_minimum_required(VERSION 2.6) project(POLARSSL C) -enable_testing() +string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}") if(CMAKE_COMPILER_IS_GNUCC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -Wall -Wextra -W -Wdeclaration-after-statement") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement") + set(CMAKE_C_FLAGS_RELEASE "-O2") set(CMAKE_C_FLAGS_DEBUG "-g3 -O0") - set(CMAKE_C_FLAGS_COVERAGE "-g3 -O0 -fprofile-arcs -ftest-coverage -lgcov") + set(CMAKE_C_FLAGS_COVERAGE "-g3 -O0 --coverage") + set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fno-omit-frame-pointer -g3 -O1") + set(CMAKE_C_FLAGS_CHECK "${CMAKE_C_FLAGS} -Werror -O1 -Wlogical-op -Wwrite-strings") + set(CMAKE_C_FLAGS_CHECKFULL "${CMAKE_C_FLAGS_CHECK} -Wcast-qual") endif(CMAKE_COMPILER_IS_GNUCC) - + +if(CMAKE_COMPILER_IS_CLANG) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement") + set(CMAKE_C_FLAGS_RELEASE "-O2") + set(CMAKE_C_FLAGS_DEBUG "-g3 -O0") + set(CMAKE_C_FLAGS_COVERAGE "-g3 -O0 --coverage") + set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fno-omit-frame-pointer -g3 -O1") + set(CMAKE_C_FLAGS_CHECK "${CMAKE_C_FLAGS} -Werror -O1 -Wpointer-arith -Wwrite-strings -Wdocumentation -Wunreachable-code") +endif(CMAKE_COMPILER_IS_CLANG) + +set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} + CACHE STRING "Choose the type of build: None Debug Release Coverage ASan Check CheckFull" + FORCE) + if(CMAKE_BUILD_TYPE STREQUAL "Coverage") if(CMAKE_COMPILER_IS_GNUCC) - set(CMAKE_SHARED_LINKER_FLAGS "-fprofile-arcs -ftest-coverage") + set(CMAKE_SHARED_LINKER_FLAGS "--coverage") endif(CMAKE_COMPILER_IS_GNUCC) + if(CMAKE_COMPILER_IS_CLANG) + set(CMAKE_SHARED_LINKER_FLAGS "--coverage") + endif(CMAKE_COMPILER_IS_CLANG) endif(CMAKE_BUILD_TYPE STREQUAL "Coverage") option(USE_PKCS11_HELPER_LIBRARY "Build PolarSSL with the pkcs11-helper library." OFF) option(ENABLE_ZLIB_SUPPORT "Build PolarSSL with zlib library." OFF) +option(ENABLE_PROGRAMS "Build PolarSSL programs." ON) +option(ENABLE_TESTING "Build PolarSSL tests." ON) + +if(ENABLE_TESTING) + enable_testing() +endif() if(LIB_INSTALL_DIR) else() @@ -30,25 +56,56 @@ if(ENABLE_ZLIB_SUPPORT) find_package(ZLIB) if(ZLIB_FOUND) - include_directories(ZLIB_INCLUDE_DIR) + include_directories(${ZLIB_INCLUDE_DIR}) endif(ZLIB_FOUND) endif(ENABLE_ZLIB_SUPPORT) add_subdirectory(library) add_subdirectory(include) -if(CMAKE_COMPILER_IS_GNUCC) - add_subdirectory(tests) -endif(CMAKE_COMPILER_IS_GNUCC) +if(ENABLE_TESTING) + if(CMAKE_COMPILER_IS_GNUCC) + add_subdirectory(tests) + endif(CMAKE_COMPILER_IS_GNUCC) + if(CMAKE_COMPILER_IS_CLANG) + add_subdirectory(tests) + endif(CMAKE_COMPILER_IS_CLANG) +endif() -add_subdirectory(programs) +if(ENABLE_PROGRAMS) + add_subdirectory(programs) +endif() ADD_CUSTOM_TARGET(apidoc COMMAND doxygen doxygen/polarssl.doxyfile WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) -ADD_CUSTOM_TARGET(memcheck +if(ENABLE_TESTING) + ADD_CUSTOM_TARGET(test-ref-config + COMMAND tests/scripts/test-ref-configs.pl + ) + + ADD_CUSTOM_TARGET(covtest + COMMAND make test + COMMAND programs/test/selftest + COMMAND cd tests && ./compat.sh + COMMAND cd tests && ./ssl-opt.sh + ) + + ADD_CUSTOM_TARGET(lcov + COMMAND rm -rf Coverage + COMMAND lcov --capture --initial --directory library/CMakeFiles/polarssl.dir -o files.info + COMMAND lcov --capture --directory library/CMakeFiles/polarssl.dir -o tests.info + COMMAND lcov --add-tracefile files.info --add-tracefile tests.info -o all.info + COMMAND lcov --remove all.info -o final.info '*.h' + COMMAND gendesc tests/Descriptions.txt -o descriptions + COMMAND genhtml --title PolarSSL --description-file descriptions --keep-descriptions --legend --no-branch-coverage -o Coverage final.info + COMMAND rm -f files.info tests.info all.info final.info descriptions + ) + + ADD_CUSTOM_TARGET(memcheck COMMAND ctest -O memcheck.log -D ExperimentalMemCheck COMMAND tail -n1 memcheck.log | grep 'Memory checking results:' > /dev/null COMMAND rm -f memcheck.log ) +endif() diff --git a/pdns/ext/polarssl/ChangeLog b/pdns/ext/polarssl/ChangeLog index 334d147fa..163bdb796 100644 --- a/pdns/ext/polarssl/ChangeLog +++ b/pdns/ext/polarssl/ChangeLog @@ -1,5 +1,278 @@ PolarSSL ChangeLog (Sorted per branch, date) += PolarSSL 1.3.8 released 2014-07-11 +Security + * Fix length checking for AEAD ciphersuites (found by Codenomicon). + It was possible to crash the server (and client) using crafted messages + when a GCM suite was chosen. + +Features + * Add CCM module and cipher mode to Cipher Layer + * Support for CCM and CCM_8 ciphersuites + * Support for parsing and verifying RSASSA-PSS signatures in the X.509 + modules (certificates, CRLs and CSRs). + * Blowfish in the cipher layer now supports variable length keys. + * Add example config.h for PSK with CCM, optimized for low RAM usage. + * Optimize for RAM usage in example config.h for NSA Suite B profile. + * Add POLARSSL_REMOVE_ARC4_CIPHERSUITES to allow removing RC4 ciphersuites + from the default list (inactive by default). + * Add server-side enforcement of sent renegotiation requests + (ssl_set_renegotiation_enforced()) + * Add SSL_CIPHERSUITES config.h flag to allow specifying a list of + ciphersuites to use and save some memory if the list is small. + +Changes + * Add LINK_WITH_PTHREAD option in CMake for explicit linking that is + required on some platforms (e.g. OpenBSD) + * Migrate zeroizing of data to polarssl_zeroize() instead of memset() + against unwanted compiler optimizations + * md_list() now returns hashes strongest first + * Selection of hash for signing ServerKeyExchange in TLS 1.2 now picks + strongest offered by client. + * All public contexts have _init() and _free() functions now for simpler + usage pattern + +Bugfix + * Fix in debug_print_msg() + * Enforce alignment in the buffer allocator even if buffer is not aligned + * Remove less-than-zero checks on unsigned numbers + * Stricter check on SSL ClientHello internal sizes compared to actual packet + size (found by TrustInSoft) + * Fix WSAStartup() return value check (found by Peter Vaskovic) + * Other minor issues (found by Peter Vaskovic) + * Fix symlink command for cross compiling with CMake (found by Andre + Heinecke) + * Fix DER output of gen_key app (found by Gergely Budai) + * Very small records were incorrectly rejected when truncated HMAC was in + use with some ciphersuites and versions (RC4 in all versions, CBC with + versions < TLS 1.1). + * Very large records using more than 224 bytes of padding were incorrectly + rejected with CBC-based ciphersuites and TLS >= 1.1 + * Very large records using less padding could cause a buffer overread of up + to 32 bytes with CBC-based ciphersuites and TLS >= 1.1 + * Restore ability to use a v1 cert as a CA if trusted locally. (This had + been removed in 1.3.6.) + * Restore ability to locally trust a self-signed cert that is not a proper + CA for use as an end entity certificate. (This had been removed in + 1.3.6.) + * Fix preprocessor checks for bn_mul PPC asm (found by Barry K. Nathan). + * Use \n\t rather than semicolons for bn_mul asm, since some assemblers + interpret semicolons as comment delimiters (found by Barry K. Nathan). + * Fix off-by-one error in parsing Supported Point Format extension that + caused some handshakes to fail. + * Fix possible miscomputation of the premaster secret with DHE-PSK key + exchange that caused some handshakes to fail with other implementations. + (Failure rate <= 1/255 with common DHM moduli.) + * Disable broken Sparc64 bn_mul assembly (found by Florian Obser). + * Fix base64_decode() to return and check length correctly (in case of + tight buffers) + * Fix mpi_write_string() to write "00" as hex output for empty MPI (found + by Hui Dong) + += PolarSSL 1.3.7 released on 2014-05-02 +Features + * debug_set_log_mode() added to determine raw or full logging + * debug_set_threshold() added to ignore messages over threshold level + * version_check_feature() added to check for compile-time options at + run-time + +Changes + * POLARSSL_CONFIG_OPTIONS has been removed. All values are individually + checked and filled in the relevant module headers + * Debug module only outputs full lines instead of parts + * Better support for the different Attribute Types from IETF PKIX (RFC 5280) + * AES-NI now compiles with "old" assemblers too + * Ciphersuites based on RC4 now have the lowest priority by default + +Bugfix + * Only iterate over actual certificates in ssl_write_certificate_request() + (found by Matthew Page) + * Typos in platform.c and pkcs11.c (found by Daniel Phillips and Steffan + Karger) + * cert_write app should use subject of issuer certificate as issuer of cert + * Fix false reject in padding check in ssl_decrypt_buf() for CBC + ciphersuites, for full SSL frames of data. + * Improve interoperability by not writing extension length in ClientHello / + ServerHello when no extensions are present (found by Matthew Page) + * rsa_check_pubkey() now allows an E up to N + * On OpenBSD, use arc4random_buf() instead of rand() to prevent warnings + * mpi_fill_random() was creating numbers larger than requested on + big-endian platform when size was not an integer number of limbs + * Fix dependencies issues in X.509 test suite. + * Some parts of ssl_tls.c were compiled even when the module was disabled. + * Fix detection of DragonflyBSD in net.c (found by Markus Pfeiffer) + * Fix detection of Clang on some Apple platforms with CMake + (found by Barry K. Nathan) + += PolarSSL 1.3.6 released on 2014-04-11 + +Features + * Support for the ALPN SSL extension + * Add option 'use_dev_random' to gen_key application + * Enable verification of the keyUsage extension for CA and leaf + certificates (POLARSSL_X509_CHECK_KEY_USAGE) + * Enable verification of the extendedKeyUsage extension + (POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) + +Changes + * x509_crt_info() now prints information about parsed extensions as well + * pk_verify() now returns a specific error code when the signature is valid + but shorter than the supplied length. + * Use UTC time to check certificate validity. + * Reject certificates with times not in UTC, per RFC 5280. + +Security + * Avoid potential timing leak in ecdsa_sign() by blinding modular division. + (Found by Watson Ladd.) + * The notAfter date of some certificates was no longer checked since 1.3.5. + This affects certificates in the user-supplied chain except the top + certificate. If the user-supplied chain contains only one certificates, + it is not affected (ie, its notAfter date is properly checked). + * Prevent potential NULL pointer dereference in ssl_read_record() (found by + TrustInSoft) + +Bugfix + * The length of various ClientKeyExchange messages was not properly checked. + * Some example server programs were not sending the close_notify alert. + * Potential memory leak in mpi_exp_mod() when error occurs during + calculation of RR. + * Fixed malloc/free default #define in platform.c (found by Gergely Budai). + * Fixed type which made POLARSSL_ENTROPY_FORCE_SHA256 uneffective (found by + Gergely Budai). + * Fix #include path in ecdsa.h which wasn't accepted by some compilers. + (found by Gergely Budai) + * Fix compile errors when POLARSSL_ERROR_STRERROR_BC is undefined (found by + Shuo Chen). + * oid_get_numeric_string() used to truncate the output without returning an + error if the output buffer was just 1 byte too small. + * dhm_parse_dhm() (hence dhm_parse_dhmfile()) did not set dhm->len. + * Calling pk_debug() on an RSA-alt key would segfault. + * pk_get_size() and pk_get_len() were off by a factor 8 for RSA-alt keys. + * Potential buffer overwrite in pem_write_buffer() because of low length + indication (found by Thijs Alkemade) + * EC curves constants, which should be only in ROM since 1.3.3, were also + stored in RAM due to missing 'const's (found by Gergely Budai). + += PolarSSL 1.3.5 released on 2014-03-26 +Features + * HMAC-DRBG as a separate module + * Option to set the Curve preference order (disabled by default) + * Single Platform compatilibity layer (for memory / printf / fprintf) + * Ability to provide alternate timing implementation + * Ability to force the entropy module to use SHA-256 as its basis + (POLARSSL_ENTROPY_FORCE_SHA256) + * Testing script ssl-opt.sh added for testing 'live' ssl option + interoperability against OpenSSL and PolarSSL + * Support for reading EC keys that use SpecifiedECDomain in some cases. + * Entropy module now supports seed writing and reading + +Changes + * Deprecated the Memory layer + * entropy_add_source(), entropy_update_manual() and entropy_gather() + now thread-safe if POLARSSL_THREADING_C defined + * Improvements to the CMake build system, contributed by Julian Ospald. + * Work around a bug of the version of Clang shipped by Apple with Mavericks + that prevented bignum.c from compiling. (Reported by Rafael Baptista.) + * Revamped the compat.sh interoperatibility script to include support for + testing against GnuTLS + * Deprecated ssl_set_own_cert_rsa() and ssl_set_own_cert_rsa_alt() + * Improvements to tests/Makefile, contributed by Oden Eriksson. + +Security + * Forbid change of server certificate during renegotiation to prevent + "triple handshake" attack when authentication mode is 'optional' (the + attack was already impossible when authentication is required). + * Check notBefore timestamp of certificates and CRLs from the future. + * Forbid sequence number wrapping + * Fixed possible buffer overflow with overlong PSK + * Possible remotely-triggered out-of-bounds memory access fixed (found by + TrustInSoft) + +Bugfix + * ecp_gen_keypair() does more tries to prevent failure because of + statistics + * Fixed bug in RSA PKCS#1 v1.5 "reversed" operations + * Fixed testing with out-of-source builds using cmake + * Fixed version-major intolerance in server + * Fixed CMake symlinking on out-of-source builds + * Fixed dependency issues in test suite + * Programs rsa_sign_pss and rsa_verify_pss were not using PSS since 1.3.0 + * Bignum's MIPS-32 assembly was used on MIPS-64, causing chaos. (Found by + Alex Wilson.) + * ssl_cache was creating entries when max_entries=0 if TIMING_C was enabled. + * m_sleep() was sleeping twice too long on most Unix platforms. + * Fixed bug with session tickets and non-blocking I/O in the unlikely case + send() would return an EAGAIN error when sending the ticket. + * ssl_cache was leaking memory when reusing a timed out entry containing a + client certificate. + * ssl_srv was leaking memory when client presented a timed out ticket + containing a client certificate + * ssl_init() was leaving a dirty pointer in ssl_context if malloc of + out_ctr failed + * ssl_handshake_init() was leaving dirty pointers in subcontexts if malloc + of one of them failed + * Fix typo in rsa_copy() that impacted PKCS#1 v2 contexts + * x509_get_current_time() uses localtime_r() to prevent thread issues + += PolarSSL 1.3.4 released on 2014-01-27 +Features + * Support for the Koblitz curves: secp192k1, secp224k1, secp256k1 + * Support for RIPEMD-160 + * Support for AES CFB8 mode + * Support for deterministic ECDSA (RFC 6979) + +Bugfix + * Potential memory leak in bignum_selftest() + * Replaced expired test certificate + * ssl_mail_client now terminates lines with CRLF, instead of LF + * net module handles timeouts on blocking sockets better (found by Tilman + Sauerbeck) + * Assembly format fixes in bn_mul.h + +Security + * Missing MPI_CHK calls added around unguarded mpi calls (found by + TrustInSoft) + += PolarSSL 1.3.3 released on 2013-12-31 +Features + * EC key generation support in gen_key app + * Support for adhering to client ciphersuite order preference + (POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE) + * Support for Curve25519 + * Support for ECDH-RSA and ECDH-ECDSA key exchanges and ciphersuites + * Support for IPv6 in the NET module + * AES-NI support for AES, AES-GCM and AES key scheduling + * SSL Pthread-based server example added (ssl_pthread_server) + +Changes + * gen_prime() speedup + * Speedup of ECP multiplication operation + * Relaxed some SHA2 ciphersuite's version requirements + * Dropped use of readdir_r() instead of readdir() with threading support + * More constant-time checks in the RSA module + * Split off curves from ecp.c into ecp_curves.c + * Curves are now stored fully in ROM + * Memory usage optimizations in ECP module + * Removed POLARSSL_THREADING_DUMMY + +Bugfix + * Fixed bug in mpi_set_bit() on platforms where t_uint is wider than int + * Fixed X.509 hostname comparison (with non-regular characters) + * SSL now gracefully handles missing RNG + * Missing defines / cases for RSA_PSK key exchange + * crypt_and_hash app checks MAC before final decryption + * Potential memory leak in ssl_ticket_keys_init() + * Memory leak in benchmark application + * Fixed x509_crt_parse_path() bug on Windows platforms + * Added missing MPI_CHK() around some statements in mpi_div_mpi() (found by + TrustInSoft) + * Fixed potential overflow in certificate size verification in + ssl_write_certificate() (found by TrustInSoft) + +Security + * Possible remotely-triggered out-of-bounds memory access fixed (found by + TrustInSoft) + = PolarSSL 1.3.2 released on 2013-11-04 Features * PK tests added to test framework @@ -107,6 +380,76 @@ Security * RSA blinding on CRT operations to counter timing attacks (found by Cyril Arnaud and Pierre-Alain Fouque) += Version 1.2.11 released 2014-07-11 +Features + * Entropy module now supports seed writing and reading + +Changes + * Introduced POLARSSL_HAVE_READDIR_R for systems without it + * Improvements to the CMake build system, contributed by Julian Ospald. + * Work around a bug of the version of Clang shipped by Apple with Mavericks + that prevented bignum.c from compiling. (Reported by Rafael Baptista.) + * Improvements to tests/Makefile, contributed by Oden Eriksson. + * Use UTC time to check certificate validity. + * Reject certificates with times not in UTC, per RFC 5280. + * Migrate zeroizing of data to polarssl_zeroize() instead of memset() + against unwanted compiler optimizations + +Security + * Forbid change of server certificate during renegotiation to prevent + "triple handshake" attack when authentication mode is optional (the + attack was already impossible when authentication is required). + * Check notBefore timestamp of certificates and CRLs from the future. + * Forbid sequence number wrapping + * Prevent potential NULL pointer dereference in ssl_read_record() (found by + TrustInSoft) + * Fix length checking for AEAD ciphersuites (found by Codenomicon). + It was possible to crash the server (and client) using crafted messages + when a GCM suite was chosen. + +Bugfix + * Fixed X.509 hostname comparison (with non-regular characters) + * SSL now gracefully handles missing RNG + * crypt_and_hash app checks MAC before final decryption + * Fixed x509_crt_parse_path() bug on Windows platforms + * Added missing MPI_CHK() around some statements in mpi_div_mpi() (found by + TrustInSoft) + * Fixed potential overflow in certificate size verification in + ssl_write_certificate() (found by TrustInSoft) + * Fix ASM format in bn_mul.h + * Potential memory leak in bignum_selftest() + * Replaced expired test certificate + * ssl_mail_client now terminates lines with CRLF, instead of LF + * Fix bug in RSA PKCS#1 v1.5 "reversed" operations + * Fixed testing with out-of-source builds using cmake + * Fixed version-major intolerance in server + * Fixed CMake symlinking on out-of-source builds + * Bignum's MIPS-32 assembly was used on MIPS-64, causing chaos. (Found by + Alex Wilson.) + * ssl_init() was leaving a dirty pointer in ssl_context if malloc of + out_ctr failed + * ssl_handshake_init() was leaving dirty pointers in subcontexts if malloc + of one of them failed + * x509_get_current_time() uses localtime_r() to prevent thread issues + * Some example server programs were not sending the close_notify alert. + * Potential memory leak in mpi_exp_mod() when error occurs during + calculation of RR. + * Improve interoperability by not writing extension length in ClientHello + when no extensions are present (found by Matthew Page) + * rsa_check_pubkey() now allows an E up to N + * On OpenBSD, use arc4random_buf() instead of rand() to prevent warnings + * mpi_fill_random() was creating numbers larger than requested on + big-endian platform when size was not an integer number of limbs + * Fix detection of DragonflyBSD in net.c (found by Markus Pfeiffer) + * Stricter check on SSL ClientHello internal sizes compared to actual packet + size (found by TrustInSoft) + * Fix preprocessor checks for bn_mul PPC asm (found by Barry K. Nathan). + * Use \n\t rather than semicolons for bn_mul asm, since some assemblers + interpret semicolons as comment delimiters (found by Barry K. Nathan). + * Disable broken Sparc64 bn_mul assembly (found by Florian Obser). + * Fix base64_decode() to return and check length correctly (in case of + tight buffers) + = Version 1.2.10 released 2013-10-07 Changes * Changed RSA blinding to a slower but thread-safe version diff --git a/pdns/ext/polarssl/README.rst b/pdns/ext/polarssl/README.rst index 52286157e..8dd823c9c 100644 --- a/pdns/ext/polarssl/README.rst +++ b/pdns/ext/polarssl/README.rst @@ -9,7 +9,7 @@ There are currently three active build systems within the PolarSSL releases: - Make - CMake -- Microsoft Visual Studio +- Microsoft Visual Studio (Visual Studio 6 and Visual Studio 2010) The main system used for development is CMake. That system is always the most up-to-date. The others should reflect all changes present in the CMake build system, but some features are not ported there by default. @@ -18,11 +18,11 @@ Make We intentionally only use the absolute minimum of **Make** functionality, as we have discovered that a lot of **Make** features are not supported on all different implementations of Make on different platforms. As such, the Makefiles sometimes require some handwork or `export` statements in order to work for your platform. -In order to build the source using Make, just enter at the command line: +In order to build the source using Make, just enter at the command line:: make -In order to run the tests, enter: +In order to run the tests, enter:: make check @@ -33,13 +33,13 @@ In case you find that you need to do something else as well, please let us know CMake ----- -In order to build the source using CMake, just enter at the command line: +In order to build the source using CMake, just enter at the command line:: cmake . make -There are 3 different active build modes specified within the CMake buildsystem: +There are 5 different active build modes specified within the CMake buildsystem: - Release. This generates the default code without any unnecessary information in the binary files. @@ -47,19 +47,23 @@ There are 3 different active build modes specified within the CMake buildsystem: This generates debug information and disables optimization of the code. - Coverage. This generates code coverage information in addition to debug information. +- ASan. + This instruments the code with AddressSanitizer to check for memory errors. +- Check. + This activates more compiler warnings and treats them as errors. Switching build modes in CMake is simple. For debug mode, enter at the command line: cmake -D CMAKE_BUILD_TYPE:String="Debug" . -In order to run the tests, enter: +In order to run the tests, enter:: make test Microsoft Visual Studio ----------------------- -The build files for Microsoft Visual Studio are generated for Visual Studio 6.0 all future Visual Studio's should be able to open and use this older version of the build files. +The build files for Microsoft Visual Studio are generated for Visual Studio 6.0 and Visual Studio 2010. The workspace 'polarssl.dsw' contains all the basic projects needed to build the library and all the programs. The files in tests are not generated and compiled, as these need a perl environment as well. @@ -71,11 +75,24 @@ We've included example programs for a lot of different features and uses in *pro Tests ===== -PolarSSL includes a elaborate test suite in *tests/* that initially requires Perl to generate the tests files (e.g. *test_suite_mpi.c*). These files are generates from a **function file** (e.g. *suites/test_suite_mpi.function*) and a **data file** (e.g. *suites/test_suite_mpi.data*). The **function file** contains the template for each test function. The **data file** contains the test cases, specified as parameters that should be pushed into a template function. +PolarSSL includes an elaborate test suite in *tests/* that initially requires Perl to generate the tests files (e.g. *test_suite_mpi.c*). These files are generates from a **function file** (e.g. *suites/test_suite_mpi.function*) and a **data file** (e.g. *suites/test_suite_mpi.data*). The **function file** contains the template for each test function. The **data file** contains the test cases, specified as parameters that should be pushed into a template function. + +Configurations +============== + +We provide some non-standard configurations focused on specific use cases in the configs/ directory. You can read more about those in configs/README.txt Contributing ============ +We graciously accept bugs and contributions from the community. There are some requirements we need to fulfil in order to be able to integrate contributions in the main code. + +Simple bug fixes to existing code do not contain copyright themselves and we can integrate those without any issue. The same goes for trivial contributions. + +For larger contributions, e.g. a new feature, the code possible falls under copyright law. We then need your consent to share in the ownership of the copyright. We have a form for that, which we will mail to you in case you submit a contribution or pull request that we deem this necessary for. + +Process +------- #. `Check for open issues `_ or `start a discussion `_ around a feature idea or a bug. diff --git a/pdns/ext/polarssl/include/polarssl/aes.h b/pdns/ext/polarssl/include/polarssl/aes.h index 1b93e2a3d..2e9092f95 100644 --- a/pdns/ext/polarssl/include/polarssl/aes.h +++ b/pdns/ext/polarssl/include/polarssl/aes.h @@ -3,7 +3,7 @@ * * \brief AES block cipher * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ #ifndef POLARSSL_AES_H #define POLARSSL_AES_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include @@ -38,6 +42,7 @@ typedef UINT32 uint32_t; #include #endif +/* padlock.c and aesni.c rely on these values! */ #define AES_ENCRYPT 1 #define AES_DECRYPT 0 @@ -54,6 +59,11 @@ extern "C" { /** * \brief AES context structure + * + * \note buf is able to hold 32 extra bytes, which can be used: + * - for alignment purposes if VIA padlock is used, and/or + * - to simplify key expansion in the 256-bit case by + * generating an extra round key */ typedef struct { @@ -63,6 +73,20 @@ typedef struct } aes_context; +/** + * \brief Initialize AES context + * + * \param ctx AES context to be initialized + */ +void aes_init( aes_context *ctx ); + +/** + * \brief Clear AES context + * + * \param ctx AES context to be cleared + */ +void aes_free( aes_context *ctx ); + /** * \brief AES key schedule (encryption) * @@ -72,7 +96,8 @@ aes_context; * * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH */ -int aes_setkey_enc( aes_context *ctx, const unsigned char *key, unsigned int keysize ); +int aes_setkey_enc( aes_context *ctx, const unsigned char *key, + unsigned int keysize ); /** * \brief AES key schedule (decryption) @@ -83,7 +108,8 @@ int aes_setkey_enc( aes_context *ctx, const unsigned char *key, unsigned int key * * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH */ -int aes_setkey_dec( aes_context *ctx, const unsigned char *key, unsigned int keysize ); +int aes_setkey_dec( aes_context *ctx, const unsigned char *key, + unsigned int keysize ); /** * \brief AES-ECB block encryption/decryption @@ -123,6 +149,7 @@ int aes_crypt_cbc( aes_context *ctx, unsigned char *output ); #endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_CIPHER_MODE_CFB) /** * \brief AES-CFB128 buffer encryption/decryption. * @@ -148,6 +175,31 @@ int aes_crypt_cfb128( aes_context *ctx, const unsigned char *input, unsigned char *output ); +/** + * \brief AES-CFB8 buffer encryption/decryption. + * + * Note: Due to the nature of CFB you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT. + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful + */ +int aes_crypt_cfb8( aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /*POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) /** * \brief AES-CTR buffer encryption/decryption * @@ -177,6 +229,7 @@ int aes_crypt_ctr( aes_context *ctx, unsigned char stream_block[16], const unsigned char *input, unsigned char *output ); +#endif /* POLARSSL_CIPHER_MODE_CTR */ #ifdef __cplusplus } diff --git a/pdns/ext/polarssl/include/polarssl/aesni.h b/pdns/ext/polarssl/include/polarssl/aesni.h new file mode 100644 index 000000000..92b23cd6b --- /dev/null +++ b/pdns/ext/polarssl/include/polarssl/aesni.h @@ -0,0 +1,107 @@ +/** + * \file aesni.h + * + * \brief AES-NI for hardware AES acceleration on some Intel processors + * + * Copyright (C) 2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_AESNI_H +#define POLARSSL_AESNI_H + +#include "aes.h" + +#define POLARSSL_AESNI_AES 0x02000000u +#define POLARSSL_AESNI_CLMUL 0x00000002u + +#if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && \ + ( defined(__amd64__) || defined(__x86_64__) ) && \ + ! defined(POLARSSL_HAVE_X86_64) +#define POLARSSL_HAVE_X86_64 +#endif + +#if defined(POLARSSL_HAVE_X86_64) + +/** + * \brief AES-NI features detection routine + * + * \param what The feature to detect + * (POLARSSL_AESNI_AES or POLARSSL_AESNI_CLMUL) + * + * \return 1 if CPU has support for the feature, 0 otherwise + */ +int aesni_supports( unsigned int what ); + +/** + * \brief AES-NI AES-ECB block en(de)cryption + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + * + * \return 0 on success (cannot fail) + */ +int aesni_crypt_ecb( aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ); + +/** + * \brief GCM multiplication: c = a * b in GF(2^128) + * + * \param c Result + * \param a First operand + * \param b Second operand + * + * \note Both operands and result are bit strings interpreted as + * elements of GF(2^128) as per the GCM spec. + */ +void aesni_gcm_mult( unsigned char c[16], + const unsigned char a[16], + const unsigned char b[16] ); + +/** + * \brief Compute decryption round keys from encryption round keys + * + * \param invkey Round keys for the equivalent inverse cipher + * \param fwdkey Original round keys (for encryption) + * \param nr Number of rounds (that is, number of round keys minus one) + */ +void aesni_inverse_key( unsigned char *invkey, + const unsigned char *fwdkey, int nr ); + +/** + * \brief Perform key expansion (for encryption) + * + * \param rk Destination buffer where the round keys are written + * \param key Encryption key + * \param bits Key size in bits (must be 128, 192 or 256) + * + * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH + */ +int aesni_setkey_enc( unsigned char *rk, + const unsigned char *key, + size_t bits ); + +#endif /* POLARSSL_HAVE_X86_64 */ + +#endif /* POLARSSL_AESNI_H */ diff --git a/pdns/ext/polarssl/include/polarssl/arc4.h b/pdns/ext/polarssl/include/polarssl/arc4.h index 9333265d3..555f54fab 100644 --- a/pdns/ext/polarssl/include/polarssl/arc4.h +++ b/pdns/ext/polarssl/include/polarssl/arc4.h @@ -3,7 +3,7 @@ * * \brief The ARCFOUR stream cipher * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ #ifndef POLARSSL_ARC4_H #define POLARSSL_ARC4_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include @@ -51,13 +55,28 @@ typedef struct arc4_context; /** - * \brief ARC4 key schedule + * \brief Initialize ARC4 context * * \param ctx ARC4 context to be initialized + */ +void arc4_init( arc4_context *ctx ); + +/** + * \brief Clear ARC4 context + * + * \param ctx ARC4 context to be cleared + */ +void arc4_free( arc4_context *ctx ); + +/** + * \brief ARC4 key schedule + * + * \param ctx ARC4 context to be setup * \param key the secret key * \param keylen length of the key, in bytes */ -void arc4_setup( arc4_context *ctx, const unsigned char *key, unsigned int keylen ); +void arc4_setup( arc4_context *ctx, const unsigned char *key, + unsigned int keylen ); /** * \brief ARC4 cipher function diff --git a/pdns/ext/polarssl/include/polarssl/asn1.h b/pdns/ext/polarssl/include/polarssl/asn1.h index 45fd6cd87..eacdd082b 100644 --- a/pdns/ext/polarssl/include/polarssl/asn1.h +++ b/pdns/ext/polarssl/include/polarssl/asn1.h @@ -27,7 +27,11 @@ #ifndef POLARSSL_ASN1_H #define POLARSSL_ASN1_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_BIGNUM_C) #include "bignum.h" @@ -35,15 +39,15 @@ #include -/** +/** * \addtogroup asn1_module - * \{ + * \{ */ - + /** * \name ASN1 Error codes * These error codes are OR'ed to X509 error codes for - * higher error granularity. + * higher error granularity. * ASN1 is a standard to specify data structures. * \{ */ @@ -93,9 +97,13 @@ /** Returns the size of the binary string, without the trailing \\0 */ #define OID_SIZE(x) (sizeof(x) - 1) -/** Compares two asn1_buf structures for the same OID. Only works for - * 'defined' oid_str values (OID_HMAC_SHA1), you cannot use a 'unsigned - * char *oid' here! +/** + * Compares an asn1_buf structure to a reference OID. + * + * Only works for 'defined' oid_str values (OID_HMAC_SHA1), you cannot use a + * 'unsigned char *oid' here! + * + * Warning: returns true when the OIDs are equal (unlike memcmp)! */ #define OID_CMP(oid_str, oid_buf) \ ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \ @@ -270,7 +278,7 @@ int asn1_get_sequence_of( unsigned char **p, int asn1_get_mpi( unsigned char **p, const unsigned char *end, mpi *X ); -#endif +#endif /* POLARSSL_BIGNUM_C */ /** * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence. diff --git a/pdns/ext/polarssl/include/polarssl/asn1write.h b/pdns/ext/polarssl/include/polarssl/asn1write.h index d7f7b521a..7a7fbf7b3 100644 --- a/pdns/ext/polarssl/include/polarssl/asn1write.h +++ b/pdns/ext/polarssl/include/polarssl/asn1write.h @@ -3,7 +3,7 @@ * * \brief ASN.1 buffer writing functionality * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -29,7 +29,8 @@ #include "asn1.h" -#define ASN1_CHK_ADD(g, f) do { if( ( ret = f ) < 0 ) return( ret ); else g += ret; } while( 0 ) +#define ASN1_CHK_ADD(g, f) do { if( ( ret = f ) < 0 ) return( ret ); else \ + g += ret; } while( 0 ) #ifdef __cplusplus extern "C" { @@ -57,7 +58,8 @@ int asn1_write_len( unsigned char **p, unsigned char *start, size_t len ); * * \return the length written or a negative error code */ -int asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ); +int asn1_write_tag( unsigned char **p, unsigned char *start, + unsigned char tag ); /** * \brief Write raw buffer data @@ -85,7 +87,7 @@ int asn1_write_raw_buffer( unsigned char **p, unsigned char *start, * \return the length written or a negative error code */ int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X ); -#endif +#endif /* POLARSSL_BIGNUM_C */ /** * \brief Write a NULL tag (ASN1_NULL) with zero data in ASN.1 format diff --git a/pdns/ext/polarssl/include/polarssl/bignum.h b/pdns/ext/polarssl/include/polarssl/bignum.h index 9bed027d9..cd7592c4f 100644 --- a/pdns/ext/polarssl/include/polarssl/bignum.h +++ b/pdns/ext/polarssl/include/polarssl/bignum.h @@ -3,7 +3,7 @@ * * \brief Multi-precision integer library * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -30,7 +30,11 @@ #include #include +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) #include @@ -47,7 +51,7 @@ typedef UINT32 uint32_t; typedef UINT64 uint64_t; #else #include -#endif +#endif /* _MSC_VER && !EFIX64 && !EFI32 */ #define POLARSSL_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */ #define POLARSSL_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */ @@ -58,14 +62,14 @@ typedef UINT64 uint64_t; #define POLARSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */ #define POLARSSL_ERR_MPI_MALLOC_FAILED -0x0010 /**< Memory allocation failed. */ -#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup +#define MPI_CHK(f) do { if( ( ret = f ) != 0 ) goto cleanup; } while( 0 ) /* * Maximum size MPIs are allowed to grow to in number of limbs. */ #define POLARSSL_MPI_MAX_LIMBS 10000 -#if !defined(POLARSSL_CONFIG_OPTIONS) +#if !defined(POLARSSL_MPI_WINDOW_SIZE) /* * Maximum window size used for modular exponentiation. Default: 6 * Minimum value: 1. Maximum value: 6. @@ -76,7 +80,9 @@ typedef UINT64 uint64_t; * Reduction in size, reduces speed. */ #define POLARSSL_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ +#endif /* !POLARSSL_MPI_WINDOW_SIZE */ +#if !defined(POLARSSL_MPI_MAX_SIZE) /* * Maximum size of MPIs allowed in bits and bytes for user-MPIs. * ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits ) @@ -85,8 +91,7 @@ typedef UINT64 uint64_t; * of limbs required (POLARSSL_MPI_MAX_LIMBS) is higher. */ #define POLARSSL_MPI_MAX_SIZE 512 /**< Maximum number of bytes for usable MPIs. */ - -#endif /* !POLARSSL_CONFIG_OPTIONS */ +#endif /* !POLARSSL_MPI_MAX_SIZE */ #define POLARSSL_MPI_MAX_BITS ( 8 * POLARSSL_MPI_MAX_SIZE ) /**< Maximum number of bits for usable MPIs. */ @@ -127,12 +132,18 @@ typedef uint16_t t_uint; typedef uint32_t t_udbl; #define POLARSSL_HAVE_UDBL #else - #if ( defined(_MSC_VER) && defined(_M_AMD64) ) + /* + * 32-bit integers can be forced on 64-bit arches (eg. for testing purposes) + * by defining POLARSSL_HAVE_INT32 and undefining POLARSSL_HAVE_ASM + */ + #if ( ! defined(POLARSSL_HAVE_INT32) && \ + defined(_MSC_VER) && defined(_M_AMD64) ) #define POLARSSL_HAVE_INT64 typedef int64_t t_sint; typedef uint64_t t_uint; #else - #if ( defined(__GNUC__) && ( \ + #if ( ! defined(POLARSSL_HAVE_INT32) && \ + defined(__GNUC__) && ( \ defined(__amd64__) || defined(__x86_64__) || \ defined(__ppc64__) || defined(__powerpc64__) || \ defined(__ia64__) || defined(__alpha__) || \ @@ -156,8 +167,8 @@ typedef uint32_t t_udbl; #define POLARSSL_HAVE_UDBL #endif #endif - #endif - #endif + #endif /* !POLARSSL_HAVE_INT32 && __GNUC__ && 64-bit platform */ + #endif /* !POLARSSL_HAVE_INT32 && _MSC_VER && _M_AMD64 */ #endif /* POLARSSL_HAVE_INT16 */ #endif /* POLARSSL_HAVE_INT8 */ @@ -201,6 +212,17 @@ void mpi_free( mpi *X ); */ int mpi_grow( mpi *X, size_t nblimbs ); +/** + * \brief Resize down, keeping at least the specified number of limbs + * + * \param X MPI to shrink + * \param nblimbs The minimum number of limbs to keep + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_shrink( mpi *X, size_t nblimbs ); + /** * \brief Copy the contents of Y into X * @@ -220,6 +242,44 @@ int mpi_copy( mpi *X, const mpi *Y ); */ void mpi_swap( mpi *X, mpi *Y ); +/** + * \brief Safe conditional assignement X = Y if assign is 1 + * + * \param X MPI to conditionally assign to + * \param Y Value to be assigned + * \param assign 1: perform the assignment, 0: keep X's original value + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * + * \note This function is equivalent to + * if( assign ) mpi_copy( X, Y ); + * except that it avoids leaking any information about whether + * the assignment was done or not (the above code may leak + * information through branch prediction and/or memory access + * patterns analysis). + */ +int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign ); + +/** + * \brief Safe conditional swap X <-> Y if swap is 1 + * + * \param X First mpi value + * \param Y Second mpi value + * \param assign 1: perform the swap, 0: keep X and Y's original values + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * + * \note This function is equivalent to + * if( assign ) mpi_swap( X, Y ); + * except that it avoids leaking any information about whether + * the assignment was done or not (the above code may leak + * information through branch prediction and/or memory access + * patterns analysis). + */ +int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char assign ); + /** * \brief Set value from integer * @@ -354,7 +414,9 @@ int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout ); int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen ); /** - * \brief Export X into unsigned binary data, big endian + * \brief Export X into unsigned binary data, big endian. + * Always fills the whole buffer, which will start with zeros + * if the number is smaller. * * \param X Source MPI * \param buf Output buffer @@ -509,8 +571,9 @@ int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B ); /** * \brief Baseline multiplication: X = A * b - * Note: b is an unsigned integer type, thus - * Negative values of b are ignored. + * Note: despite the functon signature, b is treated as a + * t_uint. Negative values of b are treated as large positive + * values. * * \param X Destination MPI * \param A Left-hand MPI @@ -584,7 +647,7 @@ int mpi_mod_int( t_uint *r, const mpi *A, t_sint b ); /** * \brief Sliding-window exponentiation: X = A^E mod N * - * \param X Destination MPI + * \param X Destination MPI * \param A Left-hand MPI * \param E Exponent MPI * \param N Modular MPI @@ -592,8 +655,8 @@ int mpi_mod_int( t_uint *r, const mpi *A, t_sint b ); * * \return 0 if successful, * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, - * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even or if - * E is negative + * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even or + * if E is negative * * \note _RR is used to avoid re-computing R*R mod N across * multiple calls, which speeds up things a bit. It can @@ -661,7 +724,8 @@ int mpi_is_prime( mpi *X, * \brief Prime number generation * * \param X Destination MPI - * \param nbits Required size of X in bits ( 3 <= nbits <= POLARSSL_MPI_MAX_BITS ) + * \param nbits Required size of X in bits + * ( 3 <= nbits <= POLARSSL_MPI_MAX_BITS ) * \param dh_flag If 1, then (X-1)/2 will be prime too * \param f_rng RNG function * \param p_rng RNG parameter diff --git a/pdns/ext/polarssl/include/polarssl/blowfish.h b/pdns/ext/polarssl/include/polarssl/blowfish.h index 45b138764..c652b463d 100644 --- a/pdns/ext/polarssl/include/polarssl/blowfish.h +++ b/pdns/ext/polarssl/include/polarssl/blowfish.h @@ -3,7 +3,7 @@ * * \brief Blowfish block cipher * - * Copyright (C) 2012-2013, Brainspark B.V. + * Copyright (C) 2012-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ #ifndef POLARSSL_BLOWFISH_H #define POLARSSL_BLOWFISH_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include @@ -42,7 +46,7 @@ typedef UINT32 uint32_t; #define BLOWFISH_DECRYPT 0 #define BLOWFISH_MAX_KEY 448 #define BLOWFISH_MIN_KEY 32 -#define BLOWFISH_ROUNDS 16 /* when increasing this value, make sure to extend the initialisation vectors */ +#define BLOWFISH_ROUNDS 16 /**< Rounds to use. When increasing this value, make sure to extend the initialisation vectors */ #define BLOWFISH_BLOCKSIZE 8 /* Blowfish uses 64 bit blocks */ #define POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH -0x0016 /**< Invalid key length. */ @@ -66,6 +70,20 @@ typedef struct } blowfish_context; +/** + * \brief Initialize Blowfish context + * + * \param ctx Blowfish context to be initialized + */ +void blowfish_init( blowfish_context *ctx ); + +/** + * \brief Clear Blowfish context + * + * \param ctx Blowfish context to be cleared + */ +void blowfish_free( blowfish_context *ctx ); + /** * \brief Blowfish key schedule * @@ -75,7 +93,8 @@ blowfish_context; * * \return 0 if successful, or POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH */ -int blowfish_setkey( blowfish_context *ctx, const unsigned char *key, unsigned int keysize ); +int blowfish_setkey( blowfish_context *ctx, const unsigned char *key, + unsigned int keysize ); /** * \brief Blowfish-ECB block encryption/decryption @@ -105,7 +124,8 @@ int blowfish_crypt_ecb( blowfish_context *ctx, * \param input buffer holding the input data * \param output buffer holding the output data * - * \return 0 if successful, or POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH + * \return 0 if successful, or + * POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH */ int blowfish_crypt_cbc( blowfish_context *ctx, int mode, diff --git a/pdns/ext/polarssl/include/polarssl/bn_mul.h b/pdns/ext/polarssl/include/polarssl/bn_mul.h index 1c2da136a..64b59ff1e 100644 --- a/pdns/ext/polarssl/include/polarssl/bn_mul.h +++ b/pdns/ext/polarssl/include/polarssl/bn_mul.h @@ -48,102 +48,95 @@ #if defined(__GNUC__) #if defined(__i386__) -#define MULADDC_INIT \ - asm( " \ - movl %%ebx, %0; \ - movl %5, %%esi; \ - movl %6, %%edi; \ - movl %7, %%ecx; \ - movl %8, %%ebx; \ - " - -#define MULADDC_CORE \ - " \ - lodsl; \ - mull %%ebx; \ - addl %%ecx, %%eax; \ - adcl $0, %%edx; \ - addl (%%edi), %%eax; \ - adcl $0, %%edx; \ - movl %%edx, %%ecx; \ - stosl; \ - " +#define MULADDC_INIT \ + asm( \ + "movl %%ebx, %0 \n\t" \ + "movl %5, %%esi \n\t" \ + "movl %6, %%edi \n\t" \ + "movl %7, %%ecx \n\t" \ + "movl %8, %%ebx \n\t" + +#define MULADDC_CORE \ + "lodsl \n\t" \ + "mull %%ebx \n\t" \ + "addl %%ecx, %%eax \n\t" \ + "adcl $0, %%edx \n\t" \ + "addl (%%edi), %%eax \n\t" \ + "adcl $0, %%edx \n\t" \ + "movl %%edx, %%ecx \n\t" \ + "stosl \n\t" #if defined(POLARSSL_HAVE_SSE2) -#define MULADDC_HUIT \ - " \ - movd %%ecx, %%mm1; \ - movd %%ebx, %%mm0; \ - movd (%%edi), %%mm3; \ - paddq %%mm3, %%mm1; \ - movd (%%esi), %%mm2; \ - pmuludq %%mm0, %%mm2; \ - movd 4(%%esi), %%mm4; \ - pmuludq %%mm0, %%mm4; \ - movd 8(%%esi), %%mm6; \ - pmuludq %%mm0, %%mm6; \ - movd 12(%%esi), %%mm7; \ - pmuludq %%mm0, %%mm7; \ - paddq %%mm2, %%mm1; \ - movd 4(%%edi), %%mm3; \ - paddq %%mm4, %%mm3; \ - movd 8(%%edi), %%mm5; \ - paddq %%mm6, %%mm5; \ - movd 12(%%edi), %%mm4; \ - paddq %%mm4, %%mm7; \ - movd %%mm1, (%%edi); \ - movd 16(%%esi), %%mm2; \ - pmuludq %%mm0, %%mm2; \ - psrlq $32, %%mm1; \ - movd 20(%%esi), %%mm4; \ - pmuludq %%mm0, %%mm4; \ - paddq %%mm3, %%mm1; \ - movd 24(%%esi), %%mm6; \ - pmuludq %%mm0, %%mm6; \ - movd %%mm1, 4(%%edi); \ - psrlq $32, %%mm1; \ - movd 28(%%esi), %%mm3; \ - pmuludq %%mm0, %%mm3; \ - paddq %%mm5, %%mm1; \ - movd 16(%%edi), %%mm5; \ - paddq %%mm5, %%mm2; \ - movd %%mm1, 8(%%edi); \ - psrlq $32, %%mm1; \ - paddq %%mm7, %%mm1; \ - movd 20(%%edi), %%mm5; \ - paddq %%mm5, %%mm4; \ - movd %%mm1, 12(%%edi); \ - psrlq $32, %%mm1; \ - paddq %%mm2, %%mm1; \ - movd 24(%%edi), %%mm5; \ - paddq %%mm5, %%mm6; \ - movd %%mm1, 16(%%edi); \ - psrlq $32, %%mm1; \ - paddq %%mm4, %%mm1; \ - movd 28(%%edi), %%mm5; \ - paddq %%mm5, %%mm3; \ - movd %%mm1, 20(%%edi); \ - psrlq $32, %%mm1; \ - paddq %%mm6, %%mm1; \ - movd %%mm1, 24(%%edi); \ - psrlq $32, %%mm1; \ - paddq %%mm3, %%mm1; \ - movd %%mm1, 28(%%edi); \ - addl $32, %%edi; \ - addl $32, %%esi; \ - psrlq $32, %%mm1; \ - movd %%mm1, %%ecx; \ - " - -#define MULADDC_STOP \ - " \ - emms; \ - movl %4, %%ebx; \ - movl %%ecx, %1; \ - movl %%edi, %2; \ - movl %%esi, %3; \ - " \ +#define MULADDC_HUIT \ + "movd %%ecx, %%mm1 \n\t" \ + "movd %%ebx, %%mm0 \n\t" \ + "movd (%%edi), %%mm3 \n\t" \ + "paddq %%mm3, %%mm1 \n\t" \ + "movd (%%esi), %%mm2 \n\t" \ + "pmuludq %%mm0, %%mm2 \n\t" \ + "movd 4(%%esi), %%mm4 \n\t" \ + "pmuludq %%mm0, %%mm4 \n\t" \ + "movd 8(%%esi), %%mm6 \n\t" \ + "pmuludq %%mm0, %%mm6 \n\t" \ + "movd 12(%%esi), %%mm7 \n\t" \ + "pmuludq %%mm0, %%mm7 \n\t" \ + "paddq %%mm2, %%mm1 \n\t" \ + "movd 4(%%edi), %%mm3 \n\t" \ + "paddq %%mm4, %%mm3 \n\t" \ + "movd 8(%%edi), %%mm5 \n\t" \ + "paddq %%mm6, %%mm5 \n\t" \ + "movd 12(%%edi), %%mm4 \n\t" \ + "paddq %%mm4, %%mm7 \n\t" \ + "movd %%mm1, (%%edi) \n\t" \ + "movd 16(%%esi), %%mm2 \n\t" \ + "pmuludq %%mm0, %%mm2 \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "movd 20(%%esi), %%mm4 \n\t" \ + "pmuludq %%mm0, %%mm4 \n\t" \ + "paddq %%mm3, %%mm1 \n\t" \ + "movd 24(%%esi), %%mm6 \n\t" \ + "pmuludq %%mm0, %%mm6 \n\t" \ + "movd %%mm1, 4(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "movd 28(%%esi), %%mm3 \n\t" \ + "pmuludq %%mm0, %%mm3 \n\t" \ + "paddq %%mm5, %%mm1 \n\t" \ + "movd 16(%%edi), %%mm5 \n\t" \ + "paddq %%mm5, %%mm2 \n\t" \ + "movd %%mm1, 8(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "paddq %%mm7, %%mm1 \n\t" \ + "movd 20(%%edi), %%mm5 \n\t" \ + "paddq %%mm5, %%mm4 \n\t" \ + "movd %%mm1, 12(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "paddq %%mm2, %%mm1 \n\t" \ + "movd 24(%%edi), %%mm5 \n\t" \ + "paddq %%mm5, %%mm6 \n\t" \ + "movd %%mm1, 16(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "paddq %%mm4, %%mm1 \n\t" \ + "movd 28(%%edi), %%mm5 \n\t" \ + "paddq %%mm5, %%mm3 \n\t" \ + "movd %%mm1, 20(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "paddq %%mm6, %%mm1 \n\t" \ + "movd %%mm1, 24(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "paddq %%mm3, %%mm1 \n\t" \ + "movd %%mm1, 28(%%edi) \n\t" \ + "addl $32, %%edi \n\t" \ + "addl $32, %%esi \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "movd %%mm1, %%ecx \n\t" + +#define MULADDC_STOP \ + "emms \n\t" \ + "movl %4, %%ebx \n\t" \ + "movl %%ecx, %1 \n\t" \ + "movl %%edi, %2 \n\t" \ + "movl %%esi, %3 \n\t" \ : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ : "eax", "ecx", "edx", "esi", "edi" \ @@ -151,13 +144,11 @@ #else -#define MULADDC_STOP \ - " \ - movl %4, %%ebx; \ - movl %%ecx, %1; \ - movl %%edi, %2; \ - movl %%esi, %3; \ - " \ +#define MULADDC_STOP \ + "movl %4, %%ebx \n\t" \ + "movl %%ecx, %1 \n\t" \ + "movl %%edi, %2 \n\t" \ + "movl %%esi, %3 \n\t" \ : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ : "eax", "ecx", "edx", "esi", "edi" \ @@ -167,266 +158,287 @@ #if defined(__amd64__) || defined (__x86_64__) -#define MULADDC_INIT \ - asm( "movq %0, %%rsi " :: "m" (s)); \ - asm( "movq %0, %%rdi " :: "m" (d)); \ - asm( "movq %0, %%rcx " :: "m" (c)); \ - asm( "movq %0, %%rbx " :: "m" (b)); \ - asm( "xorq %r8, %r8 " ); - -#define MULADDC_CORE \ - asm( "movq (%rsi),%rax " ); \ - asm( "mulq %rbx " ); \ - asm( "addq $8, %rsi " ); \ - asm( "addq %rcx, %rax " ); \ - asm( "movq %r8, %rcx " ); \ - asm( "adcq $0, %rdx " ); \ - asm( "nop " ); \ - asm( "addq %rax, (%rdi) " ); \ - asm( "adcq %rdx, %rcx " ); \ - asm( "addq $8, %rdi " ); - -#define MULADDC_STOP \ - asm( "movq %%rcx, %0 " : "=m" (c)); \ - asm( "movq %%rdi, %0 " : "=m" (d)); \ - asm( "movq %%rsi, %0 " : "=m" (s) :: \ - "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" ); +#define MULADDC_INIT \ + asm( \ + "movq %3, %%rsi \n\t" \ + "movq %4, %%rdi \n\t" \ + "movq %5, %%rcx \n\t" \ + "movq %6, %%rbx \n\t" \ + "xorq %%r8, %%r8 \n\t" + +#define MULADDC_CORE \ + "movq (%%rsi), %%rax \n\t" \ + "mulq %%rbx \n\t" \ + "addq $8, %%rsi \n\t" \ + "addq %%rcx, %%rax \n\t" \ + "movq %%r8, %%rcx \n\t" \ + "adcq $0, %%rdx \n\t" \ + "nop \n\t" \ + "addq %%rax, (%%rdi) \n\t" \ + "adcq %%rdx, %%rcx \n\t" \ + "addq $8, %%rdi \n\t" + +#define MULADDC_STOP \ + "movq %%rcx, %0 \n\t" \ + "movq %%rdi, %1 \n\t" \ + "movq %%rsi, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" \ + ); #endif /* AMD64 */ #if defined(__mc68020__) || defined(__mcpu32__) -#define MULADDC_INIT \ - asm( "movl %0, %%a2 " :: "m" (s)); \ - asm( "movl %0, %%a3 " :: "m" (d)); \ - asm( "movl %0, %%d3 " :: "m" (c)); \ - asm( "movl %0, %%d2 " :: "m" (b)); \ - asm( "moveq #0, %d0 " ); +#define MULADDC_INIT \ + asm( \ + "movl %3, %%a2 \n\t" \ + "movl %4, %%a3 \n\t" \ + "movl %5, %%d3 \n\t" \ + "movl %6, %%d2 \n\t" \ + "moveq #0, %%d0 \n\t" -#define MULADDC_CORE \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d4:%d1 " ); \ - asm( "addl %d3, %d1 " ); \ - asm( "addxl %d0, %d4 " ); \ - asm( "moveq #0, %d3 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "addxl %d4, %d3 " ); +#define MULADDC_CORE \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d4:%%d1 \n\t" \ + "addl %%d3, %%d1 \n\t" \ + "addxl %%d0, %%d4 \n\t" \ + "moveq #0, %%d3 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "addxl %%d4, %%d3 \n\t" -#define MULADDC_STOP \ - asm( "movl %%d3, %0 " : "=m" (c)); \ - asm( "movl %%a3, %0 " : "=m" (d)); \ - asm( "movl %%a2, %0 " : "=m" (s) :: \ - "d0", "d1", "d2", "d3", "d4", "a2", "a3" ); +#define MULADDC_STOP \ + "movl %%d3, %0 \n\t" \ + "movl %%a3, %1 \n\t" \ + "movl %%a2, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "d0", "d1", "d2", "d3", "d4", "a2", "a3" \ + ); -#define MULADDC_HUIT \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d4:%d1 " ); \ - asm( "addxl %d3, %d1 " ); \ - asm( "addxl %d0, %d4 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d3:%d1 " ); \ - asm( "addxl %d4, %d1 " ); \ - asm( "addxl %d0, %d3 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d4:%d1 " ); \ - asm( "addxl %d3, %d1 " ); \ - asm( "addxl %d0, %d4 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d3:%d1 " ); \ - asm( "addxl %d4, %d1 " ); \ - asm( "addxl %d0, %d3 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d4:%d1 " ); \ - asm( "addxl %d3, %d1 " ); \ - asm( "addxl %d0, %d4 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d3:%d1 " ); \ - asm( "addxl %d4, %d1 " ); \ - asm( "addxl %d0, %d3 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d4:%d1 " ); \ - asm( "addxl %d3, %d1 " ); \ - asm( "addxl %d0, %d4 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d3:%d1 " ); \ - asm( "addxl %d4, %d1 " ); \ - asm( "addxl %d0, %d3 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "addxl %d0, %d3 " ); +#define MULADDC_HUIT \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d4:%%d1 \n\t" \ + "addxl %%d3, %%d1 \n\t" \ + "addxl %%d0, %%d4 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d3:%%d1 \n\t" \ + "addxl %%d4, %%d1 \n\t" \ + "addxl %%d0, %%d3 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d4:%%d1 \n\t" \ + "addxl %%d3, %%d1 \n\t" \ + "addxl %%d0, %%d4 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d3:%%d1 \n\t" \ + "addxl %%d4, %%d1 \n\t" \ + "addxl %%d0, %%d3 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d4:%%d1 \n\t" \ + "addxl %%d3, %%d1 \n\t" \ + "addxl %%d0, %%d4 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d3:%%d1 \n\t" \ + "addxl %%d4, %%d1 \n\t" \ + "addxl %%d0, %%d3 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d4:%%d1 \n\t" \ + "addxl %%d3, %%d1 \n\t" \ + "addxl %%d0, %%d4 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d3:%%d1 \n\t" \ + "addxl %%d4, %%d1 \n\t" \ + "addxl %%d0, %%d3 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "addxl %%d0, %%d3 \n\t" #endif /* MC68000 */ -#if defined(__powerpc__) || defined(__ppc__) #if defined(__powerpc64__) || defined(__ppc64__) #if defined(__MACH__) && defined(__APPLE__) -#define MULADDC_INIT \ - asm( "ld r3, %0 " :: "m" (s)); \ - asm( "ld r4, %0 " :: "m" (d)); \ - asm( "ld r5, %0 " :: "m" (c)); \ - asm( "ld r6, %0 " :: "m" (b)); \ - asm( "addi r3, r3, -8 " ); \ - asm( "addi r4, r4, -8 " ); \ - asm( "addic r5, r5, 0 " ); - -#define MULADDC_CORE \ - asm( "ldu r7, 8(r3) " ); \ - asm( "mulld r8, r7, r6 " ); \ - asm( "mulhdu r9, r7, r6 " ); \ - asm( "adde r8, r8, r5 " ); \ - asm( "ld r7, 8(r4) " ); \ - asm( "addze r5, r9 " ); \ - asm( "addc r8, r8, r7 " ); \ - asm( "stdu r8, 8(r4) " ); - -#define MULADDC_STOP \ - asm( "addze r5, r5 " ); \ - asm( "addi r4, r4, 8 " ); \ - asm( "addi r3, r3, 8 " ); \ - asm( "std r5, %0 " : "=m" (c)); \ - asm( "std r4, %0 " : "=m" (d)); \ - asm( "std r3, %0 " : "=m" (s) :: \ - "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); - -#else - -#define MULADDC_INIT \ - asm( "ld %%r3, %0 " :: "m" (s)); \ - asm( "ld %%r4, %0 " :: "m" (d)); \ - asm( "ld %%r5, %0 " :: "m" (c)); \ - asm( "ld %%r6, %0 " :: "m" (b)); \ - asm( "addi %r3, %r3, -8 " ); \ - asm( "addi %r4, %r4, -8 " ); \ - asm( "addic %r5, %r5, 0 " ); +#define MULADDC_INIT \ + asm( \ + "ld r3, %3 \n\t" \ + "ld r4, %4 \n\t" \ + "ld r5, %5 \n\t" \ + "ld r6, %6 \n\t" \ + "addi r3, r3, -8 \n\t" \ + "addi r4, r4, -8 \n\t" \ + "addic r5, r5, 0 \n\t" + +#define MULADDC_CORE \ + "ldu r7, 8(r3) \n\t" \ + "mulld r8, r7, r6 \n\t" \ + "mulhdu r9, r7, r6 \n\t" \ + "adde r8, r8, r5 \n\t" \ + "ld r7, 8(r4) \n\t" \ + "addze r5, r9 \n\t" \ + "addc r8, r8, r7 \n\t" \ + "stdu r8, 8(r4) \n\t" + +#define MULADDC_STOP \ + "addze r5, r5 \n\t" \ + "addi r4, r4, 8 \n\t" \ + "addi r3, r3, 8 \n\t" \ + "std r5, %0 \n\t" \ + "std r4, %1 \n\t" \ + "std r3, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ + ); -#define MULADDC_CORE \ - asm( "ldu %r7, 8(%r3) " ); \ - asm( "mulld %r8, %r7, %r6 " ); \ - asm( "mulhdu %r9, %r7, %r6 " ); \ - asm( "adde %r8, %r8, %r5 " ); \ - asm( "ld %r7, 8(%r4) " ); \ - asm( "addze %r5, %r9 " ); \ - asm( "addc %r8, %r8, %r7 " ); \ - asm( "stdu %r8, 8(%r4) " ); -#define MULADDC_STOP \ - asm( "addze %r5, %r5 " ); \ - asm( "addi %r4, %r4, 8 " ); \ - asm( "addi %r3, %r3, 8 " ); \ - asm( "std %%r5, %0 " : "=m" (c)); \ - asm( "std %%r4, %0 " : "=m" (d)); \ - asm( "std %%r3, %0 " : "=m" (s) :: \ - "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); +#else /* __MACH__ && __APPLE__ */ + +#define MULADDC_INIT \ + asm( \ + "ld %%r3, %3 \n\t" \ + "ld %%r4, %4 \n\t" \ + "ld %%r5, %5 \n\t" \ + "ld %%r6, %6 \n\t" \ + "addi %%r3, %%r3, -8 \n\t" \ + "addi %%r4, %%r4, -8 \n\t" \ + "addic %%r5, %%r5, 0 \n\t" + +#define MULADDC_CORE \ + "ldu %%r7, 8(%%r3) \n\t" \ + "mulld %%r8, %%r7, %%r6 \n\t" \ + "mulhdu %%r9, %%r7, %%r6 \n\t" \ + "adde %%r8, %%r8, %%r5 \n\t" \ + "ld %%r7, 8(%%r4) \n\t" \ + "addze %%r5, %%r9 \n\t" \ + "addc %%r8, %%r8, %%r7 \n\t" \ + "stdu %%r8, 8(%%r4) \n\t" + +#define MULADDC_STOP \ + "addze %%r5, %%r5 \n\t" \ + "addi %%r4, %%r4, 8 \n\t" \ + "addi %%r3, %%r3, 8 \n\t" \ + "std %%r5, %0 \n\t" \ + "std %%r4, %1 \n\t" \ + "std %%r3, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ + ); -#endif +#endif /* __MACH__ && __APPLE__ */ -#else /* PPC32 */ +#elif defined(__powerpc__) || defined(__ppc__) /* end PPC64/begin PPC32 */ #if defined(__MACH__) && defined(__APPLE__) -#define MULADDC_INIT \ - asm( "lwz r3, %0 " :: "m" (s)); \ - asm( "lwz r4, %0 " :: "m" (d)); \ - asm( "lwz r5, %0 " :: "m" (c)); \ - asm( "lwz r6, %0 " :: "m" (b)); \ - asm( "addi r3, r3, -4 " ); \ - asm( "addi r4, r4, -4 " ); \ - asm( "addic r5, r5, 0 " ); - -#define MULADDC_CORE \ - asm( "lwzu r7, 4(r3) " ); \ - asm( "mullw r8, r7, r6 " ); \ - asm( "mulhwu r9, r7, r6 " ); \ - asm( "adde r8, r8, r5 " ); \ - asm( "lwz r7, 4(r4) " ); \ - asm( "addze r5, r9 " ); \ - asm( "addc r8, r8, r7 " ); \ - asm( "stwu r8, 4(r4) " ); - -#define MULADDC_STOP \ - asm( "addze r5, r5 " ); \ - asm( "addi r4, r4, 4 " ); \ - asm( "addi r3, r3, 4 " ); \ - asm( "stw r5, %0 " : "=m" (c)); \ - asm( "stw r4, %0 " : "=m" (d)); \ - asm( "stw r3, %0 " : "=m" (s) :: \ - "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); - -#else +#define MULADDC_INIT \ + asm( \ + "lwz r3, %3 \n\t" \ + "lwz r4, %4 \n\t" \ + "lwz r5, %5 \n\t" \ + "lwz r6, %6 \n\t" \ + "addi r3, r3, -4 \n\t" \ + "addi r4, r4, -4 \n\t" \ + "addic r5, r5, 0 \n\t" -#define MULADDC_INIT \ - asm( "lwz %%r3, %0 " :: "m" (s)); \ - asm( "lwz %%r4, %0 " :: "m" (d)); \ - asm( "lwz %%r5, %0 " :: "m" (c)); \ - asm( "lwz %%r6, %0 " :: "m" (b)); \ - asm( "addi %r3, %r3, -4 " ); \ - asm( "addi %r4, %r4, -4 " ); \ - asm( "addic %r5, %r5, 0 " ); +#define MULADDC_CORE \ + "lwzu r7, 4(r3) \n\t" \ + "mullw r8, r7, r6 \n\t" \ + "mulhwu r9, r7, r6 \n\t" \ + "adde r8, r8, r5 \n\t" \ + "lwz r7, 4(r4) \n\t" \ + "addze r5, r9 \n\t" \ + "addc r8, r8, r7 \n\t" \ + "stwu r8, 4(r4) \n\t" -#define MULADDC_CORE \ - asm( "lwzu %r7, 4(%r3) " ); \ - asm( "mullw %r8, %r7, %r6 " ); \ - asm( "mulhwu %r9, %r7, %r6 " ); \ - asm( "adde %r8, %r8, %r5 " ); \ - asm( "lwz %r7, 4(%r4) " ); \ - asm( "addze %r5, %r9 " ); \ - asm( "addc %r8, %r8, %r7 " ); \ - asm( "stwu %r8, 4(%r4) " ); +#define MULADDC_STOP \ + "addze r5, r5 \n\t" \ + "addi r4, r4, 4 \n\t" \ + "addi r3, r3, 4 \n\t" \ + "stw r5, %0 \n\t" \ + "stw r4, %1 \n\t" \ + "stw r3, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ + ); -#define MULADDC_STOP \ - asm( "addze %r5, %r5 " ); \ - asm( "addi %r4, %r4, 4 " ); \ - asm( "addi %r3, %r3, 4 " ); \ - asm( "stw %%r5, %0 " : "=m" (c)); \ - asm( "stw %%r4, %0 " : "=m" (d)); \ - asm( "stw %%r3, %0 " : "=m" (s) :: \ - "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); +#else /* __MACH__ && __APPLE__ */ + +#define MULADDC_INIT \ + asm( \ + "lwz %%r3, %3 \n\t" \ + "lwz %%r4, %4 \n\t" \ + "lwz %%r5, %5 \n\t" \ + "lwz %%r6, %6 \n\t" \ + "addi %%r3, %%r3, -4 \n\t" \ + "addi %%r4, %%r4, -4 \n\t" \ + "addic %%r5, %%r5, 0 \n\t" + +#define MULADDC_CORE \ + "lwzu %%r7, 4(%%r3) \n\t" \ + "mullw %%r8, %%r7, %%r6 \n\t" \ + "mulhwu %%r9, %%r7, %%r6 \n\t" \ + "adde %%r8, %%r8, %%r5 \n\t" \ + "lwz %%r7, 4(%%r4) \n\t" \ + "addze %%r5, %%r9 \n\t" \ + "addc %%r8, %%r8, %%r7 \n\t" \ + "stwu %%r8, 4(%%r4) \n\t" + +#define MULADDC_STOP \ + "addze %%r5, %%r5 \n\t" \ + "addi %%r4, %%r4, 4 \n\t" \ + "addi %%r3, %%r3, 4 \n\t" \ + "stw %%r5, %0 \n\t" \ + "stw %%r4, %1 \n\t" \ + "stw %%r3, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ + ); -#endif +#endif /* __MACH__ && __APPLE__ */ #endif /* PPC32 */ -#endif /* PPC64 */ - -#if defined(__sparc__) && defined(__sparc64__) - -#define MULADDC_INIT \ - asm( \ - " \ - ldx %3, %%o0; \ - ldx %4, %%o1; \ - ld %5, %%o2; \ - ld %6, %%o3; \ - " -#define MULADDC_CORE \ - " \ - ld [%%o0], %%o4; \ - inc 4, %%o0; \ - ld [%%o1], %%o5; \ - umul %%o3, %%o4, %%o4; \ - addcc %%o4, %%o2, %%o4; \ - rd %%y, %%g1; \ - addx %%g1, 0, %%g1; \ - addcc %%o4, %%o5, %%o4; \ - st %%o4, [%%o1]; \ - addx %%g1, 0, %%o2; \ - inc 4, %%o1; \ - " - -#define MULADDC_STOP \ - " \ - st %%o2, %0; \ - stx %%o1, %1; \ - stx %%o0, %2; \ - " \ +/* + * The Sparc64 assembly is reported to be broken. + * Disable it for now, until we're able to fix it. + */ +#if 0 && defined(__sparc__) && defined(__sparc64__) + +#define MULADDC_INIT \ + asm( \ + "ldx %3, %%o0 \n\t" \ + "ldx %4, %%o1 \n\t" \ + "ld %5, %%o2 \n\t" \ + "ld %6, %%o3 \n\t" + +#define MULADDC_CORE \ + "ld [%%o0], %%o4 \n\t" \ + "inc 4, %%o0 \n\t" \ + "ld [%%o1], %%o5 \n\t" \ + "umul %%o3, %%o4, %%o4 \n\t" \ + "addcc %%o4, %%o2, %%o4 \n\t" \ + "rd %%y, %%g1 \n\t" \ + "addx %%g1, 0, %%g1 \n\t" \ + "addcc %%o4, %%o5, %%o4 \n\t" \ + "st %%o4, [%%o1] \n\t" \ + "addx %%g1, 0, %%o2 \n\t" \ + "inc 4, %%o1 \n\t" + + #define MULADDC_STOP \ + "st %%o2, %0 \n\t" \ + "stx %%o1, %1 \n\t" \ + "stx %%o0, %2 \n\t" \ : "=m" (c), "=m" (d), "=m" (s) \ : "m" (s), "m" (d), "m" (c), "m" (b) \ : "g1", "o0", "o1", "o2", "o3", "o4", \ @@ -436,36 +448,30 @@ #if defined(__sparc__) && !defined(__sparc64__) -#define MULADDC_INIT \ - asm( \ - " \ - ld %3, %%o0; \ - ld %4, %%o1; \ - ld %5, %%o2; \ - ld %6, %%o3; \ - " - -#define MULADDC_CORE \ - " \ - ld [%%o0], %%o4; \ - inc 4, %%o0; \ - ld [%%o1], %%o5; \ - umul %%o3, %%o4, %%o4; \ - addcc %%o4, %%o2, %%o4; \ - rd %%y, %%g1; \ - addx %%g1, 0, %%g1; \ - addcc %%o4, %%o5, %%o4; \ - st %%o4, [%%o1]; \ - addx %%g1, 0, %%o2; \ - inc 4, %%o1; \ - " - -#define MULADDC_STOP \ - " \ - st %%o2, %0; \ - st %%o1, %1; \ - st %%o0, %2; \ - " \ +#define MULADDC_INIT \ + asm( \ + "ld %3, %%o0 \n\t" \ + "ld %4, %%o1 \n\t" \ + "ld %5, %%o2 \n\t" \ + "ld %6, %%o3 \n\t" + +#define MULADDC_CORE \ + "ld [%%o0], %%o4 \n\t" \ + "inc 4, %%o0 \n\t" \ + "ld [%%o1], %%o5 \n\t" \ + "umul %%o3, %%o4, %%o4 \n\t" \ + "addcc %%o4, %%o2, %%o4 \n\t" \ + "rd %%y, %%g1 \n\t" \ + "addx %%g1, 0, %%g1 \n\t" \ + "addcc %%o4, %%o5, %%o4 \n\t" \ + "st %%o4, [%%o1] \n\t" \ + "addx %%g1, 0, %%o2 \n\t" \ + "inc 4, %%o1 \n\t" + +#define MULADDC_STOP \ + "st %%o2, %0 \n\t" \ + "st %%o1, %1 \n\t" \ + "st %%o0, %2 \n\t" \ : "=m" (c), "=m" (d), "=m" (s) \ : "m" (s), "m" (d), "m" (c), "m" (b) \ : "g1", "o0", "o1", "o2", "o3", "o4", \ @@ -476,73 +482,81 @@ #if defined(__microblaze__) || defined(microblaze) -#define MULADDC_INIT \ - asm( "lwi r3, %0 " :: "m" (s)); \ - asm( "lwi r4, %0 " :: "m" (d)); \ - asm( "lwi r5, %0 " :: "m" (c)); \ - asm( "lwi r6, %0 " :: "m" (b)); \ - asm( "andi r7, r6, 0xffff" ); \ - asm( "bsrli r6, r6, 16 " ); +#define MULADDC_INIT \ + asm( \ + "lwi r3, %3 \n\t" \ + "lwi r4, %4 \n\t" \ + "lwi r5, %5 \n\t" \ + "lwi r6, %6 \n\t" \ + "andi r7, r6, 0xffff \n\t" \ + "bsrli r6, r6, 16 \n\t" -#define MULADDC_CORE \ - asm( "lhui r8, r3, 0 " ); \ - asm( "addi r3, r3, 2 " ); \ - asm( "lhui r9, r3, 0 " ); \ - asm( "addi r3, r3, 2 " ); \ - asm( "mul r10, r9, r6 " ); \ - asm( "mul r11, r8, r7 " ); \ - asm( "mul r12, r9, r7 " ); \ - asm( "mul r13, r8, r6 " ); \ - asm( "bsrli r8, r10, 16 " ); \ - asm( "bsrli r9, r11, 16 " ); \ - asm( "add r13, r13, r8 " ); \ - asm( "add r13, r13, r9 " ); \ - asm( "bslli r10, r10, 16 " ); \ - asm( "bslli r11, r11, 16 " ); \ - asm( "add r12, r12, r10 " ); \ - asm( "addc r13, r13, r0 " ); \ - asm( "add r12, r12, r11 " ); \ - asm( "addc r13, r13, r0 " ); \ - asm( "lwi r10, r4, 0 " ); \ - asm( "add r12, r12, r10 " ); \ - asm( "addc r13, r13, r0 " ); \ - asm( "add r12, r12, r5 " ); \ - asm( "addc r5, r13, r0 " ); \ - asm( "swi r12, r4, 0 " ); \ - asm( "addi r4, r4, 4 " ); +#define MULADDC_CORE \ + "lhui r8, r3, 0 \n\t" \ + "addi r3, r3, 2 \n\t" \ + "lhui r9, r3, 0 \n\t" \ + "addi r3, r3, 2 \n\t" \ + "mul r10, r9, r6 \n\t" \ + "mul r11, r8, r7 \n\t" \ + "mul r12, r9, r7 \n\t" \ + "mul r13, r8, r6 \n\t" \ + "bsrli r8, r10, 16 \n\t" \ + "bsrli r9, r11, 16 \n\t" \ + "add r13, r13, r8 \n\t" \ + "add r13, r13, r9 \n\t" \ + "bslli r10, r10, 16 \n\t" \ + "bslli r11, r11, 16 \n\t" \ + "add r12, r12, r10 \n\t" \ + "addc r13, r13, r0 \n\t" \ + "add r12, r12, r11 \n\t" \ + "addc r13, r13, r0 \n\t" \ + "lwi r10, r4, 0 \n\t" \ + "add r12, r12, r10 \n\t" \ + "addc r13, r13, r0 \n\t" \ + "add r12, r12, r5 \n\t" \ + "addc r5, r13, r0 \n\t" \ + "swi r12, r4, 0 \n\t" \ + "addi r4, r4, 4 \n\t" -#define MULADDC_STOP \ - asm( "swi r5, %0 " : "=m" (c)); \ - asm( "swi r4, %0 " : "=m" (d)); \ - asm( "swi r3, %0 " : "=m" (s) :: \ - "r3", "r4" , "r5" , "r6" , "r7" , "r8" , \ - "r9", "r10", "r11", "r12", "r13" ); +#define MULADDC_STOP \ + "swi r5, %0 \n\t" \ + "swi r4, %1 \n\t" \ + "swi r3, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r3", "r4" "r5", "r6", "r7", "r8", \ + "r9", "r10", "r11", "r12", "r13" \ + ); #endif /* MicroBlaze */ #if defined(__tricore__) #define MULADDC_INIT \ - asm( "ld.a %%a2, %0 " :: "m" (s)); \ - asm( "ld.a %%a3, %0 " :: "m" (d)); \ - asm( "ld.w %%d4, %0 " :: "m" (c)); \ - asm( "ld.w %%d1, %0 " :: "m" (b)); \ - asm( "xor %d5, %d5 " ); + asm( \ + "ld.a %%a2, %3 \n\t" \ + "ld.a %%a3, %4 \n\t" \ + "ld.w %%d4, %5 \n\t" \ + "ld.w %%d1, %6 \n\t" \ + "xor %%d5, %%d5 \n\t" #define MULADDC_CORE \ - asm( "ld.w %d0, [%a2+] " ); \ - asm( "madd.u %e2, %e4, %d0, %d1 " ); \ - asm( "ld.w %d0, [%a3] " ); \ - asm( "addx %d2, %d2, %d0 " ); \ - asm( "addc %d3, %d3, 0 " ); \ - asm( "mov %d4, %d3 " ); \ - asm( "st.w [%a3+], %d2 " ); + "ld.w %%d0, [%%a2+] \n\t" \ + "madd.u %%e2, %%e4, %%d0, %%d1 \n\t" \ + "ld.w %%d0, [%%a3] \n\t" \ + "addx %%d2, %%d2, %%d0 \n\t" \ + "addc %%d3, %%d3, 0 \n\t" \ + "mov %%d4, %%d3 \n\t" \ + "st.w [%%a3+], %%d2 \n\t" #define MULADDC_STOP \ - asm( "st.w %0, %%d4 " : "=m" (c)); \ - asm( "st.a %0, %%a3 " : "=m" (d)); \ - asm( "st.a %0, %%a2 " : "=m" (s) :: \ - "d0", "d1", "e2", "d4", "a2", "a3" ); + "st.w %0, %%d4 \n\t" \ + "st.a %1, %%a3 \n\t" \ + "st.a %2, %%a2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "d0", "d1", "e2", "d4", "a2", "a3" \ + ); #endif /* TriCore */ @@ -550,59 +564,53 @@ #if defined(__thumb__) && !defined(__thumb2__) -#define MULADDC_INIT \ - asm( \ - " \ - ldr r0, %3; \ - ldr r1, %4; \ - ldr r2, %5; \ - ldr r3, %6; \ - lsr r7, r3, #16; \ - mov r9, r7; \ - lsl r7, r3, #16; \ - lsr r7, r7, #16; \ - mov r8, r7; \ - " - -#define MULADDC_CORE \ - " \ - ldmia r0!, {r6}; \ - lsr r7, r6, #16; \ - lsl r6, r6, #16; \ - lsr r6, r6, #16; \ - mov r4, r8; \ - mul r4, r6; \ - mov r3, r9; \ - mul r6, r3; \ - mov r5, r9; \ - mul r5, r7; \ - mov r3, r8; \ - mul r7, r3; \ - lsr r3, r6, #16; \ - add r5, r5, r3; \ - lsr r3, r7, #16; \ - add r5, r5, r3; \ - add r4, r4, r2; \ - mov r2, #0; \ - adc r5, r2; \ - lsl r3, r6, #16; \ - add r4, r4, r3; \ - adc r5, r2; \ - lsl r3, r7, #16; \ - add r4, r4, r3; \ - adc r5, r2; \ - ldr r3, [r1]; \ - add r4, r4, r3; \ - adc r2, r5; \ - stmia r1!, {r4}; \ - " - -#define MULADDC_STOP \ - " \ - str r2, %0; \ - str r1, %1; \ - str r0, %2; \ - " \ +#define MULADDC_INIT \ + asm( \ + "ldr r0, %3 \n\t" \ + "ldr r1, %4 \n\t" \ + "ldr r2, %5 \n\t" \ + "ldr r3, %6 \n\t" \ + "lsr r7, r3, #16 \n\t" \ + "mov r9, r7 \n\t" \ + "lsl r7, r3, #16 \n\t" \ + "lsr r7, r7, #16 \n\t" \ + "mov r8, r7 \n\t" + +#define MULADDC_CORE \ + "ldmia r0!, {r6} \n\t" \ + "lsr r7, r6, #16 \n\t" \ + "lsl r6, r6, #16 \n\t" \ + "lsr r6, r6, #16 \n\t" \ + "mov r4, r8 \n\t" \ + "mul r4, r6 \n\t" \ + "mov r3, r9 \n\t" \ + "mul r6, r3 \n\t" \ + "mov r5, r9 \n\t" \ + "mul r5, r7 \n\t" \ + "mov r3, r8 \n\t" \ + "mul r7, r3 \n\t" \ + "lsr r3, r6, #16 \n\t" \ + "add r5, r5, r3 \n\t" \ + "lsr r3, r7, #16 \n\t" \ + "add r5, r5, r3 \n\t" \ + "add r4, r4, r2 \n\t" \ + "mov r2, #0 \n\t" \ + "adc r5, r2 \n\t" \ + "lsl r3, r6, #16 \n\t" \ + "add r4, r4, r3 \n\t" \ + "adc r5, r2 \n\t" \ + "lsl r3, r7, #16 \n\t" \ + "add r4, r4, r3 \n\t" \ + "adc r5, r2 \n\t" \ + "ldr r3, [r1] \n\t" \ + "add r4, r4, r3 \n\t" \ + "adc r2, r5 \n\t" \ + "stmia r1!, {r4} \n\t" + +#define MULADDC_STOP \ + "str r2, %0 \n\t" \ + "str r1, %1 \n\t" \ + "str r0, %2 \n\t" \ : "=m" (c), "=m" (d), "=m" (s) \ : "m" (s), "m" (d), "m" (c), "m" (b) \ : "r0", "r1", "r2", "r3", "r4", "r5", \ @@ -611,32 +619,26 @@ #else -#define MULADDC_INIT \ - asm( \ - " \ - ldr r0, %3; \ - ldr r1, %4; \ - ldr r2, %5; \ - ldr r3, %6; \ - " - -#define MULADDC_CORE \ - " \ - ldr r4, [r0], #4; \ - mov r5, #0; \ - ldr r6, [r1]; \ - umlal r2, r5, r3, r4; \ - adds r7, r6, r2; \ - adc r2, r5, #0; \ - str r7, [r1], #4; \ - " - -#define MULADDC_STOP \ - " \ - str r2, %0; \ - str r1, %1; \ - str r0, %2; \ - " \ +#define MULADDC_INIT \ + asm( \ + "ldr r0, %3 \n\t" \ + "ldr r1, %4 \n\t" \ + "ldr r2, %5 \n\t" \ + "ldr r3, %6 \n\t" + +#define MULADDC_CORE \ + "ldr r4, [r0], #4 \n\t" \ + "mov r5, #0 \n\t" \ + "ldr r6, [r1] \n\t" \ + "umlal r2, r5, r3, r4 \n\t" \ + "adds r7, r6, r2 \n\t" \ + "adc r2, r5, #0 \n\t" \ + "str r7, [r1], #4 \n\t" + +#define MULADDC_STOP \ + "str r2, %0 \n\t" \ + "str r1, %1 \n\t" \ + "str r0, %2 \n\t" \ : "=m" (c), "=m" (d), "=m" (s) \ : "m" (s), "m" (d), "m" (c), "m" (b) \ : "r0", "r1", "r2", "r3", "r4", "r5", \ @@ -649,64 +651,71 @@ #if defined(__alpha__) -#define MULADDC_INIT \ - asm( "ldq $1, %0 " :: "m" (s)); \ - asm( "ldq $2, %0 " :: "m" (d)); \ - asm( "ldq $3, %0 " :: "m" (c)); \ - asm( "ldq $4, %0 " :: "m" (b)); - -#define MULADDC_CORE \ - asm( "ldq $6, 0($1) " ); \ - asm( "addq $1, 8, $1 " ); \ - asm( "mulq $6, $4, $7 " ); \ - asm( "umulh $6, $4, $6 " ); \ - asm( "addq $7, $3, $7 " ); \ - asm( "cmpult $7, $3, $3 " ); \ - asm( "ldq $5, 0($2) " ); \ - asm( "addq $7, $5, $7 " ); \ - asm( "cmpult $7, $5, $5 " ); \ - asm( "stq $7, 0($2) " ); \ - asm( "addq $2, 8, $2 " ); \ - asm( "addq $6, $3, $3 " ); \ - asm( "addq $5, $3, $3 " ); - -#define MULADDC_STOP \ - asm( "stq $3, %0 " : "=m" (c)); \ - asm( "stq $2, %0 " : "=m" (d)); \ - asm( "stq $1, %0 " : "=m" (s) :: \ - "$1", "$2", "$3", "$4", "$5", "$6", "$7" ); +#define MULADDC_INIT \ + asm( \ + "ldq $1, %3 \n\t" \ + "ldq $2, %4 \n\t" \ + "ldq $3, %5 \n\t" \ + "ldq $4, %6 \n\t" +#define MULADDC_CORE \ + "ldq $6, 0($1) \n\t" \ + "addq $1, 8, $1 \n\t" \ + "mulq $6, $4, $7 \n\t" \ + "umulh $6, $4, $6 \n\t" \ + "addq $7, $3, $7 \n\t" \ + "cmpult $7, $3, $3 \n\t" \ + "ldq $5, 0($2) \n\t" \ + "addq $7, $5, $7 \n\t" \ + "cmpult $7, $5, $5 \n\t" \ + "stq $7, 0($2) \n\t" \ + "addq $2, 8, $2 \n\t" \ + "addq $6, $3, $3 \n\t" \ + "addq $5, $3, $3 \n\t" + +#define MULADDC_STOP \ + "stq $3, %0 \n\t" \ + "stq $2, %1 \n\t" \ + "stq $1, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "$1", "$2", "$3", "$4", "$5", "$6", "$7" \ + ); #endif /* Alpha */ -#if defined(__mips__) +#if defined(__mips__) && !defined(__mips64__) -#define MULADDC_INIT \ - asm( "lw $10, %0 " :: "m" (s)); \ - asm( "lw $11, %0 " :: "m" (d)); \ - asm( "lw $12, %0 " :: "m" (c)); \ - asm( "lw $13, %0 " :: "m" (b)); +#define MULADDC_INIT \ + asm( \ + "lw $10, %3 \n\t" \ + "lw $11, %4 \n\t" \ + "lw $12, %5 \n\t" \ + "lw $13, %6 \n\t" -#define MULADDC_CORE \ - asm( "lw $14, 0($10) " ); \ - asm( "multu $13, $14 " ); \ - asm( "addi $10, $10, 4 " ); \ - asm( "mflo $14 " ); \ - asm( "mfhi $9 " ); \ - asm( "addu $14, $12, $14 " ); \ - asm( "lw $15, 0($11) " ); \ - asm( "sltu $12, $14, $12 " ); \ - asm( "addu $15, $14, $15 " ); \ - asm( "sltu $14, $15, $14 " ); \ - asm( "addu $12, $12, $9 " ); \ - asm( "sw $15, 0($11) " ); \ - asm( "addu $12, $12, $14 " ); \ - asm( "addi $11, $11, 4 " ); +#define MULADDC_CORE \ + "lw $14, 0($10) \n\t" \ + "multu $13, $14 \n\t" \ + "addi $10, $10, 4 \n\t" \ + "mflo $14 \n\t" \ + "mfhi $9 \n\t" \ + "addu $14, $12, $14 \n\t" \ + "lw $15, 0($11) \n\t" \ + "sltu $12, $14, $12 \n\t" \ + "addu $15, $14, $15 \n\t" \ + "sltu $14, $15, $14 \n\t" \ + "addu $12, $12, $9 \n\t" \ + "sw $15, 0($11) \n\t" \ + "addu $12, $12, $14 \n\t" \ + "addi $11, $11, 4 \n\t" -#define MULADDC_STOP \ - asm( "sw $12, %0 " : "=m" (c)); \ - asm( "sw $11, %0 " : "=m" (d)); \ - asm( "sw $10, %0 " : "=m" (s) :: \ - "$9", "$10", "$11", "$12", "$13", "$14", "$15" ); +#define MULADDC_STOP \ + "sw $12, %0 \n\t" \ + "sw $11, %1 \n\t" \ + "sw $10, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "$9", "$10", "$11", "$12", "$13", "$14", "$15" \ + ); #endif /* MIPS */ #endif /* GNUC */ diff --git a/pdns/ext/polarssl/include/polarssl/camellia.h b/pdns/ext/polarssl/include/polarssl/camellia.h index c98512f3d..8488d1df8 100644 --- a/pdns/ext/polarssl/include/polarssl/camellia.h +++ b/pdns/ext/polarssl/include/polarssl/camellia.h @@ -3,7 +3,7 @@ * * \brief Camellia block cipher * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ #ifndef POLARSSL_CAMELLIA_H #define POLARSSL_CAMELLIA_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include @@ -62,16 +66,31 @@ typedef struct } camellia_context; +/** + * \brief Initialize CAMELLIA context + * + * \param ctx CAMELLIA context to be initialized + */ +void camellia_init( camellia_context *ctx ); + +/** + * \brief Clear CAMELLIA context + * + * \param ctx CAMELLIA context to be cleared + */ +void camellia_free( camellia_context *ctx ); + /** * \brief CAMELLIA key schedule (encryption) * * \param ctx CAMELLIA context to be initialized * \param key encryption key * \param keysize must be 128, 192 or 256 - * + * * \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH */ -int camellia_setkey_enc( camellia_context *ctx, const unsigned char *key, unsigned int keysize ); +int camellia_setkey_enc( camellia_context *ctx, const unsigned char *key, + unsigned int keysize ); /** * \brief CAMELLIA key schedule (decryption) @@ -79,10 +98,11 @@ int camellia_setkey_enc( camellia_context *ctx, const unsigned char *key, unsign * \param ctx CAMELLIA context to be initialized * \param key decryption key * \param keysize must be 128, 192 or 256 - * + * * \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH */ -int camellia_setkey_dec( camellia_context *ctx, const unsigned char *key, unsigned int keysize ); +int camellia_setkey_dec( camellia_context *ctx, const unsigned char *key, + unsigned int keysize ); /** * \brief CAMELLIA-ECB block encryption/decryption @@ -91,7 +111,7 @@ int camellia_setkey_dec( camellia_context *ctx, const unsigned char *key, unsign * \param mode CAMELLIA_ENCRYPT or CAMELLIA_DECRYPT * \param input 16-byte input block * \param output 16-byte output block - * + * * \return 0 if successful */ int camellia_crypt_ecb( camellia_context *ctx, @@ -111,8 +131,9 @@ int camellia_crypt_ecb( camellia_context *ctx, * \param iv initialization vector (updated after use) * \param input buffer holding the input data * \param output buffer holding the output data - * - * \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH + * + * \return 0 if successful, or + * POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH */ int camellia_crypt_cbc( camellia_context *ctx, int mode, @@ -138,7 +159,8 @@ int camellia_crypt_cbc( camellia_context *ctx, * \param input buffer holding the input data * \param output buffer holding the output data * - * \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH + * \return 0 if successful, or + * POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH */ int camellia_crypt_cfb128( camellia_context *ctx, int mode, diff --git a/pdns/ext/polarssl/include/polarssl/ccm.h b/pdns/ext/polarssl/include/polarssl/ccm.h new file mode 100644 index 000000000..439152f9f --- /dev/null +++ b/pdns/ext/polarssl/include/polarssl/ccm.h @@ -0,0 +1,134 @@ +/** + * \file ccm.h + * + * \brief Counter with CBC-MAC (CCM) for 128-bit block ciphers + * + * Copyright (C) 2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_CCM_H +#define POLARSSL_CCM_H + +#include "cipher.h" + +#define POLARSSL_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to function. */ +#define POLARSSL_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief CCM context structure + */ +typedef struct { + cipher_context_t cipher_ctx; /*!< cipher context used */ +} +ccm_context; + +/** + * \brief CCM initialization (encryption and decryption) + * + * \param ctx CCM context to be initialized + * \param cipher cipher to use (a 128-bit block cipher) + * \param key encryption key + * \param keysize key size in bits (must be acceptable by the cipher) + * + * \return 0 if successful, or a cipher specific error code + */ +int ccm_init( ccm_context *ctx, cipher_id_t cipher, + const unsigned char *key, unsigned int keysize ); + +/** + * \brief Free a CCM context and underlying cipher sub-context + * + * \param ctx CCM context to free + */ +void ccm_free( ccm_context *ctx ); + +/** + * \brief CCM buffer encryption + * + * \param ctx CCM context + * \param length length of the input data in bytes + * \param iv nonce (initialization vector) + * \param iv_len length of IV in bytes + * must be 2, 3, 4, 5, 6, 7 or 8 + * \param add additional data + * \param add_len length of additional data in bytes + * must be less than 2^16 - 2^8 + * \param input buffer holding the input data + * \param output buffer for holding the output data + * must be at least 'length' bytes wide + * \param tag buffer for holding the tag + * \param tag_len length of the tag to generate in bytes + * must be 4, 6, 8, 10, 14 or 16 + * + * \note The tag is written to a separate buffer. To get the tag + * concatenated with the output as in the CCM spec, use + * tag = output + length and make sure the output buffer is + * at least length + tag_len wide. + * + * \return 0 if successful + */ +int ccm_encrypt_and_tag( ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ); + +/** + * \brief CCM buffer authenticated decryption + * + * \param ctx CCM context + * \param length length of the input data + * \param iv initialization vector + * \param iv_len length of IV + * \param add additional data + * \param add_len length of additional data + * \param input buffer holding the input data + * \param output buffer for holding the output data + * \param tag buffer holding the tag + * \param tag_len length of the tag + * + * \return 0 if successful and authenticated, + * POLARSSL_ERR_CCM_AUTH_FAILED if tag does not match + */ +int ccm_auth_decrypt( ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ); + +#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C) +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int ccm_self_test( int verbose ); +#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* POLARSSL_CGM_H */ diff --git a/pdns/ext/polarssl/include/polarssl/check_config.h b/pdns/ext/polarssl/include/polarssl/check_config.h new file mode 100644 index 000000000..328b881ea --- /dev/null +++ b/pdns/ext/polarssl/include/polarssl/check_config.h @@ -0,0 +1,326 @@ +/** + * \file check_config.h + * + * \brief Consistency checks for configuration options + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * It is recommended to include this file from your config.h + * in order to catch dependency issues early. + */ + +#ifndef POLARSSL_CHECK_CONFIG_H +#define POLARSSL_CHECK_CONFIG_H + +#if defined(POLARSSL_AESNI_C) && !defined(POLARSSL_HAVE_ASM) +#error "POLARSSL_AESNI_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_CERTS_C) && !defined(POLARSSL_PEM_PARSE_C) +#error "POLARSSL_CERTS_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_CTR_DRBG_C) && !defined(POLARSSL_AES_C) +#error "POLARSSL_CTR_DRBG_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_DHM_C) && !defined(POLARSSL_BIGNUM_C) +#error "POLARSSL_DHM_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_ECDH_C) && !defined(POLARSSL_ECP_C) +#error "POLARSSL_ECDH_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_ECDSA_C) && \ + ( !defined(POLARSSL_ECP_C) || \ + !defined(POLARSSL_ASN1_PARSE_C) || \ + !defined(POLARSSL_ASN1_WRITE_C) ) +#error "POLARSSL_ECDSA_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_ECDSA_DETERMINISTIC) && !defined(POLARSSL_HMAC_DRBG_C) +#error "POLARSSL_ECDSA_DETERMINISTIC defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_ECP_C) && ( !defined(POLARSSL_BIGNUM_C) || ( \ + !defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_BP256R1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_BP384R1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_BP512R1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) ) ) +#error "POLARSSL_ECP_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_ENTROPY_C) && (!defined(POLARSSL_SHA512_C) && \ + !defined(POLARSSL_SHA256_C)) +#error "POLARSSL_ENTROPY_C defined, but not all prerequisites" +#endif +#if defined(POLARSSL_ENTROPY_C) && defined(POLARSSL_SHA512_C) && \ + defined(CTR_DRBG_ENTROPY_LEN) && (CTR_DRBG_ENTROPY_LEN > 64) +#error "CTR_DRBG_ENTROPY_LEN value too high" +#endif +#if defined(POLARSSL_ENTROPY_C) && \ + ( !defined(POLARSSL_SHA512_C) || defined(POLARSSL_ENTROPY_FORCE_SHA256) ) \ + && defined(CTR_DRBG_ENTROPY_LEN) && (CTR_DRBG_ENTROPY_LEN > 32) +#error "CTR_DRBG_ENTROPY_LEN value too high" +#endif +#if defined(POLARSSL_ENTROPY_C) && \ + defined(POLARSSL_ENTROPY_FORCE_SHA256) && !defined(POLARSSL_SHA256_C) +#error "POLARSSL_ENTROPY_FORCE_SHA256 defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_GCM_C) && ( \ + !defined(POLARSSL_AES_C) && !defined(POLARSSL_CAMELLIA_C) ) +#error "POLARSSL_GCM_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_HAVEGE_C) && !defined(POLARSSL_TIMING_C) +#error "POLARSSL_HAVEGE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_HMAC_DRBG) && !defined(POLARSSL_MD_C) +#error "POLARSSL_HMAC_DRBG_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \ + ( !defined(POLARSSL_ECDH_C) || !defined(POLARSSL_X509_CRT_PARSE_C) ) +#error "POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + ( !defined(POLARSSL_ECDH_C) || !defined(POLARSSL_X509_CRT_PARSE_C) ) +#error "POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(POLARSSL_DHM_C) +#error "POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \ + !defined(POLARSSL_ECDH_C) +#error "POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + ( !defined(POLARSSL_DHM_C) || !defined(POLARSSL_RSA_C) || \ + !defined(POLARSSL_X509_CRT_PARSE_C) || !defined(POLARSSL_PKCS1_V15) ) +#error "POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + ( !defined(POLARSSL_ECDH_C) || !defined(POLARSSL_RSA_C) || \ + !defined(POLARSSL_X509_CRT_PARSE_C) || !defined(POLARSSL_PKCS1_V15) ) +#error "POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ + ( !defined(POLARSSL_ECDH_C) || !defined(POLARSSL_ECDSA_C) || \ + !defined(POLARSSL_X509_CRT_PARSE_C) ) +#error "POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ + ( !defined(POLARSSL_RSA_C) || !defined(POLARSSL_X509_CRT_PARSE_C) ||\ + !defined(POLARSSL_PKCS1_V15) ) +#error "POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \ + ( !defined(POLARSSL_RSA_C) || !defined(POLARSSL_X509_CRT_PARSE_C) ||\ + !defined(POLARSSL_PKCS1_V15) ) +#error "POLARSSL_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) && \ + ( !defined(POLARSSL_PLATFORM_C) || !defined(POLARSSL_PLATFORM_MEMORY) ) +#error "POLARSSL_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_PADLOCK_C) && !defined(POLARSSL_HAVE_ASM) +#error "POLARSSL_PADLOCK_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_PBKDF2_C) && !defined(POLARSSL_MD_C) +#error "POLARSSL_PBKDF2_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_PEM_PARSE_C) && !defined(POLARSSL_BASE64_C) +#error "POLARSSL_PEM_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_PEM_WRITE_C) && !defined(POLARSSL_BASE64_C) +#error "POLARSSL_PEM_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_PK_PARSE_C) && !defined(POLARSSL_PK_C) +#error "POLARSSL_PK_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_PK_WRITE_C) && !defined(POLARSSL_PK_C) +#error "POLARSSL_PK_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_PKCS11_C) && !defined(POLARSSL_PK_C) +#error "POLARSSL_PKCS11_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_RSA_C) && ( !defined(POLARSSL_BIGNUM_C) || \ + !defined(POLARSSL_OID_C) ) +#error "POLARSSL_RSA_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) && \ + ( !defined(POLARSSL_RSA_C) || !defined(POLARSSL_PKCS1_V21) ) +#error "POLARSSL_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_PROTO_SSL3) && ( !defined(POLARSSL_MD5_C) || \ + !defined(POLARSSL_SHA1_C) ) +#error "POLARSSL_SSL_PROTO_SSL3 defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_PROTO_TLS1) && ( !defined(POLARSSL_MD5_C) || \ + !defined(POLARSSL_SHA1_C) ) +#error "POLARSSL_SSL_PROTO_TLS1 defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_PROTO_TLS1_1) && ( !defined(POLARSSL_MD5_C) || \ + !defined(POLARSSL_SHA1_C) ) +#error "POLARSSL_SSL_PROTO_TLS1_1 defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_PROTO_TLS1_2) && ( !defined(POLARSSL_SHA1_C) && \ + !defined(POLARSSL_SHA256_C) && !defined(POLARSSL_SHA512_C) ) +#error "POLARSSL_SSL_PROTO_TLS1_2 defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_CLI_C) && !defined(POLARSSL_SSL_TLS_C) +#error "POLARSSL_SSL_CLI_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_TLS_C) && ( !defined(POLARSSL_CIPHER_C) || \ + !defined(POLARSSL_MD_C) ) +#error "POLARSSL_SSL_TLS_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_SRV_C) && !defined(POLARSSL_SSL_TLS_C) +#error "POLARSSL_SSL_SRV_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_TLS_C) && (!defined(POLARSSL_SSL_PROTO_SSL3) && \ + !defined(POLARSSL_SSL_PROTO_TLS1) && !defined(POLARSSL_SSL_PROTO_TLS1_1) && \ + !defined(POLARSSL_SSL_PROTO_TLS1_2)) +#error "POLARSSL_SSL_TLS_C defined, but no protocols are active" +#endif + +#if defined(POLARSSL_SSL_TLS_C) && (defined(POLARSSL_SSL_PROTO_SSL3) && \ + defined(POLARSSL_SSL_PROTO_TLS1_1) && !defined(POLARSSL_SSL_PROTO_TLS1)) +#error "Illegal protocol selection" +#endif + +#if defined(POLARSSL_SSL_TLS_C) && (defined(POLARSSL_SSL_PROTO_TLS1) && \ + defined(POLARSSL_SSL_PROTO_TLS1_2) && !defined(POLARSSL_SSL_PROTO_TLS1_1)) +#error "Illegal protocol selection" +#endif + +#if defined(POLARSSL_SSL_TLS_C) && (defined(POLARSSL_SSL_PROTO_SSL3) && \ + defined(POLARSSL_SSL_PROTO_TLS1_2) && (!defined(POLARSSL_SSL_PROTO_TLS1) || \ + !defined(POLARSSL_SSL_PROTO_TLS1_1))) +#error "Illegal protocol selection" +#endif + +#if defined(POLARSSL_SSL_SESSION_TICKETS) && defined(POLARSSL_SSL_TLS_C) && \ + ( !defined(POLARSSL_AES_C) || !defined(POLARSSL_SHA256_C) || \ + !defined(POLARSSL_CIPHER_MODE_CBC) ) +#error "POLARSSL_SSL_SESSION_TICKETS_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) && \ + !defined(POLARSSL_X509_CRT_PARSE_C) +#error "POLARSSL_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_THREADING_PTHREAD) +#if !defined(POLARSSL_THREADING_C) || defined(POLARSSL_THREADING_IMPL) +#error "POLARSSL_THREADING_PTHREAD defined, but not all prerequisites" +#endif +#define POLARSSL_THREADING_IMPL +#endif + +#if defined(POLARSSL_THREADING_ALT) +#if !defined(POLARSSL_THREADING_C) || defined(POLARSSL_THREADING_IMPL) +#error "POLARSSL_THREADING_ALT defined, but not all prerequisites" +#endif +#define POLARSSL_THREADING_IMPL +#endif + +#if defined(POLARSSL_THREADING_C) && !defined(POLARSSL_THREADING_IMPL) +#error "POLARSSL_THREADING_C defined, single threading implementation required" +#endif +#undef POLARSSL_THREADING_IMPL + +#if defined(POLARSSL_VERSION_FEATURES) && !defined(POLARSSL_VERSION_C) +#error "POLARSSL_VERSION_FEATURES defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_X509_USE_C) && ( !defined(POLARSSL_BIGNUM_C) || \ + !defined(POLARSSL_OID_C) || !defined(POLARSSL_ASN1_PARSE_C) || \ + !defined(POLARSSL_PK_PARSE_C) ) +#error "POLARSSL_X509_USE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_X509_CREATE_C) && ( !defined(POLARSSL_BIGNUM_C) || \ + !defined(POLARSSL_OID_C) || !defined(POLARSSL_ASN1_WRITE_C) || \ + !defined(POLARSSL_PK_WRITE_C) ) +#error "POLARSSL_X509_CREATE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_X509_CRT_PARSE_C) && ( !defined(POLARSSL_X509_USE_C) ) +#error "POLARSSL_X509_CRT_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_X509_CRL_PARSE_C) && ( !defined(POLARSSL_X509_USE_C) ) +#error "POLARSSL_X509_CRL_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_X509_CSR_PARSE_C) && ( !defined(POLARSSL_X509_USE_C) ) +#error "POLARSSL_X509_CSR_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_X509_CRT_WRITE_C) && ( !defined(POLARSSL_X509_CREATE_C) ) +#error "POLARSSL_X509_CRT_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_X509_CSR_WRITE_C) && ( !defined(POLARSSL_X509_CREATE_C) ) +#error "POLARSSL_X509_CSR_WRITE_C defined, but not all prerequisites" +#endif + +#endif /* POLARSSL_CHECK_CONFIG_H */ diff --git a/pdns/ext/polarssl/include/polarssl/cipher.h b/pdns/ext/polarssl/include/polarssl/cipher.h index c7ad5b780..087e59068 100644 --- a/pdns/ext/polarssl/include/polarssl/cipher.h +++ b/pdns/ext/polarssl/include/polarssl/cipher.h @@ -1,11 +1,11 @@ /** * \file cipher.h - * + * * \brief Generic cipher wrapper. * * \author Adriaan de Jong * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -30,9 +30,13 @@ #ifndef POLARSSL_CIPHER_H #define POLARSSL_CIPHER_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif -#if defined(POLARSSL_GCM_C) +#if defined(POLARSSL_GCM_C) || defined(POLARSSL_CCM_C) #define POLARSSL_CIPHER_MODE_AEAD #endif @@ -57,6 +61,9 @@ #define POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */ #define POLARSSL_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */ +#define POLARSSL_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length */ +#define POLARSSL_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length */ + #ifdef __cplusplus extern "C" { #endif @@ -116,6 +123,12 @@ typedef enum { POLARSSL_CIPHER_BLOWFISH_CFB64, POLARSSL_CIPHER_BLOWFISH_CTR, POLARSSL_CIPHER_ARC4_128, + POLARSSL_CIPHER_AES_128_CCM, + POLARSSL_CIPHER_AES_192_CCM, + POLARSSL_CIPHER_AES_256_CCM, + POLARSSL_CIPHER_CAMELLIA_128_CCM, + POLARSSL_CIPHER_CAMELLIA_192_CCM, + POLARSSL_CIPHER_CAMELLIA_256_CCM, } cipher_type_t; typedef enum { @@ -123,10 +136,11 @@ typedef enum { POLARSSL_MODE_ECB, POLARSSL_MODE_CBC, POLARSSL_MODE_CFB, - POLARSSL_MODE_OFB, + POLARSSL_MODE_OFB, /* Unused! */ POLARSSL_MODE_CTR, POLARSSL_MODE_GCM, POLARSSL_MODE_STREAM, + POLARSSL_MODE_CCM, } cipher_mode_t; typedef enum { @@ -169,29 +183,34 @@ typedef struct { /** Encrypt using ECB */ int (*ecb_func)( void *ctx, operation_t mode, - const unsigned char *input, unsigned char *output ); + const unsigned char *input, unsigned char *output ); /** Encrypt using CBC */ - int (*cbc_func)( void *ctx, operation_t mode, size_t length, unsigned char *iv, - const unsigned char *input, unsigned char *output ); + int (*cbc_func)( void *ctx, operation_t mode, size_t length, + unsigned char *iv, const unsigned char *input, + unsigned char *output ); /** Encrypt using CFB (Full length) */ int (*cfb_func)( void *ctx, operation_t mode, size_t length, size_t *iv_off, - unsigned char *iv, const unsigned char *input, unsigned char *output ); + unsigned char *iv, const unsigned char *input, + unsigned char *output ); /** Encrypt using CTR */ - int (*ctr_func)( void *ctx, size_t length, size_t *nc_off, unsigned char *nonce_counter, - unsigned char *stream_block, const unsigned char *input, unsigned char *output ); + int (*ctr_func)( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ); /** Encrypt using STREAM */ int (*stream_func)( void *ctx, size_t length, const unsigned char *input, unsigned char *output ); /** Set key for encryption purposes */ - int (*setkey_enc_func)( void *ctx, const unsigned char *key, unsigned int key_length); + int (*setkey_enc_func)( void *ctx, const unsigned char *key, + unsigned int key_length ); /** Set key for decryption purposes */ - int (*setkey_dec_func)( void *ctx, const unsigned char *key, unsigned int key_length); + int (*setkey_dec_func)( void *ctx, const unsigned char *key, + unsigned int key_length); /** Allocate a new context */ void * (*ctx_alloc_func)( void ); @@ -222,8 +241,8 @@ typedef struct { * For cipher that accept many sizes: recommended size */ unsigned int iv_size; - /** Flag for ciphers that accept many sizes of IV/NONCE */ - int accepts_variable_iv_size; + /** Flags for variable IV size, variable key size, etc. */ + int flags; /** block size, in bytes */ unsigned int block_size; @@ -312,16 +331,32 @@ const cipher_info_t *cipher_info_from_values( const cipher_id_t cipher_id, int key_length, const cipher_mode_t mode ); +/** + * \brief Initialize a cipher_context (as NONE) + */ +void cipher_init( cipher_context_t *ctx ); + +/** + * \brief Free and clear the cipher-specific context of ctx. + * Freeing ctx itself remains the responsibility of the + * caller. + */ +void cipher_free( cipher_context_t *ctx ); + /** * \brief Initialises and fills the cipher context structure with * the appropriate values. * + * \note Currently also clears structure. In future versions you + * will be required to call cipher_init() on the structure + * first. + * * \param ctx context to initialise. May not be NULL. * \param cipher_info cipher to use. * - * \return \c 0 on success, - * \c POLARSSL_ERR_CIPHER_BAD_INPUT_DATA on parameter failure, - * \c POLARSSL_ERR_CIPHER_ALLOC_FAILED if allocation of the + * \return 0 on success, + * POLARSSL_ERR_CIPHER_BAD_INPUT_DATA on parameter failure, + * POLARSSL_ERR_CIPHER_ALLOC_FAILED if allocation of the * cipher-specific context failed. */ int cipher_init_ctx( cipher_context_t *ctx, const cipher_info_t *cipher_info ); @@ -330,10 +365,11 @@ int cipher_init_ctx( cipher_context_t *ctx, const cipher_info_t *cipher_info ); * \brief Free the cipher-specific context of ctx. Freeing ctx * itself remains the responsibility of the caller. * + * \note Deprecated: Redirects to cipher_free() + * * \param ctx Free the cipher-specific context * - * \returns 0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA if - * parameter verification fails. + * \returns 0 */ int cipher_free_ctx( cipher_context_t *ctx ); @@ -470,8 +506,8 @@ static inline operation_t cipher_get_operation( const cipher_context_t *ctx ) * parameter verification fails or a cipher specific * error code. */ -int cipher_setkey( cipher_context_t *ctx, const unsigned char *key, int key_length, - const operation_t operation ); +int cipher_setkey( cipher_context_t *ctx, const unsigned char *key, + int key_length, const operation_t operation ); #if defined(POLARSSL_CIPHER_MODE_WITH_PADDING) /** @@ -497,7 +533,7 @@ int cipher_set_padding_mode( cipher_context_t *ctx, cipher_padding_t mode ); * \param iv_len IV length for ciphers with variable-size IV; * discarded by ciphers with fixed-size IV. * - * \returns O on success, or POLARSSL_ERR_CIPHER_BAD_INPUT_DATA + * \returns 0 on success, or POLARSSL_ERR_CIPHER_BAD_INPUT_DATA * * \note Some ciphers don't use IVs nor NONCE. For these * ciphers, this function has no effect. @@ -515,25 +551,21 @@ int cipher_set_iv( cipher_context_t *ctx, */ int cipher_reset( cipher_context_t *ctx ); -#if defined(POLARSSL_CIPHER_MODE_AEAD) +#if defined(POLARSSL_GCM_C) /** * \brief Add additional data (for AEAD ciphers). - * This function has no effect for non-AEAD ciphers. - * For AEAD ciphers, it may or may not be called - * repeatedly, and/or interleaved with calls to - * cipher_udpate(), depending on the cipher. - * E.g. for GCM is must be called exactly once, right - * after cipher_reset(). + * Currently only supported with GCM. + * Must be called exactly once, after cipher_reset(). * * \param ctx generic cipher context * \param ad Additional data to use. * \param ad_len Length of ad. * - * \returns 0 on success, or a specific error code. + * \return 0 on success, or a specific error code. */ int cipher_update_ad( cipher_context_t *ctx, const unsigned char *ad, size_t ad_len ); -#endif /* POLARSSL_CIPHER_MODE_AEAD */ +#endif /* POLARSSL_GCM_C */ /** * \brief Generic cipher update function. Encrypts/decrypts @@ -564,8 +596,8 @@ int cipher_update_ad( cipher_context_t *ctx, * function, except the last one before cipher_finish(), * must have ilen a multiple of the block size. */ -int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen ); +int cipher_update( cipher_context_t *ctx, const unsigned char *input, + size_t ilen, unsigned char *output, size_t *olen ); /** * \brief Generic cipher finalisation function. If data still @@ -587,10 +619,10 @@ int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ile int cipher_finish( cipher_context_t *ctx, unsigned char *output, size_t *olen ); -#if defined(POLARSSL_CIPHER_MODE_AEAD) +#if defined(POLARSSL_GCM_C) /** * \brief Write tag for AEAD ciphers. - * No effect for other ciphers. + * Currently only supported with GCM. * Must be called after cipher_finish(). * * \param ctx Generic cipher context @@ -604,9 +636,8 @@ int cipher_write_tag( cipher_context_t *ctx, /** * \brief Check tag for AEAD ciphers. - * No effect for other ciphers. - * Calling time depends on the cipher: - * for GCM, must be called after cipher_finish(). + * Currently only supported with GCM. + * Must be called after cipher_finish(). * * \param ctx Generic cipher context * \param tag Buffer holding the tag @@ -616,6 +647,103 @@ int cipher_write_tag( cipher_context_t *ctx, */ int cipher_check_tag( cipher_context_t *ctx, const unsigned char *tag, size_t tag_len ); +#endif /* POLARSSL_GCM_C */ + +/** + * \brief Generic all-in-one encryption/decryption + * (for all ciphers except AEAD constructs). + * + * \param ctx generic cipher context + * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) + * \param iv_len IV length for ciphers with variable-size IV; + * discarded by ciphers with fixed-size IV. + * \param input buffer holding the input data + * \param ilen length of the input data + * \param output buffer for the output data. Should be able to hold at + * least ilen + block_size. Cannot be the same buffer as + * input! + * \param olen length of the output data, will be filled with the + * actual number of bytes written. + * + * \note Some ciphers don't use IVs nor NONCE. For these + * ciphers, use iv = NULL and iv_len = 0. + * + * \returns 0 on success, or + * POLARSSL_ERR_CIPHER_BAD_INPUT_DATA, or + * POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption + * expected a full block but was not provided one, or + * POLARSSL_ERR_CIPHER_INVALID_PADDING on invalid padding + * while decrypting, or + * a cipher specific error code. + */ +int cipher_crypt( cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen ); + +#if defined(POLARSSL_CIPHER_MODE_AEAD) +/** + * \brief Generic autenticated encryption (AEAD ciphers). + * + * \param ctx generic cipher context + * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) + * \param iv_len IV length for ciphers with variable-size IV; + * discarded by ciphers with fixed-size IV. + * \param ad Additional data to authenticate. + * \param ad_len Length of ad. + * \param input buffer holding the input data + * \param ilen length of the input data + * \param output buffer for the output data. + * Should be able to hold at least ilen. + * \param olen length of the output data, will be filled with the + * actual number of bytes written. + * \param tag buffer for the authentication tag + * \param tag_len desired tag length + * + * \returns 0 on success, or + * POLARSSL_ERR_CIPHER_BAD_INPUT_DATA, or + * a cipher specific error code. + */ +int cipher_auth_encrypt( cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + unsigned char *tag, size_t tag_len ); + +/** + * \brief Generic autenticated decryption (AEAD ciphers). + * + * \param ctx generic cipher context + * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) + * \param iv_len IV length for ciphers with variable-size IV; + * discarded by ciphers with fixed-size IV. + * \param ad Additional data to be authenticated. + * \param ad_len Length of ad. + * \param input buffer holding the input data + * \param ilen length of the input data + * \param output buffer for the output data. + * Should be able to hold at least ilen. + * \param olen length of the output data, will be filled with the + * actual number of bytes written. + * \param tag buffer holding the authentication tag + * \param tag_len length of the authentication tag + * + * \returns 0 on success, or + * POLARSSL_ERR_CIPHER_BAD_INPUT_DATA, or + * POLARSSL_ERR_CIPHER_AUTH_FAILED if data isn't authentic, + * or a cipher specific error code. + * + * \note If the data is not authentic, then the output buffer + * is zeroed out to prevent the unauthentic plaintext to + * be used by mistake, making this interface safer. + */ +int cipher_auth_decrypt( cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + const unsigned char *tag, size_t tag_len ); #endif /* POLARSSL_CIPHER_MODE_AEAD */ /** diff --git a/pdns/ext/polarssl/include/polarssl/cipher_wrap.h b/pdns/ext/polarssl/include/polarssl/cipher_wrap.h index 63bd093fc..46bc757a8 100644 --- a/pdns/ext/polarssl/include/polarssl/cipher_wrap.h +++ b/pdns/ext/polarssl/include/polarssl/cipher_wrap.h @@ -1,6 +1,6 @@ /** * \file cipher_wrap.h - * + * * \brief Cipher wrappers. * * \author Adriaan de Jong @@ -29,7 +29,11 @@ #ifndef POLARSSL_CIPHER_WRAP_H #define POLARSSL_CIPHER_WRAP_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include "cipher.h" #ifdef __cplusplus diff --git a/pdns/ext/polarssl/include/polarssl/compat-1.2.h b/pdns/ext/polarssl/include/polarssl/compat-1.2.h index 64d1d6365..15b5aa1f2 100644 --- a/pdns/ext/polarssl/include/polarssl/compat-1.2.h +++ b/pdns/ext/polarssl/include/polarssl/compat-1.2.h @@ -27,7 +27,11 @@ #ifndef POLARSSL_COMPAT_1_2_H #define POLARSSL_COMPAT_1_2_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif // Comment out to disable prototype change warnings #define SHOW_PROTOTYPE_CHANGE_WARNINGS @@ -58,42 +62,42 @@ */ typedef sha256_context sha2_context; -inline void sha2_starts( sha256_context *ctx, int is224 ) { +static inline void sha2_starts( sha256_context *ctx, int is224 ) { sha256_starts( ctx, is224 ); } -inline void sha2_update( sha256_context *ctx, const unsigned char *input, +static inline void sha2_update( sha256_context *ctx, const unsigned char *input, size_t ilen ) { sha256_update( ctx, input, ilen ); } -inline void sha2_finish( sha256_context *ctx, unsigned char output[32] ) { +static inline void sha2_finish( sha256_context *ctx, unsigned char output[32] ) { sha256_finish( ctx, output ); } -inline int sha2_file( const char *path, unsigned char output[32], int is224 ) { +static inline int sha2_file( const char *path, unsigned char output[32], int is224 ) { return sha256_file( path, output, is224 ); } -inline void sha2( const unsigned char *input, size_t ilen, +static inline void sha2( const unsigned char *input, size_t ilen, unsigned char output[32], int is224 ) { sha256( input, ilen, output, is224 ); } -inline void sha2_hmac_starts( sha256_context *ctx, const unsigned char *key, +static inline void sha2_hmac_starts( sha256_context *ctx, const unsigned char *key, size_t keylen, int is224 ) { sha256_hmac_starts( ctx, key, keylen, is224 ); } -inline void sha2_hmac_update( sha256_context *ctx, const unsigned char *input, size_t ilen ) { +static inline void sha2_hmac_update( sha256_context *ctx, const unsigned char *input, size_t ilen ) { sha256_hmac_update( ctx, input, ilen ); } -inline void sha2_hmac_finish( sha256_context *ctx, unsigned char output[32] ) { +static inline void sha2_hmac_finish( sha256_context *ctx, unsigned char output[32] ) { sha256_hmac_finish( ctx, output ); } -inline void sha2_hmac_reset( sha256_context *ctx ) { +static inline void sha2_hmac_reset( sha256_context *ctx ) { sha256_hmac_reset( ctx ); } -inline void sha2_hmac( const unsigned char *key, size_t keylen, +static inline void sha2_hmac( const unsigned char *key, size_t keylen, const unsigned char *input, size_t ilen, unsigned char output[32], int is224 ) { sha256_hmac( key, keylen, input, ilen, output, is224 ); } -inline int sha2_self_test( int verbose ) { +static inline int sha2_self_test( int verbose ) { return sha256_self_test( verbose ); } #endif /* POLARSSL_SHA256_C */ @@ -107,42 +111,42 @@ inline int sha2_self_test( int verbose ) { */ typedef sha512_context sha4_context; -inline void sha4_starts( sha512_context *ctx, int is384 ) { +static inline void sha4_starts( sha512_context *ctx, int is384 ) { sha512_starts( ctx, is384 ); } -inline void sha4_update( sha512_context *ctx, const unsigned char *input, +static inline void sha4_update( sha512_context *ctx, const unsigned char *input, size_t ilen ) { sha512_update( ctx, input, ilen ); } -inline void sha4_finish( sha512_context *ctx, unsigned char output[64] ) { +static inline void sha4_finish( sha512_context *ctx, unsigned char output[64] ) { sha512_finish( ctx, output ); } -inline int sha4_file( const char *path, unsigned char output[64], int is384 ) { +static inline int sha4_file( const char *path, unsigned char output[64], int is384 ) { return sha512_file( path, output, is384 ); } -inline void sha4( const unsigned char *input, size_t ilen, +static inline void sha4( const unsigned char *input, size_t ilen, unsigned char output[32], int is384 ) { sha512( input, ilen, output, is384 ); } -inline void sha4_hmac_starts( sha512_context *ctx, const unsigned char *key, +static inline void sha4_hmac_starts( sha512_context *ctx, const unsigned char *key, size_t keylen, int is384 ) { sha512_hmac_starts( ctx, key, keylen, is384 ); } -inline void sha4_hmac_update( sha512_context *ctx, const unsigned char *input, size_t ilen ) { +static inline void sha4_hmac_update( sha512_context *ctx, const unsigned char *input, size_t ilen ) { sha512_hmac_update( ctx, input, ilen ); } -inline void sha4_hmac_finish( sha512_context *ctx, unsigned char output[64] ) { +static inline void sha4_hmac_finish( sha512_context *ctx, unsigned char output[64] ) { sha512_hmac_finish( ctx, output ); } -inline void sha4_hmac_reset( sha512_context *ctx ) { +static inline void sha4_hmac_reset( sha512_context *ctx ) { sha512_hmac_reset( ctx ); } -inline void sha4_hmac( const unsigned char *key, size_t keylen, +static inline void sha4_hmac( const unsigned char *key, size_t keylen, const unsigned char *input, size_t ilen, unsigned char output[64], int is384 ) { sha512_hmac( key, keylen, input, ilen, output, is384 ); } -inline int sha4_self_test( int verbose ) { +static inline int sha4_self_test( int verbose ) { return sha512_self_test( verbose ); } #endif /* POLARSSL_SHA512_C */ @@ -167,7 +171,7 @@ inline int sha4_self_test( int verbose ) { #warning "rsa_pkcs1_verify() prototype changed. Manual change required if used" #warning "rsa_pkcs1_decrypt() prototype changed. Manual change required if used" #endif -#endif +#endif /* POLARSSL_RSA_C */ #if defined(POLARSSL_DHM_C) #if defined(SHOW_PROTOTYPE_CHANGE_WARNINGS) @@ -202,13 +206,13 @@ inline int sha4_self_test( int verbose ) { #define POLARSSL_ERR_X509_CERT_INVALID_SERIAL POLARSSL_ERR_X509_INVALID_SERIAL #define POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION POLARSSL_ERR_X509_UNKNOWN_VERSION -inline int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial ) { +static inline int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial ) { return x509_serial_gets( buf, size, serial ); } -inline int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn ) { +static inline int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn ) { return x509_dn_gets( buf, size, dn ); } -inline int x509parse_time_expired( const x509_time *time ) { +static inline int x509parse_time_expired( const x509_time *time ) { return x509_time_expired( time ); } #endif /* POLARSSL_X509_USE_C || POLARSSL_X509_CREATE_C */ @@ -218,33 +222,33 @@ inline int x509parse_time_expired( const x509_time *time ) { #include "x509_crt.h" typedef x509_crt x509_cert; -inline int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, +static inline int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen ) { return x509_crt_parse_der( chain, buf, buflen ); } -inline int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen ) { +static inline int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen ) { return x509_crt_parse( chain, buf, buflen ); } -inline int x509parse_crtfile( x509_cert *chain, const char *path ) { +static inline int x509parse_crtfile( x509_cert *chain, const char *path ) { return x509_crt_parse_file( chain, path ); } -inline int x509parse_crtpath( x509_cert *chain, const char *path ) { +static inline int x509parse_crtpath( x509_cert *chain, const char *path ) { return x509_crt_parse_path( chain, path ); } -inline int x509parse_cert_info( char *buf, size_t size, const char *prefix, +static inline int x509parse_cert_info( char *buf, size_t size, const char *prefix, const x509_cert *crt ) { return x509_crt_info( buf, size, prefix, crt ); } -inline int x509parse_verify( x509_cert *crt, x509_cert *trust_ca, +static inline int x509parse_verify( x509_cert *crt, x509_cert *trust_ca, x509_crl *ca_crl, const char *cn, int *flags, int (*f_vrfy)(void *, x509_cert *, int, int *), void *p_vrfy ) { return x509_crt_verify( crt, trust_ca, ca_crl, cn, flags, f_vrfy, p_vrfy ); } -inline int x509parse_revoked( const x509_cert *crt, const x509_crl *crl ) { +static inline int x509parse_revoked( const x509_cert *crt, const x509_crl *crl ) { return x509_crt_revoked( crt, crl ); } -inline void x509_free( x509_cert *crt ) { +static inline void x509_free( x509_cert *crt ) { x509_crt_free( crt ); } #endif /* POLARSSL_X509_CRT_PARSE_C */ @@ -252,13 +256,13 @@ inline void x509_free( x509_cert *crt ) { #if defined(POLARSSL_X509_CRL_PARSE_C) #define POLARSSL_X509_PARSE_C #include "x509_crl.h" -inline int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen ) { +static inline int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen ) { return x509_crl_parse( chain, buf, buflen ); } -inline int x509parse_crlfile( x509_crl *chain, const char *path ) { +static inline int x509parse_crlfile( x509_crl *chain, const char *path ) { return x509_crl_parse_file( chain, path ); } -inline int x509parse_crl_info( char *buf, size_t size, const char *prefix, +static inline int x509parse_crl_info( char *buf, size_t size, const char *prefix, const x509_crl *crl ) { return x509_crl_info( buf, size, prefix, crl ); } @@ -267,13 +271,13 @@ inline int x509parse_crl_info( char *buf, size_t size, const char *prefix, #if defined(POLARSSL_X509_CSR_PARSE_C) #define POLARSSL_X509_PARSE_C #include "x509_csr.h" -inline int x509parse_csr( x509_csr *csr, const unsigned char *buf, size_t buflen ) { +static inline int x509parse_csr( x509_csr *csr, const unsigned char *buf, size_t buflen ) { return x509_csr_parse( csr, buf, buflen ); } -inline int x509parse_csrfile( x509_csr *csr, const char *path ) { +static inline int x509parse_csrfile( x509_csr *csr, const char *path ) { return x509_csr_parse_file( csr, path ); } -inline int x509parse_csr_info( char *buf, size_t size, const char *prefix, +static inline int x509parse_csr_info( char *buf, size_t size, const char *prefix, const x509_csr *csr ) { return x509_csr_info( buf, size, prefix, csr ); } @@ -295,7 +299,7 @@ inline int x509parse_csr_info( char *buf, size_t size, const char *prefix, #define POLARSSL_ERR_X509_CERT_INVALID_PUBKEY POLARSSL_ERR_PK_INVALID_PUBKEY #if defined(POLARSSL_FS_IO) -inline int x509parse_keyfile( rsa_context *rsa, const char *path, +static inline int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd ) { int ret; pk_context pk; @@ -310,7 +314,7 @@ inline int x509parse_keyfile( rsa_context *rsa, const char *path, pk_free( &pk ); return( ret ); } -inline int x509parse_public_keyfile( rsa_context *rsa, const char *path ) { +static inline int x509parse_public_keyfile( rsa_context *rsa, const char *path ) { int ret; pk_context pk; pk_init( &pk ); @@ -326,7 +330,7 @@ inline int x509parse_public_keyfile( rsa_context *rsa, const char *path ) { } #endif /* POLARSSL_FS_IO */ -inline int x509parse_key( rsa_context *rsa, const unsigned char *key, +static inline int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen, const unsigned char *pwd, size_t pwdlen ) { int ret; @@ -343,7 +347,7 @@ inline int x509parse_key( rsa_context *rsa, const unsigned char *key, return( ret ); } -inline int x509parse_public_key( rsa_context *rsa, +static inline int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen ) { int ret; @@ -363,7 +367,7 @@ inline int x509parse_public_key( rsa_context *rsa, #if defined(POLARSSL_PK_WRITE_C) && defined(POLARSSL_RSA_C) #include "pk.h" -inline int x509_write_pubkey_der( unsigned char *buf, size_t len, rsa_context *rsa ) { +static inline int x509_write_pubkey_der( unsigned char *buf, size_t len, rsa_context *rsa ) { int ret; pk_context ctx; if( ( ret = pk_init_ctx( &ctx, pk_info_from_type( POLARSSL_PK_RSA ) ) ) != 0 ) return( ret ); @@ -372,7 +376,7 @@ inline int x509_write_pubkey_der( unsigned char *buf, size_t len, rsa_context *r pk_free( &ctx ); return( ret ); } -inline int x509_write_key_der( unsigned char *buf, size_t len, rsa_context *rsa ) { +static inline int x509_write_key_der( unsigned char *buf, size_t len, rsa_context *rsa ) { int ret; pk_context ctx; if( ( ret = pk_init_ctx( &ctx, pk_info_from_type( POLARSSL_PK_RSA ) ) ) != 0 ) return( ret ); diff --git a/pdns/ext/polarssl/include/polarssl/config.h b/pdns/ext/polarssl/include/polarssl/config.h index a631a4a90..d43365ff5 100644 --- a/pdns/ext/polarssl/include/polarssl/config.h +++ b/pdns/ext/polarssl/include/polarssl/config.h @@ -3,7 +3,7 @@ * * \brief Configuration options (set of defines) * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -94,24 +94,79 @@ //#define POLARSSL_HAVE_SSE2 /** - * \def POLARSSL_HAVE_READDIR_R + * \def POLARSSL_HAVE_TIME + * + * System has time.h and time() / localtime() / gettimeofday(). + * + * Comment if your system does not support time functions + */ +#define POLARSSL_HAVE_TIME + +/** + * \def POLARSSL_HAVE_IPV6 * - * (Non Windows) System has readdir_r(). + * System supports the basic socket interface for IPv6 (RFC 3493), + * specifically getaddrinfo(), freeaddrinfo() and struct sockaddr_storage. * - * Required for x509_crt_parse_path() in non-Windows systems. + * Note: on Windows/MingW, XP or higher is required. * - * Comment if your system does not have support. + * Comment if your system does not support the IPv6 socket interface */ -#define POLARSSL_HAVE_READDIR_R +#define POLARSSL_HAVE_IPV6 /** - * \def POLARSSL_HAVE_TIME + * \def POLARSSL_PLATFORM_MEMORY * - * System has time.h and time() / localtime() / gettimeofday(). + * Enable the memory allocation layer. * - * Comment if your system does not support time functions + * By default PolarSSL uses the system-provided malloc() and free(). + * This allows different allocators (self-implemented or provided) to be + * provided to the platform abstraction layer. + * + * Enabling POLARSSL_PLATFORM_MEMORY will provide "platform_set_malloc_free()" + * to allow you to set an alternative malloc() and free() function pointer. + * + * Requires: POLARSSL_PLATFORM_C + * + * Enable this layer to allow use of alternative memory allocators. */ -#define POLARSSL_HAVE_TIME +//#define POLARSSL_PLATFORM_MEMORY + +/** + * \def POLARSSL_PLATFORM_NO_STD_FUNCTIONS + * + * Do not assign standard functions in the platform layer (e.g. malloc() to + * POLARSSL_PLATFORM_STD_MALLOC and printf() to POLARSSL_PLATFORM_STD_PRINTF) + * + * This makes sure there are no linking errors on platforms that do not support + * these functions. You will HAVE to provide alternatives, either at runtime + * via the platform_set_xxx() functions or at compile time by setting + * the POLARSSL_PLATFORM_STD_XXX defines. + * + * Requires: POLARSSL_PLATFORM_C + * + * Uncomment to prevent default assignment of standard functions in the + * platform layer. + */ +//#define POLARSSL_PLATFORM_NO_STD_FUNCTIONS + +/** + * \def POLARSSL_PLATFORM_XXX_ALT + * + * Uncomment a macro to let PolarSSL support the function in the platform + * abstraction layer. + * + * Example: In case you uncomment POLARSSL_PLATFORM_PRINTF_ALT, PolarSSL will + * provide a function "platform_set_printf()" that allows you to set an + * alternative printf function pointer. + * + * All these define require POLARSSL_PLATFORM_C to be defined! + * + * Uncomment a macro to enable alternate implementation of specific base + * platform function + */ +//#define POLARSSL_PLATFORM_PRINTF_ALT +//#define POLARSSL_PLATFORM_FPRINTF_ALT /* \} name SECTION: System support */ /** @@ -122,6 +177,19 @@ * \{ */ +/** + * \def POLARSSL_TIMING_ALT + * + * Uncomment to provide your own alternate implementation for hardclock(), + * get_timer(), set_alarm() and m_sleep(). + * + * Only works if you have POLARSSL_TIMING_C enabled. + * + * You will need to provide a header "timing_alt.h" and an implementation at + * compile time. + */ +//#define POLARSSL_TIMING_ALT + /** * \def POLARSSL_XXX_ALT * @@ -147,6 +215,7 @@ //#define POLARSSL_MD2_ALT //#define POLARSSL_MD4_ALT //#define POLARSSL_MD5_ALT +//#define POLARSSL_RIPEMD160_ALT //#define POLARSSL_SHA1_ALT //#define POLARSSL_SHA256_ALT //#define POLARSSL_SHA512_ALT @@ -191,6 +260,8 @@ * * Requires POLARSSL_ENABLE_WEAK_CIPHERSUITES as well to enable * the following ciphersuites: + * TLS_ECDH_ECDSA_WITH_NULL_SHA + * TLS_ECDH_RSA_WITH_NULL_SHA * TLS_ECDHE_ECDSA_WITH_NULL_SHA * TLS_ECDHE_RSA_WITH_NULL_SHA * TLS_ECDHE_PSK_WITH_NULL_SHA384 @@ -210,8 +281,8 @@ * TLS_PSK_WITH_NULL_SHA * * Uncomment this macro to enable the NULL cipher and ciphersuites -#define POLARSSL_CIPHER_NULL_CIPHER */ +//#define POLARSSL_CIPHER_NULL_CIPHER /** * \def POLARSSL_CIPHER_PADDING_XXX @@ -240,8 +311,21 @@ * TLS_DHE_RSA_WITH_DES_CBC_SHA * * Uncomment this macro to enable weak ciphersuites -#define POLARSSL_ENABLE_WEAK_CIPHERSUITES */ +//#define POLARSSL_ENABLE_WEAK_CIPHERSUITES + +/** + * \def POLARSSL_REMOVE_ARC4_CIPHERSUITES + * + * Remove RC4 ciphersuites by default in SSL / TLS. + * This flag removes the ciphersuites based on RC4 from the default list as + * returned by ssl_list_ciphersuites(). However, it is still possible to + * enable (some of) them with ssl_set_ciphersuites() by including them + * explicitly. + * + * Uncomment this macro to remove RC4 ciphersuites by default. + */ +//#define POLARSSL_REMOVE_ARC4_CIPHERSUITES /** * \def POLARSSL_ECP_XXXX_ENABLED @@ -256,9 +340,16 @@ #define POLARSSL_ECP_DP_SECP256R1_ENABLED #define POLARSSL_ECP_DP_SECP384R1_ENABLED #define POLARSSL_ECP_DP_SECP521R1_ENABLED +#define POLARSSL_ECP_DP_SECP192K1_ENABLED +#define POLARSSL_ECP_DP_SECP224K1_ENABLED +#define POLARSSL_ECP_DP_SECP256K1_ENABLED #define POLARSSL_ECP_DP_BP256R1_ENABLED #define POLARSSL_ECP_DP_BP384R1_ENABLED #define POLARSSL_ECP_DP_BP512R1_ENABLED +//#define POLARSSL_ECP_DP_M221_ENABLED // Not implemented yet! +#define POLARSSL_ECP_DP_M255_ENABLED +//#define POLARSSL_ECP_DP_M383_ENABLED // Not implemented yet! +//#define POLARSSL_ECP_DP_M511_ENABLED // Not implemented yet! /** * \def POLARSSL_ECP_NIST_OPTIM @@ -271,6 +362,20 @@ */ #define POLARSSL_ECP_NIST_OPTIM +/** + * \def POLARSSL_ECDSA_DETERMINISTIC + * + * Enable deterministic ECDSA (RFC 6979). + * Standard ECDSA is "fragile" in the sense that lack of entropy when signing + * may result in a compromise of the long-term signing key. This is avoided by + * the deterministic variant. + * + * Requires: POLARSSL_HMAC_DRBG_C + * + * Comment this macro to disable deterministic ECDSA. + */ +#define POLARSSL_ECDSA_DETERMINISTIC + /** * \def POLARSSL_KEY_EXCHANGE_PSK_ENABLED * @@ -465,12 +570,77 @@ */ #define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED +/** + * \def POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + * + * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +#define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED + * + * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_RSA_WITH_RC4_128_SHA + * TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +#define POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED + +/** + * \def POLARSSL_PK_PARSE_EC_EXTENDED + * + * Enhance support for reading EC keys using variants of SEC1 not allowed by + * RFC 5915 and RFC 5480. + * + * Currently this means parsing the SpecifiedECDomain choice of EC + * parameters (only known groups are supported, not arbitrary domains, to + * avoid validation issues). + * + * Disable if you only need to support RFC 5915 + 5480 key formats. + */ +#define POLARSSL_PK_PARSE_EC_EXTENDED + /** * \def POLARSSL_ERROR_STRERROR_BC * * Make available the backward compatible error_strerror() next to the * current polarssl_strerror(). * + * For new code, it is recommended to use polarssl_strerror() instead and + * disable this. + * * Disable if you run into name conflicts and want to really remove the * error_strerror() */ @@ -480,7 +650,11 @@ * \def POLARSSL_ERROR_STRERROR_DUMMY * * Enable a dummy error function to make use of polarssl_strerror() in - * third party libraries easier. + * third party libraries easier when POLARSSL_ERROR_C is disabled + * (no effect when POLARSSL_ERROR_C is enabled). + * + * You can safely disable this if POLARSSL_ERROR_C is enabled, or if you're + * not using polarssl_strerror() or error_strerror() in your application. * * Disable if you run into name conflicts and want to really remove the * polarssl_strerror() @@ -509,7 +683,7 @@ * Do not add default entropy sources. These are the platform specific, * hardclock and HAVEGE based poll functions. * - * This is useful to have more control over the added entropy sources in an + * This is useful to have more control over the added entropy sources in an * application. * * Uncomment this macro to prevent loading of default entropy functions. @@ -527,6 +701,22 @@ */ //#define POLARSSL_NO_PLATFORM_ENTROPY +/** + * \def POLARSSL_ENTROPY_FORCE_SHA256 + * + * Force the entropy accumulator to use a SHA-256 accumulator instead of the + * default SHA-512 based one (if both are available). + * + * Requires: POLARSSL_SHA256_C + * + * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option + * if you have performance concerns. + * + * This option is only useful if both POLARSSL_SHA256_C and + * POLARSSL_SHA512_C are defined. Otherwise the available hash module is used. + */ +//#define POLARSSL_ENTROPY_FORCE_SHA256 + /** * \def POLARSSL_MEMORY_DEBUG * @@ -535,7 +725,6 @@ * function for 'debug output' of allocated memory. * * Requires: POLARSSL_MEMORY_BUFFER_ALLOC_C - * fprintf() * * Uncomment this macro to let the buffer allocator print out error messages. */ @@ -642,6 +831,16 @@ */ #define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO +/** + * \def POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE + * + * Pick the ciphersuite according to the client's preferences rather than ours + * in the SSL Server module (POLARSSL_SSL_SRV_C). + * + * Uncomment this macro to respect client's ciphersuite order + */ +//#define POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE + /** * \def POLARSSL_SSL_MAX_FRAGMENT_LENGTH * @@ -699,6 +898,16 @@ */ #define POLARSSL_SSL_PROTO_TLS1_2 +/** + * \def POLARSSL_SSL_ALPN + * + * Enable support for Application Layer Protocol Negotiation. + * draft-ietf-tls-applayerprotoneg-05 + * + * Comment this macro to disable support for ALPN. + */ +#define POLARSSL_SSL_ALPN + /** * \def POLARSSL_SSL_SESSION_TICKETS * @@ -731,28 +940,29 @@ #define POLARSSL_SSL_TRUNCATED_HMAC /** - * \def POLARSSL_THREADING_ALT + * \def POLARSSL_SSL_SET_CURVES * - * Provide your own alternate threading implementation. + * Enable ssl_set_curves(). * - * Requires: POLARSSL_THREADING_C + * This is disabled by default since it breaks binary compatibility with the + * 1.3.x line. If you choose to enable it, you will need to rebuild your + * application against the new header files, relinking will not be enough. + * It will be enabled by default, or no longer an option, in the 1.4 branch. * - * Uncomment this to allow your own alternate threading implementation. + * Uncomment to make ssl_set_curves() available. */ -//#define POLARSSL_THREADING_ALT +//#define POLARSSL_SSL_SET_CURVES /** - * \def POLARSSL_THREADING_DUMMY + * \def POLARSSL_THREADING_ALT * - * Provide a dummy threading implementation. - * Warning: If you use this, all claims of thread-safety in the documentation - * are void! + * Provide your own alternate threading implementation. * * Requires: POLARSSL_THREADING_C * - * Uncomment this to enable code to compile like with threading enabled + * Uncomment this to allow your own alternate threading implementation. */ -//#define POLARSSL_THREADING_DUMMY +//#define POLARSSL_THREADING_ALT /** * \def POLARSSL_THREADING_PTHREAD @@ -765,6 +975,19 @@ */ //#define POLARSSL_THREADING_PTHREAD +/** + * \def POLARSSL_VERSION_FEATURES + * + * Allow run-time checking of compile-time enabled features. Thus allowing users + * to check at run-time if the library is for instance compiled with threading + * support via version_check_feature(). + * + * Requires: POLARSSL_VERSION_C + * + * Comment this to disable run-time checking and save ROM space + */ +#define POLARSSL_VERSION_FEATURES + /** * \def POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 * @@ -785,12 +1008,53 @@ */ //#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION +/** + * \def POLARSSL_X509_CHECK_KEY_USAGE + * + * Enable verification of the keyUsage extension (CA and leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused + * (intermediate) CA and leaf certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip keyUsage checking for both CA and leaf certificates. + */ +#define POLARSSL_X509_CHECK_KEY_USAGE + +/** + * \def POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE + * + * Enable verification of the extendedKeyUsage extension (leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip extendedKeyUsage checking for certificates. + */ +#define POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE + +/** + * \def POLARSSL_X509_RSASSA_PSS_SUPPORT + * + * Enable parsing and verification of X.509 certificates, CRLs and CSRS + * signed with RSASSA-PSS (aka PKCS#1 v2.1). + * + * Comment this macro to disallow using RSASSA-PSS in certificates. + */ +#define POLARSSL_X509_RSASSA_PSS_SUPPORT + /** * \def POLARSSL_ZLIB_SUPPORT * * If set, the SSL/TLS module uses ZLIB to support compression and * decompression of packet data. * + * \warning TLS-level compression MAY REDUCE SECURITY! See for example the + * CRIME attack. Before enabling this option, you should examine with care if + * CRIME or similar exploits may be a applicable to your use case. + * * Used in: library/ssl_tls.c * library/ssl_cli.c * library/ssl_srv.c @@ -809,6 +1073,20 @@ * \{ */ +/** + * \def POLARSSL_AESNI_C + * + * Enable AES-NI support on x86-64. + * + * Module: library/aesni.c + * Caller: library/aes.c + * + * Requires: POLARSSL_HAVE_ASM + * + * This modules adds support for the AES-NI instructions on x86-64 + */ +#define POLARSSL_AESNI_C + /** * \def POLARSSL_AES_C * @@ -821,6 +1099,18 @@ * * This module enables the following ciphersuites (if other requisites are * enabled as well): + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 * TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 * TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 @@ -882,6 +1172,8 @@ * * This module enables the following ciphersuites (if other requisites are * enabled as well): + * TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * TLS_ECDH_RSA_WITH_RC4_128_SHA * TLS_ECDHE_ECDSA_WITH_RC4_128_SHA * TLS_ECDHE_RSA_WITH_RC4_128_SHA * TLS_ECDHE_PSK_WITH_RC4_128_SHA @@ -941,10 +1233,11 @@ * Module: library/bignum.c * Caller: library/dhm.c * library/ecp.c + * library/ecdsa.c * library/rsa.c * library/ssl_tls.c * - * This module is required for RSA and DHM support. + * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. */ #define POLARSSL_BIGNUM_C @@ -967,6 +1260,14 @@ * * This module enables the following ciphersuites (if other requisites are * enabled as well): + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 * TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 * TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 @@ -1004,6 +1305,20 @@ */ #define POLARSSL_CAMELLIA_C +/** + * \def POLARSSL_CCM_C + * + * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. + * + * Module: library/ccm.c + * + * Requires: POLARSSL_AES_C or POLARSSL_CAMELLIA_C + * + * This module enables the AES-CCM ciphersuites, if other requisites are + * enabled as well. + */ +#define POLARSSL_CCM_C + /** * \def POLARSSL_CERTS_C * @@ -1069,6 +1384,8 @@ * * This module enables the following ciphersuites (if other requisites are * enabled as well): + * TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA * TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA * TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA @@ -1148,7 +1465,7 @@ * Module: library/entropy.c * Caller: * - * Requires: POLARSSL_SHA512_C + * Requires: POLARSSL_SHA512_C or POLARSSL_SHA256_C * * This module provides a generic entropy pool */ @@ -1162,7 +1479,7 @@ * Module: library/error.c * Caller: * - * This module enables err_strerror(). + * This module enables polarssl_strerror(). */ #define POLARSSL_ERROR_C @@ -1203,6 +1520,20 @@ */ //#define POLARSSL_HAVEGE_C +/** + * \def POLARSSL_HMAC_DRBG_C + * + * Enable the HMAC_DRBG random generator. + * + * Module: library/hmac_drbg.c + * Caller: + * + * Requires: POLARSSL_MD_C + * + * Uncomment to enable the HMAC_DRBG random number geerator. + */ +#define POLARSSL_HMAC_DRBG_C + /** * \def POLARSSL_MD_C * @@ -1256,15 +1587,7 @@ /** * \def POLARSSL_MEMORY_C - * - * Enable the memory allocation layer. - * By default PolarSSL uses the system-provided malloc() and free(). - * (As long as POLARSSL_MEMORY_STDMALLOC and POLARSSL_MEMORY_STDFREE - * are defined and unmodified) - * - * This allows different allocators (self-implemented or provided) - * - * Enable this layer to allow use of alternative memory allocators. + * Deprecated since 1.3.5. Please use POLARSSL_PLATFORM_MEMORY instead. */ //#define POLARSSL_MEMORY_C @@ -1277,7 +1600,8 @@ * * Module: library/memory_buffer_alloc.c * - * Requires: POLARSSL_MEMORY_C + * Requires: POLARSSL_PLATFORM_C + * POLARSSL_PLATFORM_MEMORY (to use it within PolarSSL) * * Enable this module to enable the buffer memory allocator. */ @@ -1325,6 +1649,8 @@ * Module: library/padlock.c * Caller: library/aes.c * + * Requires: POLARSSL_HAVE_ASM + * * This modules adds support for the VIA PadLock on x86. */ #define POLARSSL_PADLOCK_C @@ -1466,6 +1792,30 @@ */ #define POLARSSL_PKCS12_C +/** + * \def POLARSSL_PLATFORM_C + * + * Enable the platform abstraction layer that allows you to re-assign + * functions like malloc(), free(), printf(), fprintf() + * + * Module: library/platform.c + * Caller: Most other .c files + * + * This module enables abstraction of common (libc) functions. + */ +#define POLARSSL_PLATFORM_C + +/** + * \def POLARSSL_RIPEMD160_C + * + * Enable the RIPEMD-160 hash algorithm. + * + * Module: library/ripemd160.c + * Caller: library/md.c + * + */ +#define POLARSSL_RIPEMD160_C + /** * \def POLARSSL_RSA_C * @@ -1604,8 +1954,8 @@ * This allows different threading implementations (self-implemented or * provided). * - * You will have to enable either POLARSSL_THREADING_ALT, - * POLARSSL_THREADING_PTHREAD or POLARSSL_THREADING_DUMMY. + * You will have to enable either POLARSSL_THREADING_ALT or + * POLARSSL_THREADING_PTHREAD. * * Enable this layer to allow use of mutexes within PolarSSL */ @@ -1752,308 +2102,79 @@ * This section allows for the setting of module specific sizes and * configuration options. The default values are already present in the * relevant header files and should suffice for the regular use cases. - * Our advice is to enable POLARSSL_CONFIG_OPTIONS and change values here - * only if you have a good reason and know the consequences. * - * If POLARSSL_CONFIG_OPTIONS is undefined here the options in the module - * header file take precedence. + * Our advice is to enable options and change their values here + * only if you have a good reason and know the consequences. * * Please check the respective header file for documentation on these * parameters (to prevent duplicate documentation). - * - * Uncomment POLARSSL_CONFIG_OPTIONS to enable using the values defined here. * \{ */ -//#define POLARSSL_CONFIG_OPTIONS /**< Enable config.h module value configuration */ -#if defined(POLARSSL_CONFIG_OPTIONS) +/* MPI / BIGNUM options */ +//#define POLARSSL_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ +//#define POLARSSL_MPI_MAX_SIZE 512 /**< Maximum number of bytes for usable MPIs. */ -// MPI / BIGNUM options -// -#define POLARSSL_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ -#define POLARSSL_MPI_MAX_SIZE 512 /**< Maximum number of bytes for usable MPIs. */ +/* CTR_DRBG options */ +//#define CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ +//#define CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ -// CTR_DRBG options -// -#define CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ -#define CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -#define CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -#define CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -#define CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ +/* HMAC_DRBG options */ +//#define POLARSSL_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define POLARSSL_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define POLARSSL_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define POLARSSL_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ -// Entropy options -// -#define ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ -#define ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ +/* ECP options */ +//#define POLARSSL_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ +//#define POLARSSL_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ +//#define POLARSSL_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ -// Memory options -#define MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ -#define POLARSSL_MEMORY_STDMALLOC malloc /**< Default allocator to use, can be undefined */ -#define POLARSSL_MEMORY_STDFREE free /**< Default free to use, can be undefined */ +/* Entropy options */ +//#define ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +//#define ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ -// SSL Cache options -// -#define SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ -#define SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ +/* Memory buffer allocator options */ +//#define POLARSSL_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ -// SSL options -// -#define SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */ -#define SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ +/* Platform options */ +//#define POLARSSL_PLATFORM_STD_MEM_HDR /**< Header to include if POLARSSL_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ +//#define POLARSSL_PLATFORM_STD_MALLOC malloc /**< Default allocator to use, can be undefined */ +//#define POLARSSL_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ +//#define POLARSSL_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +//#define POLARSSL_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ -#endif /* POLARSSL_CONFIG_OPTIONS */ +/* SSL Cache options */ +//#define SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ +//#define SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ -/* \} name */ +/* SSL options */ +//#define SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */ +//#define SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ +//#define POLARSSL_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ -/* - * Sanity checks on defines and dependencies +/** + * Complete list of ciphersuites to use, in order of preference. + * + * \warning No dependency checking is done on that field! This option can only + * be used to restrict the set of available ciphersuites. It is your + * responsibility to make sure the needed modules are active. + * + * Use this to save a few hundred bytes of ROM (default ordering of all + * available ciphersuites) and a few to a few hundred bytes of RAM. + * + * The value below is only an example, not the default. */ -#if defined(POLARSSL_CERTS_C) && !defined(POLARSSL_PEM_PARSE_C) -#error "POLARSSL_CERTS_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_CTR_DRBG_C) && !defined(POLARSSL_AES_C) -#error "POLARSSL_CTR_DRBG_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_DHM_C) && !defined(POLARSSL_BIGNUM_C) -#error "POLARSSL_DHM_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_ECDH_C) && !defined(POLARSSL_ECP_C) -#error "POLARSSL_ECDH_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_ECDSA_C) && \ - ( !defined(POLARSSL_ECP_C) || \ - !defined(POLARSSL_ASN1_PARSE_C) || \ - !defined(POLARSSL_ASN1_WRITE_C) ) -#error "POLARSSL_ECDSA_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_ECP_C) && ( !defined(POLARSSL_BIGNUM_C) || ( \ - !defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) && \ - !defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) && \ - !defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) && \ - !defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) && \ - !defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) && \ - !defined(POLARSSL_ECP_DP_BP256R1_ENABLED) && \ - !defined(POLARSSL_ECP_DP_BP384R1_ENABLED) && \ - !defined(POLARSSL_ECP_DP_BP512R1_ENABLED) ) ) -#error "POLARSSL_ECP_C defined, but not all prerequisites" -#endif +//#define SSL_CIPHERSUITES TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 -#if defined(POLARSSL_ENTROPY_C) && (!defined(POLARSSL_SHA512_C) && \ - !defined(POLARSSL_SHA256_C)) -#error "POLARSSL_ENTROPY_C defined, but not all prerequisites" -#endif -#if defined(POLARSSL_ENTROPY_C) && defined(POLARSSL_SHA512_C) && \ - defined(POLARSSL_CONFIG_OPTIONS) && (CTR_DRBG_ENTROPY_LEN > 64) -#error "CTR_DRBG_ENTROPY_LEN value too high" -#endif -#if defined(POLARSSL_ENTROPY_C) && !defined(POLARSSL_SHA512_C) && \ - defined(POLARSSL_CONFIG_OPTIONS) && (CTR_DRBG_ENTROPY_LEN > 32) -#error "CTR_DRBG_ENTROPY_LEN value too high" -#endif +/* Debug options */ +//#define POLARSSL_DEBUG_DFL_MODE POLARSSL_DEBUG_LOG_FULL /**< Default log: Full or Raw */ -#if defined(POLARSSL_GCM_C) && ( \ - !defined(POLARSSL_AES_C) && !defined(POLARSSL_CAMELLIA_C) ) -#error "POLARSSL_GCM_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_HAVEGE_C) && !defined(POLARSSL_TIMING_C) -#error "POLARSSL_HAVEGE_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(POLARSSL_DHM_C) -#error "POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \ - !defined(POLARSSL_ECDH_C) -#error "POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ - ( !defined(POLARSSL_DHM_C) || !defined(POLARSSL_RSA_C) || \ - !defined(POLARSSL_X509_CRT_PARSE_C) || !defined(POLARSSL_PKCS1_V15) ) -#error "POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ - ( !defined(POLARSSL_ECDH_C) || !defined(POLARSSL_RSA_C) || \ - !defined(POLARSSL_X509_CRT_PARSE_C) || !defined(POLARSSL_PKCS1_V15) ) -#error "POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ - ( !defined(POLARSSL_ECDH_C) || !defined(POLARSSL_ECDSA_C) || \ - !defined(POLARSSL_X509_CRT_PARSE_C) ) -#error "POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites" -#endif +/* \} name SECTION: Module configuration options */ -#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ - ( !defined(POLARSSL_RSA_C) || !defined(POLARSSL_X509_CRT_PARSE_C) ||\ - !defined(POLARSSL_PKCS1_V15) ) -#error "POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \ - ( !defined(POLARSSL_RSA_C) || !defined(POLARSSL_X509_CRT_PARSE_C) ||\ - !defined(POLARSSL_PKCS1_V15) ) -#error "POLARSSL_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) && !defined(POLARSSL_MEMORY_C) -#error "POLARSSL_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_PBKDF2_C) && !defined(POLARSSL_MD_C) -#error "POLARSSL_PBKDF2_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_PEM_PARSE_C) && !defined(POLARSSL_BASE64_C) -#error "POLARSSL_PEM_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_PEM_WRITE_C) && !defined(POLARSSL_BASE64_C) -#error "POLARSSL_PEM_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_PK_PARSE_C) && !defined(POLARSSL_PK_C) -#error "POLARSSL_PK_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_PK_WRITE_C) && !defined(POLARSSL_PK_C) -#error "POLARSSL_PK_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_PKCS11_C) && !defined(POLARSSL_PK_C) -#error "POLARSSL_PKCS11_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_RSA_C) && ( !defined(POLARSSL_BIGNUM_C) || \ - !defined(POLARSSL_OID_C) ) -#error "POLARSSL_RSA_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_SSL_PROTO_SSL3) && ( !defined(POLARSSL_MD5_C) || \ - !defined(POLARSSL_SHA1_C) ) -#error "POLARSSL_SSL_PROTO_SSL3 defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_SSL_PROTO_TLS1) && ( !defined(POLARSSL_MD5_C) || \ - !defined(POLARSSL_SHA1_C) ) -#error "POLARSSL_SSL_PROTO_TLS1 defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_SSL_PROTO_TLS1_1) && ( !defined(POLARSSL_MD5_C) || \ - !defined(POLARSSL_SHA1_C) ) -#error "POLARSSL_SSL_PROTO_TLS1_1 defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_SSL_PROTO_TLS1_2) && ( !defined(POLARSSL_SHA1_C) && \ - !defined(POLARSSL_SHA256_C) && !defined(POLARSSL_SHA512_C) ) -#error "POLARSSL_SSL_PROTO_TLS1_2 defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_SSL_CLI_C) && !defined(POLARSSL_SSL_TLS_C) -#error "POLARSSL_SSL_CLI_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_SSL_TLS_C) && ( !defined(POLARSSL_CIPHER_C) || \ - !defined(POLARSSL_MD_C) ) -#error "POLARSSL_SSL_TLS_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_SSL_SRV_C) && !defined(POLARSSL_SSL_TLS_C) -#error "POLARSSL_SSL_SRV_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_SSL_TLS_C) && (!defined(POLARSSL_SSL_PROTO_SSL3) && \ - !defined(POLARSSL_SSL_PROTO_TLS1) && !defined(POLARSSL_SSL_PROTO_TLS1_1) && \ - !defined(POLARSSL_SSL_PROTO_TLS1_2)) -#error "POLARSSL_SSL_TLS_C defined, but no protocols are active" -#endif - -#if defined(POLARSSL_SSL_TLS_C) && (defined(POLARSSL_SSL_PROTO_SSL3) && \ - defined(POLARSSL_SSL_PROTO_TLS1_1) && !defined(POLARSSL_SSL_PROTO_TLS1)) -#error "Illegal protocol selection" -#endif - -#if defined(POLARSSL_SSL_TLS_C) && (defined(POLARSSL_SSL_PROTO_TLS1) && \ - defined(POLARSSL_SSL_PROTO_TLS1_2) && !defined(POLARSSL_SSL_PROTO_TLS1_1)) -#error "Illegal protocol selection" -#endif - -#if defined(POLARSSL_SSL_TLS_C) && (defined(POLARSSL_SSL_PROTO_SSL3) && \ - defined(POLARSSL_SSL_PROTO_TLS1_2) && (!defined(POLARSSL_SSL_PROTO_TLS1) || \ - !defined(POLARSSL_SSL_PROTO_TLS1_1))) -#error "Illegal protocol selection" -#endif - -#if defined(POLARSSL_SSL_SESSION_TICKETS) && defined(POLARSSL_SSL_TLS_C) && \ - ( !defined(POLARSSL_AES_C) || !defined(POLARSSL_SHA256_C) || \ - !defined(POLARSSL_CIPHER_MODE_CBC) ) -#error "POLARSSL_SSL_SESSION_TICKETS_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_THREADING_DUMMY) -#if !defined(POLARSSL_THREADING_C) || defined(POLARSSL_THREADING_IMPL) -#error "POLARSSL_THREADING_DUMMY defined, but not all prerequisites" -#endif -#define POLARSSL_THREADING_IMPL -#endif - -#if defined(POLARSSL_THREADING_PTHREAD) -#if !defined(POLARSSL_THREADING_C) || defined(POLARSSL_THREADING_IMPL) -#error "POLARSSL_THREADING_PTHREAD defined, but not all prerequisites" -#endif -#define POLARSSL_THREADING_IMPL -#endif - -#if defined(POLARSSL_THREADING_ALT) -#if !defined(POLARSSL_THREADING_C) || defined(POLARSSL_THREADING_IMPL) -#error "POLARSSL_THREADING_ALT defined, but not all prerequisites" -#endif -#define POLARSSL_THREADING_IMPL -#endif - -#if defined(POLARSSL_THREADING_C) && !defined(POLARSSL_THREADING_IMPL) -#error "POLARSSL_THREADING_C defined, single threading implementation required" -#endif -#undef POLARSSL_THREADING_IMPL - -#if defined(POLARSSL_X509_USE_C) && ( !defined(POLARSSL_BIGNUM_C) || \ - !defined(POLARSSL_OID_C) || !defined(POLARSSL_ASN1_PARSE_C) || \ - !defined(POLARSSL_PK_PARSE_C) ) -#error "POLARSSL_X509_USE_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_X509_CREATE_C) && ( !defined(POLARSSL_BIGNUM_C) || \ - !defined(POLARSSL_OID_C) || !defined(POLARSSL_ASN1_WRITE_C) || \ - !defined(POLARSSL_PK_WRITE_C) ) -#error "POLARSSL_X509_CREATE_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_X509_CRT_PARSE_C) && ( !defined(POLARSSL_X509_USE_C) ) -#error "POLARSSL_X509_CRT_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_X509_CRL_PARSE_C) && ( !defined(POLARSSL_X509_USE_C) ) -#error "POLARSSL_X509_CRL_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_X509_CSR_PARSE_C) && ( !defined(POLARSSL_X509_USE_C) ) -#error "POLARSSL_X509_CSR_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_X509_CRT_WRITE_C) && ( !defined(POLARSSL_X509_CREATE_C) ) -#error "POLARSSL_X509_CRT_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(POLARSSL_X509_CSR_WRITE_C) && ( !defined(POLARSSL_X509_CREATE_C) ) -#error "POLARSSL_X509_CSR_WRITE_C defined, but not all prerequisites" -#endif +#include "check_config.h" -#endif /* config.h */ +#endif /* POLARSSL_CONFIG_H */ diff --git a/pdns/ext/polarssl/include/polarssl/ctr_drbg.h b/pdns/ext/polarssl/include/polarssl/ctr_drbg.h index 756b5a326..bebbfe931 100644 --- a/pdns/ext/polarssl/include/polarssl/ctr_drbg.h +++ b/pdns/ext/polarssl/include/polarssl/ctr_drbg.h @@ -3,7 +3,7 @@ * * \brief CTR_DRBG based on AES-256 (NIST SP 800-90) * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -42,17 +42,39 @@ #define CTR_DRBG_SEEDLEN ( CTR_DRBG_KEYSIZE + CTR_DRBG_BLOCKSIZE ) /**< The seed length (counter + AES key) */ -#if !defined(POLARSSL_CONFIG_OPTIONS) -#if defined(POLARSSL_SHA512_C) +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(CTR_DRBG_ENTROPY_LEN) +#if defined(POLARSSL_SHA512_C) && !defined(POLARSSL_ENTROPY_FORCE_SHA256) #define CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ #else #define CTR_DRBG_ENTROPY_LEN 32 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ #endif +#endif + +#if !defined(CTR_DRBG_RESEED_INTERVAL) #define CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +#endif + +#if !defined(CTR_DRBG_MAX_INPUT) #define CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +#endif + +#if !defined(CTR_DRBG_MAX_REQUEST) #define CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +#endif + +#if !defined(CTR_DRBG_MAX_SEED_INPUT) #define CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ -#endif /* !POLARSSL_CONFIG_OPTIONS */ +#endif + +/* \} name SECTION: Module settings */ #define CTR_DRBG_PR_OFF 0 /**< No prediction resistance */ #define CTR_DRBG_PR_ON 1 /**< Prediction resistance enabled */ @@ -69,8 +91,9 @@ typedef struct unsigned char counter[16]; /*!< counter (V) */ int reseed_counter; /*!< reseed counter */ int prediction_resistance; /*!< enable prediction resistance (Automatic - reseed before every random generation) */ - size_t entropy_len; /*!< amount of entropy grabbed on each (re)seed */ + reseed before every random generation) */ + size_t entropy_len; /*!< amount of entropy grabbed on each + (re)seed */ int reseed_interval; /*!< reseed interval */ aes_context aes_ctx; /*!< AES context */ @@ -86,7 +109,7 @@ ctr_drbg_context; /** * \brief CTR_DRBG initialization - * + * * Note: Personalization data can be provided in addition to the more generic * entropy source to make this instantiation as unique as possible. * @@ -107,6 +130,13 @@ int ctr_drbg_init( ctr_drbg_context *ctx, const unsigned char *custom, size_t len ); +/** + * \brief Clear CTR_CRBG context data + * + * \param ctx CTR_DRBG context to clear + */ +void ctr_drbg_free( ctr_drbg_context *ctx ); + /** * \brief Enable / disable prediction resistance (Default: Off) * @@ -141,7 +171,7 @@ void ctr_drbg_set_reseed_interval( ctr_drbg_context *ctx, /** * \brief CTR_DRBG reseeding (extracts data from entropy source) - * + * * \param ctx CTR_DRBG context * \param additional Additional data to add to state (Can be NULL) * \param len Length of additional data @@ -204,7 +234,8 @@ int ctr_drbg_random( void *p_rng, * \param ctx CTR_DRBG context * \param path Name of the file * - * \return 0 if successful, 1 on file error, or + * \return 0 if successful, + * POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR on file error, or * POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED */ int ctr_drbg_write_seed_file( ctr_drbg_context *ctx, const char *path ); @@ -216,12 +247,13 @@ int ctr_drbg_write_seed_file( ctr_drbg_context *ctx, const char *path ); * \param ctx CTR_DRBG context * \param path Name of the file * - * \return 0 if successful, 1 on file error, + * \return 0 if successful, + * POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR on file error, * POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or * POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG */ int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path ); -#endif +#endif /* POLARSSL_FS_IO */ /** * \brief Checkup routine @@ -231,7 +263,9 @@ int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path ); int ctr_drbg_self_test( int verbose ); /* Internal functions (do not call directly) */ -int ctr_drbg_init_entropy_len( ctr_drbg_context *, int (*)(void *, unsigned char *, size_t), void *, const unsigned char *, size_t, size_t ); +int ctr_drbg_init_entropy_len( ctr_drbg_context *, + int (*)(void *, unsigned char *, size_t), void *, + const unsigned char *, size_t, size_t ); #ifdef __cplusplus } diff --git a/pdns/ext/polarssl/include/polarssl/debug.h b/pdns/ext/polarssl/include/polarssl/debug.h index 7335ad372..0dd79d52f 100644 --- a/pdns/ext/polarssl/include/polarssl/debug.h +++ b/pdns/ext/polarssl/include/polarssl/debug.h @@ -27,7 +27,11 @@ #ifndef POLARSSL_DEBUG_H #define POLARSSL_DEBUG_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include "ssl.h" #if defined(POLARSSL_ECP_C) #include "ecp.h" @@ -35,6 +39,24 @@ #if defined(POLARSSL_DEBUG_C) +#define POLARSSL_DEBUG_LOG_FULL 0 /**< Include file:line in log lines */ +#define POLARSSL_DEBUG_LOG_RAW 1 /**< Only log raw debug lines */ + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(POLARSSL_DEBUG_DFL_MODE) +#define POLARSSL_DEBUG_DFL_MODE POLARSSL_DEBUG_LOG_FULL /**< Default log: Full or Raw */ +#endif + +/* \} name SECTION: Module settings */ + + #define SSL_DEBUG_MSG( level, args ) \ debug_print_msg( ssl, level, __FILE__, __LINE__, debug_fmt args ); @@ -59,7 +81,7 @@ debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt ); #endif -#else +#else /* POLARSSL_DEBUG_C */ #define SSL_DEBUG_MSG( level, args ) do { } while( 0 ) #define SSL_DEBUG_RET( level, text, ret ) do { } while( 0 ) @@ -68,12 +90,30 @@ #define SSL_DEBUG_ECP( level, text, X ) do { } while( 0 ) #define SSL_DEBUG_CRT( level, text, crt ) do { } while( 0 ) -#endif +#endif /* POLARSSL_DEBUG_C */ #ifdef __cplusplus extern "C" { #endif +/** + * \brief Set the log mode for the debug functions globally + * (Default value: POLARSSL_DEBUG_DFL_MODE) + * + * \param log_mode The log mode to use (POLARSSL_DEBUG_LOG_FULL or + * POLARSSL_DEBUG_LOG_RAW) + */ +void debug_set_log_mode( int log_mode ); + +/** + * \brief Set the level threshold to handle globally. Messages that have a + * level over the threshold value are ignored. + * (Default value: 0 (No debug)) + * + * \param threshold maximum level of messages to pass on + */ +void debug_set_threshold( int threshold ); + char *debug_fmt( const char *format, ... ); void debug_print_msg( const ssl_context *ssl, int level, diff --git a/pdns/ext/polarssl/include/polarssl/des.h b/pdns/ext/polarssl/include/polarssl/des.h index d29bd1dee..89bb394e0 100644 --- a/pdns/ext/polarssl/include/polarssl/des.h +++ b/pdns/ext/polarssl/include/polarssl/des.h @@ -3,7 +3,7 @@ * * \brief DES block cipher * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ #ifndef POLARSSL_DES_H #define POLARSSL_DES_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include @@ -73,6 +77,34 @@ typedef struct } des3_context; +/** + * \brief Initialize DES context + * + * \param ctx DES context to be initialized + */ +void des_init( des_context *ctx ); + +/** + * \brief Clear DES context + * + * \param ctx DES context to be cleared + */ +void des_free( des_context *ctx ); + +/** + * \brief Initialize Triple-DES context + * + * \param ctx DES3 context to be initialized + */ +void des3_init( des3_context *ctx ); + +/** + * \brief Clear Triple-DES context + * + * \param ctx DES3 context to be cleared + */ +void des3_free( des3_context *ctx ); + /** * \brief Set key parity on the given key to odd. * @@ -132,7 +164,8 @@ int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ); * * \return 0 */ -int des3_set2key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] ); +int des3_set2key_enc( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 2] ); /** * \brief Triple-DES key schedule (112-bit, decryption) @@ -142,7 +175,8 @@ int des3_set2key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * * * \return 0 */ -int des3_set2key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] ); +int des3_set2key_dec( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 2] ); /** * \brief Triple-DES key schedule (168-bit, encryption) @@ -152,7 +186,8 @@ int des3_set2key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * * * \return 0 */ -int des3_set3key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] ); +int des3_set3key_enc( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 3] ); /** * \brief Triple-DES key schedule (168-bit, decryption) @@ -162,7 +197,8 @@ int des3_set3key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * * * \return 0 */ -int des3_set3key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] ); +int des3_set3key_dec( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 3] ); /** * \brief DES-ECB block encryption/decryption diff --git a/pdns/ext/polarssl/include/polarssl/dhm.h b/pdns/ext/polarssl/include/polarssl/dhm.h index 4665ff9f9..064472f35 100644 --- a/pdns/ext/polarssl/include/polarssl/dhm.h +++ b/pdns/ext/polarssl/include/polarssl/dhm.h @@ -43,6 +43,8 @@ #define POLARSSL_ERR_DHM_FILE_IO_ERROR -0x3480 /**< Read/write of file failed. */ /** + * RFC 2409 defines a number of standardized Diffie-Hellman groups + * that can be used. * RFC 3526 defines a number of standardized Diffie-Hellman groups * for IKE. * RFC 5114 defines a number of standardized Diffie-Hellman groups @@ -51,11 +53,22 @@ * Some are included here for convenience. * * Included are: + * RFC 2409 6.2. 1024-bit MODP Group (Second Oakley Group) * RFC 3526 3. 2048-bit MODP Group * RFC 3526 4. 3072-bit MODP Group * RFC 5114 2.1. 1024-bit MODP Group with 160-bit Prime Order Subgroup * RFC 5114 2.2. 2048-bit MODP Group with 224-bit Prime Order Subgroup */ +#define POLARSSL_DHM_RFC2409_MODP_1024_P \ + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \ + "FFFFFFFFFFFFFFFF" + +#define POLARSSL_DHM_RFC2409_MODP_1024_G "02" + #define POLARSSL_DHM_RFC3526_MODP_2048_P \ "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ @@ -156,6 +169,13 @@ typedef struct } dhm_context; +/** + * \brief Initialize DHM context + * + * \param ctx DHM context to be initialized + */ +void dhm_init( dhm_context *ctx ); + /** * \brief Parse the ServerKeyExchange parameters * @@ -224,7 +244,8 @@ int dhm_make_public( dhm_context *ctx, int x_size, * * \param ctx DHM context * \param output destination buffer - * \param olen number of chars written + * \param olen on entry, must hold the size of the destination buffer + * on exit, holds the actual number of bytes written * \param f_rng RNG function, for blinding purposes * \param p_rng RNG parameter * @@ -242,7 +263,9 @@ int dhm_calc_secret( dhm_context *ctx, void *p_rng ); /** - * \brief Free the components of a DHM key + * \brief Free and clear the components of a DHM key + * + * \param ctx DHM context to free and clear */ void dhm_free( dhm_context *ctx ); @@ -285,4 +308,4 @@ int dhm_self_test( int verbose ); } #endif -#endif +#endif /* dhm.h */ diff --git a/pdns/ext/polarssl/include/polarssl/ecdh.h b/pdns/ext/polarssl/include/polarssl/ecdh.h index 4c82f25f2..525cade98 100644 --- a/pdns/ext/polarssl/include/polarssl/ecdh.h +++ b/pdns/ext/polarssl/include/polarssl/ecdh.h @@ -33,28 +33,38 @@ extern "C" { #endif +/** + * When importing from an EC key, select if it is our key or the peer's key + */ +typedef enum +{ + POLARSSL_ECDH_OURS, + POLARSSL_ECDH_THEIRS, +} ecdh_side; + /** * \brief ECDH context structure */ typedef struct { - ecp_group grp; /*!< ellipitic curve used */ - mpi d; /*!< our secret value */ - ecp_point Q; /*!< our public value */ - ecp_point Qp; /*!< peer's public value */ - mpi z; /*!< shared secret */ - int point_format; /*!< format for point export */ - ecp_point Vi; /*!< blinding value (for later) */ - ecp_point Vf; /*!< un-blinding value (for later) */ - mpi _d; /*!< previous d */ + ecp_group grp; /*!< elliptic curve used */ + mpi d; /*!< our secret value (private key) */ + ecp_point Q; /*!< our public value (public key) */ + ecp_point Qp; /*!< peer's public value (public key) */ + mpi z; /*!< shared secret */ + int point_format; /*!< format for point export in TLS messages */ + ecp_point Vi; /*!< blinding value (for later) */ + ecp_point Vf; /*!< un-blinding value (for later) */ + mpi _d; /*!< previous d (for later) */ } ecdh_context; /** - * \brief Generate a public key + * \brief Generate a public key. + * Raw function that only does the core computation. * * \param grp ECP group - * \param d Destination MPI (secret exponent) + * \param d Destination MPI (secret exponent, aka private key) * \param Q Destination point (public key) * \param f_rng RNG function * \param p_rng RNG parameter @@ -68,11 +78,12 @@ int ecdh_gen_public( ecp_group *grp, mpi *d, ecp_point *Q, /** * \brief Compute shared secret + * Raw function that only does the core computation. * * \param grp ECP group * \param z Destination MPI (shared secret) * \param Q Public key from other party - * \param d Our secret exponent + * \param d Our secret exponent (private key) * \param f_rng RNG function (see notes) * \param p_rng RNG parameter * @@ -103,7 +114,8 @@ void ecdh_init( ecdh_context *ctx ); void ecdh_free( ecdh_context *ctx ); /** - * \brief Setup and write the ServerKeyExhange parameters + * \brief Generate a public key and a TLS ServerKeyExchange payload. + * (First function used by a TLS server for ECDHE.) * * \param ctx ECDH context * \param olen number of chars written @@ -123,7 +135,8 @@ int ecdh_make_params( ecdh_context *ctx, size_t *olen, void *p_rng ); /** - * \brief Parse the ServerKeyExhange parameters + * \brief Parse and procress a TLS ServerKeyExhange payload. + * (First function used by a TLS client for ECDHE.) * * \param ctx ECDH context * \param buf pointer to start of input buffer @@ -135,7 +148,23 @@ int ecdh_read_params( ecdh_context *ctx, const unsigned char **buf, const unsigned char *end ); /** - * \brief Setup and export the client's public value + * \brief Setup an ECDH context from an EC key. + * (Used by clients and servers in place of the + * ServerKeyEchange for static ECDH: import ECDH parameters + * from a certificate's EC key information.) + * + * \param ctx ECDH constext to set + * \param key EC key to use + * \param side Is it our key (1) or the peer's key (0) ? + * + * \return 0 if successful, or an POLARSSL_ERR_ECP_XXX error code + */ +int ecdh_get_params( ecdh_context *ctx, const ecp_keypair *key, + ecdh_side side ); + +/** + * \brief Generate a public key and a TLS ClientKeyExchange payload. + * (Second function used by a TLS client for ECDH(E).) * * \param ctx ECDH context * \param olen number of bytes actually written @@ -152,7 +181,8 @@ int ecdh_make_public( ecdh_context *ctx, size_t *olen, void *p_rng ); /** - * \brief Parse and import the client's public value + * \brief Parse and process a TLS ClientKeyExchange payload. + * (Second function used by a TLS server for ECDH(E).) * * \param ctx ECDH context * \param buf start of input buffer @@ -164,7 +194,8 @@ int ecdh_read_public( ecdh_context *ctx, const unsigned char *buf, size_t blen ); /** - * \brief Derive and export the shared secret + * \brief Derive and export the shared secret. + * (Last function used by both TLS client en servers.) * * \param ctx ECDH context * \param olen number of bytes written @@ -191,4 +222,4 @@ int ecdh_self_test( int verbose ); } #endif -#endif +#endif /* ecdh.h */ diff --git a/pdns/ext/polarssl/include/polarssl/ecdsa.h b/pdns/ext/polarssl/include/polarssl/ecdsa.h index ee60d2695..d99a17a28 100644 --- a/pdns/ext/polarssl/include/polarssl/ecdsa.h +++ b/pdns/ext/polarssl/include/polarssl/ecdsa.h @@ -29,6 +29,10 @@ #include "ecp.h" +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +#include "md.h" +#endif + /** * \brief ECDSA context structure * @@ -36,7 +40,7 @@ */ typedef struct { - ecp_group grp; /*!< ellipitic curve used */ + ecp_group grp; /*!< elliptic curve used */ mpi d; /*!< secret signature key */ ecp_point Q; /*!< public signature key */ mpi r; /*!< first integer from signature */ @@ -67,6 +71,27 @@ int ecdsa_sign( ecp_group *grp, mpi *r, mpi *s, const mpi *d, const unsigned char *buf, size_t blen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +/** + * \brief Compute ECDSA signature of a previously hashed message + * (deterministic version) + * + * \param grp ECP group + * \param r First output integer + * \param s Second output integer + * \param d Private signing key + * \param buf Message hash + * \param blen Length of buf + * \param md_alg MD algorithm used to hash the message + * + * \return 0 if successful, + * or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code + */ +int ecdsa_sign_det( ecp_group *grp, mpi *r, mpi *s, + const mpi *d, const unsigned char *buf, size_t blen, + md_type_t md_alg ); +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ + /** * \brief Verify ECDSA signature of a previously hashed message * @@ -112,6 +137,34 @@ int ecdsa_write_signature( ecdsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +/** + * \brief Compute ECDSA signature and write it to buffer, + * serialized as defined in RFC 4492 page 20. + * Deterministic version, RFC 6979. + * (Not thread-safe to use same context in multiple threads) + * + * \param ctx ECDSA context + * \param hash Message hash + * \param hlen Length of hash + * \param sig Buffer that will hold the signature + * \param slen Length of the signature written + * \param md_alg MD algorithm used to hash the message + * + * \note The "sig" buffer must be at least as large as twice the + * size of the curve used, plus 7 (eg. 71 bytes if a 256-bit + * curve is used). + * + * \return 0 if successful, + * or a POLARSSL_ERR_ECP, POLARSSL_ERR_MPI or + * POLARSSL_ERR_ASN1 error code + */ +int ecdsa_write_signature_det( ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + md_type_t md_alg ); +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ + /** * \brief Read and verify an ECDSA signature * @@ -122,7 +175,9 @@ int ecdsa_write_signature( ecdsa_context *ctx, * \param slen Size of sig * * \return 0 if successful, - * POLARSSL_ERR_ECP_BAD_INPUT_DATA if signature is invalid + * POLARSSL_ERR_ECP_BAD_INPUT_DATA if signature is invalid, + * POLARSSL_ERR_ECP_SIG_LEN_MISTMATCH if the signature is + * valid but its actual length is less than siglen, * or a POLARSSL_ERR_ECP or POLARSSL_ERR_MPI error code */ int ecdsa_read_signature( ecdsa_context *ctx, @@ -178,4 +233,4 @@ int ecdsa_self_test( int verbose ); } #endif -#endif +#endif /* ecdsa.h */ diff --git a/pdns/ext/polarssl/include/polarssl/ecp.h b/pdns/ext/polarssl/include/polarssl/ecp.h index 02f6f9349..7192f1e6c 100644 --- a/pdns/ext/polarssl/include/polarssl/ecp.h +++ b/pdns/ext/polarssl/include/polarssl/ecp.h @@ -39,6 +39,7 @@ #define POLARSSL_ERR_ECP_MALLOC_FAILED -0x4D80 /**< Memory allocation failed. */ #define POLARSSL_ERR_ECP_RANDOM_FAILED -0x4D00 /**< Generation of random value, such as (ephemeral) key, failed. */ #define POLARSSL_ERR_ECP_INVALID_KEY -0x4C80 /**< Invalid private or public key. */ +#define POLARSSL_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 /**< Signature is valid but shorter than the user-supplied length. */ #ifdef __cplusplus extern "C" { @@ -64,12 +65,21 @@ typedef enum POLARSSL_ECP_DP_BP256R1, /*!< 256-bits Brainpool curve */ POLARSSL_ECP_DP_BP384R1, /*!< 384-bits Brainpool curve */ POLARSSL_ECP_DP_BP512R1, /*!< 512-bits Brainpool curve */ + POLARSSL_ECP_DP_M221, /*!< (not implemented yet) */ + POLARSSL_ECP_DP_M255, /*!< Curve25519 */ + POLARSSL_ECP_DP_M383, /*!< (not implemented yet) */ + POLARSSL_ECP_DP_M511, /*!< (not implemented yet) */ + POLARSSL_ECP_DP_SECP192K1, /*!< 192-bits "Koblitz" curve */ + POLARSSL_ECP_DP_SECP224K1, /*!< 224-bits "Koblitz" curve */ + POLARSSL_ECP_DP_SECP256K1, /*!< 256-bits "Koblitz" curve */ } ecp_group_id; /** - * Number of supported curves (plus one for NONE) + * Number of supported curves (plus one for NONE). + * + * (Montgomery curves excluded for now.) */ -#define POLARSSL_ECP_DP_MAX 9 +#define POLARSSL_ECP_DP_MAX 12 /** * Curve information for use by other modules @@ -102,10 +112,19 @@ ecp_point; /** * \brief ECP group structure * - * The curves we consider are defined by y^2 = x^3 + A x + B mod P, - * and a generator for a large subgroup of order N is fixed. + * We consider two types of curves equations: + * 1. Short Weierstrass y^2 = x^3 + A x + B mod P (SEC1 + RFC 4492) + * 2. Montgomery, y^2 = x^3 + A x^2 + x mod P (M255 + draft) + * In both cases, a generator G for a prime-order subgroup is fixed. In the + * short weierstrass, this subgroup is actually the whole curve, and its + * cardinal is denoted by N. + * + * In the case of Short Weierstrass curves, our code requires that N is an odd + * prime. (Use odd in ecp_mul() and prime in ecdsa_sign() for blinding.) * - * pbits and nbits must be the size of P and N in bits. + * In the case of Montgomery curves, we don't store A but (A + 2) / 4 which is + * the quantity actually used in the formulas. Also, nbits is not the size of N + * but the required size for private keys. * * If modp is NULL, reduction modulo P is done using a generic algorithm. * Otherwise, it must point to a function that takes an mpi in the range @@ -118,18 +137,18 @@ typedef struct { ecp_group_id id; /*!< internal group identifier */ mpi P; /*!< prime modulus of the base field */ - mpi A; /*!< linear term in the equation */ - mpi B; /*!< constant term in the equation */ - ecp_point G; /*!< generator of the subgroup used */ - mpi N; /*!< the order of G */ + mpi A; /*!< 1. A in the equation, or 2. (A + 2) / 4 */ + mpi B; /*!< 1. B in the equation, or 2. unused */ + ecp_point G; /*!< generator of the (sub)group used */ + mpi N; /*!< 1. the order of G, or 2. unused */ size_t pbits; /*!< number of bits in P */ - size_t nbits; /*!< number of bits in N */ - unsigned int h; /*!< cofactor (unused now: assume 1) */ + size_t nbits; /*!< number of bits in 1. P, or 2. private keys */ + unsigned int h; /*!< internal: 1 if the constants are static */ int (*modp)(mpi *); /*!< function for fast reduction mod P */ - int (*t_pre)(ecp_point *, void *); /*!< currently unused */ - int (*t_post)(ecp_point *, void *); /*!< currently unused */ - void *t_data; /*!< currently unused */ - ecp_point *T; /*!< pre-computed points for ecp_mul() */ + int (*t_pre)(ecp_point *, void *); /*!< unused */ + int (*t_post)(ecp_point *, void *); /*!< unused */ + void *t_data; /*!< unused */ + ecp_point *T; /*!< pre-computed points for ecp_mul_comb() */ size_t T_size; /*!< number for pre-computed points */ } ecp_group; @@ -149,24 +168,64 @@ typedef struct } ecp_keypair; +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(POLARSSL_ECP_MAX_BITS) /** * Maximum size of the groups (that is, of N and P) */ -#define POLARSSL_ECP_MAX_BITS 521 +#define POLARSSL_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ +#endif + #define POLARSSL_ECP_MAX_BYTES ( ( POLARSSL_ECP_MAX_BITS + 7 ) / 8 ) #define POLARSSL_ECP_MAX_PT_LEN ( 2 * POLARSSL_ECP_MAX_BYTES + 1 ) +#if !defined(POLARSSL_ECP_WINDOW_SIZE) /* - * Maximum window size (actually, NAF width) used for point multipliation. - * Default: 8. - * Minimum value: 2. Maximum value: 8. + * Maximum "window" size used for point multiplication. + * Default: 6. + * Minimum value: 2. Maximum value: 7. * * Result is an array of at most ( 1 << ( POLARSSL_ECP_WINDOW_SIZE - 1 ) ) - * points used for point multiplication. + * points used for point multiplication. This value is directly tied to EC + * peak memory usage, so decreasing it by one should roughly cut memory usage + * by two (if large curves are in use). * - * Reduction in size may reduce speed for big curves. + * Reduction in size may reduce speed, but larger curves are impacted first. + * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1): + * w-size: 6 5 4 3 2 + * 521 145 141 135 120 97 + * 384 214 209 198 177 146 + * 256 320 320 303 262 226 + + * 224 475 475 453 398 342 + * 192 640 640 633 587 476 */ -#define POLARSSL_ECP_WINDOW_SIZE 8 /**< Maximum NAF width used. */ +#define POLARSSL_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ +#endif /* POLARSSL_ECP_WINDOW_SIZE */ + +#if !defined(POLARSSL_ECP_FIXED_POINT_OPTIM) +/* + * Trade memory for speed on fixed-point multiplication. + * + * This speeds up repeated multiplication of the generator (that is, the + * multiplication in ECDSA signatures, and half of the multiplications in + * ECDSA verification and ECDHE) by a factor roughly 3 to 4. + * + * The cost is increasing EC peak memory usage by a factor roughly 2. + * + * Change this value to 0 to reduce peak memory usage. + */ +#define POLARSSL_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ +#endif /* POLARSSL_ECP_FIXED_POINT_OPTIM */ + +/* \} name SECTION: Module settings */ /* * Point formats, from RFC 4492's enum ECPointFormat @@ -180,12 +239,22 @@ ecp_keypair; #define POLARSSL_ECP_TLS_NAMED_CURVE 3 /**< ECCurveType's named_curve */ /** - * \brief Return the list of supported curves with associated info + * \brief Get the list of supported curves in order of preferrence + * (full information) * * \return A statically allocated array, the last entry is 0. */ const ecp_curve_info *ecp_curve_list( void ); +/** + * \brief Get the list of supported curves in order of preferrence + * (grp_id only) + * + * \return A statically allocated array, + * terminated with POLARSSL_ECP_DP_NONE. + */ +const ecp_group_id *ecp_grp_id_list( void ); + /** * \brief Get curve information from an internal group identifier * @@ -198,12 +267,21 @@ const ecp_curve_info *ecp_curve_info_from_grp_id( ecp_group_id grp_id ); /** * \brief Get curve information from a TLS NamedCurve value * - * \param grp_id A POLARSSL_ECP_DP_XXX value + * \param tls_id A POLARSSL_ECP_DP_XXX value * * \return The associated curve information or NULL */ const ecp_curve_info *ecp_curve_info_from_tls_id( uint16_t tls_id ); +/** + * \brief Get curve information from a human-readable name + * + * \param name The name + * + * \return The associated curve information or NULL + */ +const ecp_curve_info *ecp_curve_info_from_name( const char *name ); + /** * \brief Initialize a point (as zero) */ @@ -315,8 +393,10 @@ int ecp_point_write_binary( const ecp_group *grp, const ecp_point *P, * \param ilen Actual length of input * * \return 0 if successful, - * POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid - * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + * POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE if the point format + * is not implemented. * * \note This function does NOT check that the point actually * belongs to the given group, see ecp_check_pubkey() for @@ -429,6 +509,9 @@ int ecp_tls_write_group( const ecp_group *grp, size_t *olen, * * \return 0 if successful, * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + * + * \note This function does not support Montgomery curves, such as + * Curve25519. */ int ecp_add( const ecp_group *grp, ecp_point *R, const ecp_point *P, const ecp_point *Q ); @@ -443,6 +526,9 @@ int ecp_add( const ecp_group *grp, ecp_point *R, * * \return 0 if successful, * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + * + * \note This function does not support Montgomery curves, such as + * Curve25519. */ int ecp_sub( const ecp_group *grp, ecp_point *R, const ecp_point *P, const ecp_point *Q ); @@ -459,28 +545,24 @@ int ecp_sub( const ecp_group *grp, ecp_point *R, * \param p_rng RNG parameter * * \return 0 if successful, + * POLARSSL_ERR_ECP_INVALID_KEY if m is not a valid privkey + * or P is not a valid pubkey, * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed - * POLARSSL_ERR_ECP_BAD_INPUT_DATA if m < 0 of m has greater - * bit length than N, the number of points in the group. - * - * \note In order to prevent simple timing attacks, this function - * executes a constant number of operations (that is, point - * doubling and addition of distinct points) for random m in - * the allowed range. - * - * \note If f_rng is not NULL, it is used to randomize projective - * coordinates of indermediate results, in order to prevent - * more elaborate timing attacks relying on intermediate - * operations. (This is a prophylactic measure since no such - * attack has been published yet.) Since this contermeasure - * has very low overhead, it is recommended to always provide - * a non-NULL f_rng parameter when using secret inputs. + * + * \note In order to prevent timing attacks, this function + * executes the exact same sequence of (base field) + * operations for any valid m. It avoids any if-branch or + * array index depending on the value of m. + * + * \note If f_rng is not NULL, it is used to randomize intermediate + * results in order to prevent potential timing attacks + * targeting these results. It is recommended to always + * provide a non-NULL f_rng (the overhead is negligible). */ int ecp_mul( ecp_group *grp, ecp_point *R, const mpi *m, const ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); - /** * \brief Check that a point is a valid public key on this curve * @@ -539,15 +621,31 @@ int ecp_gen_keypair( ecp_group *grp, mpi *d, ecp_point *Q, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); +/** + * \brief Generate a keypair + * + * \param grp_id ECP group identifier + * \param key Destination keypair + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful, + * or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code + */ +int ecp_gen_key( ecp_group_id grp_id, ecp_keypair *key, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +#if defined(POLARSSL_SELF_TEST) /** * \brief Checkup routine * - * \return 0 if successful, or 1 if the test failed + * \return 0 if successful, or 1 if a test failed */ int ecp_self_test( int verbose ); +#endif #ifdef __cplusplus } #endif -#endif +#endif /* ecp.h */ diff --git a/pdns/ext/polarssl/include/polarssl/entropy.h b/pdns/ext/polarssl/include/polarssl/entropy.h index 235b7733c..f5fa92808 100644 --- a/pdns/ext/polarssl/include/polarssl/entropy.h +++ b/pdns/ext/polarssl/include/polarssl/entropy.h @@ -3,7 +3,7 @@ * * \brief Entropy accumulator implementation * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -29,9 +29,13 @@ #include +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif -#if defined(POLARSSL_SHA512_C) +#if defined(POLARSSL_SHA512_C) && !defined(POLARSSL_ENTROPY_FORCE_SHA256) #include "sha512.h" #define POLARSSL_ENTROPY_SHA512_ACCUMULATOR #else @@ -52,11 +56,25 @@ #define POLARSSL_ERR_ENTROPY_SOURCE_FAILED -0x003C /**< Critical entropy source failure. */ #define POLARSSL_ERR_ENTROPY_MAX_SOURCES -0x003E /**< No more sources can be added. */ #define POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040 /**< No sources have been added to poll. */ +#define POLARSSL_ERR_ENTROPY_FILE_IO_ERROR -0x0058 /**< Read/write error in file. */ -#if !defined(POLARSSL_CONFIG_OPTIONS) +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(ENTROPY_MAX_SOURCES) #define ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +#endif + +#if !defined(ENTROPY_MAX_GATHER) #define ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ -#endif /* !POLARSSL_CONFIG_OPTIONS */ +#endif + +/* \} name SECTION: Module settings */ #if defined(POLARSSL_ENTROPY_SHA512_ACCUMULATOR) #define ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */ @@ -64,6 +82,7 @@ #define ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */ #endif +#define ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */ #define ENTROPY_SOURCE_MANUAL ENTROPY_MAX_SOURCES #ifdef __cplusplus @@ -81,7 +100,8 @@ extern "C" { * \return 0 if no critical failures occurred, * POLARSSL_ERR_ENTROPY_SOURCE_FAILED otherwise */ -typedef int (*f_source_ptr)(void *, unsigned char *, size_t, size_t *); +typedef int (*f_source_ptr)(void *data, unsigned char *output, size_t len, + size_t *olen); /** * \brief Entropy source state @@ -132,6 +152,7 @@ void entropy_free( entropy_context *ctx ); /** * \brief Adds an entropy source to poll + * (Thread-safe if POLARSSL_THREADING_C is enabled) * * \param ctx Entropy context * \param f_source Entropy function @@ -147,6 +168,7 @@ int entropy_add_source( entropy_context *ctx, /** * \brief Trigger an extra gather poll for the accumulator + * (Thread-safe if POLARSSL_THREADING_C is enabled) * * \param ctx Entropy context * @@ -155,12 +177,13 @@ int entropy_add_source( entropy_context *ctx, int entropy_gather( entropy_context *ctx ); /** - * \brief Retrieve entropy from the accumulator (Max ENTROPY_BLOCK_SIZE) + * \brief Retrieve entropy from the accumulator + * (Maximum length: ENTROPY_BLOCK_SIZE) * (Thread-safe if POLARSSL_THREADING_C is enabled) * * \param data Entropy context * \param output Buffer to fill - * \param len Length of buffer + * \param len Number of bytes desired, must be at most ENTROPY_BLOCK_SIZE * * \return 0 if successful, or POLARSSL_ERR_ENTROPY_SOURCE_FAILED */ @@ -168,7 +191,8 @@ int entropy_func( void *data, unsigned char *output, size_t len ); /** * \brief Add data to the accumulator manually - * + * (Thread-safe if POLARSSL_THREADING_C is enabled) + * * \param ctx Entropy context * \param data Data to add * \param len Length of data @@ -178,6 +202,43 @@ int entropy_func( void *data, unsigned char *output, size_t len ); int entropy_update_manual( entropy_context *ctx, const unsigned char *data, size_t len ); +#if defined(POLARSSL_FS_IO) +/** + * \brief Write a seed file + * + * \param ctx Entropy context + * \param path Name of the file + * + * \return 0 if successful, + * POLARSSL_ERR_ENTROPY_FILE_IO_ERROR on file error, or + * POLARSSL_ERR_ENTROPY_SOURCE_FAILED + */ +int entropy_write_seed_file( entropy_context *ctx, const char *path ); + +/** + * \brief Read and update a seed file. Seed is added to this + * instance. No more than ENTROPY_MAX_SEED_SIZE bytes are + * read from the seed file. The rest is ignored. + * + * \param ctx Entropy context + * \param path Name of the file + * + * \return 0 if successful, + * POLARSSL_ERR_ENTROPY_FILE_IO_ERROR on file error, + * POLARSSL_ERR_ENTROPY_SOURCE_FAILED + */ +int entropy_update_seed_file( entropy_context *ctx, const char *path ); +#endif /* POLARSSL_FS_IO */ + +#if defined(POLARSSL_SELF_TEST) +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if a test failed + */ +int entropy_self_test( int verbose ); +#endif /* POLARSSL_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/pdns/ext/polarssl/include/polarssl/entropy_poll.h b/pdns/ext/polarssl/include/polarssl/entropy_poll.h index 011659829..92efa0045 100644 --- a/pdns/ext/polarssl/include/polarssl/entropy_poll.h +++ b/pdns/ext/polarssl/include/polarssl/entropy_poll.h @@ -29,7 +29,11 @@ #include +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #ifdef __cplusplus extern "C" { diff --git a/pdns/ext/polarssl/include/polarssl/error.h b/pdns/ext/polarssl/include/polarssl/error.h index 55a8a45af..cdee952e0 100644 --- a/pdns/ext/polarssl/include/polarssl/error.h +++ b/pdns/ext/polarssl/include/polarssl/error.h @@ -41,15 +41,17 @@ * * 16 bit error code bit-segmentation * - * 1 bit - Intentionally not used + * 1 bit - Sign bit * 3 bits - High level module ID * 5 bits - Module-dependent error code - * 6 bits - Low level module errors - * 1 bit - Intentionally not used + * 7 bits - Low level module errors * - * Low-level module errors (0x007E-0x0002) + * For historical reasons, low-level error codes are divided in even and odd, + * even codes were assigned first, and -1 is reserved for other errors. * - * Module Nr Codes assigned + * Low-level module errors (0x0002-0x007E, 0x0003-0x007F) + * + * Module Nr Codes assigned * MPI 7 0x0002-0x0010 * GCM 2 0x0012-0x0014 * BLOWFISH 2 0x0016-0x0018 @@ -58,12 +60,13 @@ * CAMELLIA 2 0x0024-0x0026 * XTEA 1 0x0028-0x0028 * BASE64 2 0x002A-0x002C - * OID 1 0x002E-0x002E + * OID 1 0x002E-0x002E 0x000B-0x000B * PADLOCK 1 0x0030-0x0030 * DES 1 0x0032-0x0032 - * CTR_DBRG 3 0x0034-0x003A + * CTR_DBRG 4 0x0034-0x003A * ENTROPY 3 0x003C-0x0040 * NET 11 0x0042-0x0056 + * ENTROPY 1 0x0058-0x0058 * ASN1 7 0x0060-0x006C * MD2 1 0x0070-0x0070 * MD4 1 0x0072-0x0072 @@ -72,23 +75,26 @@ * SHA256 1 0x0078-0x0078 * SHA512 1 0x007A-0x007A * PBKDF2 1 0x007C-0x007C + * RIPEMD160 1 0x007E-0x007E + * HMAC_DRBG 4 0x0003-0x0009 + * CCM 2 0x000D-0x000F * - * High-level module nr (3 bits - 0x1...-0x8...) + * High-level module nr (3 bits - 0x0...-0x7...) * Name ID Nr of Errors * PEM 1 9 * PKCS#12 1 4 (Started from top) * X509 2 18 - * PK 2 13 (Started from top) + * PK 2 14 (Started from top, plus 0x2000) * DHM 3 9 * PKCS5 3 4 (Started from top) * RSA 4 9 - * ECP 4 7 (Started from top) + * ECP 4 8 (Started from top) * MD 5 4 * CIPHER 6 6 - * SSL 6 8 (Started from top) + * SSL 6 9 (Started from top) * SSL 7 31 * - * Module dependent error code (5 bits 0x.08.-0x.F8.) + * Module dependent error code (5 bits 0x.00.-0x.F8.) */ #ifdef __cplusplus diff --git a/pdns/ext/polarssl/include/polarssl/gcm.h b/pdns/ext/polarssl/include/polarssl/gcm.h index e4267c645..c2829a009 100644 --- a/pdns/ext/polarssl/include/polarssl/gcm.h +++ b/pdns/ext/polarssl/include/polarssl/gcm.h @@ -201,7 +201,7 @@ int gcm_finish( gcm_context *ctx, /** * \brief Free a GCM context and underlying cipher sub-context * - * \param ctx + * \param ctx GCM context to free */ void gcm_free( gcm_context *ctx ); diff --git a/pdns/ext/polarssl/include/polarssl/havege.h b/pdns/ext/polarssl/include/polarssl/havege.h index 5998903ec..536eb0882 100644 --- a/pdns/ext/polarssl/include/polarssl/havege.h +++ b/pdns/ext/polarssl/include/polarssl/havege.h @@ -53,6 +53,13 @@ havege_state; */ void havege_init( havege_state *hs ); +/** + * \brief Clear HAVEGE state + * + * \param hs HAVEGE state to be cleared + */ +void havege_free( havege_state *hs ); + /** * \brief HAVEGE rand function * diff --git a/pdns/ext/polarssl/include/polarssl/hmac_drbg.h b/pdns/ext/polarssl/include/polarssl/hmac_drbg.h new file mode 100644 index 000000000..2d765d519 --- /dev/null +++ b/pdns/ext/polarssl/include/polarssl/hmac_drbg.h @@ -0,0 +1,284 @@ +/** + * \file hmac_drbg.h + * + * \brief HMAC_DRBG (NIST SP 800-90A) + * + * Copyright (C) 2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_HMAC_DRBG_H +#define POLARSSL_HMAC_DRBG_H + +#include "md.h" + +/* + * Error codes + */ +#define POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG -0x0003 /**< Too many random requested in single call. */ +#define POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG -0x0005 /**< Input too large (Entropy + additional). */ +#define POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR -0x0007 /**< Read/write error in file. */ +#define POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED -0x0009 /**< The entropy source failed. */ + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(POLARSSL_HMAC_DRBG_RESEED_INTERVAL) +#define POLARSSL_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +#endif + +#if !defined(POLARSSL_HMAC_DRBG_MAX_INPUT) +#define POLARSSL_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +#endif + +#if !defined(POLARSSL_HMAC_DRBG_MAX_REQUEST) +#define POLARSSL_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +#endif + +#if !defined(POLARSSL_HMAC_DRBG_MAX_SEED_INPUT) +#define POLARSSL_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ +#endif + +/* \} name SECTION: Module settings */ + +#define POLARSSL_HMAC_DRBG_PR_OFF 0 /**< No prediction resistance */ +#define POLARSSL_HMAC_DRBG_PR_ON 1 /**< Prediction resistance enabled */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * HMAC_DRBG context. + */ +typedef struct +{ + /* Working state: the key K is not stored explicitely, + * but is implied by the HMAC context */ + md_context_t md_ctx; /*!< HMAC context (inc. K) */ + unsigned char V[POLARSSL_MD_MAX_SIZE]; /*!< V in the spec */ + int reseed_counter; /*!< reseed counter */ + + /* Administrative state */ + size_t entropy_len; /*!< entropy bytes grabbed on each (re)seed */ + int prediction_resistance; /*!< enable prediction resistance (Automatic + reseed before every random generation) */ + int reseed_interval; /*!< reseed interval */ + + /* Callbacks */ + int (*f_entropy)(void *, unsigned char *, size_t); /*!< entropy function */ + void *p_entropy; /*!< context for the entropy function */ +} hmac_drbg_context; + +/** + * \brief HMAC_DRBG initialisation + * + * \param ctx HMAC_DRBG context to be initialised + * \param md_info MD algorithm to use for HMAC_DRBG + * \param f_entropy Entropy callback (p_entropy, buffer to fill, buffer + * length) + * \param p_entropy Entropy context + * \param custom Personalization data (Device specific identifiers) + * (Can be NULL) + * \param len Length of personalization data + * + * \note The "security strength" as defined by NIST is set to: + * 128 bits if md_alg is SHA-1, + * 192 bits if md_alg is SHA-224, + * 256 bits if md_alg is SHA-256 or higher. + * Note that SHA-256 is just as efficient as SHA-224. + * + * \return 0 if successful, or + * POLARSSL_ERR_MD_BAD_INPUT_DATA, or + * POLARSSL_ERR_MD_ALLOC_FAILED, or + * POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED. + */ +int hmac_drbg_init( hmac_drbg_context *ctx, + const md_info_t * md_info, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len ); + +/** + * \brief Initilisation of simpified HMAC_DRBG (never reseeds). + * (For use with deterministic ECDSA.) + * + * \param ctx HMAC_DRBG context to be initialised + * \param md_info MD algorithm to use for HMAC_DRBG + * \param data Concatenation of entropy string and additional data + * \param data_len Length of data in bytes + * + * \return 0 if successful, or + * POLARSSL_ERR_MD_BAD_INPUT_DATA, or + * POLARSSL_ERR_MD_ALLOC_FAILED. + */ +int hmac_drbg_init_buf( hmac_drbg_context *ctx, + const md_info_t * md_info, + const unsigned char *data, size_t data_len ); + +/** + * \brief Enable / disable prediction resistance (Default: Off) + * + * Note: If enabled, entropy is used for ctx->entropy_len before each call! + * Only use this if you have ample supply of good entropy! + * + * \param ctx HMAC_DRBG context + * \param resistance POLARSSL_HMAC_DRBG_PR_ON or POLARSSL_HMAC_DRBG_PR_OFF + */ +void hmac_drbg_set_prediction_resistance( hmac_drbg_context *ctx, + int resistance ); + +/** + * \brief Set the amount of entropy grabbed on each reseed + * (Default: given by the security strength, which + * depends on the hash used, see \c hmac_drbg_init() ) + * + * \param ctx HMAC_DRBG context + * \param len Amount of entropy to grab, in bytes + */ +void hmac_drbg_set_entropy_len( hmac_drbg_context *ctx, + size_t len ); + +/** + * \brief Set the reseed interval + * (Default: POLARSSL_HMAC_DRBG_RESEED_INTERVAL) + * + * \param ctx HMAC_DRBG context + * \param interval Reseed interval + */ +void hmac_drbg_set_reseed_interval( hmac_drbg_context *ctx, + int interval ); + +/** + * \brief HMAC_DRBG update state + * + * \param ctx HMAC_DRBG context + * \param additional Additional data to update state with, or NULL + * \param add_len Length of additional data, or 0 + * + * \note Additional data is optional, pass NULL and 0 as second + * third argument if no additional data is being used. + */ +void hmac_drbg_update( hmac_drbg_context *ctx, + const unsigned char *additional, size_t add_len ); + +/** + * \brief HMAC_DRBG reseeding (extracts data from entropy source) + * + * \param ctx HMAC_DRBG context + * \param additional Additional data to add to state (Can be NULL) + * \param len Length of additional data + * + * \return 0 if successful, or + * POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + */ +int hmac_drbg_reseed( hmac_drbg_context *ctx, + const unsigned char *additional, size_t len ); + +/** + * \brief HMAC_DRBG generate random with additional update input + * + * Note: Automatically reseeds if reseed_counter is reached or PR is enabled. + * + * \param p_rng HMAC_DRBG context + * \param output Buffer to fill + * \param output_len Length of the buffer + * \param additional Additional data to update with (can be NULL) + * \param add_len Length of additional data (can be 0) + * + * \return 0 if successful, or + * POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or + * POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG, or + * POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG. + */ +int hmac_drbg_random_with_add( void *p_rng, + unsigned char *output, size_t output_len, + const unsigned char *additional, + size_t add_len ); + +/** + * \brief HMAC_DRBG generate random + * + * Note: Automatically reseeds if reseed_counter is reached or PR is enabled. + * + * \param p_rng HMAC_DRBG context + * \param output Buffer to fill + * \param out_len Length of the buffer + * + * \return 0 if successful, or + * POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or + * POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG + */ +int hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ); + +/** + * \brief Free an HMAC_DRBG context + * + * \param ctx HMAC_DRBG context to free. + */ +void hmac_drbg_free( hmac_drbg_context *ctx ); + +#if defined(POLARSSL_FS_IO) +/** + * \brief Write a seed file + * + * \param ctx HMAC_DRBG context + * \param path Name of the file + * + * \return 0 if successful, 1 on file error, or + * POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + */ +int hmac_drbg_write_seed_file( hmac_drbg_context *ctx, const char *path ); + +/** + * \brief Read and update a seed file. Seed is added to this + * instance + * + * \param ctx HMAC_DRBG context + * \param path Name of the file + * + * \return 0 if successful, 1 on file error, + * POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED or + * POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG + */ +int hmac_drbg_update_seed_file( hmac_drbg_context *ctx, const char *path ); +#endif /* POLARSSL_FS_IO */ + + +#if defined(POLARSSL_SELF_TEST) +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int hmac_drbg_self_test( int verbose ); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* hmac_drbg.h */ diff --git a/pdns/ext/polarssl/include/polarssl/md.h b/pdns/ext/polarssl/include/polarssl/md.h index eecf78113..81d8a2e5c 100644 --- a/pdns/ext/polarssl/include/polarssl/md.h +++ b/pdns/ext/polarssl/include/polarssl/md.h @@ -1,11 +1,11 @@ /** * \file md.h - * + * * \brief Generic message digest wrapper * * \author Adriaan de Jong * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -58,6 +58,7 @@ typedef enum { POLARSSL_MD_SHA256, POLARSSL_MD_SHA384, POLARSSL_MD_SHA512, + POLARSSL_MD_RIPEMD160, } md_type_t; #if defined(POLARSSL_SHA512_C) @@ -91,16 +92,18 @@ typedef struct { /** Generic digest function */ void (*digest_func)( const unsigned char *input, size_t ilen, - unsigned char *output ); + unsigned char *output ); /** Generic file digest function */ int (*file_func)( const char *path, unsigned char *output ); /** HMAC Initialisation function */ - void (*hmac_starts_func)( void *ctx, const unsigned char *key, size_t keylen ); + void (*hmac_starts_func)( void *ctx, const unsigned char *key, + size_t keylen ); /** HMAC update function */ - void (*hmac_update_func)( void *ctx, const unsigned char *input, size_t ilen ); + void (*hmac_update_func)( void *ctx, const unsigned char *input, + size_t ilen ); /** HMAC finalisation function */ void (*hmac_finish_func)( void *ctx, unsigned char *output); @@ -110,8 +113,8 @@ typedef struct { /** Generic HMAC function */ void (*hmac_func)( const unsigned char *key, size_t keylen, - const unsigned char *input, size_t ilen, - unsigned char *output ); + const unsigned char *input, size_t ilen, + unsigned char *output ); /** Allocate a new context */ void * (*ctx_alloc_func)( void ); @@ -170,8 +173,24 @@ const md_info_t *md_info_from_string( const char *md_name ); const md_info_t *md_info_from_type( md_type_t md_type ); /** - * \brief Initialises and fills the message digest context structure with - * the appropriate values. + * \brief Initialize a md_context (as NONE) + */ +void md_init( md_context_t *ctx ); + +/** + * \brief Free and clear the message-specific context of ctx. + * Freeing ctx itself remains the responsibility of the + * caller. + */ +void md_free( md_context_t *ctx ); + +/** + * \brief Initialises and fills the message digest context structure + * with the appropriate values. + * + * \note Currently also clears structure. In future versions you + * will be required to call md_init() on the structure + * first. * * \param ctx context to initialise. May not be NULL. The * digest-specific context (ctx->md_ctx) must be NULL. It will @@ -188,10 +207,11 @@ int md_init_ctx( md_context_t *ctx, const md_info_t *md_info ); * \brief Free the message-specific context of ctx. Freeing ctx itself * remains the responsibility of the caller. * + * \note Deprecated: Redirects to md_free() + * * \param ctx Free the message-specific context * - * \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter - * verification fails. + * \returns 0 */ int md_free_ctx( md_context_t *ctx ); @@ -298,7 +318,8 @@ int md( const md_info_t *md_info, const unsigned char *input, size_t ilen, * failed, POLARSSL_ERR_MD_FILE_READ_FAILED if fread failed, * POLARSSL_ERR_MD_BAD_INPUT_DATA if md_info was NULL. */ -int md_file( const md_info_t *md_info, const char *path, unsigned char *output ); +int md_file( const md_info_t *md_info, const char *path, + unsigned char *output ); /** * \brief Generic HMAC context setup @@ -310,7 +331,8 @@ int md_file( const md_info_t *md_info, const char *path, unsigned char *output ) * \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter * verification fails. */ -int md_hmac_starts( md_context_t *ctx, const unsigned char *key, size_t keylen ); +int md_hmac_starts( md_context_t *ctx, const unsigned char *key, + size_t keylen ); /** * \brief Generic HMAC process buffer @@ -322,7 +344,8 @@ int md_hmac_starts( md_context_t *ctx, const unsigned char *key, size_t keylen ) * \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter * verification fails. */ -int md_hmac_update( md_context_t *ctx, const unsigned char *input, size_t ilen ); +int md_hmac_update( md_context_t *ctx, const unsigned char *input, + size_t ilen ); /** * \brief Generic HMAC final digest diff --git a/pdns/ext/polarssl/include/polarssl/md2.h b/pdns/ext/polarssl/include/polarssl/md2.h index a8e23d0da..952b0bfce 100644 --- a/pdns/ext/polarssl/include/polarssl/md2.h +++ b/pdns/ext/polarssl/include/polarssl/md2.h @@ -3,7 +3,7 @@ * * \brief MD2 message digest algorithm (hash function) * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ #ifndef POLARSSL_MD2_H #define POLARSSL_MD2_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include @@ -56,6 +60,20 @@ typedef struct } md2_context; +/** + * \brief Initialize MD2 context + * + * \param ctx MD2 context to be initialized + */ +void md2_init( md2_context *ctx ); + +/** + * \brief Clear MD2 context + * + * \param ctx MD2 context to be cleared + */ +void md2_free( md2_context *ctx ); + /** * \brief MD2 context setup * @@ -118,7 +136,8 @@ int md2_file( const char *path, unsigned char output[16] ); * \param key HMAC secret key * \param keylen length of the HMAC key */ -void md2_hmac_starts( md2_context *ctx, const unsigned char *key, size_t keylen ); +void md2_hmac_starts( md2_context *ctx, const unsigned char *key, + size_t keylen ); /** * \brief MD2 HMAC process buffer @@ -127,7 +146,8 @@ void md2_hmac_starts( md2_context *ctx, const unsigned char *key, size_t keylen * \param input buffer holding the data * \param ilen length of the input data */ -void md2_hmac_update( md2_context *ctx, const unsigned char *input, size_t ilen ); +void md2_hmac_update( md2_context *ctx, const unsigned char *input, + size_t ilen ); /** * \brief MD2 HMAC final digest diff --git a/pdns/ext/polarssl/include/polarssl/md4.h b/pdns/ext/polarssl/include/polarssl/md4.h index a1b5d459e..fc5a5cd27 100644 --- a/pdns/ext/polarssl/include/polarssl/md4.h +++ b/pdns/ext/polarssl/include/polarssl/md4.h @@ -3,7 +3,7 @@ * * \brief MD4 message digest algorithm (hash function) * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ #ifndef POLARSSL_MD4_H #define POLARSSL_MD4_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include @@ -62,6 +66,20 @@ typedef struct } md4_context; +/** + * \brief Initialize MD4 context + * + * \param ctx MD4 context to be initialized + */ +void md4_init( md4_context *ctx ); + +/** + * \brief Clear MD4 context + * + * \param ctx MD4 context to be cleared + */ +void md4_free( md4_context *ctx ); + /** * \brief MD4 context setup * @@ -124,7 +142,8 @@ int md4_file( const char *path, unsigned char output[16] ); * \param key HMAC secret key * \param keylen length of the HMAC key */ -void md4_hmac_starts( md4_context *ctx, const unsigned char *key, size_t keylen ); +void md4_hmac_starts( md4_context *ctx, const unsigned char *key, + size_t keylen ); /** * \brief MD4 HMAC process buffer @@ -133,7 +152,8 @@ void md4_hmac_starts( md4_context *ctx, const unsigned char *key, size_t keylen * \param input buffer holding the data * \param ilen length of the input data */ -void md4_hmac_update( md4_context *ctx, const unsigned char *input, size_t ilen ); +void md4_hmac_update( md4_context *ctx, const unsigned char *input, + size_t ilen ); /** * \brief MD4 HMAC final digest diff --git a/pdns/ext/polarssl/include/polarssl/md5.h b/pdns/ext/polarssl/include/polarssl/md5.h index df2a61b8a..2f378f6cd 100644 --- a/pdns/ext/polarssl/include/polarssl/md5.h +++ b/pdns/ext/polarssl/include/polarssl/md5.h @@ -27,7 +27,11 @@ #ifndef POLARSSL_MD5_H #define POLARSSL_MD5_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include @@ -62,6 +66,20 @@ typedef struct } md5_context; +/** + * \brief Initialize MD5 context + * + * \param ctx MD5 context to be initialized + */ +void md5_init( md5_context *ctx ); + +/** + * \brief Clear MD5 context + * + * \param ctx MD5 context to be cleared + */ +void md5_free( md5_context *ctx ); + /** * \brief MD5 context setup * diff --git a/pdns/ext/polarssl/include/polarssl/md_wrap.h b/pdns/ext/polarssl/include/polarssl/md_wrap.h index a41c875fc..eb1db0f1e 100644 --- a/pdns/ext/polarssl/include/polarssl/md_wrap.h +++ b/pdns/ext/polarssl/include/polarssl/md_wrap.h @@ -1,6 +1,6 @@ /** * \file md_wrap.h - * + * * \brief Message digest wrappers. * * \author Adriaan de Jong @@ -29,7 +29,11 @@ #ifndef POLARSSL_MD_WRAP_H #define POLARSSL_MD_WRAP_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include "md.h" #ifdef __cplusplus @@ -45,6 +49,9 @@ extern const md_info_t md4_info; #if defined(POLARSSL_MD5_C) extern const md_info_t md5_info; #endif +#if defined(POLARSSL_RIPEMD160_C) +extern const md_info_t ripemd160_info; +#endif #if defined(POLARSSL_SHA1_C) extern const md_info_t sha1_info; #endif diff --git a/pdns/ext/polarssl/include/polarssl/memory.h b/pdns/ext/polarssl/include/polarssl/memory.h index 6a3dab94b..3af39511b 100644 --- a/pdns/ext/polarssl/include/polarssl/memory.h +++ b/pdns/ext/polarssl/include/polarssl/memory.h @@ -1,9 +1,9 @@ /** * \file memory.h * - * \brief Memory allocation layer + * \brief Memory allocation layer (Deprecated to platform layer) * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,105 +27,26 @@ #ifndef POLARSSL_MEMORY_H #define POLARSSL_MEMORY_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include -#if !defined(POLARSSL_CONFIG_OPTIONS) -#define POLARSSL_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ - -#define POLARSSL_MEMORY_STDMALLOC malloc /**< Default allocator to use, can be undefined */ -#define POLARSSL_MEMORY_STDFREE free /**< Default free to use, can be undefined */ -#endif /* POLARSSL_CONFIG_OPTIONS */ - -#define MEMORY_VERIFY_NONE 0 -#define MEMORY_VERIFY_ALLOC (1 << 0) -#define MEMORY_VERIFY_FREE (1 << 1) -#define MEMORY_VERIFY_ALWAYS (MEMORY_VERIFY_ALLOC | MEMORY_VERIFY_FREE) - -#ifdef __cplusplus -extern "C" { +#if defined(POLARSSL_MEMORY_C) && !defined(POLARSSL_PLATFORM_MEMORY) +#define POLARSSL_PLATFORM_MEMORY #endif -/* - * The function pointers for malloc and free - */ -extern void * (*polarssl_malloc)( size_t len ); -extern void (*polarssl_free)( void *ptr ); +#include "platform.h" +#include "memory_buffer_alloc.h" -/** - * \brief Set your own memory implementation function pointers - * - * \param malloc_func the malloc function implementation - * \param free_func the free function implementation - * - * \return 0 if successful - */ int memory_set_own( void * (*malloc_func)( size_t ), - void (*free_func)( void * ) ); - -#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) -/** - * \brief Initialize use of stack-based memory allocator. - * The stack-based allocator does memory management inside the - * presented buffer and does not call malloc() and free(). - * It sets the global polarssl_malloc() and polarssl_free() pointers - * to its own functions. - * (Provided polarssl_malloc() and polarssl_free() are thread-safe if - * POLARSSL_THREADING_C is defined) - * - * \note This code is not optimized and provides a straight-forward - * implementation of a stack-based memory allocator. - * - * \param buf buffer to use as heap - * \param len size of the buffer - * - * \return 0 if successful - */ -int memory_buffer_alloc_init( unsigned char *buf, size_t len ); - -/** - * \brief Free the mutex for thread-safety and clear remaining memory - */ -void memory_buffer_alloc_free(); - -/** - * \brief Determine when the allocator should automatically verify the state - * of the entire chain of headers / meta-data. - * (Default: MEMORY_VERIFY_NONE) - * - * \param verify One of MEMORY_VERIFY_NONE, MEMORY_VERIFY_ALLOC, - * MEMORY_VERIFY_FREE or MEMORY_VERIFY_ALWAYS - */ -void memory_buffer_set_verify( int verify ); - -#if defined(POLARSSL_MEMORY_DEBUG) -/** - * \brief Print out the status of the allocated memory (primarily for use - * after a program should have de-allocated all memory) - * Prints out a list of 'still allocated' blocks and their stack - * trace if POLARSSL_MEMORY_BACKTRACE is defined. - */ -void memory_buffer_alloc_status(); -#endif /* POLARSSL_MEMORY_DEBUG */ - -/** - * \brief Verifies that all headers in the memory buffer are correct - * and contain sane values. Helps debug buffer-overflow errors. - * - * Prints out first failure if POLARSSL_MEMORY_DEBUG is defined. - * Prints out full header information if POLARSSL_MEMORY_DEBUG_HEADERS - * is defined. (Includes stack trace information for each block if - * POLARSSL_MEMORY_BACKTRACE is defined as well). - * - * \returns 0 if verified, 1 otherwise - */ -int memory_buffer_alloc_verify(); - -#endif /* POLARSSL_MEMORY_BUFFER_ALLOC_C */ - -#ifdef __cplusplus + void (*free_func)( void * ) ) +{ + return platform_set_malloc_free( malloc_func, free_func ); } -#endif + #endif /* memory.h */ diff --git a/pdns/ext/polarssl/include/polarssl/memory_buffer_alloc.h b/pdns/ext/polarssl/include/polarssl/memory_buffer_alloc.h new file mode 100644 index 000000000..c44975258 --- /dev/null +++ b/pdns/ext/polarssl/include/polarssl/memory_buffer_alloc.h @@ -0,0 +1,122 @@ +/** + * \file memory_buffer_alloc.h + * + * \brief Buffer-based memory allocator + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_MEMORY_BUFFER_ALLOC_H +#define POLARSSL_MEMORY_BUFFER_ALLOC_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(POLARSSL_MEMORY_ALIGN_MULTIPLE) +#define POLARSSL_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ +#endif + +/* \} name SECTION: Module settings */ + +#define MEMORY_VERIFY_NONE 0 +#define MEMORY_VERIFY_ALLOC (1 << 0) +#define MEMORY_VERIFY_FREE (1 << 1) +#define MEMORY_VERIFY_ALWAYS (MEMORY_VERIFY_ALLOC | MEMORY_VERIFY_FREE) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Initialize use of stack-based memory allocator. + * The stack-based allocator does memory management inside the + * presented buffer and does not call malloc() and free(). + * It sets the global polarssl_malloc() and polarssl_free() pointers + * to its own functions. + * (Provided polarssl_malloc() and polarssl_free() are thread-safe if + * POLARSSL_THREADING_C is defined) + * + * \note This code is not optimized and provides a straight-forward + * implementation of a stack-based memory allocator. + * + * \param buf buffer to use as heap + * \param len size of the buffer + * + * \return 0 if successful + */ +int memory_buffer_alloc_init( unsigned char *buf, size_t len ); + +/** + * \brief Free the mutex for thread-safety and clear remaining memory + */ +void memory_buffer_alloc_free( void ); + +/** + * \brief Determine when the allocator should automatically verify the state + * of the entire chain of headers / meta-data. + * (Default: MEMORY_VERIFY_NONE) + * + * \param verify One of MEMORY_VERIFY_NONE, MEMORY_VERIFY_ALLOC, + * MEMORY_VERIFY_FREE or MEMORY_VERIFY_ALWAYS + */ +void memory_buffer_set_verify( int verify ); + +#if defined(POLARSSL_MEMORY_DEBUG) +/** + * \brief Print out the status of the allocated memory (primarily for use + * after a program should have de-allocated all memory) + * Prints out a list of 'still allocated' blocks and their stack + * trace if POLARSSL_MEMORY_BACKTRACE is defined. + */ +void memory_buffer_alloc_status( void ); +#endif /* POLARSSL_MEMORY_DEBUG */ + +/** + * \brief Verifies that all headers in the memory buffer are correct + * and contain sane values. Helps debug buffer-overflow errors. + * + * Prints out first failure if POLARSSL_MEMORY_DEBUG is defined. + * Prints out full header information if POLARSSL_MEMORY_DEBUG_HEADERS + * is defined. (Includes stack trace information for each block if + * POLARSSL_MEMORY_BACKTRACE is defined as well). + * + * \returns 0 if verified, 1 otherwise + */ +int memory_buffer_alloc_verify( void ); + +#ifdef __cplusplus +} +#endif + +#endif /* memory_buffer_alloc.h */ diff --git a/pdns/ext/polarssl/include/polarssl/net.h b/pdns/ext/polarssl/include/polarssl/net.h index 88302ac0a..22698b4ce 100644 --- a/pdns/ext/polarssl/include/polarssl/net.h +++ b/pdns/ext/polarssl/include/polarssl/net.h @@ -82,9 +82,10 @@ int net_bind( int *fd, const char *bind_ip, int port ); * \param bind_fd Relevant socket * \param client_fd Will contain the connected client socket * \param client_ip Will contain the client IP address + * Must be at least 4 bytes, or 16 if IPv6 is supported * * \return 0 if successful, POLARSSL_ERR_NET_ACCEPT_FAILED, or - * POLARSSL_ERR_NET_WOULD_BLOCK is bind_fd was set to + * POLARSSL_ERR_NET_WANT_READ is bind_fd was set to * non-blocking and accept() is blocking. */ int net_accept( int bind_fd, int *client_fd, void *client_ip ); diff --git a/pdns/ext/polarssl/include/polarssl/oid.h b/pdns/ext/polarssl/include/polarssl/oid.h index 93ef8a6ab..c4d5c3fba 100644 --- a/pdns/ext/polarssl/include/polarssl/oid.h +++ b/pdns/ext/polarssl/include/polarssl/oid.h @@ -3,7 +3,7 @@ * * \brief Object Identifier (OID) database * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -28,7 +28,11 @@ #define POLARSSL_OID_H #include +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include "asn1.h" #include "pk.h" #if defined(POLARSSL_CIPHER_C) @@ -44,6 +48,7 @@ #endif #define POLARSSL_ERR_OID_NOT_FOUND -0x002E /**< OID is not found. */ +#define POLARSSL_ERR_OID_BUF_TOO_SMALL -0x000B /**< output buffer is too small */ /* * Top level OID tuples @@ -58,7 +63,7 @@ */ #define OID_COUNTRY_US "\x86\x48" /* {us(840)} */ #define OID_ORG_RSA_DATA_SECURITY "\x86\xf7\x0d" /* {rsadsi(113549)} */ -#define OID_RSA_COMPANY OID_ISO_MEMBER_BODIES OID_COUNTRY_US \ +#define OID_RSA_COMPANY OID_ISO_MEMBER_BODIES OID_COUNTRY_US \ OID_ORG_RSA_DATA_SECURITY /* {iso(1) member-body(2) us(840) rsadsi(113549)} */ #define OID_ORG_ANSI_X9_62 "\xce\x3d" /* ansi-X9-62(10045) */ #define OID_ANSI_X9_62 OID_ISO_MEMBER_BODIES OID_COUNTRY_US \ @@ -104,14 +109,23 @@ */ #define OID_AT OID_ISO_CCITT_DS "\x04" /**< id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4} */ #define OID_AT_CN OID_AT "\x03" /**< id-at-commonName AttributeType:= {id-at 3} */ +#define OID_AT_SUR_NAME OID_AT "\x04" /**< id-at-surName AttributeType:= {id-at 4} */ #define OID_AT_SERIAL_NUMBER OID_AT "\x05" /**< id-at-serialNumber AttributeType:= {id-at 5} */ #define OID_AT_COUNTRY OID_AT "\x06" /**< id-at-countryName AttributeType:= {id-at 6} */ #define OID_AT_LOCALITY OID_AT "\x07" /**< id-at-locality AttributeType:= {id-at 7} */ #define OID_AT_STATE OID_AT "\x08" /**< id-at-state AttributeType:= {id-at 8} */ #define OID_AT_ORGANIZATION OID_AT "\x0A" /**< id-at-organizationName AttributeType:= {id-at 10} */ #define OID_AT_ORG_UNIT OID_AT "\x0B" /**< id-at-organizationalUnitName AttributeType:= {id-at 11} */ +#define OID_AT_TITLE OID_AT "\x0C" /**< id-at-title AttributeType:= {id-at 12} */ #define OID_AT_POSTAL_ADDRESS OID_AT "\x10" /**< id-at-postalAddress AttributeType:= {id-at 16} */ #define OID_AT_POSTAL_CODE OID_AT "\x11" /**< id-at-postalCode AttributeType:= {id-at 17} */ +#define OID_AT_GIVEN_NAME OID_AT "\x2A" /**< id-at-givenName AttributeType:= {id-at 42} */ +#define OID_AT_INITIALS OID_AT "\x2B" /**< id-at-initials AttributeType:= {id-at 43} */ +#define OID_AT_GENERATION_QUALIFIER OID_AT "\x2C" /**< id-at-generationQualifier AttributeType:= {id-at 44} */ +#define OID_AT_DN_QUALIFIER OID_AT "\x2E" /**< id-at-dnQualifier AttributeType:= {id-at 46} */ +#define OID_AT_PSEUDONYM OID_AT "\x41" /**< id-at-pseudonym AttributeType:= {id-at 65} */ + +#define OID_DOMAIN_COMPONENT "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x19" /** id-domainComponent AttributeType:= {itu-t(0) data(9) pss(2342) ucl(19200300) pilot(100) pilotAttributeType(1) domainComponent(25)} */ /* * OIDs for standard certificate extensions @@ -193,6 +207,10 @@ #define OID_PKCS9_EMAIL OID_PKCS9 "\x01" /**< emailAddress AttributeType ::= { pkcs-9 1 } */ +/* RFC 4055 */ +#define OID_RSASSA_PSS OID_PKCS1 "\x0a" /**< id-RSASSA-PSS ::= { pkcs-1 10 } */ +#define OID_MGF1 OID_PKCS1 "\x08" /**< id-mgf1 ::= { pkcs-1 8 } */ + /* * Digest algorithms */ @@ -263,7 +281,7 @@ #define OID_EC_ALG_ECDH OID_CERTICOM "\x01\x0c" /* - * ECParameters namedCurve identifiers, from RFC 5480 and RFC 5639 + * ECParameters namedCurve identifiers, from RFC 5480, RFC 5639, and SEC2 */ /* secp192r1 OBJECT IDENTIFIER ::= { @@ -286,6 +304,18 @@ * iso(1) identified-organization(3) certicom(132) curve(0) 35 } */ #define OID_EC_GRP_SECP521R1 OID_CERTICOM "\x00\x23" +/* secp192k1 OBJECT IDENTIFIER ::= { + * iso(1) identified-organization(3) certicom(132) curve(0) 31 } */ +#define OID_EC_GRP_SECP192K1 OID_CERTICOM "\x00\x1f" + +/* secp224k1 OBJECT IDENTIFIER ::= { + * iso(1) identified-organization(3) certicom(132) curve(0) 32 } */ +#define OID_EC_GRP_SECP224K1 OID_CERTICOM "\x00\x20" + +/* secp256k1 OBJECT IDENTIFIER ::= { + * iso(1) identified-organization(3) certicom(132) curve(0) 10 } */ +#define OID_EC_GRP_SECP256K1 OID_CERTICOM "\x00\x0a" + /* RFC 5639 4.1 * ecStdCurvesAndGeneration OBJECT IDENTIFIER::= {iso(1) * identified-organization(3) teletrust(36) algorithm(3) signature- @@ -304,7 +334,16 @@ #define OID_EC_GRP_BP512R1 OID_EC_BRAINPOOL_V1 "\x0D" /* - * ECDSA signature identifers, from RFC 5480 + * SEC1 C.1 + * + * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } + * id-fieldType OBJECT IDENTIFIER ::= { ansi-X9-62 fieldType(1)} + */ +#define OID_ANSI_X9_62_FIELD_TYPE OID_ANSI_X9_62 "\x01" +#define OID_ANSI_X9_62_PRIME_FIELD OID_ANSI_X9_62_FIELD_TYPE "\x01" + +/* + * ECDSA signature identifiers, from RFC 5480 */ #define OID_ANSI_X9_62_SIG OID_ANSI_X9_62 "\x04" /* signatures(4) */ #define OID_ANSI_X9_62_SIG_SHA2 OID_ANSI_X9_62_SIG "\x03" /* ecdsa-with-SHA2(3) */ @@ -355,7 +394,8 @@ typedef struct { * \param size size of the buffer * \param oid OID to translate * - * \return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL or actual length used + * \return Length of the string written (excluding final NULL) or + * POLARSSL_ERR_OID_BUF_TO_SMALL in case of error */ int oid_get_numeric_string( char *buf, size_t size, const asn1_buf *oid ); diff --git a/pdns/ext/polarssl/include/polarssl/openssl.h b/pdns/ext/polarssl/include/polarssl/openssl.h index 0e9de221c..b77e7dacb 100644 --- a/pdns/ext/polarssl/include/polarssl/openssl.h +++ b/pdns/ext/polarssl/include/polarssl/openssl.h @@ -98,7 +98,7 @@ inline rsa_context* d2i_RSA_PUBKEY( void *ignore, unsigned char **bufptr, memset( rsa, 0, sizeof( rsa_context ) ); - if( ( len == 94 && + if( ( len == 94 && mpi_read_binary( &rsa->N, &buffer[ 25], 64 ) == 0 && mpi_read_binary( &rsa->E, &buffer[ 91], 3 ) == 0 ) || ( len == 162 && diff --git a/pdns/ext/polarssl/include/polarssl/padlock.h b/pdns/ext/polarssl/include/polarssl/padlock.h index 8df93c034..3c5f7258b 100644 --- a/pdns/ext/polarssl/include/polarssl/padlock.h +++ b/pdns/ext/polarssl/include/polarssl/padlock.h @@ -1,9 +1,10 @@ /** * \file padlock.h * - * \brief VIA PadLock ACE for HW encryption/decryption supported by some processors + * \brief VIA PadLock ACE for HW encryption/decryption supported by some + * processors * - * Copyright (C) 2006-2010, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -59,7 +60,7 @@ extern "C" { /** * \brief PadLock detection routine * - * \param The feature to detect + * \param feature The feature to detect * * \return 1 if CPU has support for the feature, 0 otherwise */ diff --git a/pdns/ext/polarssl/include/polarssl/pk.h b/pdns/ext/polarssl/include/polarssl/pk.h index 251c690e5..754dda219 100644 --- a/pdns/ext/polarssl/include/polarssl/pk.h +++ b/pdns/ext/polarssl/include/polarssl/pk.h @@ -28,7 +28,11 @@ #ifndef POLARSSL_PK_H #define POLARSSL_PK_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include "md.h" @@ -57,6 +61,7 @@ #define POLARSSL_ERR_PK_INVALID_ALG -0x2A80 /**< The algorithm tag or value is invalid. */ #define POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE -0x2A00 /**< Elliptic curve is unsupported (only NIST curves are supported). */ #define POLARSSL_ERR_PK_FEATURE_UNAVAILABLE -0x2980 /**< Unavailable feature, e.g. RSA disabled for RSA key. */ +#define POLARSSL_ERR_PK_SIG_LEN_MISMATCH -0x2000 /**< The signature is valid but its length is less than expected. */ #if defined(POLARSSL_RSA_C) @@ -94,8 +99,20 @@ typedef enum { POLARSSL_PK_ECKEY_DH, POLARSSL_PK_ECDSA, POLARSSL_PK_RSA_ALT, + POLARSSL_PK_RSASSA_PSS, } pk_type_t; +/** + * \brief Options for RSASSA-PSS signature verification. + * See \c rsa_rsassa_pss_verify_ext() + */ +typedef struct +{ + md_type_t mgf1_hash_id; + int expected_salt_len; + +} pk_rsassa_pss_options; + /** * \brief Types for interfacing with the debug module */ @@ -188,7 +205,7 @@ typedef int (*pk_rsa_alt_decrypt_func)( void *ctx, int mode, size_t *olen, size_t output_max_len ); typedef int (*pk_rsa_alt_sign_func)( void *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - int mode, int hash_id, unsigned int hashlen, + int mode, md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, unsigned char *sig ); typedef size_t (*pk_rsa_alt_key_len_func)( void *ctx ); @@ -234,7 +251,7 @@ int pk_init_ctx( pk_context *ctx, const pk_info_t *info ); * \param key RSA key pointer * \param decrypt_func Decryption function * \param sign_func Signing function - * \param key_len_func Function returning key length + * \param key_len_func Function returning key length in bytes * * \return 0 on success, or POLARSSL_ERR_PK_BAD_INPUT_DATA if the * context wasn't already initialized as RSA_ALT. @@ -278,7 +295,7 @@ static inline size_t pk_get_len( const pk_context *ctx ) int pk_can_do( pk_context *ctx, pk_type_t type ); /** - * \brief Verify signature + * \brief Verify signature (including padding if relevant). * * \param ctx PK context to use * \param md_alg Hash algorithm used (see notes) @@ -288,8 +305,14 @@ int pk_can_do( pk_context *ctx, pk_type_t type ); * \param sig_len Signature length * * \return 0 on success (signature is valid), + * POLARSSL_ERR_PK_SIG_LEN_MISMATCH if the signature is + * valid but its actual length is less than sig_len, * or a specific error code. * + * \note For RSA keys, the default padding type is PKCS#1 v1.5. + * Use \c pk_verify_ext( POLARSSL_PK_RSASSA_PSS, ... ) + * to verify RSASSA_PSS signatures. + * * \note If hash_len is 0, then the length associated with md_alg * is used instead, or an error returned if it is invalid. * @@ -300,7 +323,41 @@ int pk_verify( pk_context *ctx, md_type_t md_alg, const unsigned char *sig, size_t sig_len ); /** - * \brief Make signature + * \brief Verify signature, with options. + * (Includes verification of the padding depending on type.) + * + * \param type Signature type (inc. possible padding type) to verify + * \param options Pointer to type-specific options, or NULL + * \param ctx PK context to use + * \param md_alg Hash algorithm used (see notes) + * \param hash Hash of the message to sign + * \param hash_len Hash length or 0 (see notes) + * \param sig Signature to verify + * \param sig_len Signature length + * + * \return 0 on success (signature is valid), + * POLARSSL_ERR_PK_TYPE_MISMATCH if the PK context can't be + * used for this type of signatures, + * POLARSSL_ERR_PK_SIG_LEN_MISMATCH if the signature is + * valid but its actual length is less than sig_len, + * or a specific error code. + * + * \note If hash_len is 0, then the length associated with md_alg + * is used instead, or an error returned if it is invalid. + * + * \note md_alg may be POLARSSL_MD_NONE, only if hash_len != 0 + * + * \note If type is POLARSSL_PK_RSASSA_PSS, then options must point + * to a pk_rsassa_pss_options structure, + * otherwise it must be NULL. + */ +int pk_verify_ext( pk_type_t type, const void *options, + pk_context *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ); + +/** + * \brief Make signature, including padding if relevant. * * \param ctx PK context to use * \param md_alg Hash algorithm used (see notes) @@ -313,6 +370,10 @@ int pk_verify( pk_context *ctx, md_type_t md_alg, * * \return 0 on success, or a specific error code. * + * \note For RSA keys, the default padding type is PKCS#1 v1.5. + * There is no interface in the PK module to make RSASSA-PSS + * signatures yet. + * * \note If hash_len is 0, then the length associated with md_alg * is used instead, or an error returned if it is invalid. * @@ -324,7 +385,7 @@ int pk_sign( pk_context *ctx, md_type_t md_alg, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); /** - * \brief Decrypt message + * \brief Decrypt message (including padding if relevant). * * \param ctx PK context to use * \param input Input to decrypt @@ -335,6 +396,8 @@ int pk_sign( pk_context *ctx, md_type_t md_alg, * \param f_rng RNG function * \param p_rng RNG parameter * + * \note For RSA keys, the default padding type is PKCS#1 v1.5. + * * \return 0 on success, or a specific error code. */ int pk_decrypt( pk_context *ctx, @@ -343,7 +406,7 @@ int pk_decrypt( pk_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); /** - * \brief Encrypt message + * \brief Encrypt message (including padding if relevant). * * \param ctx PK context to use * \param input Message to encrypt @@ -354,6 +417,8 @@ int pk_decrypt( pk_context *ctx, * \param f_rng RNG function * \param p_rng RNG parameter * + * \note For RSA keys, the default padding type is PKCS#1 v1.5. + * * \return 0 on success, or a specific error code. */ int pk_encrypt( pk_context *ctx, @@ -400,6 +465,12 @@ pk_type_t pk_get_type( const pk_context *ctx ); * \param pwd password for decryption (optional) * \param pwdlen size of the password * + * \note On entry, ctx must be empty, either freshly initialised + * with pk_init() or reset with pk_free(). If you need a + * specific key type, check the result with pk_can_do(). + * + * \note The key is also checked for correctness. + * * \return 0 if successful, or a specific PK or PEM error code */ int pk_parse_key( pk_context *ctx, @@ -414,6 +485,12 @@ int pk_parse_key( pk_context *ctx, * \param key input buffer * \param keylen size of the buffer * + * \note On entry, ctx must be empty, either freshly initialised + * with pk_init() or reset with pk_free(). If you need a + * specific key type, check the result with pk_can_do(). + * + * \note The key is also checked for correctness. + * * \return 0 if successful, or a specific PK or PEM error code */ int pk_parse_public_key( pk_context *ctx, @@ -428,6 +505,12 @@ int pk_parse_public_key( pk_context *ctx, * \param path filename to read the private key from * \param password password to decrypt the file (can be NULL) * + * \note On entry, ctx must be empty, either freshly initialised + * with pk_init() or reset with pk_free(). If you need a + * specific key type, check the result with pk_can_do(). + * + * \note The key is also checked for correctness. + * * \return 0 if successful, or a specific PK or PEM error code */ int pk_parse_keyfile( pk_context *ctx, @@ -440,6 +523,12 @@ int pk_parse_keyfile( pk_context *ctx, * \param ctx key to be initialized * \param path filename to read the private key from * + * \note On entry, ctx must be empty, either freshly initialised + * with pk_init() or reset with pk_free(). If you need a + * specific key type, check the result with pk_can_do(). + * + * \note The key is also checked for correctness. + * * \return 0 if successful, or a specific PK or PEM error code */ int pk_parse_public_keyfile( pk_context *ctx, const char *path ); @@ -453,14 +542,14 @@ int pk_parse_public_keyfile( pk_context *ctx, const char *path ); * return value to determine where you should start * using the buffer * - * \param key private to write away + * \param ctx private to write away * \param buf buffer to write to * \param size size of the buffer * * \return length of data written if successful, or a specific * error code */ -int pk_write_key_der( pk_context *pk, unsigned char *buf, size_t size ); +int pk_write_key_der( pk_context *ctx, unsigned char *buf, size_t size ); /** * \brief Write a public key to a SubjectPublicKeyInfo DER structure @@ -468,37 +557,37 @@ int pk_write_key_der( pk_context *pk, unsigned char *buf, size_t size ); * return value to determine where you should start * using the buffer * - * \param key public key to write away + * \param ctx public key to write away * \param buf buffer to write to * \param size size of the buffer * * \return length of data written if successful, or a specific * error code */ -int pk_write_pubkey_der( pk_context *key, unsigned char *buf, size_t size ); +int pk_write_pubkey_der( pk_context *ctx, unsigned char *buf, size_t size ); #if defined(POLARSSL_PEM_WRITE_C) /** * \brief Write a public key to a PEM string * - * \param key public key to write away + * \param ctx public key to write away * \param buf buffer to write to * \param size size of the buffer * * \return 0 successful, or a specific error code */ -int pk_write_pubkey_pem( pk_context *key, unsigned char *buf, size_t size ); +int pk_write_pubkey_pem( pk_context *ctx, unsigned char *buf, size_t size ); /** * \brief Write a private key to a PKCS#1 or SEC1 PEM string * - * \param key private to write away + * \param ctx private to write away * \param buf buffer to write to * \param size size of the buffer * * \return 0 successful, or a specific error code */ -int pk_write_key_pem( pk_context *key, unsigned char *buf, size_t size ); +int pk_write_key_pem( pk_context *ctx, unsigned char *buf, size_t size ); #endif /* POLARSSL_PEM_WRITE_C */ #endif /* POLARSSL_PK_WRITE_C */ diff --git a/pdns/ext/polarssl/include/polarssl/pk_wrap.h b/pdns/ext/polarssl/include/polarssl/pk_wrap.h index 91a671e02..7baafb95d 100644 --- a/pdns/ext/polarssl/include/polarssl/pk_wrap.h +++ b/pdns/ext/polarssl/include/polarssl/pk_wrap.h @@ -28,7 +28,11 @@ #ifndef POLARSSL_PK_WRAP_H #define POLARSSL_PK_WRAP_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include "pk.h" diff --git a/pdns/ext/polarssl/include/polarssl/pkcs11.h b/pdns/ext/polarssl/include/polarssl/pkcs11.h index c0515e67c..84f862dd9 100644 --- a/pdns/ext/polarssl/include/polarssl/pkcs11.h +++ b/pdns/ext/polarssl/include/polarssl/pkcs11.h @@ -5,7 +5,7 @@ * * \author Adriaan de Jong * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -29,7 +29,11 @@ #ifndef POLARSSL_PKCS11_H #define POLARSSL_PKCS11_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_PKCS11_C) @@ -89,7 +93,8 @@ int pkcs11_priv_key_init( pkcs11_context *priv_key, void pkcs11_priv_key_free( pkcs11_context *priv_key ); /** - * \brief Do an RSA private key decrypt, then remove the message padding + * \brief Do an RSA private key decrypt, then remove the message + * padding * * \param ctx PKCS #11 context * \param mode must be RSA_PRIVATE, for compatibility with rsa.c's signature @@ -115,8 +120,8 @@ int pkcs11_decrypt( pkcs11_context *ctx, * * \param ctx PKCS #11 context * \param mode must be RSA_PRIVATE, for compatibility with rsa.c's signature - * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512} - * \param hashlen message digest length (for SIG_RSA_RAW only) + * \param md_alg a POLARSSL_MD_* (use POLARSSL_MD_NONE for signing raw data) + * \param hashlen message digest length (for POLARSSL_MD_NONE only) * \param hash buffer holding the message digest * \param sig buffer that will hold the ciphertext * @@ -128,7 +133,7 @@ int pkcs11_decrypt( pkcs11_context *ctx, */ int pkcs11_sign( pkcs11_context *ctx, int mode, - int hash_id, + md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, unsigned char *sig ); @@ -144,14 +149,14 @@ static inline int ssl_pkcs11_decrypt( void *ctx, int mode, size_t *olen, output_max_len ); } -static inline int ssl_pkcs11_sign( void *ctx, +static inline int ssl_pkcs11_sign( void *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - int mode, int hash_id, unsigned int hashlen, + int mode, md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, unsigned char *sig ) { ((void) f_rng); ((void) p_rng); - return pkcs11_sign( (pkcs11_context *) ctx, mode, hash_id, + return pkcs11_sign( (pkcs11_context *) ctx, mode, md_alg, hashlen, hash, sig ); } diff --git a/pdns/ext/polarssl/include/polarssl/pkcs12.h b/pdns/ext/polarssl/include/polarssl/pkcs12.h index 51bea3da1..4bd5018af 100644 --- a/pdns/ext/polarssl/include/polarssl/pkcs12.h +++ b/pdns/ext/polarssl/include/polarssl/pkcs12.h @@ -38,9 +38,9 @@ #define POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT -0x1E80 /**< PBE ASN.1 data not as expected. */ #define POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH -0x1E00 /**< Given private key password does not allow for correct decryption. */ -#define PKCS12_DERIVE_KEY 1 /*< encryption/decryption key */ -#define PKCS12_DERIVE_IV 2 /*< initialization vector */ -#define PKCS12_DERIVE_MAC_KEY 3 /*< integrity / MAC key */ +#define PKCS12_DERIVE_KEY 1 /**< encryption/decryption key */ +#define PKCS12_DERIVE_IV 2 /**< initialization vector */ +#define PKCS12_DERIVE_MAC_KEY 3 /**< integrity / MAC key */ #define PKCS12_PBE_DECRYPT 0 #define PKCS12_PBE_ENCRYPT 1 diff --git a/pdns/ext/polarssl/include/polarssl/platform.h b/pdns/ext/polarssl/include/polarssl/platform.h new file mode 100644 index 000000000..eae887afc --- /dev/null +++ b/pdns/ext/polarssl/include/polarssl/platform.h @@ -0,0 +1,128 @@ +/** + * \file platform.h + * + * \brief PolarSSL Platform abstraction layer + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_PLATFORM_H +#define POLARSSL_PLATFORM_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(POLARSSL_PLATFORM_NO_STD_FUNCTIONS) +#include +#if !defined(POLARSSL_PLATFORM_STD_PRINTF) +#define POLARSSL_PLATFORM_STD_PRINTF printf /**< Default printf to use */ +#endif +#if !defined(POLARSSL_PLATFORM_STD_FPRINTF) +#define POLARSSL_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use */ +#endif +#if !defined(POLARSSL_PLATFORM_STD_MALLOC) +#define POLARSSL_PLATFORM_STD_MALLOC malloc /**< Default allocator to use */ +#endif +#if !defined(POLARSSL_PLATFORM_STD_FREE) +#define POLARSSL_PLATFORM_STD_FREE free /**< Default free to use */ +#endif +#else /* POLARSSL_PLATFORM_NO_STD_FUNCTIONS */ +#if defined(POLARSSL_PLATFORM_STD_MEM_HDR) +#include POLARSSL_PLATFORM_STD_MEM_HDR +#endif +#endif /* POLARSSL_PLATFORM_NO_STD_FUNCTIONS */ + +/* \} name SECTION: Module settings */ + +/* + * The function pointers for malloc and free + */ +#if defined(POLARSSL_PLATFORM_MEMORY) +extern void * (*polarssl_malloc)( size_t len ); +extern void (*polarssl_free)( void *ptr ); + +/** + * \brief Set your own memory implementation function pointers + * + * \param malloc_func the malloc function implementation + * \param free_func the free function implementation + * + * \return 0 if successful + */ +int platform_set_malloc_free( void * (*malloc_func)( size_t ), + void (*free_func)( void * ) ); +#else /* POLARSSL_PLATFORM_ENTROPY */ +#define polarssl_malloc malloc +#define polarssl_free free +#endif /* POLARSSL_PLATFORM_ENTROPY */ + +/* + * The function pointers for printf + */ +#if defined(POLARSSL_PLATFORM_PRINTF_ALT) +extern int (*polarssl_printf)( const char *format, ... ); + +/** + * \brief Set your own printf function pointer + * + * \param printf_func the printf function implementation + * + * \return 0 + */ +int platform_set_printf( int (*printf_func)( const char *, ... ) ); +#else /* POLARSSL_PLATFORM_PRINTF_ALT */ +#define polarssl_printf printf +#endif /* POLARSSL_PLATFORM_PRINTF_ALT */ + +/* + * The function pointers for fprintf + */ +#if defined(POLARSSL_PLATFORM_FPRINTF_ALT) +extern int (*polarssl_fprintf)( FILE *stream, const char *format, ... ); + +int platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *, + ... ) ); +#else +#define polarssl_fprintf fprintf +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* platform.h */ diff --git a/pdns/ext/polarssl/include/polarssl/ripemd160.h b/pdns/ext/polarssl/include/polarssl/ripemd160.h new file mode 100644 index 000000000..e3b66c90f --- /dev/null +++ b/pdns/ext/polarssl/include/polarssl/ripemd160.h @@ -0,0 +1,204 @@ +/** + * \file ripemd160.h + * + * \brief RIPE MD-160 message digest + * + * Copyright (C) 2014-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_RIPEMD160_H +#define POLARSSL_RIPEMD160_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#define POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR -0x007E /**< Read/write error in file. */ + +#if !defined(POLARSSL_RIPEMD160_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief RIPEMD-160 context structure + */ +typedef struct +{ + uint32_t total[2]; /*!< number of bytes processed */ + uint32_t state[5]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ + + unsigned char ipad[64]; /*!< HMAC: inner padding */ + unsigned char opad[64]; /*!< HMAC: outer padding */ +} +ripemd160_context; + +/** + * \brief Initialize RIPEMD-160 context + * + * \param ctx RIPEMD-160 context to be initialized + */ +void ripemd160_init( ripemd160_context *ctx ); + +/** + * \brief Clear RIPEMD-160 context + * + * \param ctx RIPEMD-160 context to be cleared + */ +void ripemd160_free( ripemd160_context *ctx ); + +/** + * \brief RIPEMD-160 context setup + * + * \param ctx context to be initialized + */ +void ripemd160_starts( ripemd160_context *ctx ); + +/** + * \brief RIPEMD-160 process buffer + * + * \param ctx RIPEMD-160 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void ripemd160_update( ripemd160_context *ctx, + const unsigned char *input, size_t ilen ); + +/** + * \brief RIPEMD-160 final digest + * + * \param ctx RIPEMD-160 context + * \param output RIPEMD-160 checksum result + */ +void ripemd160_finish( ripemd160_context *ctx, unsigned char output[20] ); + +/* Internal use */ +void ripemd160_process( ripemd160_context *ctx, const unsigned char data[64] ); + +#ifdef __cplusplus +} +#endif + +#else /* POLARSSL_RIPEMD160_ALT */ +#include "ripemd160.h" +#endif /* POLARSSL_RIPEMD160_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Output = RIPEMD-160( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output RIPEMD-160 checksum result + */ +void ripemd160( const unsigned char *input, size_t ilen, + unsigned char output[20] ); + +#if defined(POLARSSL_FS_IO) +/** + * \brief Output = RIPEMD-160( file contents ) + * + * \param path input file name + * \param output RIPEMD-160 checksum result + * + * \return 0 if successful, or POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR + */ +int ripemd160_file( const char *path, unsigned char output[20] ); +#endif /* POLARSSL_FS_IO */ + +/** + * \brief RIPEMD-160 HMAC context setup + * + * \param ctx HMAC context to be initialized + * \param key HMAC secret key + * \param keylen length of the HMAC key + */ +void ripemd160_hmac_starts( ripemd160_context *ctx, + const unsigned char *key, size_t keylen ); + +/** + * \brief RIPEMD-160 HMAC process buffer + * + * \param ctx HMAC context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void ripemd160_hmac_update( ripemd160_context *ctx, + const unsigned char *input, size_t ilen ); + +/** + * \brief RIPEMD-160 HMAC final digest + * + * \param ctx HMAC context + * \param output RIPEMD-160 HMAC checksum result + */ +void ripemd160_hmac_finish( ripemd160_context *ctx, unsigned char output[20] ); + +/** + * \brief RIPEMD-160 HMAC context reset + * + * \param ctx HMAC context to be reset + */ +void ripemd160_hmac_reset( ripemd160_context *ctx ); + +/** + * \brief Output = HMAC-RIPEMD-160( hmac key, input buffer ) + * + * \param key HMAC secret key + * \param keylen length of the HMAC key + * \param input buffer holding the data + * \param ilen length of the input data + * \param output HMAC-RIPEMD-160 result + */ +void ripemd160_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[20] ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int ripemd160_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* ripemd160.h */ diff --git a/pdns/ext/polarssl/include/polarssl/rsa.h b/pdns/ext/polarssl/include/polarssl/rsa.h index e7b619159..c06c7d505 100644 --- a/pdns/ext/polarssl/include/polarssl/rsa.h +++ b/pdns/ext/polarssl/include/polarssl/rsa.h @@ -3,7 +3,7 @@ * * \brief The RSA public-key cryptosystem * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ #ifndef POLARSSL_RSA_H #define POLARSSL_RSA_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include "bignum.h" #include "md.h" @@ -61,6 +65,8 @@ #define RSA_SIGN 1 #define RSA_CRYPT 2 +#define RSA_SALT_LEN_ANY -1 + /* * The above constants may be used even if the RSA module is compile out, * eg for alternative (PKCS#11) RSA implemenations in the PK layers. @@ -122,11 +128,32 @@ rsa_context; * * \note The hash_id parameter is actually ignored * when using RSA_PKCS_V15 padding. + * + * \note Choice of padding mode is strictly enforced for private key + * operations, since there might be security concerns in + * mixing padding modes. For public key operations it's merely + * a default value, which can be overriden by calling specific + * rsa_rsaes_xxx or rsa_rsassa_xxx functions. + * + * \note The chosen hash is always used for OEAP encryption. + * For PSS signatures, it's always used for making signatures, + * but can be overriden (and always is, if set to + * POLARSSL_MD_NONE) for verifying them. */ void rsa_init( rsa_context *ctx, int padding, int hash_id); +/** + * \brief Set padding for an already initialized RSA context + * See \c rsa_init() for details. + * + * \param ctx RSA context to be set + * \param padding RSA_PKCS_V15 or RSA_PKCS_V21 + * \param hash_id RSA_PKCS_V21 hash identifier + */ +void rsa_set_padding( rsa_context *ctx, int padding, int hash_id); + /** * \brief Generate an RSA keypair * @@ -386,11 +413,8 @@ int rsa_rsaes_oaep_decrypt( rsa_context *ctx, * \note The "sig" buffer must be as large as the size * of ctx->N (eg. 128 bytes if RSA-1024 is used). * - * \note In case of PKCS#1 v2.1 encoding keep in mind that - * the hash_id in the RSA context is the one used for the - * encoding. hash_id in the function call is the type of hash - * that is encoded. According to RFC 3447 it is advised to - * keep both hashes the same. + * \note In case of PKCS#1 v2.1 encoding, see comments on + * \note \c rsa_rsassa_pss_sign() for details on md_alg and hash_id. */ int rsa_pkcs1_sign( rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -447,9 +471,8 @@ int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx, * \note The "sig" buffer must be as large as the size * of ctx->N (eg. 128 bytes if RSA-1024 is used). * - * \note In case of PKCS#1 v2.1 encoding keep in mind that - * the hash_id in the RSA context is the one used for the - * encoding. hash_id in the function call is the type of hash + * \note The hash_id in the RSA context is the one used for the + * encoding. md_alg in the function call is the type of hash * that is encoded. According to RFC 3447 it is advised to * keep both hashes the same. */ @@ -482,11 +505,8 @@ int rsa_rsassa_pss_sign( rsa_context *ctx, * \note The "sig" buffer must be as large as the size * of ctx->N (eg. 128 bytes if RSA-1024 is used). * - * \note In case of PKCS#1 v2.1 encoding keep in mind that - * the hash_id in the RSA context is the one used for the - * verification. hash_id in the function call is the type of hash - * that is verified. According to RFC 3447 it is advised to - * keep both hashes the same. + * \note In case of PKCS#1 v2.1 encoding, see comments on + * \c rsa_rsassa_pss_verify() about md_alg and hash_id. */ int rsa_pkcs1_verify( rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -526,7 +546,7 @@ int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx, /** * \brief Perform a PKCS#1 v2.1 PSS verification (RSASSA-PSS-VERIFY) - * \brief Do a public RSA and check the message digest + * (This is the "simple" version.) * * \param ctx points to an RSA public key * \param f_rng RNG function (Only needed for RSA_PRIVATE) @@ -543,11 +563,11 @@ int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx, * \note The "sig" buffer must be as large as the size * of ctx->N (eg. 128 bytes if RSA-1024 is used). * - * \note In case of PKCS#1 v2.1 encoding keep in mind that - * the hash_id in the RSA context is the one used for the - * verification. hash_id in the function call is the type of hash - * that is verified. According to RFC 3447 it is advised to - * keep both hashes the same. + * \note The hash_id in the RSA context is the one used for the + * verification. md_alg in the function call is the type of + * hash that is verified. According to RFC 3447 it is advised to + * keep both hashes the same. If hash_id in the RSA context is + * unset, the md_alg from the function call is used. */ int rsa_rsassa_pss_verify( rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -558,6 +578,41 @@ int rsa_rsassa_pss_verify( rsa_context *ctx, const unsigned char *hash, const unsigned char *sig ); +/** + * \brief Perform a PKCS#1 v2.1 PSS verification (RSASSA-PSS-VERIFY) + * (This is the version with "full" options.) + * + * \param ctx points to an RSA public key + * \param f_rng RNG function (Only needed for RSA_PRIVATE) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param md_alg a POLARSSL_MD_* (use POLARSSL_MD_NONE for signing raw data) + * \param hashlen message digest length (for POLARSSL_MD_NONE only) + * \param hash buffer holding the message digest + * \param mgf1_hash_id message digest used for mask generation + * \param expected_salt_len Length of the salt used in padding, use + * RSA_SALT_LEN_ANY to accept any salt length + * \param sig buffer holding the ciphertext + * + * \return 0 if the verify operation was successful, + * or an POLARSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * + * \note The hash_id in the RSA context is ignored. + */ +int rsa_rsassa_pss_verify_ext( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + md_type_t mgf1_hash_id, + int expected_salt_len, + const unsigned char *sig ); + /** * \brief Copy the components of an RSA context * diff --git a/pdns/ext/polarssl/include/polarssl/sha1.h b/pdns/ext/polarssl/include/polarssl/sha1.h index e1d8e27ca..cb0c4367f 100644 --- a/pdns/ext/polarssl/include/polarssl/sha1.h +++ b/pdns/ext/polarssl/include/polarssl/sha1.h @@ -3,7 +3,7 @@ * * \brief SHA-1 cryptographic hash function * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ #ifndef POLARSSL_SHA1_H #define POLARSSL_SHA1_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include @@ -62,6 +66,20 @@ typedef struct } sha1_context; +/** + * \brief Initialize SHA-1 context + * + * \param ctx SHA-1 context to be initialized + */ +void sha1_init( sha1_context *ctx ); + +/** + * \brief Clear SHA-1 context + * + * \param ctx SHA-1 context to be cleared + */ +void sha1_free( sha1_context *ctx ); + /** * \brief SHA-1 context setup * @@ -127,7 +145,8 @@ int sha1_file( const char *path, unsigned char output[20] ); * \param key HMAC secret key * \param keylen length of the HMAC key */ -void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, size_t keylen ); +void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, + size_t keylen ); /** * \brief SHA-1 HMAC process buffer @@ -136,7 +155,8 @@ void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, size_t keyle * \param input buffer holding the data * \param ilen length of the input data */ -void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, size_t ilen ); +void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, + size_t ilen ); /** * \brief SHA-1 HMAC final digest diff --git a/pdns/ext/polarssl/include/polarssl/sha256.h b/pdns/ext/polarssl/include/polarssl/sha256.h index 89df578e9..b14367410 100644 --- a/pdns/ext/polarssl/include/polarssl/sha256.h +++ b/pdns/ext/polarssl/include/polarssl/sha256.h @@ -3,7 +3,7 @@ * * \brief SHA-224 and SHA-256 cryptographic hash function * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ #ifndef POLARSSL_SHA256_H #define POLARSSL_SHA256_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include @@ -63,6 +67,20 @@ typedef struct } sha256_context; +/** + * \brief Initialize SHA-256 context + * + * \param ctx SHA-256 context to be initialized + */ +void sha256_init( sha256_context *ctx ); + +/** + * \brief Clear SHA-256 context + * + * \param ctx SHA-256 context to be cleared + */ +void sha256_free( sha256_context *ctx ); + /** * \brief SHA-256 context setup * @@ -78,7 +96,8 @@ void sha256_starts( sha256_context *ctx, int is224 ); * \param input buffer holding the data * \param ilen length of the input data */ -void sha256_update( sha256_context *ctx, const unsigned char *input, size_t ilen ); +void sha256_update( sha256_context *ctx, const unsigned char *input, + size_t ilen ); /** * \brief SHA-256 final digest @@ -143,7 +162,8 @@ void sha256_hmac_starts( sha256_context *ctx, const unsigned char *key, * \param input buffer holding the data * \param ilen length of the input data */ -void sha256_hmac_update( sha256_context *ctx, const unsigned char *input, size_t ilen ); +void sha256_hmac_update( sha256_context *ctx, const unsigned char *input, + size_t ilen ); /** * \brief SHA-256 HMAC final digest diff --git a/pdns/ext/polarssl/include/polarssl/sha512.h b/pdns/ext/polarssl/include/polarssl/sha512.h index 2c61637ee..dfbae4a73 100644 --- a/pdns/ext/polarssl/include/polarssl/sha512.h +++ b/pdns/ext/polarssl/include/polarssl/sha512.h @@ -3,7 +3,7 @@ * * \brief SHA-384 and SHA-512 cryptographic hash function * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ #ifndef POLARSSL_SHA512_H #define POLARSSL_SHA512_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include @@ -64,6 +68,20 @@ typedef struct } sha512_context; +/** + * \brief Initialize SHA-512 context + * + * \param ctx SHA-512 context to be initialized + */ +void sha512_init( sha512_context *ctx ); + +/** + * \brief Clear SHA-512 context + * + * \param ctx SHA-512 context to be cleared + */ +void sha512_free( sha512_context *ctx ); + /** * \brief SHA-512 context setup * @@ -79,7 +97,8 @@ void sha512_starts( sha512_context *ctx, int is384 ); * \param input buffer holding the data * \param ilen length of the input data */ -void sha512_update( sha512_context *ctx, const unsigned char *input, size_t ilen ); +void sha512_update( sha512_context *ctx, const unsigned char *input, + size_t ilen ); /** * \brief SHA-512 final digest @@ -141,7 +160,8 @@ void sha512_hmac_starts( sha512_context *ctx, const unsigned char *key, * \param input buffer holding the data * \param ilen length of the input data */ -void sha512_hmac_update( sha512_context *ctx, const unsigned char *input, size_t ilen ); +void sha512_hmac_update( sha512_context *ctx, const unsigned char *input, + size_t ilen ); /** * \brief SHA-512 HMAC final digest diff --git a/pdns/ext/polarssl/include/polarssl/ssl.h b/pdns/ext/polarssl/include/polarssl/ssl.h index e51e5078d..bd7f1f775 100644 --- a/pdns/ext/polarssl/include/polarssl/ssl.h +++ b/pdns/ext/polarssl/include/polarssl/ssl.h @@ -3,7 +3,7 @@ * * \brief SSL/TLS functions. * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,9 +27,14 @@ #ifndef POLARSSL_SSL_H #define POLARSSL_SSL_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include "net.h" #include "bignum.h" +#include "ecp.h" #include "ssl_ciphersuites.h" @@ -83,6 +88,12 @@ #define POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED #endif +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +#define POLARSSL_KEY_EXCHANGE__SOME__ECDHE_ENABLED +#endif + #if defined(_MSC_VER) && !defined(inline) #define inline _inline #else @@ -101,7 +112,7 @@ #define POLARSSL_ERR_SSL_CONN_EOF -0x7280 /**< The connection indicated an EOF. */ #define POLARSSL_ERR_SSL_UNKNOWN_CIPHER -0x7300 /**< An unknown cipher was received. */ #define POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN -0x7380 /**< The server has no ciphersuites in common with the client. */ -#define POLARSSL_ERR_SSL_NO_SESSION_FOUND -0x7400 /**< No session to recover was found. */ +#define POLARSSL_ERR_SSL_NO_RNG -0x7400 /**< No RNG was provided to the SSL module. */ #define POLARSSL_ERR_SSL_NO_CLIENT_CERTIFICATE -0x7480 /**< No client certification received from the client, but required by the authentication mode. */ #define POLARSSL_ERR_SSL_CERTIFICATE_TOO_LARGE -0x7500 /**< Our own certificate(s) is/are too large to send in an SSL message.*/ #define POLARSSL_ERR_SSL_CERTIFICATE_REQUIRED -0x7580 /**< The own certificate is not set, but needed by the server. */ @@ -131,8 +142,9 @@ #define POLARSSL_ERR_SSL_BAD_HS_NEW_SESSION_TICKET -0x6E00 /**< Processing of the NewSessionTicket handshake message failed. */ #define POLARSSL_ERR_SSL_SESSION_TICKET_EXPIRED -0x6D80 /**< Session ticket has expired. */ #define POLARSSL_ERR_SSL_PK_TYPE_MISMATCH -0x6D00 /**< Public key type mismatch (eg, asked for RSA key exchange and presented EC key) */ -#define POLARSSL_ERR_SSL_UNKNOWN_IDENTITY -0x6C80 /**< Unkown identity received (eg, PSK identity) */ +#define POLARSSL_ERR_SSL_UNKNOWN_IDENTITY -0x6C80 /**< Unknown identity received (eg, PSK identity) */ #define POLARSSL_ERR_SSL_INTERNAL_ERROR -0x6C00 /**< Internal error (eg, unexpected failure in lower-level module) */ +#define POLARSSL_ERR_SSL_COUNTER_WRAPPING -0x6B80 /**< A counter would wrap (eg, too many messages exchanged). */ /* * Various constants @@ -157,10 +169,10 @@ #else #if defined(POLARSSL_SSL_PROTO_TLS1_2) #define SSL_MIN_MINOR_VERSION SSL_MINOR_VERSION_3 -#endif -#endif -#endif -#endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ +#endif /* POLARSSL_SSL_PROTO_TLS1_1 */ +#endif /* POLARSSL_SSL_PROTO_TLS1 */ +#endif /* POLARSSL_SSL_PROTO_SSL3 */ /* Determine maximum supported version */ #define SSL_MAX_MAJOR_VERSION SSL_MAJOR_VERSION_3 @@ -176,10 +188,10 @@ #else #if defined(POLARSSL_SSL_PROTO_SSL3) #define SSL_MAX_MINOR_VERSION SSL_MINOR_VERSION_0 -#endif -#endif -#endif -#endif +#endif /* POLARSSL_SSL_PROTO_SSL3 */ +#endif /* POLARSSL_SSL_PROTO_TLS1 */ +#endif /* POLARSSL_SSL_PROTO_TLS1_1 */ +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ /* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c * NONE must be zero so that memset()ing structure to zero works */ @@ -210,6 +222,9 @@ #define SSL_RENEGOTIATION_DISABLED 0 #define SSL_RENEGOTIATION_ENABLED 1 +#define SSL_RENEGOTIATION_NOT_ENFORCED -1 +#define SSL_RENEGO_MAX_RECORDS_DEFAULT 16 + #define SSL_LEGACY_NO_RENEGOTIATION 0 #define SSL_LEGACY_ALLOW_RENEGOTIATION 1 #define SSL_LEGACY_BREAK_HANDSHAKE 2 @@ -221,24 +236,36 @@ #define SSL_SESSION_TICKETS_DISABLED 0 #define SSL_SESSION_TICKETS_ENABLED 1 -#if !defined(POLARSSL_CONFIG_OPTIONS) +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(SSL_DEFAULT_TICKET_LIFETIME) #define SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ -#endif /* !POLARSSL_CONFIG_OPTIONS */ +#endif /* * Size of the input / output buffer. * Note: the RFC defines the default size of SSL / TLS messages. If you * change the value here, other clients / servers may not be able to * communicate with you anymore. Only change this value if you control - * both sides of the connection and have it reduced at both sides! + * both sides of the connection and have it reduced at both sides, or + * if you're using the Max Fragment Length extension and you know all your + * peers are using it too! */ -#if !defined(POLARSSL_CONFIG_OPTIONS) +#if !defined(SSL_MAX_CONTENT_LEN) #define SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */ -#endif /* !POLARSSL_CONFIG_OPTIONS */ +#endif + +/* \} name SECTION: Module settings */ /* - * Allow an extra 512 bytes for the record header - * and encryption overhead (counter + MAC + padding) + * Allow extra bytes for record, authentication and encryption overhead: + * counter (8) + header (5) + IV(16) + MAC (16-48) + padding (0-256) * and allow for a maximum of 1024 of compression expansion if * enabled. */ @@ -248,9 +275,37 @@ #define SSL_COMPRESSION_ADD 0 #endif -#define SSL_BUFFER_LEN (SSL_MAX_CONTENT_LEN + SSL_COMPRESSION_ADD + 512) +#if defined(POLARSSL_RC4_C) || defined(POLARSSL_CIPHER_MODE_CBC) +/* Ciphersuites using HMAC */ +#if defined(POLARSSL_SHA512_C) +#define SSL_MAC_ADD 48 /* SHA-384 used for HMAC */ +#elif defined(POLARSSL_SHA256_C) +#define SSL_MAC_ADD 32 /* SHA-256 used for HMAC */ +#else +#define SSL_MAC_ADD 20 /* SHA-1 used for HMAC */ +#endif +#else +/* AEAD ciphersuites: GCM and CCM use a 128 bits tag */ +#define SSL_MAC_ADD 16 +#endif -#define SSL_EMPTY_RENEGOTIATION_INFO 0xFF /**< renegotiation info ext */ +#if defined(POLARSSL_CIPHER_MODE_CBC) +#define SSL_PADDING_ADD 256 +#else +#define SSL_PADDING_ADD 0 +#endif + +#define SSL_BUFFER_LEN ( SSL_MAX_CONTENT_LEN \ + + SSL_COMPRESSION_ADD \ + + 29 /* counter + header + IV */ \ + + SSL_MAC_ADD \ + + SSL_PADDING_ADD \ + ) + +/* + * Signaling ciphersuite values (SCSV) + */ +#define SSL_EMPTY_RENEGOTIATION_INFO 0xFF /**< renegotiation info ext */ /* * Supported Signature and Hash algorithms (For TLS 1.2) @@ -313,6 +368,7 @@ #define SSL_ALERT_MSG_UNSUPPORTED_EXT 110 /* 0x6E */ #define SSL_ALERT_MSG_UNRECOGNIZED_NAME 112 /* 0x70 */ #define SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY 115 /* 0x73 */ +#define SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL 120 /* 0x78 */ #define SSL_HS_HELLO_REQUEST 0 #define SSL_HS_CLIENT_HELLO 1 @@ -341,6 +397,8 @@ #define TLS_EXT_SIG_ALG 13 +#define TLS_EXT_ALPN 16 + #define TLS_EXT_SESSION_TICKET 35 #define TLS_EXT_RENEGOTIATION_INFO 0xFF01 @@ -355,12 +413,43 @@ /* * Size defines */ -#if !defined(POLARSSL_MPI_MAX_SIZE) -#define POLARSSL_PREMASTER_SIZE 512 -#else -#define POLARSSL_PREMASTER_SIZE POLARSSL_MPI_MAX_SIZE +#if !defined(POLARSSL_PSK_MAX_LEN) +#define POLARSSL_PSK_MAX_LEN 32 /* 256 bits */ #endif +/* Dummy type used only for its size */ +union _ssl_premaster_secret +{ +#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) + unsigned char _pms_rsa[48]; /* RFC 5246 8.1.1 */ +#endif +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) + unsigned char _pms_dhm[POLARSSL_MPI_MAX_SIZE]; /* RFC 5246 8.1.2 */ +#endif +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + unsigned char _pms_ecdh[POLARSSL_ECP_MAX_BYTES]; /* RFC 4492 5.10 */ +#endif +#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) + unsigned char _pms_psk[4 + 2 * POLARSSL_PSK_MAX_LEN]; /* RFC 4279 2 */ +#endif +#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) + unsigned char _pms_dhe_psk[4 + POLARSSL_MPI_MAX_SIZE + + POLARSSL_PSK_MAX_LEN]; /* RFC 4279 3 */ +#endif +#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) + unsigned char _pms_rsa_psk[52 + POLARSSL_PSK_MAX_LEN]; /* RFC 4279 4 */ +#endif +#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) + unsigned char _pms_ecdhe_psk[4 + POLARSSL_ECP_MAX_BYTES + + POLARSSL_PSK_MAX_LEN]; /* RFC 5489 2 */ +#endif +}; + +#define POLARSSL_PREMASTER_SIZE sizeof( union _ssl_premaster_secret ) + #ifdef __cplusplus extern "C" { #endif @@ -371,10 +460,10 @@ extern "C" { */ typedef int (*rsa_decrypt_func)( void *ctx, int mode, size_t *olen, const unsigned char *input, unsigned char *output, - size_t output_max_len ); + size_t output_max_len ); typedef int (*rsa_sign_func)( void *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - int mode, int hash_id, unsigned int hashlen, + int mode, md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, unsigned char *sig ); typedef size_t (*rsa_key_len_func)( void *ctx ); @@ -471,8 +560,8 @@ struct _ssl_transform #if defined(POLARSSL_SSL_PROTO_SSL3) /* Needed only for SSL v3.0 secret */ - unsigned char mac_enc[32]; /*!< SSL v3.0 secret (enc) */ - unsigned char mac_dec[32]; /*!< SSL v3.0 secret (dec) */ + unsigned char mac_enc[48]; /*!< SSL v3.0 secret (enc) */ + unsigned char mac_dec[48]; /*!< SSL v3.0 secret (dec) */ #endif /* POLARSSL_SSL_PROTO_SSL3 */ md_context_t md_ctx_enc; /*!< MAC (encryption) */ @@ -498,8 +587,8 @@ struct _ssl_handshake_params /* * Handshake specific crypto variables */ - int sig_alg; /*!< Signature algorithm */ - int cert_type; /*!< Requested cert type */ + int sig_alg; /*!< Hash algorithm for signature */ + int cert_type; /*!< Requested cert type */ int verify_sig_alg; /*!< Signature algorithm for verify */ #if defined(POLARSSL_DHM_C) dhm_context dhm_ctx; /*!< DHM key exchange */ @@ -521,7 +610,7 @@ struct _ssl_handshake_params #if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI */ #endif -#endif +#endif /* POLARSSL_X509_CRT_PARSE_C */ /* * Checksum contexts @@ -596,6 +685,7 @@ struct _ssl_context */ int state; /*!< SSL handshake: current state */ int renegotiation; /*!< Initial or renegotiation */ + int renego_records_seen; /*!< Records since renego request */ int major_ver; /*!< equal to SSL_MAJOR_VERSION_3 */ int minor_ver; /*!< either 0 (SSL3) or 1 (TLS1.0) */ @@ -720,7 +810,11 @@ struct _ssl_context int verify_result; /*!< verification result */ int disable_renegotiation; /*!< enable/disable renegotiation */ int allow_legacy_renegotiation; /*!< allow legacy renegotiation */ + int renego_max_records; /*!< grace period for renegotiation */ const int *ciphersuite_list[4]; /*!< allowed ciphersuites / version */ +#if defined(POLARSSL_SSL_SET_CURVES) + const ecp_group_id *curve_list; /*!< allowed curves */ +#endif #if defined(POLARSSL_SSL_TRUNCATED_HMAC) int trunc_hmac; /*!< negotiate truncated hmac? */ #endif @@ -752,6 +846,14 @@ struct _ssl_context size_t hostname_len; #endif +#if defined(POLARSSL_SSL_ALPN) + /* + * ALPN extension + */ + const char **alpn_list; /*!< ordered list of supported protocols */ + const char *alpn_chosen; /*!< negotiated protocol */ +#endif + /* * Secure renegotiation */ @@ -779,7 +881,7 @@ extern int (*ssl_hw_record_reset)(ssl_context *ssl); extern int (*ssl_hw_record_write)(ssl_context *ssl); extern int (*ssl_hw_record_read)(ssl_context *ssl); extern int (*ssl_hw_record_finish)(ssl_context *ssl); -#endif +#endif /* POLARSSL_SSL_HW_RECORD_ACCEL */ /** * \brief Returns the list of ciphersuites supported by the SSL/TLS module. @@ -790,8 +892,8 @@ extern int (*ssl_hw_record_finish)(ssl_context *ssl); const int *ssl_list_ciphersuites( void ); /** - * \brief Return the name of the ciphersuite associated with the given - * ID + * \brief Return the name of the ciphersuite associated with the + * given ID * * \param ciphersuite_id SSL ciphersuite ID * @@ -800,8 +902,8 @@ const int *ssl_list_ciphersuites( void ); const char *ssl_get_ciphersuite_name( const int ciphersuite_id ); /** - * \brief Return the ID of the ciphersuite associated with the given - * name + * \brief Return the ID of the ciphersuite associated with the + * given name * * \param ciphersuite_name SSL ciphersuite name * @@ -859,6 +961,12 @@ void ssl_set_endpoint( ssl_context *ssl, int endpoint ); * * SSL_VERIFY_REQUIRED: peer *must* present a valid certificate, * handshake is aborted if verification failed. + * + * \note On client, SSL_VERIFY_REQUIRED is the recommended mode. + * With SSL_VERIFY_OPTIONAL, the user needs to call ssl_get_verify_result() at + * the right time(s), which may not be obvious, while REQUIRED always perform + * the verification as soon as possible. For example, REQUIRED was protecting + * against the "triple handshake" attack even before it was found. */ void ssl_set_authmode( ssl_context *ssl, int authmode ); @@ -972,17 +1080,22 @@ void ssl_set_session_cache( ssl_context *ssl, int ssl_set_session( ssl_context *ssl, const ssl_session *session ); /** - * \brief Set the list of allowed ciphersuites + * \brief Set the list of allowed ciphersuites and the preference + * order. First in the list has the highest preference. * (Overrides all version specific lists) * + * Note: The PolarSSL SSL server uses its own preferences + * over the preference of the connection SSL client unless + * POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE is defined! + * * \param ssl SSL context * \param ciphersuites 0-terminated list of allowed ciphersuites */ void ssl_set_ciphersuites( ssl_context *ssl, const int *ciphersuites ); /** - * \brief Set the list of allowed ciphersuites for a specific - * version of the protocol. + * \brief Set the list of allowed ciphersuites and the + * preference order for a specific version of the protocol. * (Only useful on the server side) * * \param ssl SSL context @@ -1038,6 +1151,9 @@ int ssl_set_own_cert( ssl_context *ssl, x509_crt *own_cert, * up your certificate chain. The top certificate (self-signed) * can be omitted. * + * \warning This backwards-compatibility function is deprecated! + * Please use \c ssl_set_own_cert() instead. + * * \param ssl SSL context * \param own_cert own public certificate chain * \param rsa_key own private RSA key @@ -1060,6 +1176,10 @@ int ssl_set_own_cert_rsa( ssl_context *ssl, x509_crt *own_cert, * up your certificate chain. The top certificate (self-signed) * can be omitted. * + * \warning This backwards-compatibility function is deprecated! + * Please use \c pk_init_ctx_rsa_alt() + * and \c ssl_set_own_cert() instead. + * * \param ssl SSL context * \param own_cert own public certificate chain * \param rsa_key alternate implementation private RSA key @@ -1097,7 +1217,7 @@ int ssl_set_psk( ssl_context *ssl, const unsigned char *psk, size_t psk_len, * * If set, the PSK callback is called for each * handshake where a PSK ciphersuite was negotiated. - * The callback provides the identity received and wants to + * The caller provides the identity received and wants to * receive the actual PSK data and length. * * The callback has the following parameters: (void *parameter, @@ -1142,7 +1262,29 @@ int ssl_set_dh_param( ssl_context *ssl, const char *dhm_P, const char *dhm_G ); * \return 0 if successful */ int ssl_set_dh_param_ctx( ssl_context *ssl, dhm_context *dhm_ctx ); -#endif +#endif /* POLARSSL_DHM_C */ + +#if defined(POLARSSL_SSL_SET_CURVES) +/** + * \brief Set the allowed curves in order of preference. + * (Default: all defined curves.) + * + * On server: this only affects selection of the ECDHE curve; + * the curves used for ECDH and ECDSA are determined by the + * list of available certificates instead. + * + * On client: this affects the list of curves offered for any + * use. The server can override our preference order. + * + * Both sides: limits the set of curves used by peer to the + * listed curves for any use (ECDH(E), certificates). + * + * \param ssl SSL context + * \param curves Ordered list of allowed curves, + * terminated by POLARSSL_ECP_DP_NONE. + */ +void ssl_set_curves( ssl_context *ssl, const ecp_group_id *curves ); +#endif /* POLARSSL_SSL_SET_CURVES */ #if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) /** @@ -1182,6 +1324,30 @@ void ssl_set_sni( ssl_context *ssl, void *p_sni ); #endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */ +#if defined(POLARSSL_SSL_ALPN) +/** + * \brief Set the supported Application Layer Protocols. + * + * \param ssl SSL context + * \param protos NULL-terminated list of supported protocols, + * in decreasing preference order. + * + * \return 0 on success, or POLARSSL_ERR_SSL_BAD_INPUT_DATA. + */ +int ssl_set_alpn_protocols( ssl_context *ssl, const char **protos ); + +/** + * \brief Get the name of the negotiated Application Layer Protocol. + * This function should be called after the handshake is + * completed. + * + * \param ssl SSL context + * + * \return Protcol name, or NULL if no protocol was negotiated. + */ +const char *ssl_get_alpn_protocol( const ssl_context *ssl ); +#endif /* POLARSSL_SSL_ALPN */ + /** * \brief Set the maximum supported version sent from the client side * and/or accepted at the server side @@ -1296,7 +1462,7 @@ void ssl_set_renegotiation( ssl_context *ssl, int renegotiation ); /** * \brief Prevent or allow legacy renegotiation. * (Default: SSL_LEGACY_NO_RENEGOTIATION) - * + * * SSL_LEGACY_NO_RENEGOTIATION allows connections to * be established even if the peer does not support * secure renegotiation, but does not allow renegotiation @@ -1322,6 +1488,33 @@ void ssl_set_renegotiation( ssl_context *ssl, int renegotiation ); */ void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy ); +/** + * \brief Enforce server-requested renegotiation. + * (Default: enforced, max_records = 16) + * (No effect on client.) + * + * When a server requests a renegotiation, the client can + * comply or ignore the request. This function allows the + * server to decide if it should enforce its renegotiation + * requests by closing the connection if the client doesn't + * initiate a renegotiation. + * + * However, records could already be in transit from the + * client to the server when the request is emitted. In order + * to increase reliability, the server can accept a number of + * records containing application data before the ClientHello + * that was requested. + * + * The optimal value is highly dependent on the specific usage + * scenario. + * + * \param ssl SSL context + * \param max_records Use SSL_RENEGOTIATION_NOT_ENFORCED if you don't want to + * enforce renegotiation, or a non-negative value to enforce + * it but allow for a grace period of max_records records. + */ +void ssl_set_renegotiation_enforced( ssl_context *ssl, int max_records ); + /** * \brief Return the number of data bytes available to read * @@ -1489,6 +1682,13 @@ int ssl_close_notify( ssl_context *ssl ); */ void ssl_free( ssl_context *ssl ); +/** + * \brief Initialize SSL session structure + * + * \param session SSL session + */ +void ssl_session_init( ssl_session *session ); + /** * \brief Free referenced items in an SSL session including the * peer certificate and clear memory @@ -1543,7 +1743,8 @@ int ssl_write_change_cipher_spec( ssl_context *ssl ); int ssl_parse_finished( ssl_context *ssl ); int ssl_write_finished( ssl_context *ssl ); -void ssl_optimize_checksum( ssl_context *ssl, const ssl_ciphersuite_t *ciphersuite_info ); +void ssl_optimize_checksum( ssl_context *ssl, + const ssl_ciphersuite_t *ciphersuite_info ); #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) int ssl_psk_derive_premaster( ssl_context *ssl, key_exchange_type_t key_ex ); @@ -1556,6 +1757,10 @@ pk_type_t ssl_pk_alg_from_sig( unsigned char sig ); md_type_t ssl_md_alg_from_hash( unsigned char hash ); +#if defined(POLARSSL_SSL_SET_CURVES) +int ssl_curve_is_acceptable( const ssl_context *ssl, ecp_group_id grp_id ); +#endif + #if defined(POLARSSL_X509_CRT_PARSE_C) static inline pk_context *ssl_own_key( ssl_context *ssl ) { @@ -1568,6 +1773,19 @@ static inline x509_crt *ssl_own_cert( ssl_context *ssl ) return( ssl->handshake->key_cert == NULL ? NULL : ssl->handshake->key_cert->cert ); } + +/* + * Check usage of a certificate wrt extensions: + * keyUsage, extendedKeyUsage (later), and nSCertType (later). + * + * Warning: cert_endpoint is the endpoint of the cert (ie, of our peer when we + * check a cert we received from them)! + * + * Return 0 if everything is OK, -1 if not. + */ +int ssl_check_cert_usage( const x509_crt *cert, + const ssl_ciphersuite_t *ciphersuite, + int cert_endpoint ); #endif /* POLARSSL_X509_CRT_PARSE_C */ /* constant-time buffer comparison */ diff --git a/pdns/ext/polarssl/include/polarssl/ssl_cache.h b/pdns/ext/polarssl/include/polarssl/ssl_cache.h index daa07acb6..918fb608e 100644 --- a/pdns/ext/polarssl/include/polarssl/ssl_cache.h +++ b/pdns/ext/polarssl/include/polarssl/ssl_cache.h @@ -33,10 +33,23 @@ #include "threading.h" #endif -#if !defined(POLARSSL_CONFIG_OPTIONS) +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(SSL_CACHE_DEFAULT_TIMEOUT) #define SSL_CACHE_DEFAULT_TIMEOUT 86400 /*!< 1 day */ +#endif + +#if !defined(SSL_CACHE_DEFAULT_MAX_ENTRIES) #define SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /*!< Maximum entries in cache */ -#endif /* !POLARSSL_CONFIG_OPTIONS */ +#endif + +/* \} name SECTION: Module settings */ #ifdef __cplusplus extern "C" { @@ -106,7 +119,7 @@ int ssl_cache_set( void *data, const ssl_session *session ); * A timeout of 0 indicates no timeout. * * \param cache SSL cache context - * \param timeout cache entry timeout + * \param timeout cache entry timeout in seconds */ void ssl_cache_set_timeout( ssl_cache_context *cache, int timeout ); #endif /* POLARSSL_HAVE_TIME */ diff --git a/pdns/ext/polarssl/include/polarssl/ssl_ciphersuites.h b/pdns/ext/polarssl/include/polarssl/ssl_ciphersuites.h index 3a8f697d8..c4f1ffe64 100644 --- a/pdns/ext/polarssl/include/polarssl/ssl_ciphersuites.h +++ b/pdns/ext/polarssl/include/polarssl/ssl_ciphersuites.h @@ -99,20 +99,20 @@ extern "C" { #define TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 0xAC /**< TLS 1.2 */ #define TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 0xAD /**< TLS 1.2 */ -#define TLS_PSK_WITH_AES_128_CBC_SHA256 0xAE /**< TLS 1.2 */ -#define TLS_PSK_WITH_AES_256_CBC_SHA384 0xAF /**< TLS 1.2 */ -#define TLS_PSK_WITH_NULL_SHA256 0xB0 /**< Weak! TLS 1.2 */ -#define TLS_PSK_WITH_NULL_SHA384 0xB1 /**< Weak! TLS 1.2 */ +#define TLS_PSK_WITH_AES_128_CBC_SHA256 0xAE +#define TLS_PSK_WITH_AES_256_CBC_SHA384 0xAF +#define TLS_PSK_WITH_NULL_SHA256 0xB0 /**< Weak! */ +#define TLS_PSK_WITH_NULL_SHA384 0xB1 /**< Weak! */ -#define TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 0xB2 /**< TLS 1.2 */ -#define TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 0xB3 /**< TLS 1.2 */ -#define TLS_DHE_PSK_WITH_NULL_SHA256 0xB4 /**< Weak! TLS 1.2 */ -#define TLS_DHE_PSK_WITH_NULL_SHA384 0xB5 /**< Weak! TLS 1.2 */ +#define TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 0xB2 +#define TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 0xB3 +#define TLS_DHE_PSK_WITH_NULL_SHA256 0xB4 /**< Weak! */ +#define TLS_DHE_PSK_WITH_NULL_SHA384 0xB5 /**< Weak! */ -#define TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 0xB6 /**< TLS 1.2 */ -#define TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 0xB7 /**< TLS 1.2 */ -#define TLS_RSA_PSK_WITH_NULL_SHA256 0xB8 /**< Weak! TLS 1.2 */ -#define TLS_RSA_PSK_WITH_NULL_SHA384 0xB9 /**< Weak! TLS 1.2 */ +#define TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 0xB6 +#define TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 0xB7 +#define TLS_RSA_PSK_WITH_NULL_SHA256 0xB8 /**< Weak! */ +#define TLS_RSA_PSK_WITH_NULL_SHA384 0xB9 /**< Weak! */ #define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBA /**< TLS 1.2 */ #define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBE /**< TLS 1.2 */ @@ -120,12 +120,24 @@ extern "C" { #define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC0 /**< TLS 1.2 */ #define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC4 /**< TLS 1.2 */ +#define TLS_ECDH_ECDSA_WITH_NULL_SHA 0xC001 /**< Weak! */ +#define TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0xC002 /**< Not in SSL3! */ +#define TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC003 /**< Not in SSL3! */ +#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 /**< Not in SSL3! */ +#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 /**< Not in SSL3! */ + #define TLS_ECDHE_ECDSA_WITH_NULL_SHA 0xC006 /**< Weak! */ #define TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 0xC007 /**< Not in SSL3! */ #define TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC008 /**< Not in SSL3! */ #define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 /**< Not in SSL3! */ #define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A /**< Not in SSL3! */ +#define TLS_ECDH_RSA_WITH_NULL_SHA 0xC00B /**< Weak! */ +#define TLS_ECDH_RSA_WITH_RC4_128_SHA 0xC00C /**< Not in SSL3! */ +#define TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0xC00D /**< Not in SSL3! */ +#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E /**< Not in SSL3! */ +#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F /**< Not in SSL3! */ + #define TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010 /**< Weak! */ #define TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC011 /**< Not in SSL3! */ #define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 /**< Not in SSL3! */ @@ -134,30 +146,40 @@ extern "C" { #define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 /**< TLS 1.2 */ #define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 /**< TLS 1.2 */ - +#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 /**< TLS 1.2 */ +#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 /**< TLS 1.2 */ #define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 /**< TLS 1.2 */ #define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 /**< TLS 1.2 */ +#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 /**< TLS 1.2 */ +#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A /**< TLS 1.2 */ #define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B /**< TLS 1.2 */ #define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C /**< TLS 1.2 */ - +#define TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D /**< TLS 1.2 */ +#define TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E /**< TLS 1.2 */ #define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F /**< TLS 1.2 */ #define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 /**< TLS 1.2 */ +#define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 /**< TLS 1.2 */ +#define TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /**< TLS 1.2 */ #define TLS_ECDHE_PSK_WITH_RC4_128_SHA 0xC033 /**< Not in SSL3! */ #define TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA 0xC034 /**< Not in SSL3! */ #define TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA 0xC035 /**< Not in SSL3! */ #define TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA 0xC036 /**< Not in SSL3! */ -#define TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0xC037 /**< TLS 1.2 */ -#define TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 0xC038 /**< TLS 1.2 */ +#define TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0xC037 /**< Not in SSL3! */ +#define TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 0xC038 /**< Not in SSL3! */ #define TLS_ECDHE_PSK_WITH_NULL_SHA 0xC039 /**< Weak! No SSL3! */ -#define TLS_ECDHE_PSK_WITH_NULL_SHA256 0xC03A /**< Weak! TLS 1.2 */ -#define TLS_ECDHE_PSK_WITH_NULL_SHA384 0xC03B /**< Weak! TLS 1.2 */ - -#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC072 /**< TLS 1.2 */ -#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC073 /**< TLS 1.2 */ -#define TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC076 /**< TLS 1.2 */ -#define TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC077 /**< TLS 1.2 */ +#define TLS_ECDHE_PSK_WITH_NULL_SHA256 0xC03A /**< Weak! No SSL3! */ +#define TLS_ECDHE_PSK_WITH_NULL_SHA384 0xC03B /**< Weak! No SSL3! */ + +#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC072 /**< Not in SSL3! */ +#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC073 /**< Not in SSL3! */ +#define TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC074 /**< Not in SSL3! */ +#define TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC075 /**< Not in SSL3! */ +#define TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC076 /**< Not in SSL3! */ +#define TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC077 /**< Not in SSL3! */ +#define TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC078 /**< Not in SSL3! */ +#define TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC079 /**< Not in SSL3! */ #define TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07A /**< TLS 1.2 */ #define TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07B /**< TLS 1.2 */ @@ -165,25 +187,53 @@ extern "C" { #define TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07D /**< TLS 1.2 */ #define TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC086 /**< TLS 1.2 */ #define TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC087 /**< TLS 1.2 */ +#define TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC088 /**< TLS 1.2 */ +#define TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC089 /**< TLS 1.2 */ #define TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08A /**< TLS 1.2 */ #define TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08B /**< TLS 1.2 */ +#define TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08C /**< TLS 1.2 */ +#define TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08D /**< TLS 1.2 */ -#define TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC08D /**< TLS 1.2 */ +#define TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC08E /**< TLS 1.2 */ #define TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC08F /**< TLS 1.2 */ #define TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC090 /**< TLS 1.2 */ #define TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC091 /**< TLS 1.2 */ #define TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC092 /**< TLS 1.2 */ #define TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC093 /**< TLS 1.2 */ -#define TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC094 /**< TLS 1.2 */ -#define TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC095 /**< TLS 1.2 */ -#define TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC096 /**< TLS 1.2 */ -#define TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC097 /**< TLS 1.2 */ -#define TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC098 /**< TLS 1.2 */ -#define TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC099 /**< TLS 1.2 */ -#define TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC09A /**< TLS 1.2 */ -#define TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC09B /**< TLS 1.2 */ - +#define TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC094 +#define TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC095 +#define TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC096 +#define TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC097 +#define TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC098 +#define TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC099 +#define TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC09A /**< Not in SSL3! */ +#define TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC09B /**< Not in SSL3! */ + +#define TLS_RSA_WITH_AES_128_CCM 0xC09C /**< TLS 1.2 */ +#define TLS_RSA_WITH_AES_256_CCM 0xC09D /**< TLS 1.2 */ +#define TLS_DHE_RSA_WITH_AES_128_CCM 0xC09E /**< TLS 1.2 */ +#define TLS_DHE_RSA_WITH_AES_256_CCM 0xC09F /**< TLS 1.2 */ +#define TLS_RSA_WITH_AES_128_CCM_8 0xC0A0 /**< TLS 1.2 */ +#define TLS_RSA_WITH_AES_256_CCM_8 0xC0A1 /**< TLS 1.2 */ +#define TLS_DHE_RSA_WITH_AES_128_CCM_8 0xC0A2 /**< TLS 1.2 */ +#define TLS_DHE_RSA_WITH_AES_256_CCM_8 0xC0A3 /**< TLS 1.2 */ +#define TLS_PSK_WITH_AES_128_CCM 0xC0A4 /**< TLS 1.2 */ +#define TLS_PSK_WITH_AES_256_CCM 0xC0A5 /**< TLS 1.2 */ +#define TLS_DHE_PSK_WITH_AES_128_CCM 0xC0A6 /**< TLS 1.2 */ +#define TLS_DHE_PSK_WITH_AES_256_CCM 0xC0A7 /**< TLS 1.2 */ +#define TLS_PSK_WITH_AES_128_CCM_8 0xC0A8 /**< TLS 1.2 */ +#define TLS_PSK_WITH_AES_256_CCM_8 0xC0A9 /**< TLS 1.2 */ +#define TLS_DHE_PSK_WITH_AES_128_CCM_8 0xC0AA /**< TLS 1.2 */ +#define TLS_DHE_PSK_WITH_AES_256_CCM_8 0xC0AB /**< TLS 1.2 */ +/* The last two are named with PSK_DHE in the RFC, which looks like a typo */ + +#define TLS_ECDHE_ECDSA_WITH_AES_128_CCM 0xC0AC /**< TLS 1.2 */ +#define TLS_ECDHE_ECDSA_WITH_AES_256_CCM 0xC0AD /**< TLS 1.2 */ +#define TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE /**< TLS 1.2 */ +#define TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF /**< TLS 1.2 */ + +/* Reminder: update _ssl_premaster_secret when adding a new key exchange */ typedef enum { POLARSSL_KEY_EXCHANGE_NONE = 0, POLARSSL_KEY_EXCHANGE_RSA, @@ -194,11 +244,15 @@ typedef enum { POLARSSL_KEY_EXCHANGE_DHE_PSK, POLARSSL_KEY_EXCHANGE_RSA_PSK, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, + POLARSSL_KEY_EXCHANGE_ECDH_RSA, + POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, } key_exchange_type_t; typedef struct _ssl_ciphersuite_t ssl_ciphersuite_t; -#define POLARSSL_CIPHERSUITE_WEAK 0x01 /* @@ -39,10 +43,6 @@ extern "C" { #define POLARSSL_ERR_THREADING_BAD_INPUT_DATA -0x001C /**< Bad input parameters to function. */ #define POLARSSL_ERR_THREADING_MUTEX_ERROR -0x001E /**< Locking / unlocking / free failed with error code. */ -#if defined(POLARSSL_THREADING_DUMMY) -typedef void threading_mutex_t; -#endif - #if defined(POLARSSL_THREADING_PTHREAD) #include typedef pthread_mutex_t threading_mutex_t; diff --git a/pdns/ext/polarssl/include/polarssl/timing.h b/pdns/ext/polarssl/include/polarssl/timing.h index 5ab000e10..383120efe 100644 --- a/pdns/ext/polarssl/include/polarssl/timing.h +++ b/pdns/ext/polarssl/include/polarssl/timing.h @@ -3,7 +3,7 @@ * * \brief Portable interface to the CPU cycle counter * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,6 +27,16 @@ #ifndef POLARSSL_TIMING_H #define POLARSSL_TIMING_H +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if !defined(POLARSSL_TIMING_ALT) +// Regular implementation +// + #ifdef __cplusplus extern "C" { #endif @@ -68,8 +78,21 @@ void set_alarm( int seconds ); */ void m_sleep( int milliseconds ); +#if defined(POLARSSL_SELF_TEST) +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if a test failed + */ +int timing_self_test( int verbose ); +#endif + #ifdef __cplusplus } #endif +#else /* POLARSSL_TIMING_ALT */ +#include "timing_alt.h" +#endif /* POLARSSL_TIMING_ALT */ + #endif /* timing.h */ diff --git a/pdns/ext/polarssl/include/polarssl/version.h b/pdns/ext/polarssl/include/polarssl/version.h index 8e2ae7e67..1ee2a3b5a 100644 --- a/pdns/ext/polarssl/include/polarssl/version.h +++ b/pdns/ext/polarssl/include/polarssl/version.h @@ -3,7 +3,7 @@ * * \brief Run-time version information * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -31,7 +31,11 @@ #ifndef POLARSSL_VERSION_H #define POLARSSL_VERSION_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif /** * The version number x.y.z is split into three parts. @@ -39,16 +43,16 @@ */ #define POLARSSL_VERSION_MAJOR 1 #define POLARSSL_VERSION_MINOR 3 -#define POLARSSL_VERSION_PATCH 2 +#define POLARSSL_VERSION_PATCH 8 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define POLARSSL_VERSION_NUMBER 0x01030200 -#define POLARSSL_VERSION_STRING "1.3.2" -#define POLARSSL_VERSION_STRING_FULL "PolarSSL 1.3.2" +#define POLARSSL_VERSION_NUMBER 0x01030800 +#define POLARSSL_VERSION_STRING "1.3.8" +#define POLARSSL_VERSION_STRING_FULL "PolarSSL 1.3.8" #if defined(POLARSSL_VERSION_C) @@ -75,11 +79,32 @@ void version_get_string( char *string ); /** * Get the full version string ("PolarSSL x.y.z"). * - * \param string The string that will receive the value. - * (Should be at least 18 bytes in size) + * \param string The string that will receive the value. The PolarSSL version + * string will use 18 bytes AT MOST including a terminating + * null byte. + * (So the buffer should be at least 18 bytes to receive this + * version string). */ void version_get_string_full( char *string ); +/** + * \brief Check if support for a feature was compiled into this + * PolarSSL binary. This allows you to see at runtime if the + * library was for instance compiled with or without + * Multi-threading support. + * + * Note: only checks against defines in the sections "System + * support", "PolarSSL modules" and "PolarSSL feature + * support" in config.h + * + * \param feature The string for the define to check (e.g. "POLARSSL_AES_C") + * + * \return 0 if the feature is present, -1 if the feature is not + * present and -2 if support for feature checking as a whole + * was not compiled in. + */ +int version_check_feature( const char *feature ); + #ifdef __cplusplus } #endif diff --git a/pdns/ext/polarssl/include/polarssl/x509.h b/pdns/ext/polarssl/include/polarssl/x509.h index a45653770..583cb8320 100644 --- a/pdns/ext/polarssl/include/polarssl/x509.h +++ b/pdns/ext/polarssl/include/polarssl/x509.h @@ -3,7 +3,7 @@ * * \brief X.509 generic defines and structures * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ #ifndef POLARSSL_X509_H #define POLARSSL_X509_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include "asn1.h" #include "pk.h" @@ -78,6 +82,8 @@ #define BADCERT_MISSING 0x40 /**< Certificate was missing. */ #define BADCERT_SKIP_VERIFY 0x80 /**< Certificate verification was skipped. */ #define BADCERT_OTHER 0x0100 /**< Other reason (can be used by verify callback) */ +#define BADCERT_FUTURE 0x0200 /**< The certificate validity starts in the future. */ +#define BADCRL_FUTURE 0x0400 /**< The CRL is from the future */ /* \} name */ /* \} addtogroup x509_module */ @@ -108,24 +114,27 @@ /* * X.509 extension types + * + * Comments refer to the status for using certificates. Status can be + * different for writing certificates or reading CRLs or CSRs. */ #define EXT_AUTHORITY_KEY_IDENTIFIER (1 << 0) #define EXT_SUBJECT_KEY_IDENTIFIER (1 << 1) -#define EXT_KEY_USAGE (1 << 2) +#define EXT_KEY_USAGE (1 << 2) /* Parsed but not used */ #define EXT_CERTIFICATE_POLICIES (1 << 3) #define EXT_POLICY_MAPPINGS (1 << 4) -#define EXT_SUBJECT_ALT_NAME (1 << 5) +#define EXT_SUBJECT_ALT_NAME (1 << 5) /* Supported (DNS) */ #define EXT_ISSUER_ALT_NAME (1 << 6) #define EXT_SUBJECT_DIRECTORY_ATTRS (1 << 7) -#define EXT_BASIC_CONSTRAINTS (1 << 8) +#define EXT_BASIC_CONSTRAINTS (1 << 8) /* Supported */ #define EXT_NAME_CONSTRAINTS (1 << 9) #define EXT_POLICY_CONSTRAINTS (1 << 10) -#define EXT_EXTENDED_KEY_USAGE (1 << 11) +#define EXT_EXTENDED_KEY_USAGE (1 << 11) /* Parsed but not used */ #define EXT_CRL_DISTRIBUTION_POINTS (1 << 12) #define EXT_INIHIBIT_ANYPOLICY (1 << 13) #define EXT_FRESHEST_CRL (1 << 14) -#define EXT_NS_CERT_TYPE (1 << 16) +#define EXT_NS_CERT_TYPE (1 << 16) /* Parsed (and then ?) */ /* * Storage format identifiers @@ -207,6 +216,8 @@ int x509_serial_gets( char *buf, size_t size, const x509_buf *serial ); /** * \brief Give an known OID, return its descriptive string. + * (Deprecated. Use oid_get_extended_key_usage() instead.) + * Warning: only works for extended_key_usage OIDs! * * \param oid buffer containing the oid * @@ -223,22 +234,33 @@ const char *x509_oid_get_description( x509_buf *oid ); * \param size Maximum size of buffer * \param oid Buffer containing the OID * - * \return The amount of data written to the buffer, or -1 in - * case of an error. + * \return Length of the string written (excluding final NULL) or + * POLARSSL_ERR_OID_BUF_TO_SMALL in case of error */ int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid ); /** * \brief Check a given x509_time against the system time and check - * if it is valid. + * if it is not expired. * * \param time x509_time to check * - * \return Return 0 if the x509_time is still valid, - * or 1 otherwise. + * \return 0 if the x509_time is still valid, + * 1 otherwise. */ int x509_time_expired( const x509_time *time ); +/** + * \brief Check a given x509_time against the system time and check + * if it is not from the future. + * + * \param time x509_time to check + * + * \return 0 if the x509_time is already valid, + * 1 otherwise. + */ +int x509_time_future( const x509_time *time ); + /** * \brief Checkup routine * @@ -254,9 +276,17 @@ int x509_get_name( unsigned char **p, const unsigned char *end, x509_name *cur ); int x509_get_alg_null( unsigned char **p, const unsigned char *end, x509_buf *alg ); +int x509_get_alg( unsigned char **p, const unsigned char *end, + x509_buf *alg, x509_buf *params ); +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) +int x509_get_rsassa_pss_params( const x509_buf *params, + md_type_t *md_alg, md_type_t *mgf_md, + int *salt_len ); +#endif int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig ); -int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg, - pk_type_t *pk_alg ); +int x509_get_sig_alg( const x509_buf *sig_oid, const x509_buf *sig_params, + md_type_t *md_alg, pk_type_t *pk_alg, + void **sig_opts ); int x509_get_time( unsigned char **p, const unsigned char *end, x509_time *time ); int x509_get_serial( unsigned char **p, const unsigned char *end, @@ -264,9 +294,14 @@ int x509_get_serial( unsigned char **p, const unsigned char *end, int x509_get_ext( unsigned char **p, const unsigned char *end, x509_buf *ext, int tag ); int x509_load_file( const char *path, unsigned char **buf, size_t *n ); +int x509_sig_alg_gets( char *buf, size_t size, const x509_buf *sig_oid, + pk_type_t pk_alg, md_type_t md_alg, + const void *sig_opts ); int x509_key_size_helper( char *buf, size_t size, const char *name ); int x509_string_to_names( asn1_named_data **head, const char *name ); -int x509_set_extension( asn1_named_data **head, const char *oid, size_t oid_len, int critical, const unsigned char *val, size_t val_len ); +int x509_set_extension( asn1_named_data **head, const char *oid, size_t oid_len, + int critical, const unsigned char *val, + size_t val_len ); int x509_write_extensions( unsigned char **p, unsigned char *start, asn1_named_data *first ); int x509_write_names( unsigned char **p, unsigned char *start, diff --git a/pdns/ext/polarssl/include/polarssl/x509_crl.h b/pdns/ext/polarssl/include/polarssl/x509_crl.h index 0c79916af..9f597a855 100644 --- a/pdns/ext/polarssl/include/polarssl/x509_crl.h +++ b/pdns/ext/polarssl/include/polarssl/x509_crl.h @@ -27,7 +27,11 @@ #ifndef POLARSSL_X509_CRL_H #define POLARSSL_X509_CRL_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include "x509.h" @@ -71,7 +75,7 @@ typedef struct _x509_crl x509_buf raw; /**< The raw certificate data (DER). */ x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ - int version; + int version; /**< CRL version (1=v1, 2=v2) */ x509_buf sig_oid1; x509_buf issuer_raw; /**< The raw issuer data (DER). */ @@ -88,7 +92,8 @@ typedef struct _x509_crl x509_buf sig_oid2; x509_buf sig; md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. POLARSSL_MD_SHA256 */ - pk_type_t sig_pk /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. POLARSSL_PK_RSA */; + pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. POLARSSL_PK_RSA */ + void *sig_opts; /**< Signature options to be passed to pk_verify_ext(), e.g. for RSASSA-PSS */ struct _x509_crl *next; } diff --git a/pdns/ext/polarssl/include/polarssl/x509_crt.h b/pdns/ext/polarssl/include/polarssl/x509_crt.h index a5ab1789a..4bf8e568f 100644 --- a/pdns/ext/polarssl/include/polarssl/x509_crt.h +++ b/pdns/ext/polarssl/include/polarssl/x509_crt.h @@ -27,7 +27,11 @@ #ifndef POLARSSL_X509_CRT_H #define POLARSSL_X509_CRT_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include "x509.h" @@ -55,7 +59,7 @@ typedef struct _x509_crt x509_buf raw; /**< The raw certificate data (DER). */ x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ - int version; /**< The X.509 version. (0=v1, 1=v2, 2=v3) */ + int version; /**< The X.509 version. (1=v1, 2=v2, 3=v3) */ x509_buf serial; /**< Unique id for certificate issued by a specific CA. */ x509_buf sig_oid1; /**< Signature algorithm, e.g. sha1RSA */ @@ -72,23 +76,24 @@ typedef struct _x509_crt x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */ x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */ - x509_buf v3_ext; /**< Optional X.509 v3 extensions. Only Basic Contraints are supported at this time. */ + x509_buf v3_ext; /**< Optional X.509 v3 extensions. */ x509_sequence subject_alt_names; /**< Optional list of Subject Alternative Names (Only dNSName supported). */ int ext_types; /**< Bit string containing detected and parsed extensions */ int ca_istrue; /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */ int max_pathlen; /**< Optional Basic Constraint extension value: The maximum path length to the root certificate. Path length is 1 higher than RFC 5280 'meaning', so 1+ */ - unsigned char key_usage; /**< Optional key usage extension value: See the values below */ + unsigned char key_usage; /**< Optional key usage extension value: See the values in x509.h */ x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */ - unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values below */ + unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values in x509.h */ x509_buf sig_oid2; /**< Signature algorithm. Must match sig_oid1. */ x509_buf sig; /**< Signature: hash of the tbs part signed with the private key. */ md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. POLARSSL_MD_SHA256 */ - pk_type_t sig_pk /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. POLARSSL_PK_RSA */; + pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. POLARSSL_PK_RSA */ + void *sig_opts; /**< Signature options to be passed to pk_verify_ext(), e.g. for RSASSA-PSS */ struct _x509_crt *next; /**< Next certificate in the CA-chain. */ } @@ -172,6 +177,11 @@ int x509_crt_parse_file( x509_crt *chain, const char *path ); * of failed certificates it encountered. If none complete * correctly, the first error is returned. * + * \warning This function is NOT thread-safe unless + * POLARSSL_THREADING_PTHREADS is defined. If you're using an + * alternative threading implementation, you should either use + * this function only in the main thread, or mutex it. + * * \param chain points to the start of the chain * \param path directory / folder to read the certificate files from * @@ -239,6 +249,44 @@ int x509_crt_verify( x509_crt *crt, int (*f_vrfy)(void *, x509_crt *, int, int *), void *p_vrfy ); +#if defined(POLARSSL_X509_CHECK_KEY_USAGE) +/** + * \brief Check usage of certificate against keyUsage extension. + * + * \param crt Leaf certificate used. + * \param usage Intended usage(s) (eg KU_KEY_ENCIPHERMENT before using the + * certificate to perform an RSA key exchange). + * + * \return 0 is these uses of the certificate are allowed, + * POLARSSL_ERR_X509_BAD_INPUT_DATA if the keyUsage extension + * is present but does not contain all the bits set in the + * usage argument. + * + * \note You should only call this function on leaf certificates, on + * (intermediate) CAs the keyUsage extension is automatically + * checked by \c x509_crt_verify(). + */ +int x509_crt_check_key_usage( const x509_crt *crt, int usage ); +#endif /* POLARSSL_X509_CHECK_KEY_USAGE) */ + +#if defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) +/** + * \brief Check usage of certificate against extentedJeyUsage. + * + * \param crt Leaf certificate used. + * \param usage_oid Intended usage (eg OID_SERVER_AUTH or OID_CLIENT_AUTH). + * \param usage_len Length of usage_oid (eg given by OID_SIZE()). + * + * \return 0 is this use of the certificate is allowed, + * POLARSSL_ERR_X509_BAD_INPUT_DATA if not. + * + * \note Usually only makes sense on leaf certificates. + */ +int x509_crt_check_extended_key_usage( const x509_crt *crt, + const char *usage_oid, + size_t usage_len ); +#endif /* POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) */ + #if defined(POLARSSL_X509_CRL_PARSE_C) /** * \brief Verify the certificate revocation status @@ -366,7 +414,7 @@ void x509write_crt_set_issuer_key( x509write_cert *ctx, pk_context *key ); * (e.g. POLARSSL_MD_SHA1) * * \param ctx CRT context to use - * \param md_ald MD algorithm to use + * \param md_alg MD algorithm to use */ void x509write_crt_set_md_alg( x509write_cert *ctx, md_type_t md_alg ); @@ -462,7 +510,7 @@ void x509write_crt_free( x509write_cert *ctx ); * return value to determine where you should start * using the buffer * - * \param crt certificate to write away + * \param ctx certificate to write away * \param buf buffer to write to * \param size size of the buffer * \param f_rng RNG function (for signature, see note) @@ -484,7 +532,7 @@ int x509write_crt_der( x509write_cert *ctx, unsigned char *buf, size_t size, /** * \brief Write a built up certificate to a X509 PEM string * - * \param crt certificate to write away + * \param ctx certificate to write away * \param buf buffer to write to * \param size size of the buffer * \param f_rng RNG function (for signature, see note) diff --git a/pdns/ext/polarssl/include/polarssl/x509_csr.h b/pdns/ext/polarssl/include/polarssl/x509_csr.h index 7e3830087..6591e382e 100644 --- a/pdns/ext/polarssl/include/polarssl/x509_csr.h +++ b/pdns/ext/polarssl/include/polarssl/x509_csr.h @@ -3,7 +3,7 @@ * * \brief X.509 certificate signing request parsing and writing * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ #ifndef POLARSSL_X509_CSR_H #define POLARSSL_X509_CSR_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include "x509.h" @@ -52,7 +56,7 @@ typedef struct _x509_csr x509_buf raw; /**< The raw CSR data (DER). */ x509_buf cri; /**< The raw CertificateRequestInfo body (DER). */ - int version; + int version; /**< CSR version (1=v1). */ x509_buf subject_raw; /**< The raw subject data (DER). */ x509_name subject; /**< The parsed subject data (named information object). */ @@ -62,7 +66,8 @@ typedef struct _x509_csr x509_buf sig_oid; x509_buf sig; md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. POLARSSL_MD_SHA256 */ - pk_type_t sig_pk /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. POLARSSL_PK_RSA */; + pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. POLARSSL_PK_RSA */ + void *sig_opts; /**< Signature options to be passed to pk_verify_ext(), e.g. for RSASSA-PSS */ } x509_csr; @@ -80,7 +85,19 @@ x509write_csr; #if defined(POLARSSL_X509_CSR_PARSE_C) /** - * \brief Load a Certificate Signing Request (CSR) + * \brief Load a Certificate Signing Request (CSR) in DER format + * + * \param csr CSR context to fill + * \param buf buffer holding the CRL data + * \param buflen size of the buffer + * + * \return 0 if successful, or a specific X509 error code + */ +int x509_csr_parse_der( x509_csr *csr, + const unsigned char *buf, size_t buflen ); + +/** + * \brief Load a Certificate Signing Request (CSR), DER or PEM format * * \param csr CSR context to fill * \param buf buffer holding the CRL data @@ -111,8 +128,8 @@ int x509_csr_parse_file( x509_csr *csr, const char *path ); * \param prefix A line prefix * \param csr The X509 CSR to represent * - * \return The amount of data written to the buffer, or -1 in - * case of an error. + * \return The length of the string written (exluding the terminating + * null byte), or a negative value in case of an error. */ int x509_csr_info( char *buf, size_t size, const char *prefix, const x509_csr *csr ); @@ -200,7 +217,8 @@ int x509write_csr_set_ns_cert_type( x509write_csr *ctx, unsigned char ns_cert_type ); /** - * \brief Generic function to add to or replace an extension in the CSR + * \brief Generic function to add to or replace an extension in the + * CSR * * \param ctx CSR context to use * \param oid OID of the extension diff --git a/pdns/ext/polarssl/include/polarssl/xtea.h b/pdns/ext/polarssl/include/polarssl/xtea.h index 95854d122..794c5efa3 100644 --- a/pdns/ext/polarssl/include/polarssl/xtea.h +++ b/pdns/ext/polarssl/include/polarssl/xtea.h @@ -27,7 +27,11 @@ #ifndef POLARSSL_XTEA_H #define POLARSSL_XTEA_H +#if !defined(POLARSSL_CONFIG_FILE) #include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #include @@ -60,6 +64,20 @@ typedef struct } xtea_context; +/** + * \brief Initialize XTEA context + * + * \param ctx XTEA context to be initialized + */ +void xtea_init( xtea_context *ctx ); + +/** + * \brief Clear XTEA context + * + * \param ctx XTEA context to be cleared + */ +void xtea_free( xtea_context *ctx ); + /** * \brief XTEA key schedule * diff --git a/pdns/ext/polarssl/library/Makefile.am b/pdns/ext/polarssl/library/Makefile.am index 25fbd4362..74968dedf 100644 --- a/pdns/ext/polarssl/library/Makefile.am +++ b/pdns/ext/polarssl/library/Makefile.am @@ -1,4 +1,4 @@ noinst_LTLIBRARIES=libpolarssl.la -libpolarssl_la_SOURCES=aes.c arc4.c asn1parse.c asn1write.c base64.c bignum.c blowfish.c camellia.c certs.c cipher.c cipher_wrap.c ctr_drbg.c debug.c des.c dhm.c ecdh.c ecdsa.c ecp.c entropy.c entropy_poll.c error.c gcm.c havege.c md2.c md4.c md5.c md.c md_wrap.c memory_buffer_alloc.c memory.c net.c oid.c padlock.c pbkdf2.c pem.c pk.c pkcs11.c pkcs12.c pkcs5.c pkparse.c pk_wrap.c pkwrite.c rsa.c sha1.c sha256.c sha512.c ssl_cache.c ssl_ciphersuites.c ssl_cli.c ssl_srv.c ssl_tls.c threading.c timing.c version.c x509.c x509_create.c x509_crl.c x509_crt.c x509_csr.c x509write_crt.c x509write_csr.c xtea.c +libpolarssl_la_SOURCES=aes.c aesni.c arc4.c asn1parse.c asn1write.c base64.c bignum.c blowfish.c camellia.c ccm.c certs.c cipher.c cipher_wrap.c ctr_drbg.c debug.c des.c dhm.c ecdh.c ecdsa.c ecp.c ecp_curves.c entropy.c entropy_poll.c error.c gcm.c havege.c hmac_drbg.c md2.c md4.c md5.c md.c md_wrap.c memory_buffer_alloc.c memory.c net.c oid.c padlock.c pbkdf2.c pem.c pk.c pkcs11.c pkcs12.c pkcs5.c pkparse.c pk_wrap.c pkwrite.c platform.c ripemd160.c rsa.c sha1.c sha256.c sha512.c ssl_cache.c ssl_ciphersuites.c ssl_cli.c ssl_srv.c ssl_tls.c threading.c timing.c version.c version_features.c x509.c x509_create.c x509_crl.c x509_crt.c x509_csr.c x509write_crt.c x509write_csr.c xtea.c libpolarssl_la_CPPFLAGS=-I$(srcdir)/../include -D_FILE_OFFSET_BITS=64 -Wall -W -Wdeclaration-after-statement diff --git a/pdns/ext/polarssl/library/aes.c b/pdns/ext/polarssl/library/aes.c index a3835cead..f295747c5 100644 --- a/pdns/ext/polarssl/library/aes.c +++ b/pdns/ext/polarssl/library/aes.c @@ -1,7 +1,7 @@ /* * FIPS-197 compliant AES implementation * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -29,7 +29,11 @@ * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_AES_C) @@ -37,9 +41,23 @@ #if defined(POLARSSL_PADLOCK_C) #include "polarssl/padlock.h" #endif +#if defined(POLARSSL_AESNI_C) +#include "polarssl/aesni.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif #if !defined(POLARSSL_AES_ALT) +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + /* * 32-bit integer manipulation macros (little endian) */ @@ -333,16 +351,16 @@ static const uint32_t RCON[10] = 0x0000001B, 0x00000036 }; -#else +#else /* POLARSSL_AES_ROM_TABLES */ /* * Forward S-box & tables */ static unsigned char FSb[256]; -static uint32_t FT0[256]; -static uint32_t FT1[256]; -static uint32_t FT2[256]; -static uint32_t FT3[256]; +static uint32_t FT0[256]; +static uint32_t FT1[256]; +static uint32_t FT2[256]; +static uint32_t FT3[256]; /* * Reverse S-box & tables @@ -402,10 +420,10 @@ static void aes_gen_tables( void ) { x = pow[255 - log[i]]; - y = x; y = ( (y << 1) | (y >> 7) ) & 0xFF; - x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF; - x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF; - x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF; + y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; x ^= y ^ 0x63; FSb[i] = (unsigned char) x; @@ -443,12 +461,26 @@ static void aes_gen_tables( void ) } } -#endif +#endif /* POLARSSL_AES_ROM_TABLES */ + +void aes_init( aes_context *ctx ) +{ + memset( ctx, 0, sizeof( aes_context ) ); +} + +void aes_free( aes_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( aes_context ) ); +} /* * AES key schedule (encryption) */ -int aes_setkey_enc( aes_context *ctx, const unsigned char *key, unsigned int keysize ) +int aes_setkey_enc( aes_context *ctx, const unsigned char *key, + unsigned int keysize ) { unsigned int i; uint32_t *RK; @@ -480,7 +512,12 @@ int aes_setkey_enc( aes_context *ctx, const unsigned char *key, unsigned int key #endif ctx->rk = RK = ctx->buf; - for( i = 0; i < (keysize >> 5); i++ ) +#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64) + if( aesni_supports( POLARSSL_AESNI_AES ) ) + return( aesni_setkey_enc( (unsigned char *) ctx->rk, key, keysize ) ); +#endif + + for( i = 0; i < ( keysize >> 5 ); i++ ) { GET_UINT32_LE( RK[i], key, i << 2 ); } @@ -546,10 +583,6 @@ int aes_setkey_enc( aes_context *ctx, const unsigned char *key, unsigned int key RK[15] = RK[7] ^ RK[14]; } break; - - default: - - break; } return( 0 ); @@ -558,21 +591,15 @@ int aes_setkey_enc( aes_context *ctx, const unsigned char *key, unsigned int key /* * AES key schedule (decryption) */ -int aes_setkey_dec( aes_context *ctx, const unsigned char *key, unsigned int keysize ) +int aes_setkey_dec( aes_context *ctx, const unsigned char *key, + unsigned int keysize ) { - int i, j; + int i, j, ret; aes_context cty; uint32_t *RK; uint32_t *SK; - int ret; - switch( keysize ) - { - case 128: ctx->nr = 10; break; - case 192: ctx->nr = 12; break; - case 256: ctx->nr = 14; break; - default : return( POLARSSL_ERR_AES_INVALID_KEY_LENGTH ); - } + aes_init( &cty ); #if defined(POLARSSL_PADLOCK_C) && defined(PADLOCK_ALIGN16) if( aes_padlock_ace == -1 ) @@ -584,9 +611,20 @@ int aes_setkey_dec( aes_context *ctx, const unsigned char *key, unsigned int key #endif ctx->rk = RK = ctx->buf; - ret = aes_setkey_enc( &cty, key, keysize ); - if( ret != 0 ) - return( ret ); + /* Also checks keysize */ + if( ( ret = aes_setkey_enc( &cty, key, keysize ) ) != 0 ) + goto exit; + + ctx->nr = cty.nr; + +#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64) + if( aesni_supports( POLARSSL_AESNI_AES ) ) + { + aesni_inverse_key( (unsigned char *) ctx->rk, + (const unsigned char *) cty.rk, ctx->nr ); + goto exit; + } +#endif SK = cty.rk + cty.nr * 4; @@ -611,9 +649,10 @@ int aes_setkey_dec( aes_context *ctx, const unsigned char *key, unsigned int key *RK++ = *SK++; *RK++ = *SK++; - memset( &cty, 0, sizeof( aes_context ) ); +exit: + aes_free( &cty ); - return( 0 ); + return( ret ); } #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ @@ -673,6 +712,11 @@ int aes_crypt_ecb( aes_context *ctx, int i; uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; +#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64) + if( aesni_supports( POLARSSL_AESNI_AES ) ) + return( aesni_crypt_ecb( ctx, mode, input, output ) ); +#endif + #if defined(POLARSSL_PADLOCK_C) && defined(POLARSSL_HAVE_X86) if( aes_padlock_ace ) { @@ -694,7 +738,7 @@ int aes_crypt_ecb( aes_context *ctx, if( mode == AES_DECRYPT ) { - for( i = (ctx->nr >> 1) - 1; i > 0; i-- ) + for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) { AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); @@ -728,7 +772,7 @@ int aes_crypt_ecb( aes_context *ctx, } else /* AES_ENCRYPT */ { - for( i = (ctx->nr >> 1) - 1; i > 0; i-- ) + for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) { AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); @@ -791,7 +835,7 @@ int aes_crypt_cbc( aes_context *ctx, { if( padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 ) return( 0 ); - + // If padlock data misaligned, we just fall back to // unaccelerated mode // @@ -861,7 +905,7 @@ int aes_crypt_cfb128( aes_context *ctx, *output++ = (unsigned char)( c ^ iv[n] ); iv[n] = (unsigned char) c; - n = (n + 1) & 0x0F; + n = ( n + 1 ) & 0x0F; } } else @@ -873,7 +917,7 @@ int aes_crypt_cfb128( aes_context *ctx, iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); - n = (n + 1) & 0x0F; + n = ( n + 1 ) & 0x0F; } } @@ -881,6 +925,39 @@ int aes_crypt_cfb128( aes_context *ctx, return( 0 ); } + +/* + * AES-CFB8 buffer encryption/decryption + */ +#include +int aes_crypt_cfb8( aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + unsigned char c; + unsigned char ov[17]; + + while( length-- ) + { + memcpy( ov, iv, 16 ); + aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv ); + + if( mode == AES_DECRYPT ) + ov[16] = *input; + + c = *output++ = (unsigned char)( iv[0] ^ *input++ ); + + if( mode == AES_ENCRYPT ) + ov[16] = c; + + memcpy( iv, ov + 1, 16 ); + } + + return( 0 ); +} #endif /*POLARSSL_CIPHER_MODE_CFB */ #if defined(POLARSSL_CIPHER_MODE_CTR) @@ -910,7 +987,7 @@ int aes_crypt_ctr( aes_context *ctx, c = *input++; *output++ = (unsigned char)( c ^ stream_block[n] ); - n = (n + 1) & 0x0F; + n = ( n + 1 ) & 0x0F; } *nc_off = n; @@ -918,6 +995,7 @@ int aes_crypt_ctr( aes_context *ctx, return( 0 ); } #endif /* POLARSSL_CIPHER_MODE_CTR */ + #endif /* !POLARSSL_AES_ALT */ #if defined(POLARSSL_SELF_TEST) @@ -1105,7 +1183,7 @@ static const int aes_test_ctr_len[3] = */ int aes_self_test( int verbose ) { - int i, j, u, v; + int ret = 0, i, j, u, v; unsigned char key[32]; unsigned char buf[64]; unsigned char iv[16]; @@ -1123,6 +1201,7 @@ int aes_self_test( int verbose ) aes_context ctx; memset( key, 0, 32 ); + aes_init( &ctx ); /* * ECB mode @@ -1133,8 +1212,8 @@ int aes_self_test( int verbose ) v = i & 1; if( verbose != 0 ) - printf( " AES-ECB-%3d (%s): ", 128 + u * 64, - ( v == AES_DECRYPT ) ? "dec" : "enc" ); + polarssl_printf( " AES-ECB-%3d (%s): ", 128 + u * 64, + ( v == AES_DECRYPT ) ? "dec" : "enc" ); memset( buf, 0, 16 ); @@ -1148,9 +1227,10 @@ int aes_self_test( int verbose ) if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } } else @@ -1163,18 +1243,19 @@ int aes_self_test( int verbose ) if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); #if defined(POLARSSL_CIPHER_MODE_CBC) /* @@ -1186,8 +1267,8 @@ int aes_self_test( int verbose ) v = i & 1; if( verbose != 0 ) - printf( " AES-CBC-%3d (%s): ", 128 + u * 64, - ( v == AES_DECRYPT ) ? "dec" : "enc" ); + polarssl_printf( " AES-CBC-%3d (%s): ", 128 + u * 64, + ( v == AES_DECRYPT ) ? "dec" : "enc" ); memset( iv , 0, 16 ); memset( prv, 0, 16 ); @@ -1203,9 +1284,10 @@ int aes_self_test( int verbose ) if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } } else @@ -1226,18 +1308,19 @@ int aes_self_test( int verbose ) if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); #endif /* POLARSSL_CIPHER_MODE_CBC */ #if defined(POLARSSL_CIPHER_MODE_CFB) @@ -1250,8 +1333,8 @@ int aes_self_test( int verbose ) v = i & 1; if( verbose != 0 ) - printf( " AES-CFB128-%3d (%s): ", 128 + u * 64, - ( v == AES_DECRYPT ) ? "dec" : "enc" ); + polarssl_printf( " AES-CFB128-%3d (%s): ", 128 + u * 64, + ( v == AES_DECRYPT ) ? "dec" : "enc" ); memcpy( iv, aes_test_cfb128_iv, 16 ); memcpy( key, aes_test_cfb128_key[u], 16 + u * 8 ); @@ -1267,9 +1350,10 @@ int aes_self_test( int verbose ) if( memcmp( buf, aes_test_cfb128_pt, 64 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } } else @@ -1280,18 +1364,19 @@ int aes_self_test( int verbose ) if( memcmp( buf, aes_test_cfb128_ct[u], 64 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); #endif /* POLARSSL_CIPHER_MODE_CFB */ #if defined(POLARSSL_CIPHER_MODE_CTR) @@ -1304,8 +1389,8 @@ int aes_self_test( int verbose ) v = i & 1; if( verbose != 0 ) - printf( " AES-CTR-128 (%s): ", - ( v == AES_DECRYPT ) ? "dec" : "enc" ); + polarssl_printf( " AES-CTR-128 (%s): ", + ( v == AES_DECRYPT ) ? "dec" : "enc" ); memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); memcpy( key, aes_test_ctr_key[u], 16 ); @@ -1318,14 +1403,16 @@ int aes_self_test( int verbose ) len = aes_test_ctr_len[u]; memcpy( buf, aes_test_ctr_ct[u], len ); - aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, buf, buf ); + aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); if( memcmp( buf, aes_test_ctr_pt[u], len ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } } else @@ -1333,28 +1420,35 @@ int aes_self_test( int verbose ) len = aes_test_ctr_len[u]; memcpy( buf, aes_test_ctr_pt[u], len ); - aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, buf, buf ); + aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); if( memcmp( buf, aes_test_ctr_ct[u], len ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); #endif /* POLARSSL_CIPHER_MODE_CTR */ - return( 0 ); + ret = 0; + +exit: + aes_free( &ctx ); + + return( ret ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_AES_C */ diff --git a/pdns/ext/polarssl/library/aesni.c b/pdns/ext/polarssl/library/aesni.c new file mode 100644 index 000000000..97f646ea4 --- /dev/null +++ b/pdns/ext/polarssl/library/aesni.c @@ -0,0 +1,463 @@ +/* + * AES-NI support functions + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * [AES-WP] http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-aes-instructions-set + * [CLMUL-WP] http://software.intel.com/en-us/articles/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode/ + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_AESNI_C) + +#include "polarssl/aesni.h" +#include + +#if defined(POLARSSL_HAVE_X86_64) + +/* + * AES-NI support detection routine + */ +int aesni_supports( unsigned int what ) +{ + static int done = 0; + static unsigned int c = 0; + + if( ! done ) + { + asm( "movl $1, %%eax \n\t" + "cpuid \n\t" + : "=c" (c) + : + : "eax", "ebx", "edx" ); + done = 1; + } + + return( ( c & what ) != 0 ); +} + +/* + * Binutils needs to be at least 2.19 to support AES-NI instructions. + * Unfortunately, a lot of users have a lower version now (2014-04). + * Emit bytecode directly in order to support "old" version of gas. + * + * Opcodes from the Intel architecture reference manual, vol. 3. + * We always use registers, so we don't need prefixes for memory operands. + * Operand macros are in gas order (src, dst) as opposed to Intel order + * (dst, src) in order to blend better into the surrounding assembly code. + */ +#define AESDEC ".byte 0x66,0x0F,0x38,0xDE," +#define AESDECLAST ".byte 0x66,0x0F,0x38,0xDF," +#define AESENC ".byte 0x66,0x0F,0x38,0xDC," +#define AESENCLAST ".byte 0x66,0x0F,0x38,0xDD," +#define AESIMC ".byte 0x66,0x0F,0x38,0xDB," +#define AESKEYGENA ".byte 0x66,0x0F,0x3A,0xDF," +#define PCLMULQDQ ".byte 0x66,0x0F,0x3A,0x44," + +#define xmm0_xmm0 "0xC0" +#define xmm0_xmm1 "0xC8" +#define xmm0_xmm2 "0xD0" +#define xmm0_xmm3 "0xD8" +#define xmm0_xmm4 "0xE0" +#define xmm1_xmm0 "0xC1" +#define xmm1_xmm2 "0xD1" + +/* + * AES-NI AES-ECB block en(de)cryption + */ +int aesni_crypt_ecb( aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ + asm( "movdqu (%3), %%xmm0 \n\t" // load input + "movdqu (%1), %%xmm1 \n\t" // load round key 0 + "pxor %%xmm1, %%xmm0 \n\t" // round 0 + "addq $16, %1 \n\t" // point to next round key + "subl $1, %0 \n\t" // normal rounds = nr - 1 + "test %2, %2 \n\t" // mode? + "jz 2f \n\t" // 0 = decrypt + + "1: \n\t" // encryption loop + "movdqu (%1), %%xmm1 \n\t" // load round key + AESENC xmm1_xmm0 "\n\t" // do round + "addq $16, %1 \n\t" // point to next round key + "subl $1, %0 \n\t" // loop + "jnz 1b \n\t" + "movdqu (%1), %%xmm1 \n\t" // load round key + AESENCLAST xmm1_xmm0 "\n\t" // last round + "jmp 3f \n\t" + + "2: \n\t" // decryption loop + "movdqu (%1), %%xmm1 \n\t" + AESDEC xmm1_xmm0 "\n\t" // do round + "addq $16, %1 \n\t" + "subl $1, %0 \n\t" + "jnz 2b \n\t" + "movdqu (%1), %%xmm1 \n\t" // load round key + AESDECLAST xmm1_xmm0 "\n\t" // last round + + "3: \n\t" + "movdqu %%xmm0, (%4) \n\t" // export output + : + : "r" (ctx->nr), "r" (ctx->rk), "r" (mode), "r" (input), "r" (output) + : "memory", "cc", "xmm0", "xmm1" ); + + + return( 0 ); +} + +/* + * GCM multiplication: c = a times b in GF(2^128) + * Based on [CLMUL-WP] algorithms 1 (with equation 27) and 5. + */ +void aesni_gcm_mult( unsigned char c[16], + const unsigned char a[16], + const unsigned char b[16] ) +{ + unsigned char aa[16], bb[16], cc[16]; + size_t i; + + /* The inputs are in big-endian order, so byte-reverse them */ + for( i = 0; i < 16; i++ ) + { + aa[i] = a[15 - i]; + bb[i] = b[15 - i]; + } + + asm( "movdqu (%0), %%xmm0 \n\t" // a1:a0 + "movdqu (%1), %%xmm1 \n\t" // b1:b0 + + /* + * Caryless multiplication xmm2:xmm1 = xmm0 * xmm1 + * using [CLMUL-WP] algorithm 1 (p. 13). + */ + "movdqa %%xmm1, %%xmm2 \n\t" // copy of b1:b0 + "movdqa %%xmm1, %%xmm3 \n\t" // same + "movdqa %%xmm1, %%xmm4 \n\t" // same + PCLMULQDQ xmm0_xmm1 ",0x00 \n\t" // a0*b0 = c1:c0 + PCLMULQDQ xmm0_xmm2 ",0x11 \n\t" // a1*b1 = d1:d0 + PCLMULQDQ xmm0_xmm3 ",0x10 \n\t" // a0*b1 = e1:e0 + PCLMULQDQ xmm0_xmm4 ",0x01 \n\t" // a1*b0 = f1:f0 + "pxor %%xmm3, %%xmm4 \n\t" // e1+f1:e0+f0 + "movdqa %%xmm4, %%xmm3 \n\t" // same + "psrldq $8, %%xmm4 \n\t" // 0:e1+f1 + "pslldq $8, %%xmm3 \n\t" // e0+f0:0 + "pxor %%xmm4, %%xmm2 \n\t" // d1:d0+e1+f1 + "pxor %%xmm3, %%xmm1 \n\t" // c1+e0+f1:c0 + + /* + * Now shift the result one bit to the left, + * taking advantage of [CLMUL-WP] eq 27 (p. 20) + */ + "movdqa %%xmm1, %%xmm3 \n\t" // r1:r0 + "movdqa %%xmm2, %%xmm4 \n\t" // r3:r2 + "psllq $1, %%xmm1 \n\t" // r1<<1:r0<<1 + "psllq $1, %%xmm2 \n\t" // r3<<1:r2<<1 + "psrlq $63, %%xmm3 \n\t" // r1>>63:r0>>63 + "psrlq $63, %%xmm4 \n\t" // r3>>63:r2>>63 + "movdqa %%xmm3, %%xmm5 \n\t" // r1>>63:r0>>63 + "pslldq $8, %%xmm3 \n\t" // r0>>63:0 + "pslldq $8, %%xmm4 \n\t" // r2>>63:0 + "psrldq $8, %%xmm5 \n\t" // 0:r1>>63 + "por %%xmm3, %%xmm1 \n\t" // r1<<1|r0>>63:r0<<1 + "por %%xmm4, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1 + "por %%xmm5, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1|r1>>63 + + /* + * Now reduce modulo the GCM polynomial x^128 + x^7 + x^2 + x + 1 + * using [CLMUL-WP] algorithm 5 (p. 20). + * Currently xmm2:xmm1 holds x3:x2:x1:x0 (already shifted). + */ + /* Step 2 (1) */ + "movdqa %%xmm1, %%xmm3 \n\t" // x1:x0 + "movdqa %%xmm1, %%xmm4 \n\t" // same + "movdqa %%xmm1, %%xmm5 \n\t" // same + "psllq $63, %%xmm3 \n\t" // x1<<63:x0<<63 = stuff:a + "psllq $62, %%xmm4 \n\t" // x1<<62:x0<<62 = stuff:b + "psllq $57, %%xmm5 \n\t" // x1<<57:x0<<57 = stuff:c + + /* Step 2 (2) */ + "pxor %%xmm4, %%xmm3 \n\t" // stuff:a+b + "pxor %%xmm5, %%xmm3 \n\t" // stuff:a+b+c + "pslldq $8, %%xmm3 \n\t" // a+b+c:0 + "pxor %%xmm3, %%xmm1 \n\t" // x1+a+b+c:x0 = d:x0 + + /* Steps 3 and 4 */ + "movdqa %%xmm1,%%xmm0 \n\t" // d:x0 + "movdqa %%xmm1,%%xmm4 \n\t" // same + "movdqa %%xmm1,%%xmm5 \n\t" // same + "psrlq $1, %%xmm0 \n\t" // e1:x0>>1 = e1:e0' + "psrlq $2, %%xmm4 \n\t" // f1:x0>>2 = f1:f0' + "psrlq $7, %%xmm5 \n\t" // g1:x0>>7 = g1:g0' + "pxor %%xmm4, %%xmm0 \n\t" // e1+f1:e0'+f0' + "pxor %%xmm5, %%xmm0 \n\t" // e1+f1+g1:e0'+f0'+g0' + // e0'+f0'+g0' is almost e0+f0+g0, ex\tcept for some missing + // bits carried from d. Now get those\t bits back in. + "movdqa %%xmm1,%%xmm3 \n\t" // d:x0 + "movdqa %%xmm1,%%xmm4 \n\t" // same + "movdqa %%xmm1,%%xmm5 \n\t" // same + "psllq $63, %%xmm3 \n\t" // d<<63:stuff + "psllq $62, %%xmm4 \n\t" // d<<62:stuff + "psllq $57, %%xmm5 \n\t" // d<<57:stuff + "pxor %%xmm4, %%xmm3 \n\t" // d<<63+d<<62:stuff + "pxor %%xmm5, %%xmm3 \n\t" // missing bits of d:stuff + "psrldq $8, %%xmm3 \n\t" // 0:missing bits of d + "pxor %%xmm3, %%xmm0 \n\t" // e1+f1+g1:e0+f0+g0 + "pxor %%xmm1, %%xmm0 \n\t" // h1:h0 + "pxor %%xmm2, %%xmm0 \n\t" // x3+h1:x2+h0 + + "movdqu %%xmm0, (%2) \n\t" // done + : + : "r" (aa), "r" (bb), "r" (cc) + : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" ); + + /* Now byte-reverse the outputs */ + for( i = 0; i < 16; i++ ) + c[i] = cc[15 - i]; + + return; +} + +/* + * Compute decryption round keys from encryption round keys + */ +void aesni_inverse_key( unsigned char *invkey, + const unsigned char *fwdkey, int nr ) +{ + unsigned char *ik = invkey; + const unsigned char *fk = fwdkey + 16 * nr; + + memcpy( ik, fk, 16 ); + + for( fk -= 16, ik += 16; fk > fwdkey; fk -= 16, ik += 16 ) + asm( "movdqu (%0), %%xmm0 \n\t" + AESIMC xmm0_xmm0 "\n\t" + "movdqu %%xmm0, (%1) \n\t" + : + : "r" (fk), "r" (ik) + : "memory", "xmm0" ); + + memcpy( ik, fk, 16 ); +} + +/* + * Key expansion, 128-bit case + */ +static void aesni_setkey_enc_128( unsigned char *rk, + const unsigned char *key ) +{ + asm( "movdqu (%1), %%xmm0 \n\t" // copy the original key + "movdqu %%xmm0, (%0) \n\t" // as round key 0 + "jmp 2f \n\t" // skip auxiliary routine + + /* + * Finish generating the next round key. + * + * On entry xmm0 is r3:r2:r1:r0 and xmm1 is X:stuff:stuff:stuff + * with X = rot( sub( r3 ) ) ^ RCON. + * + * On exit, xmm0 is r7:r6:r5:r4 + * with r4 = X + r0, r5 = r4 + r1, r6 = r5 + r2, r7 = r6 + r3 + * and those are written to the round key buffer. + */ + "1: \n\t" + "pshufd $0xff, %%xmm1, %%xmm1 \n\t" // X:X:X:X + "pxor %%xmm0, %%xmm1 \n\t" // X+r3:X+r2:X+r1:r4 + "pslldq $4, %%xmm0 \n\t" // r2:r1:r0:0 + "pxor %%xmm0, %%xmm1 \n\t" // X+r3+r2:X+r2+r1:r5:r4 + "pslldq $4, %%xmm0 \n\t" // etc + "pxor %%xmm0, %%xmm1 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm1, %%xmm0 \n\t" // update xmm0 for next time! + "add $16, %0 \n\t" // point to next round key + "movdqu %%xmm0, (%0) \n\t" // write it + "ret \n\t" + + /* Main "loop" */ + "2: \n\t" + AESKEYGENA xmm0_xmm1 ",0x01 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x02 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x04 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x08 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x10 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x20 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x40 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x80 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x1B \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x36 \n\tcall 1b \n\t" + : + : "r" (rk), "r" (key) + : "memory", "cc", "0" ); +} + +/* + * Key expansion, 192-bit case + */ +static void aesni_setkey_enc_192( unsigned char *rk, + const unsigned char *key ) +{ + asm( "movdqu (%1), %%xmm0 \n\t" // copy original round key + "movdqu %%xmm0, (%0) \n\t" + "add $16, %0 \n\t" + "movq 16(%1), %%xmm1 \n\t" + "movq %%xmm1, (%0) \n\t" + "add $8, %0 \n\t" + "jmp 2f \n\t" // skip auxiliary routine + + /* + * Finish generating the next 6 quarter-keys. + * + * On entry xmm0 is r3:r2:r1:r0, xmm1 is stuff:stuff:r5:r4 + * and xmm2 is stuff:stuff:X:stuff with X = rot( sub( r3 ) ) ^ RCON. + * + * On exit, xmm0 is r9:r8:r7:r6 and xmm1 is stuff:stuff:r11:r10 + * and those are written to the round key buffer. + */ + "1: \n\t" + "pshufd $0x55, %%xmm2, %%xmm2 \n\t" // X:X:X:X + "pxor %%xmm0, %%xmm2 \n\t" // X+r3:X+r2:X+r1:r4 + "pslldq $4, %%xmm0 \n\t" // etc + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm2, %%xmm0 \n\t" // update xmm0 = r9:r8:r7:r6 + "movdqu %%xmm0, (%0) \n\t" + "add $16, %0 \n\t" + "pshufd $0xff, %%xmm0, %%xmm2 \n\t" // r9:r9:r9:r9 + "pxor %%xmm1, %%xmm2 \n\t" // stuff:stuff:r9+r5:r10 + "pslldq $4, %%xmm1 \n\t" // r2:r1:r0:0 + "pxor %%xmm2, %%xmm1 \n\t" // xmm1 = stuff:stuff:r11:r10 + "movq %%xmm1, (%0) \n\t" + "add $8, %0 \n\t" + "ret \n\t" + + "2: \n\t" + AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x80 \n\tcall 1b \n\t" + + : + : "r" (rk), "r" (key) + : "memory", "cc", "0" ); +} + +/* + * Key expansion, 256-bit case + */ +static void aesni_setkey_enc_256( unsigned char *rk, + const unsigned char *key ) +{ + asm( "movdqu (%1), %%xmm0 \n\t" + "movdqu %%xmm0, (%0) \n\t" + "add $16, %0 \n\t" + "movdqu 16(%1), %%xmm1 \n\t" + "movdqu %%xmm1, (%0) \n\t" + "jmp 2f \n\t" // skip auxiliary routine + + /* + * Finish generating the next two round keys. + * + * On entry xmm0 is r3:r2:r1:r0, xmm1 is r7:r6:r5:r4 and + * xmm2 is X:stuff:stuff:stuff with X = rot( sub( r7 )) ^ RCON + * + * On exit, xmm0 is r11:r10:r9:r8 and xmm1 is r15:r14:r13:r12 + * and those have been written to the output buffer. + */ + "1: \n\t" + "pshufd $0xff, %%xmm2, %%xmm2 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm2, %%xmm0 \n\t" + "add $16, %0 \n\t" + "movdqu %%xmm0, (%0) \n\t" + + /* Set xmm2 to stuff:Y:stuff:stuff with Y = subword( r11 ) + * and proceed to generate next round key from there */ + AESKEYGENA xmm0_xmm2 ",0x00 \n\t" + "pshufd $0xaa, %%xmm2, %%xmm2 \n\t" + "pxor %%xmm1, %%xmm2 \n\t" + "pslldq $4, %%xmm1 \n\t" + "pxor %%xmm1, %%xmm2 \n\t" + "pslldq $4, %%xmm1 \n\t" + "pxor %%xmm1, %%xmm2 \n\t" + "pslldq $4, %%xmm1 \n\t" + "pxor %%xmm2, %%xmm1 \n\t" + "add $16, %0 \n\t" + "movdqu %%xmm1, (%0) \n\t" + "ret \n\t" + + /* + * Main "loop" - Generating one more key than necessary, + * see definition of aes_context.buf + */ + "2: \n\t" + AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t" + : + : "r" (rk), "r" (key) + : "memory", "cc", "0" ); +} + +/* + * Key expansion, wrapper + */ +int aesni_setkey_enc( unsigned char *rk, + const unsigned char *key, + size_t bits ) +{ + switch( bits ) + { + case 128: aesni_setkey_enc_128( rk, key ); break; + case 192: aesni_setkey_enc_192( rk, key ); break; + case 256: aesni_setkey_enc_256( rk, key ); break; + default : return( POLARSSL_ERR_AES_INVALID_KEY_LENGTH ); + } + + return( 0 ); +} + +#endif /* POLARSSL_HAVE_X86_64 */ + +#endif /* POLARSSL_AESNI_C */ diff --git a/pdns/ext/polarssl/library/arc4.c b/pdns/ext/polarssl/library/arc4.c index 85b78f5ba..54e89ea88 100644 --- a/pdns/ext/polarssl/library/arc4.c +++ b/pdns/ext/polarssl/library/arc4.c @@ -1,7 +1,7 @@ /* * An implementation of the ARCFOUR algorithm * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -28,18 +28,47 @@ * http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0 */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_ARC4_C) #include "polarssl/arc4.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + #if !defined(POLARSSL_ARC4_ALT) +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +void arc4_init( arc4_context *ctx ) +{ + memset( ctx, 0, sizeof( arc4_context ) ); +} + +void arc4_free( arc4_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( arc4_context ) ); +} + /* * ARC4 key schedule */ -void arc4_setup( arc4_context *ctx, const unsigned char *key, unsigned int keylen ) +void arc4_setup( arc4_context *ctx, const unsigned char *key, + unsigned int keylen ) { int i, j, a; unsigned int k; @@ -135,15 +164,17 @@ static const unsigned char arc4_test_ct[3][8] = */ int arc4_self_test( int verbose ) { - int i; + int i, ret = 0; unsigned char ibuf[8]; unsigned char obuf[8]; arc4_context ctx; + arc4_init( &ctx ); + for( i = 0; i < 3; i++ ) { if( verbose != 0 ) - printf( " ARC4 test #%d: ", i + 1 ); + polarssl_printf( " ARC4 test #%d: ", i + 1 ); memcpy( ibuf, arc4_test_pt[i], 8 ); @@ -153,21 +184,25 @@ int arc4_self_test( int verbose ) if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); - return( 0 ); +exit: + arc4_free( &ctx ); + + return( ret ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_ARC4_C */ diff --git a/pdns/ext/polarssl/library/asn1parse.c b/pdns/ext/polarssl/library/asn1parse.c index 957359917..97443529a 100644 --- a/pdns/ext/polarssl/library/asn1parse.c +++ b/pdns/ext/polarssl/library/asn1parse.c @@ -1,7 +1,7 @@ /* * Generic ASN.1 parsing * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,7 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_ASN1_PARSE_C) @@ -33,8 +37,8 @@ #include "polarssl/bignum.h" #endif -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else #define polarssl_malloc malloc #define polarssl_free free @@ -87,7 +91,8 @@ int asn1_get_len( unsigned char **p, if( ( end - *p ) < 5 ) return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); - *len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) | (*p)[4]; + *len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) | + (*p)[4]; (*p) += 5; break; @@ -189,7 +194,7 @@ int asn1_get_bitstring( unsigned char **p, const unsigned char *end, return( ret ); /* Check length, subtract one for actual bit string length */ - if ( bs->len < 1 ) + if( bs->len < 1 ) return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); bs->len -= 1; @@ -206,7 +211,7 @@ int asn1_get_bitstring( unsigned char **p, const unsigned char *end, if( *p != end ) return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); - return 0; + return( 0 ); } /* @@ -260,7 +265,7 @@ int asn1_get_sequence_of( unsigned char **p, *p += buf->len; /* Allocate and assign next pointer */ - if (*p < end) + if( *p < end ) { cur->next = (asn1_sequence *) polarssl_malloc( sizeof( asn1_sequence ) ); @@ -383,4 +388,4 @@ asn1_named_data *asn1_find_named_data( asn1_named_data *list, return( list ); } -#endif +#endif /* POLARSSL_ASN1_PARSE_C */ diff --git a/pdns/ext/polarssl/library/asn1write.c b/pdns/ext/polarssl/library/asn1write.c index 32d1c736f..ebc0e9766 100644 --- a/pdns/ext/polarssl/library/asn1write.c +++ b/pdns/ext/polarssl/library/asn1write.c @@ -1,7 +1,7 @@ /* * ASN.1 buffer writing functionality * - * Copyright (C) 2006-2012, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,14 +23,18 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_ASN1_WRITE_C) #include "polarssl/asn1write.h" -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else #include #define polarssl_malloc malloc @@ -109,12 +113,12 @@ int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X ) return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); (*p) -= len; - mpi_write_binary( X, *p, len ); + MPI_CHK( mpi_write_binary( X, *p, len ) ); // DER format assumes 2s complement for numbers, so the leftmost bit // should be 0 for positive numbers and 1 for negative numbers. // - if ( X->s ==1 && **p & 0x80 ) + if( X->s ==1 && **p & 0x80 ) { if( *p - start < 1 ) return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); @@ -126,7 +130,10 @@ int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X ) ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) ); - return( (int) len ); + ret = (int) len; + +cleanup: + return( ret ); } #endif /* POLARSSL_BIGNUM_C */ @@ -210,7 +217,7 @@ int asn1_write_int( unsigned char **p, unsigned char *start, int val ) len += 1; *--(*p) = val; - if ( val > 0 && **p & 0x80 ) + if( val > 0 && **p & 0x80 ) { if( *p - start < 1 ) return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); @@ -356,4 +363,4 @@ asn1_named_data *asn1_store_named_data( asn1_named_data **head, return( cur ); } -#endif +#endif /* POLARSSL_ASN1_WRITE_C */ diff --git a/pdns/ext/polarssl/library/base64.c b/pdns/ext/polarssl/library/base64.c index 3b4376dac..39a8323e8 100644 --- a/pdns/ext/polarssl/library/base64.c +++ b/pdns/ext/polarssl/library/base64.c @@ -1,7 +1,7 @@ /* * RFC 1521 base64 encoding/decoding * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,7 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_BASE64_C) @@ -36,6 +40,12 @@ typedef UINT32 uint32_t; #include #endif +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + static const unsigned char base64_enc_map[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', @@ -77,9 +87,9 @@ int base64_encode( unsigned char *dst, size_t *dlen, if( slen == 0 ) return( 0 ); - n = (slen << 3) / 6; + n = ( slen << 3 ) / 6; - switch( (slen << 3) - (n * 6) ) + switch( ( slen << 3 ) - ( n * 6 ) ) { case 2: n += 3; break; case 4: n += 2; break; @@ -92,7 +102,7 @@ int base64_encode( unsigned char *dst, size_t *dlen, return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); } - n = (slen / 3) * 3; + n = ( slen / 3 ) * 3; for( i = 0, p = dst; i < n; i += 3 ) { @@ -109,12 +119,12 @@ int base64_encode( unsigned char *dst, size_t *dlen, if( i < slen ) { C1 = *src++; - C2 = ((i + 1) < slen) ? *src++ : 0; + C2 = ( ( i + 1 ) < slen ) ? *src++ : 0; *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; - if( (i + 1) < slen ) + if( ( i + 1 ) < slen ) *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F]; else *p++ = '='; @@ -161,7 +171,8 @@ int base64_decode( unsigned char *dst, size_t *dlen, if( n == 0 ) return( 0 ); - n = ((n * 6) + 7) >> 3; + n = ( ( n * 6 ) + 7 ) >> 3; + n -= j; if( dst == NULL || *dlen < n ) { @@ -175,7 +186,7 @@ int base64_decode( unsigned char *dst, size_t *dlen, continue; j -= ( base64_dec_map[*src] == 64 ); - x = (x << 6) | ( base64_dec_map[*src] & 0x3F ); + x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F ); if( ++n == 4 ) { @@ -222,7 +233,7 @@ int base64_self_test( int verbose ) unsigned char buffer[128]; if( verbose != 0 ) - printf( " Base64 encoding test: " ); + polarssl_printf( " Base64 encoding test: " ); len = sizeof( buffer ); src = base64_test_dec; @@ -231,13 +242,13 @@ int base64_self_test( int verbose ) memcmp( base64_test_enc, buffer, 88 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) - printf( "passed\n Base64 decoding test: " ); + polarssl_printf( "passed\n Base64 decoding test: " ); len = sizeof( buffer ); src = base64_test_enc; @@ -246,17 +257,17 @@ int base64_self_test( int verbose ) memcmp( base64_test_dec, buffer, 64 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) - printf( "passed\n\n" ); + polarssl_printf( "passed\n\n" ); return( 0 ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_BASE64_C */ diff --git a/pdns/ext/polarssl/library/bignum.c b/pdns/ext/polarssl/library/bignum.c index 2a97a5902..80cf0f800 100644 --- a/pdns/ext/polarssl/library/bignum.c +++ b/pdns/ext/polarssl/library/bignum.c @@ -1,7 +1,7 @@ /* * Multi-precision integer library * - * Copyright (C) 2006-2010, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -30,22 +30,32 @@ * http://math.libtomcrypt.com/files/tommath.pdf */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_BIGNUM_C) #include "polarssl/bignum.h" #include "polarssl/bn_mul.h" -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else +#define polarssl_printf printf #define polarssl_malloc malloc #define polarssl_free free #endif #include +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + #define ciL (sizeof(t_uint)) /* chars in limb */ #define biL (ciL << 3) /* bits in limb */ #define biH (ciL << 2) /* half limb size */ @@ -79,7 +89,7 @@ void mpi_free( mpi *X ) if( X->p != NULL ) { - memset( X->p, 0, X->n * ciL ); + polarssl_zeroize( X->p, X->n * ciL ); polarssl_free( X->p ); } @@ -108,7 +118,7 @@ int mpi_grow( mpi *X, size_t nblimbs ) if( X->p != NULL ) { memcpy( p, X->p, X->n * ciL ); - memset( X->p, 0, X->n * ciL ); + polarssl_zeroize( X->p, X->n * ciL ); polarssl_free( X->p ); } @@ -119,6 +129,45 @@ int mpi_grow( mpi *X, size_t nblimbs ) return( 0 ); } +/* + * Resize down as much as possible, + * while keeping at least the specified number of limbs + */ +int mpi_shrink( mpi *X, size_t nblimbs ) +{ + t_uint *p; + size_t i; + + /* Actually resize up in this case */ + if( X->n <= nblimbs ) + return( mpi_grow( X, nblimbs ) ); + + for( i = X->n - 1; i > 0; i-- ) + if( X->p[i] != 0 ) + break; + i++; + + if( i < nblimbs ) + i = nblimbs; + + if( ( p = (t_uint *) polarssl_malloc( i * ciL ) ) == NULL ) + return( POLARSSL_ERR_MPI_MALLOC_FAILED ); + + memset( p, 0, i * ciL ); + + if( X->p != NULL ) + { + memcpy( p, X->p, i * ciL ); + polarssl_zeroize( X->p, X->n * ciL ); + polarssl_free( X->p ); + } + + X->n = i; + X->p = p; + + return( 0 ); +} + /* * Copy the contents of Y into X */ @@ -165,6 +214,70 @@ void mpi_swap( mpi *X, mpi *Y ) memcpy( Y, &T, sizeof( mpi ) ); } +/* + * Conditionally assign X = Y, without leaking information + * about whether the assignment was made or not. + * (Leaking information about the respective sizes of X and Y is ok however.) + */ +int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign ) +{ + int ret = 0; + size_t i; + + /* make sure assign is 0 or 1 */ + assign = ( assign != 0 ); + + MPI_CHK( mpi_grow( X, Y->n ) ); + + X->s = X->s * ( 1 - assign ) + Y->s * assign; + + for( i = 0; i < Y->n; i++ ) + X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign; + + for( ; i < X->n; i++ ) + X->p[i] *= ( 1 - assign ); + +cleanup: + return( ret ); +} + +/* + * Conditionally swap X and Y, without leaking information + * about whether the swap was made or not. + * Here it is not ok to simply swap the pointers, which whould lead to + * different memory access patterns when X and Y are used afterwards. + */ +int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char swap ) +{ + int ret, s; + size_t i; + t_uint tmp; + + if( X == Y ) + return( 0 ); + + /* make sure swap is 0 or 1 */ + swap = ( swap != 0 ); + + MPI_CHK( mpi_grow( X, Y->n ) ); + MPI_CHK( mpi_grow( Y, X->n ) ); + + s = X->s; + X->s = X->s * ( 1 - swap ) + Y->s * swap; + Y->s = Y->s * ( 1 - swap ) + s * swap; + + + for( i = 0; i < X->n; i++ ) + { + tmp = X->p[i]; + X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap; + Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap; + } + +cleanup: + return( ret ); +} + /* * Set value from integer */ @@ -191,7 +304,7 @@ int mpi_get_bit( const mpi *X, size_t pos ) if( X->n * biL <= pos ) return( 0 ); - return ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01; + return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 ); } /* @@ -204,20 +317,21 @@ int mpi_set_bit( mpi *X, size_t pos, unsigned char val ) size_t idx = pos % biL; if( val != 0 && val != 1 ) - return POLARSSL_ERR_MPI_BAD_INPUT_DATA; - + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + if( X->n * biL <= pos ) { if( val == 0 ) - return ( 0 ); + return( 0 ); MPI_CHK( mpi_grow( X, off + 1 ) ); } - X->p[off] = ( X->p[off] & ~( 0x01 << idx ) ) | ( val << idx ); + X->p[off] &= ~( (t_uint) 0x01 << idx ); + X->p[off] |= (t_uint) val << idx; cleanup: - + return( ret ); } @@ -312,7 +426,7 @@ int mpi_read_string( mpi *X, int radix, const char *s ) } MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) ); - X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 ); + X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 ); } } else @@ -416,7 +530,7 @@ int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen ) { c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF; - if( c == 0 && k == 0 && ( i + j + 3 ) != 0 ) + if( c == 0 && k == 0 && ( i + j ) != 2 ) continue; *(p++) = "0123456789ABCDEF" [c / 16]; @@ -512,7 +626,7 @@ int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout ) return( POLARSSL_ERR_MPI_FILE_IO_ERROR ); } else - printf( "%s%s", p, s ); + polarssl_printf( "%s%s", p, s ); cleanup: @@ -751,7 +865,7 @@ int mpi_add_abs( mpi *X, const mpi *A, const mpi *B ) if( X != A ) MPI_CHK( mpi_copy( X, A ) ); - + /* * X should always be positive as a result of unsigned additions. */ @@ -974,7 +1088,7 @@ void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b ) MULADDC_CORE MULADDC_STOP } -#else +#else /* MULADDC_HUIT */ for( ; i >= 16; i -= 16 ) { MULADDC_INIT @@ -1007,7 +1121,7 @@ void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b ) MULADDC_CORE MULADDC_STOP } -#endif +#endif /* MULADDC_HUIT */ t++; @@ -1112,14 +1226,14 @@ int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ) n = X.n - 1; t = Y.n - 1; - MPI_CHK( mpi_shift_l( &Y, biL * (n - t) ) ); + MPI_CHK( mpi_shift_l( &Y, biL * ( n - t ) ) ); while( mpi_cmp_mpi( &X, &Y ) >= 0 ) { Z.p[n - t]++; - mpi_sub_mpi( &X, &X, &Y ); + MPI_CHK( mpi_sub_mpi( &X, &X, &Y ) ); } - mpi_shift_r( &Y, biL * (n - t) ); + MPI_CHK( mpi_shift_r( &Y, biL * ( n - t ) ) ); for( i = n; i > t ; i-- ) { @@ -1127,14 +1241,24 @@ int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ) Z.p[i - t - 1] = ~0; else { -#if defined(POLARSSL_HAVE_UDBL) + /* + * The version of Clang shipped by Apple with Mavericks around + * 2014-03 can't handle 128-bit division properly. Disable + * 128-bits division for this version. Let's be optimistic and + * assume it'll be fixed in the next minor version (next + * patchlevel is probably a bit too optimistic). + */ +#if defined(POLARSSL_HAVE_UDBL) && \ + ! ( defined(__x86_64__) && defined(__APPLE__) && \ + defined(__clang_major__) && __clang_major__ == 5 && \ + defined(__clang_minor__) && __clang_minor__ == 0 ) t_udbl r; r = (t_udbl) X.p[i] << biL; r |= (t_udbl) X.p[i - 1]; r /= Y.p[t]; - if( r > ((t_udbl) 1 << biL) - 1) - r = ((t_udbl) 1 << biL) - 1; + if( r > ( (t_udbl) 1 << biL ) - 1 ) + r = ( (t_udbl) 1 << biL ) - 1; Z.p[i - t - 1] = (t_uint) r; #else @@ -1177,7 +1301,7 @@ int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ) r0 -= m; Z.p[i - t - 1] = ( q1 << biH ) | q0; -#endif +#endif /* POLARSSL_HAVE_UDBL && !64-bit Apple with Clang 5.0 */ } Z.p[i - t - 1]++; @@ -1186,25 +1310,25 @@ int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ) Z.p[i - t - 1]--; MPI_CHK( mpi_lset( &T1, 0 ) ); - T1.p[0] = (t < 1) ? 0 : Y.p[t - 1]; + T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1]; T1.p[1] = Y.p[t]; MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) ); MPI_CHK( mpi_lset( &T2, 0 ) ); - T2.p[0] = (i < 2) ? 0 : X.p[i - 2]; - T2.p[1] = (i < 1) ? 0 : X.p[i - 1]; + T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2]; + T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1]; T2.p[2] = X.p[i]; } while( mpi_cmp_mpi( &T1, &T2 ) > 0 ); MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) ); - MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) ); + MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) ); MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) ); if( mpi_cmp_int( &X, 0 ) < 0 ) { MPI_CHK( mpi_copy( &T1, &Y ) ); - MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) ); + MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) ); MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) ); Z.p[i - t - 1]--; } @@ -1212,15 +1336,15 @@ int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ) if( Q != NULL ) { - mpi_copy( Q, &Z ); + MPI_CHK( mpi_copy( Q, &Z ) ); Q->s = A->s * B->s; } if( R != NULL ) { - mpi_shift_r( &X, k ); + MPI_CHK( mpi_shift_r( &X, k ) ); X.s = A->s; - mpi_copy( R, &X ); + MPI_CHK( mpi_copy( R, &X ) ); if( mpi_cmp_int( R, 0 ) == 0 ) R->s = 1; @@ -1258,7 +1382,7 @@ int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B ) int ret; if( mpi_cmp_int( B, 0 ) < 0 ) - return POLARSSL_ERR_MPI_NEGATIVE_VALUE; + return( POLARSSL_ERR_MPI_NEGATIVE_VALUE ); MPI_CHK( mpi_div_mpi( NULL, R, A, B ) ); @@ -1285,7 +1409,7 @@ int mpi_mod_int( t_uint *r, const mpi *A, t_sint b ) return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); if( b < 0 ) - return POLARSSL_ERR_MPI_NEGATIVE_VALUE; + return( POLARSSL_ERR_MPI_NEGATIVE_VALUE ); /* * handle trivial cases @@ -1336,14 +1460,13 @@ int mpi_mod_int( t_uint *r, const mpi *A, t_sint b ) static void mpi_montg_init( t_uint *mm, const mpi *N ) { t_uint x, m0 = N->p[0]; + unsigned int i; x = m0; x += ( ( m0 + 2 ) & 4 ) << 1; - x *= ( 2 - ( m0 * x ) ); - if( biL >= 16 ) x *= ( 2 - ( m0 * x ) ); - if( biL >= 32 ) x *= ( 2 - ( m0 * x ) ); - if( biL >= 64 ) x *= ( 2 - ( m0 * x ) ); + for( i = biL; i >= 8; i /= 2 ) + x *= ( 2 - ( m0 * x ) ); *mm = ~x + 1; } @@ -1351,7 +1474,8 @@ static void mpi_montg_init( t_uint *mm, const mpi *N ) /* * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) */ -static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mpi *T ) +static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, + const mpi *T ) { size_t i, n, m; t_uint u0, u1, *d; @@ -1376,7 +1500,7 @@ static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mp *d++ = u0; d[n + 1] = 0; } - memcpy( A->p, d, (n + 1) * ciL ); + memcpy( A->p, d, ( n + 1 ) * ciL ); if( mpi_cmp_abs( A, N ) >= 0 ) mpi_sub_hlp( n, N->p, A->p ); @@ -1423,6 +1547,7 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ) */ mpi_montg_init( &mm, N ); mpi_init( &RR ); mpi_init( &T ); + mpi_init( &Apos ); memset( W, 0, sizeof( W ) ); i = mpi_msb( E ); @@ -1442,8 +1567,6 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ) * Compensate for negative A (and correct at the end) */ neg = ( A->s == -1 ); - - mpi_init( &Apos ); if( neg ) { MPI_CHK( mpi_copy( &Apos, A ) ); @@ -1470,8 +1593,9 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ) * W[1] = A * R^2 * R^-1 mod N = A * R mod N */ if( mpi_cmp_mpi( A, N ) >= 0 ) - mpi_mod_mpi( &W[1], A, N ); - else mpi_copy( &W[1], A ); + MPI_CHK( mpi_mod_mpi( &W[1], A, N ) ); + else + MPI_CHK( mpi_copy( &W[1], A ) ); mpi_montmul( &W[1], &RR, N, mm, &T ); @@ -1486,7 +1610,7 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ) /* * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1) */ - j = one << (wsize - 1); + j = one << ( wsize - 1 ); MPI_CHK( mpi_grow( &W[j], N->n + 1 ) ); MPI_CHK( mpi_copy( &W[j], &W[1] ) ); @@ -1497,7 +1621,7 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ) /* * W[i] = W[i - 1] * W[1] */ - for( i = j + 1; i < (one << wsize); i++ ) + for( i = j + 1; i < ( one << wsize ); i++ ) { MPI_CHK( mpi_grow( &W[i], N->n + 1 ) ); MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) ); @@ -1549,7 +1673,7 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ) state = 2; nbits++; - wbits |= (ei << (wsize - nbits)); + wbits |= ( ei << ( wsize - nbits ) ); if( nbits == wsize ) { @@ -1579,7 +1703,7 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ) wbits <<= 1; - if( (wbits & (one << wsize)) != 0 ) + if( ( wbits & ( one << wsize ) ) != 0 ) mpi_montmul( X, &W[1], N, mm, &T ); } @@ -1591,17 +1715,17 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ) if( neg ) { X->s = -1; - mpi_add_mpi( X, N, X ); + MPI_CHK( mpi_add_mpi( X, N, X ) ); } cleanup: - for( i = (one << (wsize - 1)); i < (one << wsize); i++ ) + for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ ) mpi_free( &W[i] ); mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos ); - if( _RR == NULL ) + if( _RR == NULL || _RR->p == NULL ) mpi_free( &RR ); return( ret ); @@ -1624,7 +1748,7 @@ int mpi_gcd( mpi *G, const mpi *A, const mpi *B ) lz = mpi_lsb( &TA ); lzt = mpi_lsb( &TB ); - if ( lzt < lz ) + if( lzt < lz ) lz = lzt; MPI_CHK( mpi_shift_r( &TA, lz ) ); @@ -1659,16 +1783,25 @@ cleanup: return( ret ); } +/* + * Fill X with size bytes of random. + * + * Use a temporary bytes representation to make sure the result is the same + * regardless of the platform endianness (useful when f_rng is actually + * deterministic, eg for tests). + */ int mpi_fill_random( mpi *X, size_t size, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret; + unsigned char buf[POLARSSL_MPI_MAX_SIZE]; - MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( size ) ) ); - MPI_CHK( mpi_lset( X, 0 ) ); + if( size > POLARSSL_MPI_MAX_SIZE ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); - MPI_CHK( f_rng( p_rng, (unsigned char *) X->p, size ) ); + MPI_CHK( f_rng( p_rng, buf, size ) ); + MPI_CHK( mpi_read_binary( X, buf, size ) ); cleanup: return( ret ); @@ -1797,40 +1930,27 @@ static const int small_prime[] = }; /* - * Miller-Rabin primality test (HAC 4.24) + * Small divisors test (X must be positive) + * + * Return values: + * 0: no small factor (possible prime, more tests needed) + * 1: certain prime + * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime + * other negative: error */ -int mpi_is_prime( mpi *X, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) +static int mpi_check_small_factors( const mpi *X ) { - int ret, xs; - size_t i, j, n, s; - mpi W, R, T, A, RR; - - if( mpi_cmp_int( X, 0 ) == 0 || - mpi_cmp_int( X, 1 ) == 0 ) - return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); - - if( mpi_cmp_int( X, 2 ) == 0 ) - return( 0 ); - - mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A ); - mpi_init( &RR ); - - xs = X->s; X->s = 1; + int ret = 0; + size_t i; + t_uint r; - /* - * test trivial factors first - */ if( ( X->p[0] & 1 ) == 0 ) return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); for( i = 0; small_prime[i] > 0; i++ ) { - t_uint r; - if( mpi_cmp_int( X, small_prime[i] ) <= 0 ) - return( 0 ); + return( 1 ); MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) ); @@ -1838,6 +1958,24 @@ int mpi_is_prime( mpi *X, return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); } +cleanup: + return( ret ); +} + +/* + * Miller-Rabin pseudo-primality test (HAC 4.24) + */ +static int mpi_miller_rabin( const mpi *X, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t i, j, n, s; + mpi W, R, T, A, RR; + + mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A ); + mpi_init( &RR ); + /* * W = |X| - 1 * R = W >> lsb( W ) @@ -1905,15 +2043,40 @@ int mpi_is_prime( mpi *X, } cleanup: - - X->s = xs; - mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A ); mpi_free( &RR ); return( ret ); } +/* + * Pseudo-primality test: small factors, then Miller-Rabin + */ +int mpi_is_prime( mpi *X, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + const mpi XX = { 1, X->n, X->p }; /* Abs(X) */ + + if( mpi_cmp_int( &XX, 0 ) == 0 || + mpi_cmp_int( &XX, 1 ) == 0 ) + return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); + + if( mpi_cmp_int( &XX, 2 ) == 0 ) + return( 0 ); + + if( ( ret = mpi_check_small_factors( &XX ) ) != 0 ) + { + if( ret == 1 ) + return( 0 ); + + return( ret ); + } + + return( mpi_miller_rabin( &XX, f_rng, p_rng ) ); +} + /* * Prime number generation */ @@ -1923,6 +2086,7 @@ int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag, { int ret; size_t k, n; + t_uint r; mpi Y; if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS ) @@ -1952,26 +2116,45 @@ int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag, } else { - MPI_CHK( mpi_sub_int( &Y, X, 1 ) ); + /* + * An necessary condition for Y and X = 2Y + 1 to be prime + * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3). + * Make sure it is satisfied, while keeping X = 3 mod 4 + */ + MPI_CHK( mpi_mod_int( &r, X, 3 ) ); + if( r == 0 ) + MPI_CHK( mpi_add_int( X, X, 8 ) ); + else if( r == 1 ) + MPI_CHK( mpi_add_int( X, X, 4 ) ); + + /* Set Y = (X-1) / 2, which is X / 2 because X is odd */ + MPI_CHK( mpi_copy( &Y, X ) ); MPI_CHK( mpi_shift_r( &Y, 1 ) ); while( 1 ) { - if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 ) + /* + * First, check small factors for X and Y + * before doing Miller-Rabin on any of them + */ + if( ( ret = mpi_check_small_factors( X ) ) == 0 && + ( ret = mpi_check_small_factors( &Y ) ) == 0 && + ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 && + ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 ) { - if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 ) - break; - - if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) - goto cleanup; + break; } if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) goto cleanup; - MPI_CHK( mpi_add_int( &Y, X, 1 ) ); - MPI_CHK( mpi_add_int( X, X, 2 ) ); - MPI_CHK( mpi_shift_r( &Y, 1 ) ); + /* + * Next candidates. We want to preserve Y = (X-1) / 2 and + * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3) + * so up Y by 6 and X by 12. + */ + MPI_CHK( mpi_add_int( X, X, 12 ) ); + MPI_CHK( mpi_add_int( &Y, &Y, 6 ) ); } } @@ -2035,18 +2218,19 @@ int mpi_self_test( int verbose ) "30879B56C61DE584A0F53A2447A51E" ) ); if( verbose != 0 ) - printf( " MPI test #1 (mul_mpi): " ); + polarssl_printf( " MPI test #1 (mul_mpi): " ); if( mpi_cmp_mpi( &X, &U ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto cleanup; } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) ); @@ -2059,19 +2243,20 @@ int mpi_self_test( int verbose ) "9EE50D0657C77F374E903CDFA4C642" ) ); if( verbose != 0 ) - printf( " MPI test #2 (div_mpi): " ); + polarssl_printf( " MPI test #2 (div_mpi): " ); if( mpi_cmp_mpi( &X, &U ) != 0 || mpi_cmp_mpi( &Y, &V ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto cleanup; } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) ); @@ -2081,18 +2266,19 @@ int mpi_self_test( int verbose ) "325D24D6A3C12710F10A09FA08AB87" ) ); if( verbose != 0 ) - printf( " MPI test #3 (exp_mod): " ); + polarssl_printf( " MPI test #3 (exp_mod): " ); if( mpi_cmp_mpi( &X, &U ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto cleanup; } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); MPI_CHK( mpi_inv_mod( &X, &A, &N ) ); @@ -2102,55 +2288,57 @@ int mpi_self_test( int verbose ) "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) ); if( verbose != 0 ) - printf( " MPI test #4 (inv_mod): " ); + polarssl_printf( " MPI test #4 (inv_mod): " ); if( mpi_cmp_mpi( &X, &U ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto cleanup; } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); if( verbose != 0 ) - printf( " MPI test #5 (simple gcd): " ); + polarssl_printf( " MPI test #5 (simple gcd): " ); - for ( i = 0; i < GCD_PAIR_COUNT; i++) + for( i = 0; i < GCD_PAIR_COUNT; i++ ) { MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) ); MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) ); - MPI_CHK( mpi_gcd( &A, &X, &Y ) ); + MPI_CHK( mpi_gcd( &A, &X, &Y ) ); - if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 ) - { - if( verbose != 0 ) - printf( "failed at %d\n", i ); + if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed at %d\n", i ); - return( 1 ); - } + ret = 1; + goto cleanup; + } } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); cleanup: if( ret != 0 && verbose != 0 ) - printf( "Unexpected error, return code = %08X\n", ret ); + polarssl_printf( "Unexpected error, return code = %08X\n", ret ); mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X ); mpi_free( &Y ); mpi_free( &U ); mpi_free( &V ); if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); return( ret ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_BIGNUM_C */ diff --git a/pdns/ext/polarssl/library/blowfish.c b/pdns/ext/polarssl/library/blowfish.c index 910d610d1..87396dc22 100644 --- a/pdns/ext/polarssl/library/blowfish.c +++ b/pdns/ext/polarssl/library/blowfish.c @@ -1,7 +1,7 @@ /* * Blowfish implementation * - * Copyright (C) 2012-2013, Brainspark B.V. + * Copyright (C) 2012-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -29,7 +29,11 @@ * */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_BLOWFISH_C) @@ -37,6 +41,11 @@ #if !defined(POLARSSL_BLOWFISH_ALT) +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + /* * 32-bit integer manipulation macros (big endian) */ @@ -71,7 +80,7 @@ static const uint32_t P[BLOWFISH_ROUNDS + 2] = { /* declarations of data at the end of this file */ static const uint32_t S[4][256]; -static uint32_t F(blowfish_context *ctx, uint32_t x) +static uint32_t F( blowfish_context *ctx, uint32_t x ) { unsigned short a, b, c, d; uint32_t y; @@ -87,10 +96,10 @@ static uint32_t F(blowfish_context *ctx, uint32_t x) y = y ^ ctx->S[2][c]; y = y + ctx->S[3][d]; - return y; + return( y ); } -static void blowfish_enc(blowfish_context *ctx, uint32_t *xl, uint32_t *xr) +static void blowfish_enc( blowfish_context *ctx, uint32_t *xl, uint32_t *xr ) { uint32_t Xl, Xr, temp; short i; @@ -98,10 +107,10 @@ static void blowfish_enc(blowfish_context *ctx, uint32_t *xl, uint32_t *xr) Xl = *xl; Xr = *xr; - for (i = 0; i < BLOWFISH_ROUNDS; ++i) + for( i = 0; i < BLOWFISH_ROUNDS; ++i ) { Xl = Xl ^ ctx->P[i]; - Xr = F(ctx, Xl) ^ Xr; + Xr = F( ctx, Xl ) ^ Xr; temp = Xl; Xl = Xr; @@ -119,7 +128,7 @@ static void blowfish_enc(blowfish_context *ctx, uint32_t *xl, uint32_t *xr) *xr = Xr; } -static void blowfish_dec(blowfish_context *ctx, uint32_t *xl, uint32_t *xr) +static void blowfish_dec( blowfish_context *ctx, uint32_t *xl, uint32_t *xr ) { uint32_t Xl, Xr, temp; short i; @@ -127,10 +136,10 @@ static void blowfish_dec(blowfish_context *ctx, uint32_t *xl, uint32_t *xr) Xl = *xl; Xr = *xr; - for (i = BLOWFISH_ROUNDS + 1; i > 1; --i) + for( i = BLOWFISH_ROUNDS + 1; i > 1; --i ) { Xl = Xl ^ ctx->P[i]; - Xr = F(ctx, Xl) ^ Xr; + Xr = F( ctx, Xl ) ^ Xr; temp = Xl; Xl = Xr; @@ -148,23 +157,37 @@ static void blowfish_dec(blowfish_context *ctx, uint32_t *xl, uint32_t *xr) *xr = Xr; } +void blowfish_init( blowfish_context *ctx ) +{ + memset( ctx, 0, sizeof( blowfish_context ) ); +} + +void blowfish_free( blowfish_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( blowfish_context ) ); +} + /* * Blowfish key schedule */ -int blowfish_setkey( blowfish_context *ctx, const unsigned char *key, unsigned int keysize ) +int blowfish_setkey( blowfish_context *ctx, const unsigned char *key, + unsigned int keysize ) { unsigned int i, j, k; uint32_t data, datal, datar; if( keysize < BLOWFISH_MIN_KEY || keysize > BLOWFISH_MAX_KEY || - ( keysize % 8 ) ) + ( keysize % 8 ) ) { - return POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH; + return( POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH ); } keysize >>= 3; - for( i = 0; i < 4; i++ ) + for( i = 0; i < 4; i++ ) { for( j = 0; j < 256; j++ ) ctx->S[i][j] = S[i][j]; @@ -215,16 +238,16 @@ int blowfish_crypt_ecb( blowfish_context *ctx, { uint32_t X0, X1; - GET_UINT32_BE( X0, input, 0 ); - GET_UINT32_BE( X1, input, 4 ); + GET_UINT32_BE( X0, input, 0 ); + GET_UINT32_BE( X1, input, 4 ); if( mode == BLOWFISH_DECRYPT ) { - blowfish_dec(ctx, &X0, &X1); + blowfish_dec( ctx, &X0, &X1 ); } else /* BLOWFISH_ENCRYPT */ { - blowfish_enc(ctx, &X0, &X1); + blowfish_enc( ctx, &X0, &X1 ); } PUT_UINT32_BE( X0, output, 0 ); @@ -313,7 +336,7 @@ int blowfish_crypt_cfb64( blowfish_context *ctx, *output++ = (unsigned char)( c ^ iv[n] ); iv[n] = (unsigned char) c; - n = (n + 1) % BLOWFISH_BLOCKSIZE; + n = ( n + 1 ) % BLOWFISH_BLOCKSIZE; } } else @@ -325,7 +348,7 @@ int blowfish_crypt_cfb64( blowfish_context *ctx, iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); - n = (n + 1) % BLOWFISH_BLOCKSIZE; + n = ( n + 1 ) % BLOWFISH_BLOCKSIZE; } } @@ -353,7 +376,8 @@ int blowfish_crypt_ctr( blowfish_context *ctx, while( length-- ) { if( n == 0 ) { - blowfish_crypt_ecb( ctx, BLOWFISH_ENCRYPT, nonce_counter, stream_block ); + blowfish_crypt_ecb( ctx, BLOWFISH_ENCRYPT, nonce_counter, + stream_block ); for( i = BLOWFISH_BLOCKSIZE; i > 0; i-- ) if( ++nonce_counter[i - 1] != 0 ) @@ -362,7 +386,7 @@ int blowfish_crypt_ctr( blowfish_context *ctx, c = *input++; *output++ = (unsigned char)( c ^ stream_block[n] ); - n = (n + 1) % BLOWFISH_BLOCKSIZE; + n = ( n + 1 ) % BLOWFISH_BLOCKSIZE; } *nc_off = n; diff --git a/pdns/ext/polarssl/library/camellia.c b/pdns/ext/polarssl/library/camellia.c index 2366caed6..a4968f411 100644 --- a/pdns/ext/polarssl/library/camellia.c +++ b/pdns/ext/polarssl/library/camellia.c @@ -1,7 +1,7 @@ /* * Camellia implementation * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -29,14 +29,29 @@ * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_CAMELLIA_C) #include "polarssl/camellia.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + #if !defined(POLARSSL_CAMELLIA_ALT) +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + /* * 32-bit integer manipulation macros (big endian) */ @@ -97,86 +112,86 @@ static const unsigned char FSb[256] = #define SBOX3(n) (unsigned char)((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff) #define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff] -#else +#else /* POLARSSL_CAMELLIA_SMALL_MEMORY */ static const unsigned char FSb[256] = { - 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65, - 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189, - 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26, - 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77, - 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153, - 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215, - 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34, - 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80, - 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210, - 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148, - 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226, - 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46, - 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89, - 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250, - 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164, - 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158 + 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65, + 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189, + 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26, + 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77, + 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153, + 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215, + 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34, + 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80, + 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210, + 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148, + 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226, + 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46, + 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89, + 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250, + 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164, + 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158 }; static const unsigned char FSb2[256] = { - 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130, - 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123, - 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52, - 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154, - 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51, - 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175, - 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68, - 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160, - 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165, - 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41, - 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197, - 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92, - 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178, - 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245, - 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73, - 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61 + 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130, + 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123, + 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52, + 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154, + 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51, + 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175, + 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68, + 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160, + 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165, + 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41, + 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197, + 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92, + 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178, + 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245, + 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73, + 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61 }; static const unsigned char FSb3[256] = { - 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160, - 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222, - 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13, - 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166, - 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204, - 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235, - 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17, - 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40, - 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105, - 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74, - 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113, - 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23, - 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172, - 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125, - 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82, - 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79 + 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160, + 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222, + 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13, + 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166, + 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204, + 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235, + 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17, + 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40, + 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105, + 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74, + 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113, + 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23, + 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172, + 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125, + 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82, + 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79 }; static const unsigned char FSb4[256] = { - 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146, - 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108, - 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4, - 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105, - 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221, - 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99, - 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141, - 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128, - 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189, - 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77, - 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215, - 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80, - 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148, - 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46, - 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250, - 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158 + 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146, + 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108, + 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4, + 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105, + 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221, + 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99, + 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141, + 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128, + 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189, + 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77, + 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215, + 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80, + 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148, + 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46, + 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250, + 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158 }; #define SBOX1(n) FSb[(n)] @@ -184,7 +199,7 @@ static const unsigned char FSb4[256] = #define SBOX3(n) FSb3[(n)] #define SBOX4(n) FSb4[(n)] -#endif +#endif /* POLARSSL_CAMELLIA_SMALL_MEMORY */ static const unsigned char shifts[2][4][4] = { @@ -258,13 +273,13 @@ static const signed char transposes[2][20] = (XR) = ((((XL) & (KL)) << 1) | (((XL) & (KL)) >> 31)) ^ (XR); \ (XL) = ((XR) | (KR)) ^ (XL); \ } - + #define FLInv(YL, YR, KL, KR) \ { \ (YL) = ((YR) | (KR)) ^ (YL); \ (YR) = ((((YL) & (KL)) << 1) | (((YL) & (KL)) >> 31)) ^ (YR); \ } - + #define SHIFT_AND_PLACE(INDEX, OFFSET) \ { \ TK[0] = KC[(OFFSET) * 4 + 0]; \ @@ -272,17 +287,18 @@ static const signed char transposes[2][20] = TK[2] = KC[(OFFSET) * 4 + 2]; \ TK[3] = KC[(OFFSET) * 4 + 3]; \ \ - for ( i = 1; i <= 4; i++ ) \ - if (shifts[(INDEX)][(OFFSET)][i -1]) \ - ROTL(TK + i * 4, TK, (15 * i) % 32); \ + for( i = 1; i <= 4; i++ ) \ + if( shifts[(INDEX)][(OFFSET)][i -1] ) \ + ROTL(TK + i * 4, TK, ( 15 * i ) % 32); \ \ - for ( i = 0; i < 20; i++ ) \ - if (indexes[(INDEX)][(OFFSET)][i] != -1) { \ - RK[indexes[(INDEX)][(OFFSET)][i]] = TK[ i ]; \ - } \ + for( i = 0; i < 20; i++ ) \ + if( indexes[(INDEX)][(OFFSET)][i] != -1 ) { \ + RK[indexes[(INDEX)][(OFFSET)][i]] = TK[ i ]; \ + } \ } -static void camellia_feistel(const uint32_t x[2], const uint32_t k[2], uint32_t z[2]) +static void camellia_feistel( const uint32_t x[2], const uint32_t k[2], + uint32_t z[2]) { uint32_t I0, I1; I0 = x[0] ^ k[0]; @@ -306,10 +322,24 @@ static void camellia_feistel(const uint32_t x[2], const uint32_t k[2], uint32_t z[1] ^= I0; } +void camellia_init( camellia_context *ctx ) +{ + memset( ctx, 0, sizeof( camellia_context ) ); +} + +void camellia_free( camellia_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( camellia_context ) ); +} + /* * Camellia key schedule (encryption) */ -int camellia_setkey_enc( camellia_context *ctx, const unsigned char *key, unsigned int keysize ) +int camellia_setkey_enc( camellia_context *ctx, const unsigned char *key, + unsigned int keysize ) { int idx; size_t i; @@ -321,8 +351,8 @@ int camellia_setkey_enc( camellia_context *ctx, const unsigned char *key, unsign RK = ctx->rk; - memset(t, 0, 64); - memset(RK, 0, sizeof(ctx->rk)); + memset( t, 0, 64 ); + memset( RK, 0, sizeof(ctx->rk) ); switch( keysize ) { @@ -332,77 +362,77 @@ int camellia_setkey_enc( camellia_context *ctx, const unsigned char *key, unsign default : return( POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH ); } - for( i = 0; i < keysize / 8; ++i) + for( i = 0; i < keysize / 8; ++i ) t[i] = key[i]; - if (keysize == 192) { - for (i = 0; i < 8; i++) + if( keysize == 192 ) { + for( i = 0; i < 8; i++ ) t[24 + i] = ~t[16 + i]; } /* * Prepare SIGMA values */ - for (i = 0; i < 6; i++) { - GET_UINT32_BE(SIGMA[i][0], SIGMA_CHARS[i], 0); - GET_UINT32_BE(SIGMA[i][1], SIGMA_CHARS[i], 4); + for( i = 0; i < 6; i++ ) { + GET_UINT32_BE( SIGMA[i][0], SIGMA_CHARS[i], 0 ); + GET_UINT32_BE( SIGMA[i][1], SIGMA_CHARS[i], 4 ); } /* * Key storage in KC * Order: KL, KR, KA, KB */ - memset(KC, 0, sizeof(KC)); + memset( KC, 0, sizeof(KC) ); /* Store KL, KR */ - for (i = 0; i < 8; i++) - GET_UINT32_BE(KC[i], t, i * 4); + for( i = 0; i < 8; i++ ) + GET_UINT32_BE( KC[i], t, i * 4 ); /* Generate KA */ - for( i = 0; i < 4; ++i) + for( i = 0; i < 4; ++i ) KC[8 + i] = KC[i] ^ KC[4 + i]; - camellia_feistel(KC + 8, SIGMA[0], KC + 10); - camellia_feistel(KC + 10, SIGMA[1], KC + 8); + camellia_feistel( KC + 8, SIGMA[0], KC + 10 ); + camellia_feistel( KC + 10, SIGMA[1], KC + 8 ); - for( i = 0; i < 4; ++i) + for( i = 0; i < 4; ++i ) KC[8 + i] ^= KC[i]; - camellia_feistel(KC + 8, SIGMA[2], KC + 10); - camellia_feistel(KC + 10, SIGMA[3], KC + 8); + camellia_feistel( KC + 8, SIGMA[2], KC + 10 ); + camellia_feistel( KC + 10, SIGMA[3], KC + 8 ); - if (keysize > 128) { + if( keysize > 128 ) { /* Generate KB */ - for( i = 0; i < 4; ++i) + for( i = 0; i < 4; ++i ) KC[12 + i] = KC[4 + i] ^ KC[8 + i]; - camellia_feistel(KC + 12, SIGMA[4], KC + 14); - camellia_feistel(KC + 14, SIGMA[5], KC + 12); + camellia_feistel( KC + 12, SIGMA[4], KC + 14 ); + camellia_feistel( KC + 14, SIGMA[5], KC + 12 ); } /* * Generating subkeys - */ + */ /* Manipulating KL */ - SHIFT_AND_PLACE(idx, 0); + SHIFT_AND_PLACE( idx, 0 ); /* Manipulating KR */ - if (keysize > 128) { - SHIFT_AND_PLACE(idx, 1); + if( keysize > 128 ) { + SHIFT_AND_PLACE( idx, 1 ); } /* Manipulating KA */ - SHIFT_AND_PLACE(idx, 2); + SHIFT_AND_PLACE( idx, 2 ); /* Manipulating KB */ - if (keysize > 128) { - SHIFT_AND_PLACE(idx, 3); + if( keysize > 128 ) { + SHIFT_AND_PLACE( idx, 3 ); } /* Do transpositions */ - for ( i = 0; i < 20; i++ ) { - if (transposes[idx][i] != -1) { + for( i = 0; i < 20; i++ ) { + if( transposes[idx][i] != -1 ) { RK[32 + 12 * idx + i] = RK[transposes[idx][i]]; } } @@ -413,29 +443,25 @@ int camellia_setkey_enc( camellia_context *ctx, const unsigned char *key, unsign /* * Camellia key schedule (decryption) */ -int camellia_setkey_dec( camellia_context *ctx, const unsigned char *key, unsigned int keysize ) +int camellia_setkey_dec( camellia_context *ctx, const unsigned char *key, + unsigned int keysize ) { - int idx; + int idx, ret; size_t i; camellia_context cty; uint32_t *RK; uint32_t *SK; - int ret; - switch( keysize ) - { - case 128: ctx->nr = 3; idx = 0; break; - case 192: - case 256: ctx->nr = 4; idx = 1; break; - default : return( POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH ); - } + camellia_init( &cty ); - RK = ctx->rk; + /* Also checks keysize */ + if( ( ret = camellia_setkey_enc( &cty, key, keysize ) ) ) + goto exit; - ret = camellia_setkey_enc(&cty, key, keysize); - if( ret != 0 ) - return( ret ); + ctx->nr = cty.nr; + idx = ( ctx->nr == 4 ); + RK = ctx->rk; SK = cty.rk + 24 * 2 + 8 * idx * 2; *RK++ = *SK++; @@ -443,7 +469,7 @@ int camellia_setkey_dec( camellia_context *ctx, const unsigned char *key, unsign *RK++ = *SK++; *RK++ = *SK++; - for (i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4) + for( i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4 ) { *RK++ = *SK++; *RK++ = *SK++; @@ -456,9 +482,10 @@ int camellia_setkey_dec( camellia_context *ctx, const unsigned char *key, unsign *RK++ = *SK++; *RK++ = *SK++; - memset( &cty, 0, sizeof( camellia_context ) ); +exit: + camellia_free( &cty ); - return( 0 ); + return( ret ); } /* @@ -487,22 +514,22 @@ int camellia_crypt_ecb( camellia_context *ctx, X[2] ^= *RK++; X[3] ^= *RK++; - while (NR) { + while( NR ) { --NR; - camellia_feistel(X, RK, X + 2); + camellia_feistel( X, RK, X + 2 ); RK += 2; - camellia_feistel(X + 2, RK, X); + camellia_feistel( X + 2, RK, X ); RK += 2; - camellia_feistel(X, RK, X + 2); + camellia_feistel( X, RK, X + 2 ); RK += 2; - camellia_feistel(X + 2, RK, X); + camellia_feistel( X + 2, RK, X ); RK += 2; - camellia_feistel(X, RK, X + 2); + camellia_feistel( X, RK, X + 2 ); RK += 2; - camellia_feistel(X + 2, RK, X); + camellia_feistel( X + 2, RK, X ); RK += 2; - if (NR) { + if( NR ) { FL(X[0], X[1], RK[0], RK[1]); RK += 2; FLInv(X[2], X[3], RK[0], RK[1]); @@ -603,7 +630,7 @@ int camellia_crypt_cfb128( camellia_context *ctx, *output++ = (unsigned char)( c ^ iv[n] ); iv[n] = (unsigned char) c; - n = (n + 1) & 0x0F; + n = ( n + 1 ) & 0x0F; } } else @@ -615,7 +642,7 @@ int camellia_crypt_cfb128( camellia_context *ctx, iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); - n = (n + 1) & 0x0F; + n = ( n + 1 ) & 0x0F; } } @@ -643,7 +670,8 @@ int camellia_crypt_ctr( camellia_context *ctx, while( length-- ) { if( n == 0 ) { - camellia_crypt_ecb( ctx, CAMELLIA_ENCRYPT, nonce_counter, stream_block ); + camellia_crypt_ecb( ctx, CAMELLIA_ENCRYPT, nonce_counter, + stream_block ); for( i = 16; i > 0; i-- ) if( ++nonce_counter[i - 1] != 0 ) @@ -652,7 +680,7 @@ int camellia_crypt_ctr( camellia_context *ctx, c = *input++; *output++ = (unsigned char)( c ^ stream_block[n] ); - n = (n + 1) & 0x0F; + n = ( n + 1 ) & 0x0F; } *nc_off = n; @@ -681,14 +709,14 @@ static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] = { { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - { 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, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, - { 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 } }, @@ -697,7 +725,7 @@ static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] = 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, - { 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, 0x00, 0x00, 0x00, 0x00, 0x00 } @@ -708,7 +736,7 @@ static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] = { { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }; @@ -884,44 +912,44 @@ int camellia_self_test( int verbose ) memset( key, 0, 32 ); - for (j = 0; j < 6; j++) { + for( j = 0; j < 6; j++ ) { u = j >> 1; v = j & 1; if( verbose != 0 ) - printf( " CAMELLIA-ECB-%3d (%s): ", 128 + u * 64, - (v == CAMELLIA_DECRYPT) ? "dec" : "enc"); + polarssl_printf( " CAMELLIA-ECB-%3d (%s): ", 128 + u * 64, + (v == CAMELLIA_DECRYPT) ? "dec" : "enc"); - for (i = 0; i < CAMELLIA_TESTS_ECB; i++ ) { - memcpy( key, camellia_test_ecb_key[u][i], 16 + 8 * u); + for( i = 0; i < CAMELLIA_TESTS_ECB; i++ ) { + memcpy( key, camellia_test_ecb_key[u][i], 16 + 8 * u ); - if (v == CAMELLIA_DECRYPT) { - camellia_setkey_dec(&ctx, key, 128 + u * 64); - memcpy(src, camellia_test_ecb_cipher[u][i], 16); - memcpy(dst, camellia_test_ecb_plain[i], 16); + if( v == CAMELLIA_DECRYPT ) { + camellia_setkey_dec( &ctx, key, 128 + u * 64 ); + memcpy( src, camellia_test_ecb_cipher[u][i], 16 ); + memcpy( dst, camellia_test_ecb_plain[i], 16 ); } else { /* CAMELLIA_ENCRYPT */ - camellia_setkey_enc(&ctx, key, 128 + u * 64); - memcpy(src, camellia_test_ecb_plain[i], 16); - memcpy(dst, camellia_test_ecb_cipher[u][i], 16); + camellia_setkey_enc( &ctx, key, 128 + u * 64 ); + memcpy( src, camellia_test_ecb_plain[i], 16 ); + memcpy( dst, camellia_test_ecb_cipher[u][i], 16 ); } - camellia_crypt_ecb(&ctx, v, src, buf); + camellia_crypt_ecb( &ctx, v, src, buf ); if( memcmp( buf, dst, 16 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); #if defined(POLARSSL_CIPHER_MODE_CBC) /* @@ -933,49 +961,49 @@ int camellia_self_test( int verbose ) v = j & 1; if( verbose != 0 ) - printf( " CAMELLIA-CBC-%3d (%s): ", 128 + u * 64, - ( v == CAMELLIA_DECRYPT ) ? "dec" : "enc" ); + polarssl_printf( " CAMELLIA-CBC-%3d (%s): ", 128 + u * 64, + ( v == CAMELLIA_DECRYPT ) ? "dec" : "enc" ); - memcpy( src, camellia_test_cbc_iv, 16); - memcpy( dst, camellia_test_cbc_iv, 16); - memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u); + memcpy( src, camellia_test_cbc_iv, 16 ); + memcpy( dst, camellia_test_cbc_iv, 16 ); + memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u ); - if (v == CAMELLIA_DECRYPT) { - camellia_setkey_dec(&ctx, key, 128 + u * 64); + if( v == CAMELLIA_DECRYPT ) { + camellia_setkey_dec( &ctx, key, 128 + u * 64 ); } else { - camellia_setkey_enc(&ctx, key, 128 + u * 64); + camellia_setkey_enc( &ctx, key, 128 + u * 64 ); } - for (i = 0; i < CAMELLIA_TESTS_CBC; i++ ) { + for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) { - if (v == CAMELLIA_DECRYPT) { + if( v == CAMELLIA_DECRYPT ) { memcpy( iv , src, 16 ); - memcpy(src, camellia_test_cbc_cipher[u][i], 16); - memcpy(dst, camellia_test_cbc_plain[i], 16); + memcpy( src, camellia_test_cbc_cipher[u][i], 16 ); + memcpy( dst, camellia_test_cbc_plain[i], 16 ); } else { /* CAMELLIA_ENCRYPT */ memcpy( iv , dst, 16 ); - memcpy(src, camellia_test_cbc_plain[i], 16); - memcpy(dst, camellia_test_cbc_cipher[u][i], 16); + memcpy( src, camellia_test_cbc_plain[i], 16 ); + memcpy( dst, camellia_test_cbc_cipher[u][i], 16 ); } - camellia_crypt_cbc(&ctx, v, 16, iv, src, buf); + camellia_crypt_cbc( &ctx, v, 16, iv, src, buf ); if( memcmp( buf, dst, 16 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } #endif /* POLARSSL_CIPHER_MODE_CBC */ if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); #if defined(POLARSSL_CIPHER_MODE_CTR) /* @@ -987,8 +1015,8 @@ int camellia_self_test( int verbose ) v = i & 1; if( verbose != 0 ) - printf( " CAMELLIA-CTR-128 (%s): ", - ( v == CAMELLIA_DECRYPT ) ? "dec" : "enc" ); + polarssl_printf( " CAMELLIA-CTR-128 (%s): ", + ( v == CAMELLIA_DECRYPT ) ? "dec" : "enc" ); memcpy( nonce_counter, camellia_test_ctr_nonce_counter[u], 16 ); memcpy( key, camellia_test_ctr_key[u], 16 ); @@ -1001,12 +1029,13 @@ int camellia_self_test( int verbose ) len = camellia_test_ctr_len[u]; memcpy( buf, camellia_test_ctr_ct[u], len ); - camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, buf, buf ); + camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); if( memcmp( buf, camellia_test_ctr_pt[u], len ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } @@ -1016,28 +1045,29 @@ int camellia_self_test( int verbose ) len = camellia_test_ctr_len[u]; memcpy( buf, camellia_test_ctr_pt[u], len ); - camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, buf, buf ); + camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); if( memcmp( buf, camellia_test_ctr_ct[u], len ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); #endif /* POLARSSL_CIPHER_MODE_CTR */ - return ( 0 ); + return( 0 ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_CAMELLIA_C */ diff --git a/pdns/ext/polarssl/library/ccm.c b/pdns/ext/polarssl/library/ccm.c new file mode 100644 index 000000000..72d766b9a --- /dev/null +++ b/pdns/ext/polarssl/library/ccm.c @@ -0,0 +1,456 @@ +/* + * NIST SP800-38C compliant CCM implementation + * + * Copyright (C) 2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * Definition of CCM: + * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf + * RFC 3610 "Counter with CBC-MAC (CCM)" + * + * Related: + * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_CCM_C) + +#include "polarssl/ccm.h" + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#define CCM_ENCRYPT 0 +#define CCM_DECRYPT 1 + +/* + * Initialize context + */ +int ccm_init( ccm_context *ctx, cipher_id_t cipher, + const unsigned char *key, unsigned int keysize ) +{ + int ret; + const cipher_info_t *cipher_info; + + memset( ctx, 0, sizeof( ccm_context ) ); + + cipher_init( &ctx->cipher_ctx ); + + cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB ); + if( cipher_info == NULL ) + return( POLARSSL_ERR_CCM_BAD_INPUT ); + + if( cipher_info->block_size != 16 ) + return( POLARSSL_ERR_CCM_BAD_INPUT ); + + if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 ) + return( ret ); + + if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize, + POLARSSL_ENCRYPT ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} + +/* + * Free context + */ +void ccm_free( ccm_context *ctx ) +{ + cipher_free( &ctx->cipher_ctx ); + polarssl_zeroize( ctx, sizeof( ccm_context ) ); +} + +/* + * Macros for common operations. + * Results in smaller compiled code than static inline functions. + */ + +/* + * Update the CBC-MAC state in y using a block in b + * (Always using b as the source helps the compiler optimise a bit better.) + */ +#define UPDATE_CBC_MAC \ + for( i = 0; i < 16; i++ ) \ + y[i] ^= b[i]; \ + \ + if( ( ret = cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \ + return( ret ); + +/* + * Encrypt or decrypt a partial block with CTR + * Warning: using b for temporary storage! src and dst must not be b! + * This avoids allocating one more 16 bytes buffer while allowing src == dst. + */ +#define CTR_CRYPT( dst, src, len ) \ + if( ( ret = cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 ) \ + return( ret ); \ + \ + for( i = 0; i < len; i++ ) \ + dst[i] = src[i] ^ b[i]; + +/* + * Authenticated encryption or decryption + */ +static int ccm_auth_crypt( ccm_context *ctx, int mode, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ) +{ + int ret; + unsigned char i; + unsigned char q = 16 - 1 - iv_len; + size_t len_left, olen; + unsigned char b[16]; + unsigned char y[16]; + unsigned char ctr[16]; + const unsigned char *src; + unsigned char *dst; + + /* + * Check length requirements: SP800-38C A.1 + * Additional requirement: a < 2^16 - 2^8 to simplify the code. + * 'length' checked later (when writing it to the first block) + */ + if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 ) + return( POLARSSL_ERR_CCM_BAD_INPUT ); + + /* Also implies q is within bounds */ + if( iv_len < 7 || iv_len > 13 ) + return( POLARSSL_ERR_CCM_BAD_INPUT ); + + if( add_len > 0xFF00 ) + return( POLARSSL_ERR_CCM_BAD_INPUT ); + + /* + * First block B_0: + * 0 .. 0 flags + * 1 .. iv_len nonce (aka iv) + * iv_len+1 .. 15 length + * + * With flags as (bits): + * 7 0 + * 6 add present? + * 5 .. 3 (t - 2) / 2 + * 2 .. 0 q - 1 + */ + b[0] = 0; + b[0] |= ( add_len > 0 ) << 6; + b[0] |= ( ( tag_len - 2 ) / 2 ) << 3; + b[0] |= q - 1; + + memcpy( b + 1, iv, iv_len ); + + for( i = 0, len_left = length; i < q; i++, len_left >>= 8 ) + b[15-i] = (unsigned char)( len_left & 0xFF ); + + if( len_left > 0 ) + return( POLARSSL_ERR_CCM_BAD_INPUT ); + + + /* Start CBC-MAC with first block */ + memset( y, 0, 16 ); + UPDATE_CBC_MAC; + + /* + * If there is additional data, update CBC-MAC with + * add_len, add, 0 (padding to a block boundary) + */ + if( add_len > 0 ) + { + size_t use_len; + len_left = add_len; + src = add; + + memset( b, 0, 16 ); + b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF ); + b[1] = (unsigned char)( ( add_len ) & 0xFF ); + + use_len = len_left < 16 - 2 ? len_left : 16 - 2; + memcpy( b + 2, src, use_len ); + len_left -= use_len; + src += use_len; + + UPDATE_CBC_MAC; + + while( len_left > 0 ) + { + use_len = len_left > 16 ? 16 : len_left; + + memset( b, 0, 16 ); + memcpy( b, src, use_len ); + UPDATE_CBC_MAC; + + len_left -= use_len; + src += use_len; + } + } + + /* + * Prepare counter block for encryption: + * 0 .. 0 flags + * 1 .. iv_len nonce (aka iv) + * iv_len+1 .. 15 counter (initially 1) + * + * With flags as (bits): + * 7 .. 3 0 + * 2 .. 0 q - 1 + */ + ctr[0] = q - 1; + memcpy( ctr + 1, iv, iv_len ); + memset( ctr + 1 + iv_len, 0, q ); + ctr[15] = 1; + + /* + * Authenticate and {en,de}crypt the message. + * + * The only difference between encryption and decryption is + * the respective order of authentication and {en,de}cryption. + */ + len_left = length; + src = input; + dst = output; + + while( len_left > 0 ) + { + unsigned char use_len = len_left > 16 ? 16 : len_left; + + if( mode == CCM_ENCRYPT ) + { + memset( b, 0, 16 ); + memcpy( b, src, use_len ); + UPDATE_CBC_MAC; + } + + CTR_CRYPT( dst, src, use_len ); + + if( mode == CCM_DECRYPT ) + { + memset( b, 0, 16 ); + memcpy( b, dst, use_len ); + UPDATE_CBC_MAC; + } + + dst += use_len; + src += use_len; + len_left -= use_len; + + /* + * Increment counter. + * No need to check for overflow thanks to the length check above. + */ + for( i = 0; i < q; i++ ) + if( ++ctr[15-i] != 0 ) + break; + } + + /* + * Authentication: reset counter and crypt/mask internal tag + */ + for( i = 0; i < q; i++ ) + ctr[15-i] = 0; + + CTR_CRYPT( y, y, 16 ); + memcpy( tag, y, tag_len ); + + return( 0 ); +} + +/* + * Authenticated encryption + */ +int ccm_encrypt_and_tag( ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ) +{ + return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len, + add, add_len, input, output, tag, tag_len ) ); +} + +/* + * Authenticated decryption + */ +int ccm_auth_decrypt( ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ) +{ + int ret; + unsigned char check_tag[16]; + unsigned char i; + int diff; + + if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length, + iv, iv_len, add, add_len, + input, output, check_tag, tag_len ) ) != 0 ) + { + return( ret ); + } + + /* Check tag in "constant-time" */ + for( diff = 0, i = 0; i < tag_len; i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) + { + polarssl_zeroize( output, length ); + return( POLARSSL_ERR_CCM_AUTH_FAILED ); + } + + return( 0 ); +} + + +#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C) + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_printf printf +#endif + +/* + * Examples 1 to 3 from SP800-38C Appendix C + */ + +#define NB_TESTS 3 + +/* + * The data is the same for all tests, only the used length changes + */ +static const unsigned char key[] = { + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f +}; + +static const unsigned char iv[] = { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b +}; + +static const unsigned char ad[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13 +}; + +static const unsigned char msg[] = { + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +}; + +static const size_t iv_len [NB_TESTS] = { 7, 8, 12 }; +static const size_t add_len[NB_TESTS] = { 8, 16, 20 }; +static const size_t msg_len[NB_TESTS] = { 4, 16, 24 }; +static const size_t tag_len[NB_TESTS] = { 4, 6, 8 }; + +static const unsigned char res[NB_TESTS][32] = { + { 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d }, + { 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, + 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, + 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd }, + { 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a, + 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b, + 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5, + 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 } +}; + +int ccm_self_test( int verbose ) +{ + ccm_context ctx; + unsigned char out[32]; + size_t i; + int ret; + + if( ccm_init( &ctx, POLARSSL_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( " CCM: setup failed" ); + + return( 1 ); + } + + for( i = 0; i < NB_TESTS; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " CCM-AES #%u: ", (unsigned int) i + 1 ); + + ret = ccm_encrypt_and_tag( &ctx, msg_len[i], + iv, iv_len[i], ad, add_len[i], + msg, out, + out + msg_len[i], tag_len[i] ); + + if( ret != 0 || + memcmp( out, res[i], msg_len[i] + tag_len[i] ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + ret = ccm_auth_decrypt( &ctx, msg_len[i], + iv, iv_len[i], ad, add_len[i], + res[i], out, + res[i] + msg_len[i], tag_len[i] ); + + if( ret != 0 || + memcmp( out, msg, msg_len[i] ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + ccm_free( &ctx ); + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */ + +#endif /* POLARSSL_CCM_C */ diff --git a/pdns/ext/polarssl/library/certs.c b/pdns/ext/polarssl/library/certs.c index 17775b889..a782bc114 100644 --- a/pdns/ext/polarssl/library/certs.c +++ b/pdns/ext/polarssl/library/certs.c @@ -1,7 +1,7 @@ /* * X.509 test certificates * - * Copyright (C) 2006-2010, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,7 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_CERTS_C) @@ -169,55 +173,56 @@ const char test_ca_pwd_rsa[] = "PolarSSLTest"; const char test_srv_crt_rsa[] = "-----BEGIN CERTIFICATE-----\r\n" -"MIIDPzCCAiegAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" +"MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" "MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" -"MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n" -"A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIFNlcnZlciAxMIIBIjAN\r\n" -"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/\r\n" -"uOhFkNvuiBZS0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFD\r\n" -"d185fAkER4KwVzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVf\r\n" -"CrFTxjB+FTms+Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTr\r\n" -"lZvc/kFeF6babFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9w\r\n" -"bp7OvViJ4lNZnm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQAB\r\n" -"o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBQfdNY/KcF0dEU7BRIsPai9Q1kCpjAf\r\n" -"BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQUFAAOC\r\n" -"AQEAvc+WwZUemsJu2IiI2Cp6liA+UAvIx98dQe3kZs2zAoF9VwQbXcYzWQ/BILkj\r\n" -"NImKbPL9x0g2jIDn4ZvGYFywMwIO/d++YbwYiQw42/v7RiMy94zBPnzeHi86dy/0\r\n" -"jpOOJUx3IXRsGLdyjb/1T11klcFqGnARiK+8VYolMPP6afKvLXX7K4kiUpsFQhUp\r\n" -"E5VeM5pV1Mci2ETOJau2cO40FJvI/C9W/wR+GAArMaw2fxG77E3laaa0LAOlexM6\r\n" -"A4KOb5f5cGTM5Ih6tEF5FVq3/9vzNIYMa1FqzacBLZF8zSHYLEimXBdzjBoN4qDU\r\n" -"/WzRyYRBRjAI49mzHX6raleqnw==\r\n" +"MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" +"AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" +"owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" +"NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" +"tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" +"hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" +"HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" +"VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" +"FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAJxnXClY\r\n" +"oHkbp70cqBrsGXLybA74czbO5RdLEgFs7rHVS9r+c293luS/KdliLScZqAzYVylw\r\n" +"UfRWvKMoWhHYKp3dEIS4xTXk6/5zXxhv9Rw8SGc8qn6vITHk1S1mPevtekgasY5Y\r\n" +"iWQuM3h4YVlRH3HHEMAD1TnAexfXHHDFQGe+Bd1iAbz1/sH9H8l4StwX6egvTK3M\r\n" +"wXRwkKkvjKaEDA9ATbZx0mI8LGsxSuCqe9r9dyjmttd47J1p1Rulz3CLzaRcVIuS\r\n" +"RRQfaD8neM9c1S/iJ/amTVqJxA1KOdOS5780WhPfSArA+g4qAmSjelc3p4wWpha8\r\n" +"zhuYwjVuX6JHG0c=\r\n" "-----END CERTIFICATE-----\r\n"; const char test_srv_key_rsa[] = "-----BEGIN RSA PRIVATE KEY-----\r\n" -"MIIEogIBAAKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/uOhFkNvuiBZS0/FDUEeW\r\n" -"Ellkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFDd185fAkER4KwVzlw7aPs\r\n" -"FRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVfCrFTxjB+FTms+Vruf5Ke\r\n" -"pgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTrlZvc/kFeF6babFtpzAK6\r\n" -"FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9wbp7OvViJ4lNZnm5akmXi\r\n" -"iD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQABAoIBABaJ9eiRQq4Ypv+w\r\n" -"UTcVpLC0oTueWzcpor1i1zjG4Vzqe/Ok2FqyGToGKMlFK7Hwwa+LEyeJ3xyV5yd4\r\n" -"v1Mw9bDZFdJC1eCBjoUAHtX6k9HOE0Vd6woVQ4Vi6OPI1g7B5Mnr/58rNrnN6TMs\r\n" -"x58NF6euecwTU811QJrZtLbX7j2Cr28yB2Vs8qyYlHwVw5jbDOv43D7vU5gmlIDN\r\n" -"0JQRuWAnOuPzZNoJr4SfJKqHNGxYYY6pHZ1s0dOTLIDb/B8KQWapA2kRmZyid2EH\r\n" -"nwzgLbAsHJCf+bQnhXjXuxtUsrcIL8noZLazlOMxwNEammglVWW23Ud/QRnFgJg5\r\n" -"UgcAcRECgYEA19uYetht5qmwdJ+12oC6zeO+vXLcyD9gon23T5J6w2YThld7/OW0\r\n" -"oArQJGgkAdaq0pcTyOIjtTQVMFygdVmCEJmxh/3RutPcTeydqW9fphKDMej32J8e\r\n" -"GniGmNGiclbcfNOS8E5TGp445yZb9P1+7AHng16bGg3Ykj5EA4G+HCcCgYEAyHAl\r\n" -"//ekk8YjQElm+8izLtFkymIK0aCtEe9C/RIRhFYBeFaotC5dStNhBOncn4ovMAPD\r\n" -"lX/92yDi9OP8PPLN3a4B9XpW3k/SS5GrbT5cwOivBHNllZSmu/2qz5WPGcjVCOrB\r\n" -"LYl3YWr2h3EGKICT03kEoTkiDBvCeOpW7cCGl2cCgYBD5whoXHz1+ptPlI4YVjZt\r\n" -"Xh86aU+ajpVPiEyJ84I6xXmO4SZXv8q6LaycR0ZMbcL+zBelMb4Z2nBv7jNrtuR7\r\n" -"ZF28cdPv+YVr3esaybZE/73VjXup4SQPH6r3l7qKTVi+y6+FeJ4b2Xn8/MwgnT23\r\n" -"8EFrye7wmzpthrjOgZnUMQKBgE9Lhsz/5J0Nis6Y+2Pqn3CLKEukg9Ewtqdct2y0\r\n" -"5Dcta0F3TyCRIxlCDKTL/BslqMtfAdY4H268UO0+8IAQMn9boqzBrHIgs/pvc5kx\r\n" -"TbKHmw2wtWR6vYersBKVgVpbCGSRssDYHGFu1n74qM4HJ/RGcR1zI9QUe1gopSFD\r\n" -"xDtLAoGAVAdWvrqDwgoL2hHW3scGpxdE/ygJDOwHnf+1B9goKAOP5lf2FJaiAxf3\r\n" -"ectoPOgZbCmm/iiDmigu703ld3O+VoCLDD4qx3R+KyALL78gtVJYzSRiKhzgCZ3g\r\n" -"mKsIVRBq4IfwiwyMNG2BYZQAwbSDjjPtn/kPBduPzPj7eriByhI=\r\n" +"MIIEpAIBAAKCAQEAwU2j3efNHdEE10lyuJmsDnjkOjxKzzoTFtBa5M2jAIin7h5r\r\n" +"lqdStJDvLXJ6PiSa/LY0rCT1d+AmZIycsCh9odrqjObJHJa8/sEEUrM21KP64bF2\r\n" +"2JDBYbRmUjaiJlOqq3ReB30Zgtsq2B+g2Q0cLUlm91slc0boC4pPaQy1AJDh2oIQ\r\n" +"Zn2uVCuLZXmRoeJhw81ASQjuaAzxi4bSRr/QuKoRAx5/VqgaHkQYDw+Fi9qLRF7i\r\n" +"GMZiL8dmjfpd2H3zJ4kpAcWQDj8n8TDISg7v1t7HxydrxwU9esQCPJodPg/oNJhb\r\n" +"y3NLUpbYEaIsgIhpOVrTD7DeWS8Rx/fqEgEwlwIDAQABAoIBAQCXR0S8EIHFGORZ\r\n" +"++AtOg6eENxD+xVs0f1IeGz57Tjo3QnXX7VBZNdj+p1ECvhCE/G7XnkgU5hLZX+G\r\n" +"Z0jkz/tqJOI0vRSdLBbipHnWouyBQ4e/A1yIJdlBtqXxJ1KE/ituHRbNc4j4kL8Z\r\n" +"/r6pvwnTI0PSx2Eqs048YdS92LT6qAv4flbNDxMn2uY7s4ycS4Q8w1JXnCeaAnYm\r\n" +"WYI5wxO+bvRELR2Mcz5DmVnL8jRyml6l6582bSv5oufReFIbyPZbQWlXgYnpu6He\r\n" +"GTc7E1zKYQGG/9+DQUl/1vQuCPqQwny0tQoX2w5tdYpdMdVm+zkLtbajzdTviJJa\r\n" +"TWzL6lt5AoGBAN86+SVeJDcmQJcv4Eq6UhtRr4QGMiQMz0Sod6ettYxYzMgxtw28\r\n" +"CIrgpozCc+UaZJLo7UxvC6an85r1b2nKPCLQFaggJ0H4Q0J/sZOhBIXaoBzWxveK\r\n" +"nupceKdVxGsFi8CDy86DBfiyFivfBj+47BbaQzPBj7C4rK7UlLjab2rDAoGBAN2u\r\n" +"AM2gchoFiu4v1HFL8D7lweEpi6ZnMJjnEu/dEgGQJFjwdpLnPbsj4c75odQ4Gz8g\r\n" +"sw9lao9VVzbusoRE/JGI4aTdO0pATXyG7eG1Qu+5Yc1YGXcCrliA2xM9xx+d7f+s\r\n" +"mPzN+WIEg5GJDYZDjAzHG5BNvi/FfM1C9dOtjv2dAoGAF0t5KmwbjWHBhcVqO4Ic\r\n" +"BVvN3BIlc1ue2YRXEDlxY5b0r8N4XceMgKmW18OHApZxfl8uPDauWZLXOgl4uepv\r\n" +"whZC3EuWrSyyICNhLY21Ah7hbIEBPF3L3ZsOwC+UErL+dXWLdB56Jgy3gZaBeW7b\r\n" +"vDrEnocJbqCm7IukhXHOBK8CgYEAwqdHB0hqyNSzIOGY7v9abzB6pUdA3BZiQvEs\r\n" +"3LjHVd4HPJ2x0N8CgrBIWOE0q8+0hSMmeE96WW/7jD3fPWwCR5zlXknxBQsfv0gP\r\n" +"3BC5PR0Qdypz+d+9zfMf625kyit4T/hzwhDveZUzHnk1Cf+IG7Q+TOEnLnWAWBED\r\n" +"ISOWmrUCgYAFEmRxgwAc/u+D6t0syCwAYh6POtscq9Y0i9GyWk89NzgC4NdwwbBH\r\n" +"4AgahOxIxXx2gxJnq3yfkJfIjwf0s2DyP0kY2y6Ua1OeomPeY9mrIS4tCuDQ6LrE\r\n" +"TB6l9VGoxJL4fyHnZb8L5gGvnB1bbD8cL6YPaDiOhcRseC9vBiEuVg==\r\n" "-----END RSA PRIVATE KEY-----\r\n"; + const char test_cli_crt_rsa[] = "-----BEGIN CERTIFICATE-----\r\n" "MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" @@ -300,6 +305,6 @@ const char *test_srv_crt = test_srv_crt_ec; const char *test_srv_key = test_srv_key_ec; const char *test_cli_crt = test_cli_crt_ec; const char *test_cli_key = test_cli_key_ec; -#endif +#endif /* POLARSSL_RSA_C */ #endif /* POLARSSL_CERTS_C */ diff --git a/pdns/ext/polarssl/library/cipher.c b/pdns/ext/polarssl/library/cipher.c index f0a770aba..5cd30f8ad 100644 --- a/pdns/ext/polarssl/library/cipher.c +++ b/pdns/ext/polarssl/library/cipher.c @@ -1,11 +1,11 @@ /** * \file cipher.c - * + * * \brief Generic cipher wrapper for PolarSSL * * \author Adriaan de Jong * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_CIPHER_C) @@ -38,6 +42,10 @@ #include "polarssl/gcm.h" #endif +#if defined(POLARSSL_CCM_C) +#include "polarssl/ccm.h" +#endif + #include #if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) @@ -49,6 +57,11 @@ #define strcasecmp _stricmp #endif +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + static int supported_init = 0; const int *cipher_list( void ) @@ -69,7 +82,7 @@ const int *cipher_list( void ) supported_init = 1; } - return supported_ciphers; + return( supported_ciphers ); } const cipher_info_t *cipher_info_from_type( const cipher_type_t cipher_type ) @@ -80,7 +93,7 @@ const cipher_info_t *cipher_info_from_type( const cipher_type_t cipher_type ) if( def->type == cipher_type ) return( def->info ); - return NULL; + return( NULL ); } const cipher_info_t *cipher_info_from_string( const char *cipher_name ) @@ -88,13 +101,13 @@ const cipher_info_t *cipher_info_from_string( const char *cipher_name ) const cipher_definition_t *def; if( NULL == cipher_name ) - return NULL; + return( NULL ); for( def = cipher_definitions; def->info != NULL; def++ ) if( ! strcasecmp( def->info->name, cipher_name ) ) return( def->info ); - return NULL; + return( NULL ); } const cipher_info_t *cipher_info_from_values( const cipher_id_t cipher_id, @@ -109,18 +122,34 @@ const cipher_info_t *cipher_info_from_values( const cipher_id_t cipher_id, def->info->mode == mode ) return( def->info ); - return NULL; + return( NULL ); +} + +void cipher_init( cipher_context_t *ctx ) +{ + memset( ctx, 0, sizeof( cipher_context_t ) ); +} + +void cipher_free( cipher_context_t *ctx ) +{ + if( ctx == NULL ) + return; + + if( ctx->cipher_ctx ) + ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); + + polarssl_zeroize( ctx, sizeof(cipher_context_t) ); } int cipher_init_ctx( cipher_context_t *ctx, const cipher_info_t *cipher_info ) { if( NULL == cipher_info || NULL == ctx ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); memset( ctx, 0, sizeof( cipher_context_t ) ); if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) ) - return POLARSSL_ERR_CIPHER_ALLOC_FAILED; + return( POLARSSL_ERR_CIPHER_ALLOC_FAILED ); ctx->cipher_info = cipher_info; @@ -135,27 +164,28 @@ int cipher_init_ctx( cipher_context_t *ctx, const cipher_info_t *cipher_info ) #endif #endif /* POLARSSL_CIPHER_MODE_WITH_PADDING */ - return 0; + return( 0 ); } +/* Deprecated, redirects to cipher_free() */ int cipher_free_ctx( cipher_context_t *ctx ) { - if( ctx == NULL || ctx->cipher_info == NULL ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + cipher_free( ctx ); - ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); - - return 0; + return( 0 ); } int cipher_setkey( cipher_context_t *ctx, const unsigned char *key, int key_length, const operation_t operation ) { if( NULL == ctx || NULL == ctx->cipher_info ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); - if( (int) ctx->cipher_info->key_length != key_length ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + if( ( ctx->cipher_info->flags & POLARSSL_CIPHER_VARIABLE_KEY_LEN ) == 0 && + (int) ctx->cipher_info->key_length != key_length ) + { + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + } ctx->key_length = key_length; ctx->operation = operation; @@ -175,7 +205,7 @@ int cipher_setkey( cipher_context_t *ctx, const unsigned char *key, return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, ctx->key_length ); - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); } int cipher_set_iv( cipher_context_t *ctx, @@ -184,13 +214,13 @@ int cipher_set_iv( cipher_context_t *ctx, size_t actual_iv_size; if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); /* avoid buffer overflow in ctx->iv */ if( iv_len > POLARSSL_MAX_IV_LENGTH ) - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); - if( ctx->cipher_info->accepts_variable_iv_size ) + if( ( ctx->cipher_info->flags & POLARSSL_CIPHER_VARIABLE_IV_LEN ) != 0 ) actual_iv_size = iv_len; else { @@ -198,70 +228,68 @@ int cipher_set_iv( cipher_context_t *ctx, /* avoid reading past the end of input buffer */ if( actual_iv_size > iv_len ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); } memcpy( ctx->iv, iv, actual_iv_size ); ctx->iv_size = actual_iv_size; - return 0; + return( 0 ); } int cipher_reset( cipher_context_t *ctx ) { if( NULL == ctx || NULL == ctx->cipher_info ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); ctx->unprocessed_len = 0; - return 0; + return( 0 ); } -#if defined(POLARSSL_CIPHER_MODE_AEAD) +#if defined(POLARSSL_GCM_C) int cipher_update_ad( cipher_context_t *ctx, const unsigned char *ad, size_t ad_len ) { if( NULL == ctx || NULL == ctx->cipher_info ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); -#if defined(POLARSSL_GCM_C) if( POLARSSL_MODE_GCM == ctx->cipher_info->mode ) { return gcm_starts( (gcm_context *) ctx->cipher_ctx, ctx->operation, ctx->iv, ctx->iv_size, ad, ad_len ); } -#endif - return 0; + return( 0 ); } -#endif /* POLARSSL_CIPHER_MODE_AEAD */ +#endif /* POLARSSL_GCM_C */ -int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen ) +int cipher_update( cipher_context_t *ctx, const unsigned char *input, + size_t ilen, unsigned char *output, size_t *olen ) { int ret; - *olen = 0; - if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) { - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); } + *olen = 0; + if( ctx->cipher_info->mode == POLARSSL_MODE_ECB ) { if( ilen != cipher_get_block_size( ctx ) ) - return POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED; + return( POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED ); *olen = ilen; if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx, ctx->operation, input, output ) ) ) { - return ret; + return( ret ); } - return 0; + return( 0 ); } #if defined(POLARSSL_GCM_C) @@ -276,7 +304,7 @@ int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ile if( input == output && ( ctx->unprocessed_len != 0 || ilen % cipher_get_block_size( ctx ) ) ) { - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); } #if defined(POLARSSL_CIPHER_MODE_CBC) @@ -296,7 +324,7 @@ int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ile ilen ); ctx->unprocessed_len += ilen; - return 0; + return( 0 ); } /* @@ -313,7 +341,7 @@ int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ile ctx->operation, cipher_get_block_size( ctx ), ctx->iv, ctx->unprocessed_data, output ) ) ) { - return ret; + return( ret ); } *olen += cipher_get_block_size( ctx ); @@ -331,7 +359,7 @@ int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ile { copy_len = ilen % cipher_get_block_size( ctx ); if( copy_len == 0 && ctx->operation == POLARSSL_DECRYPT ) - copy_len = cipher_get_block_size(ctx); + copy_len = cipher_get_block_size( ctx ); memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), copy_len ); @@ -348,13 +376,13 @@ int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ile if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, ctx->operation, ilen, ctx->iv, input, output ) ) ) { - return ret; + return( ret ); } *olen += ilen; } - return 0; + return( 0 ); } #endif /* POLARSSL_CIPHER_MODE_CBC */ @@ -365,14 +393,14 @@ int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ile ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) ) { - return ret; + return( ret ); } *olen = ilen; - return 0; + return( 0 ); } -#endif +#endif /* POLARSSL_CIPHER_MODE_CFB */ #if defined(POLARSSL_CIPHER_MODE_CTR) if( ctx->cipher_info->mode == POLARSSL_MODE_CTR ) @@ -381,14 +409,14 @@ int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ile ilen, &ctx->unprocessed_len, ctx->iv, ctx->unprocessed_data, input, output ) ) ) { - return ret; + return( ret ); } *olen = ilen; - return 0; + return( 0 ); } -#endif +#endif /* POLARSSL_CIPHER_MODE_CTR */ #if defined(POLARSSL_CIPHER_MODE_STREAM) if( ctx->cipher_info->mode == POLARSSL_MODE_STREAM ) @@ -396,16 +424,16 @@ int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ile if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx, ilen, input, output ) ) ) { - return ret; + return( ret ); } *olen = ilen; - return 0; + return( 0 ); } -#endif +#endif /* POLARSSL_CIPHER_MODE_STREAM */ - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); } #if defined(POLARSSL_CIPHER_MODE_WITH_PADDING) @@ -430,7 +458,7 @@ static int get_pkcs_padding( unsigned char *input, size_t input_len, unsigned char padding_len, bad = 0; if( NULL == input || NULL == data_len ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); padding_len = input[input_len - 1]; *data_len = input_len - padding_len; @@ -445,7 +473,7 @@ static int get_pkcs_padding( unsigned char *input, size_t input_len, for( i = 0; i < input_len; i++ ) bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx ); - return POLARSSL_ERR_CIPHER_INVALID_PADDING * (bad != 0); + return( POLARSSL_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); } #endif /* POLARSSL_CIPHER_PADDING_PKCS7 */ @@ -471,7 +499,7 @@ static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, unsigned char done = 0, prev_done, bad; if( NULL == input || NULL == data_len ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); bad = 0xFF; *data_len = 0; @@ -483,7 +511,7 @@ static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, bad &= ( input[i-1] ^ 0x80 ) | ( done == prev_done ); } - return POLARSSL_ERR_CIPHER_INVALID_PADDING * (bad != 0); + return( POLARSSL_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); } #endif /* POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS */ @@ -510,7 +538,7 @@ static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, unsigned char padding_len, bad = 0; if( NULL == input || NULL == data_len ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); padding_len = input[input_len - 1]; *data_len = input_len - padding_len; @@ -524,7 +552,7 @@ static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, for( i = 0; i < input_len - 1; i++ ) bad |= input[i] * ( i >= pad_idx ); - return POLARSSL_ERR_CIPHER_INVALID_PADDING * (bad != 0); + return( POLARSSL_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); } #endif /* POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN */ @@ -548,7 +576,7 @@ static int get_zeros_padding( unsigned char *input, size_t input_len, unsigned char done = 0, prev_done; if( NULL == input || NULL == data_len ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); *data_len = 0; for( i = input_len; i > 0; i-- ) @@ -558,7 +586,7 @@ static int get_zeros_padding( unsigned char *input, size_t input_len, *data_len |= i * ( done != prev_done ); } - return 0; + return( 0 ); } #endif /* POLARSSL_CIPHER_PADDING_ZEROS */ @@ -572,11 +600,11 @@ static int get_no_padding( unsigned char *input, size_t input_len, size_t *data_len ) { if( NULL == input || NULL == data_len ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); *data_len = input_len; - return 0; + return( 0 ); } #endif /* POLARSSL_CIPHER_MODE_WITH_PADDING */ @@ -584,7 +612,7 @@ int cipher_finish( cipher_context_t *ctx, unsigned char *output, size_t *olen ) { if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); *olen = 0; @@ -593,15 +621,15 @@ int cipher_finish( cipher_context_t *ctx, POLARSSL_MODE_GCM == ctx->cipher_info->mode || POLARSSL_MODE_STREAM == ctx->cipher_info->mode ) { - return 0; + return( 0 ); } if( POLARSSL_MODE_ECB == ctx->cipher_info->mode ) { if( ctx->unprocessed_len != 0 ) - return POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED; + return( POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - return 0; + return( 0 ); } #if defined(POLARSSL_CIPHER_MODE_CBC) @@ -615,24 +643,24 @@ int cipher_finish( cipher_context_t *ctx, if( NULL == ctx->add_padding ) { if( 0 != ctx->unprocessed_len ) - return POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED; + return( POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - return 0; + return( 0 ); } ctx->add_padding( ctx->unprocessed_data, cipher_get_iv_size( ctx ), ctx->unprocessed_len ); } - else if ( cipher_get_block_size( ctx ) != ctx->unprocessed_len ) + else if( cipher_get_block_size( ctx ) != ctx->unprocessed_len ) { /* * For decrypt operations, expect a full block, * or an empty block if no padding */ if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len ) - return 0; + return( 0 ); - return POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED; + return( POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED ); } /* cipher block */ @@ -640,7 +668,7 @@ int cipher_finish( cipher_context_t *ctx, ctx->operation, cipher_get_block_size( ctx ), ctx->iv, ctx->unprocessed_data, output ) ) ) { - return ret; + return( ret ); } /* Set output size for decryption */ @@ -650,13 +678,13 @@ int cipher_finish( cipher_context_t *ctx, /* Set output size for encryption */ *olen = cipher_get_block_size( ctx ); - return 0; + return( 0 ); } #else ((void) output); #endif /* POLARSSL_CIPHER_MODE_CBC */ - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); } #if defined(POLARSSL_CIPHER_MODE_WITH_PADDING) @@ -665,7 +693,7 @@ int cipher_set_padding_mode( cipher_context_t *ctx, cipher_padding_t mode ) if( NULL == ctx || POLARSSL_MODE_CBC != ctx->cipher_info->mode ) { - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); } switch( mode ) @@ -700,31 +728,29 @@ int cipher_set_padding_mode( cipher_context_t *ctx, cipher_padding_t mode ) break; default: - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); } - return 0; + return( 0 ); } #endif /* POLARSSL_CIPHER_MODE_WITH_PADDING */ -#if defined(POLARSSL_CIPHER_MODE_AEAD) +#if defined(POLARSSL_GCM_C) int cipher_write_tag( cipher_context_t *ctx, unsigned char *tag, size_t tag_len ) { if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); if( POLARSSL_ENCRYPT != ctx->operation ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); -#if defined(POLARSSL_GCM_C) if( POLARSSL_MODE_GCM == ctx->cipher_info->mode ) return gcm_finish( (gcm_context *) ctx->cipher_ctx, tag, tag_len ); -#endif - return 0; + return( 0 ); } - + int cipher_check_tag( cipher_context_t *ctx, const unsigned char *tag, size_t tag_len ) { @@ -733,10 +759,9 @@ int cipher_check_tag( cipher_context_t *ctx, if( NULL == ctx || NULL == ctx->cipher_info || POLARSSL_DECRYPT != ctx->operation ) { - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); } -#if defined(POLARSSL_GCM_C) if( POLARSSL_MODE_GCM == ctx->cipher_info->mode ) { unsigned char check_tag[16]; @@ -744,7 +769,7 @@ int cipher_check_tag( cipher_context_t *ctx, int diff; if( tag_len > sizeof( check_tag ) ) - return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); if( 0 != ( ret = gcm_finish( (gcm_context *) ctx->cipher_ctx, check_tag, tag_len ) ) ) @@ -761,24 +786,125 @@ int cipher_check_tag( cipher_context_t *ctx, return( 0 ); } -#endif return( 0 ); } -#endif /* POLARSSL_CIPHER_MODE_AEAD */ +#endif /* POLARSSL_GCM_C */ -#if defined(POLARSSL_SELF_TEST) +/* + * Packet-oriented wrapper for non-AEAD modes + */ +int cipher_crypt( cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen ) +{ + int ret; + size_t finish_olen; + + if( ( ret = cipher_set_iv( ctx, iv, iv_len ) ) != 0 ) + return( ret ); + + if( ( ret = cipher_reset( ctx ) ) != 0 ) + return( ret ); + + if( ( ret = cipher_update( ctx, input, ilen, output, olen ) ) != 0 ) + return( ret ); -#include + if( ( ret = cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 ) + return( ret ); -#define ASSERT(x) if (!(x)) { \ - printf( "failed with %i at %s\n", value, (#x) ); \ - return( 1 ); \ + *olen += finish_olen; + + return( 0 ); } + +#if defined(POLARSSL_CIPHER_MODE_AEAD) /* - * Checkup routine + * Packet-oriented encryption for AEAD modes */ +int cipher_auth_encrypt( cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + unsigned char *tag, size_t tag_len ) +{ +#if defined(POLARSSL_GCM_C) + if( POLARSSL_MODE_GCM == ctx->cipher_info->mode ) + { + *olen = ilen; + return( gcm_crypt_and_tag( ctx->cipher_ctx, GCM_ENCRYPT, ilen, + iv, iv_len, ad, ad_len, input, output, + tag_len, tag ) ); + } +#endif /* POLARSSL_GCM_C */ +#if defined(POLARSSL_CCM_C) + if( POLARSSL_MODE_CCM == ctx->cipher_info->mode ) + { + *olen = ilen; + return( ccm_encrypt_and_tag( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, input, output, + tag, tag_len ) ); + } +#endif /* POLARSSL_CCM_C */ + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +/* + * Packet-oriented decryption for AEAD modes + */ +int cipher_auth_decrypt( cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + const unsigned char *tag, size_t tag_len ) +{ +#if defined(POLARSSL_GCM_C) + if( POLARSSL_MODE_GCM == ctx->cipher_info->mode ) + { + int ret; + + *olen = ilen; + ret = gcm_auth_decrypt( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, + tag, tag_len, input, output ); + + if( ret == POLARSSL_ERR_GCM_AUTH_FAILED ) + ret = POLARSSL_ERR_CIPHER_AUTH_FAILED; + + return( ret ); + } +#endif /* POLARSSL_GCM_C */ +#if defined(POLARSSL_CCM_C) + if( POLARSSL_MODE_CCM == ctx->cipher_info->mode ) + { + int ret; + + *olen = ilen; + ret = ccm_auth_decrypt( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, + input, output, tag, tag_len ); + + if( ret == POLARSSL_ERR_CCM_AUTH_FAILED ) + ret = POLARSSL_ERR_CIPHER_AUTH_FAILED; + + return( ret ); + } +#endif /* POLARSSL_CCM_C */ + + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} +#endif /* POLARSSL_CIPHER_MODE_AEAD */ + + +#if defined(POLARSSL_SELF_TEST) + +/* + * Checkup routine + */ int cipher_self_test( int verbose ) { ((void) verbose); @@ -786,6 +912,6 @@ int cipher_self_test( int verbose ) return( 0 ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_CIPHER_C */ diff --git a/pdns/ext/polarssl/library/cipher_wrap.c b/pdns/ext/polarssl/library/cipher_wrap.c index 3020e14e2..47a69a97b 100644 --- a/pdns/ext/polarssl/library/cipher_wrap.c +++ b/pdns/ext/polarssl/library/cipher_wrap.c @@ -1,11 +1,11 @@ /** * \file cipher_wrap.c - * + * * \brief Generic cipher wrapper for PolarSSL * * \author Adriaan de Jong * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_CIPHER_C) @@ -57,8 +61,12 @@ #include "polarssl/gcm.h" #endif -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_CCM_C) +#include "polarssl/ccm.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else #define polarssl_malloc malloc #define polarssl_free free @@ -78,7 +86,21 @@ static void gcm_ctx_free( void *ctx ) gcm_free( ctx ); polarssl_free( ctx ); } -#endif +#endif /* POLARSSL_GCM_C */ + +#if defined(POLARSSL_CCM_C) +/* shared by all CCM ciphers */ +static void *ccm_ctx_alloc( void ) +{ + return polarssl_malloc( sizeof( ccm_context ) ); +} + +static void ccm_ctx_free( void *ctx ) +{ + ccm_free( ctx ); + polarssl_free( ctx ); +} +#endif /* POLARSSL_CCM_C */ #if defined(POLARSSL_AES_C) @@ -92,7 +114,8 @@ static int aes_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length, unsigned char *iv, const unsigned char *input, unsigned char *output ) { #if defined(POLARSSL_CIPHER_MODE_CBC) - return aes_crypt_cbc( (aes_context *) ctx, operation, length, iv, input, output ); + return aes_crypt_cbc( (aes_context *) ctx, operation, length, iv, input, + output ); #else ((void) ctx); ((void) operation); @@ -101,15 +124,17 @@ static int aes_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length, ((void) input); ((void) output); - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); #endif /* POLARSSL_CIPHER_MODE_CBC */ } -static int aes_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t length, - size_t *iv_off, unsigned char *iv, const unsigned char *input, unsigned char *output ) +static int aes_crypt_cfb128_wrap( void *ctx, operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) { #if defined(POLARSSL_CIPHER_MODE_CFB) - return aes_crypt_cfb128( (aes_context *) ctx, operation, length, iv_off, iv, input, output ); + return aes_crypt_cfb128( (aes_context *) ctx, operation, length, iv_off, iv, + input, output ); #else ((void) ctx); ((void) operation); @@ -119,12 +144,12 @@ static int aes_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t lengt ((void) input); ((void) output); - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; -#endif + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CFB */ } -static int aes_crypt_ctr_wrap( void *ctx, size_t length, - size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block, +static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, const unsigned char *input, unsigned char *output ) { #if defined(POLARSSL_CIPHER_MODE_CTR) @@ -139,27 +164,37 @@ static int aes_crypt_ctr_wrap( void *ctx, size_t length, ((void) input); ((void) output); - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; -#endif + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CTR */ } -static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length ) +static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) { return aes_setkey_dec( (aes_context *) ctx, key, key_length ); } -static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length ) +static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) { return aes_setkey_enc( (aes_context *) ctx, key, key_length ); } static void * aes_ctx_alloc( void ) { - return polarssl_malloc( sizeof( aes_context ) ); + aes_context *aes = (aes_context *) polarssl_malloc( sizeof( aes_context ) ); + + if( aes == NULL ) + return( NULL ); + + aes_init( aes ); + + return( aes ); } static void aes_ctx_free( void *ctx ) { + aes_free( (aes_context *) ctx ); polarssl_free( ctx ); } @@ -315,7 +350,8 @@ const cipher_info_t aes_256_ctr_info = { #endif /* POLARSSL_CIPHER_MODE_CTR */ #if defined(POLARSSL_GCM_C) -static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, unsigned int key_length ) +static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) { return gcm_init( (gcm_context *) ctx, POLARSSL_CIPHER_ID_AES, key, key_length ); @@ -340,7 +376,7 @@ const cipher_info_t aes_128_gcm_info = { 128, "AES-128-GCM", 12, - 1, + POLARSSL_CIPHER_VARIABLE_IV_LEN, 16, &gcm_aes_info }; @@ -351,7 +387,7 @@ const cipher_info_t aes_192_gcm_info = { 192, "AES-192-GCM", 12, - 1, + POLARSSL_CIPHER_VARIABLE_IV_LEN, 16, &gcm_aes_info }; @@ -362,27 +398,85 @@ const cipher_info_t aes_256_gcm_info = { 256, "AES-256-GCM", 12, - 1, + POLARSSL_CIPHER_VARIABLE_IV_LEN, 16, &gcm_aes_info }; #endif /* POLARSSL_GCM_C */ -#endif +#if defined(POLARSSL_CCM_C) +static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + return ccm_init( (ccm_context *) ctx, POLARSSL_CIPHER_ID_AES, + key, key_length ); +} + +const cipher_base_t ccm_aes_info = { + POLARSSL_CIPHER_ID_AES, + NULL, + NULL, + NULL, + NULL, + NULL, + ccm_aes_setkey_wrap, + ccm_aes_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +const cipher_info_t aes_128_ccm_info = { + POLARSSL_CIPHER_AES_128_CCM, + POLARSSL_MODE_CCM, + 128, + "AES-128-CCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; + +const cipher_info_t aes_192_ccm_info = { + POLARSSL_CIPHER_AES_192_CCM, + POLARSSL_MODE_CCM, + 192, + "AES-192-CCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; + +const cipher_info_t aes_256_ccm_info = { + POLARSSL_CIPHER_AES_256_CCM, + POLARSSL_MODE_CCM, + 256, + "AES-256-CCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; +#endif /* POLARSSL_CCM_C */ + +#endif /* POLARSSL_AES_C */ #if defined(POLARSSL_CAMELLIA_C) static int camellia_crypt_ecb_wrap( void *ctx, operation_t operation, const unsigned char *input, unsigned char *output ) { - return camellia_crypt_ecb( (camellia_context *) ctx, operation, input, output ); + return camellia_crypt_ecb( (camellia_context *) ctx, operation, input, + output ); } -static int camellia_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output ) +static int camellia_crypt_cbc_wrap( void *ctx, operation_t operation, + size_t length, unsigned char *iv, + const unsigned char *input, unsigned char *output ) { #if defined(POLARSSL_CIPHER_MODE_CBC) - return camellia_crypt_cbc( (camellia_context *) ctx, operation, length, iv, input, output ); + return camellia_crypt_cbc( (camellia_context *) ctx, operation, length, iv, + input, output ); #else ((void) ctx); ((void) operation); @@ -391,15 +485,17 @@ static int camellia_crypt_cbc_wrap( void *ctx, operation_t operation, size_t len ((void) input); ((void) output); - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); #endif /* POLARSSL_CIPHER_MODE_CBC */ } -static int camellia_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t length, - size_t *iv_off, unsigned char *iv, const unsigned char *input, unsigned char *output ) +static int camellia_crypt_cfb128_wrap( void *ctx, operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) { #if defined(POLARSSL_CIPHER_MODE_CFB) - return camellia_crypt_cfb128( (camellia_context *) ctx, operation, length, iv_off, iv, input, output ); + return camellia_crypt_cfb128( (camellia_context *) ctx, operation, length, + iv_off, iv, input, output ); #else ((void) ctx); ((void) operation); @@ -409,17 +505,17 @@ static int camellia_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t ((void) input); ((void) output); - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; -#endif + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CFB */ } -static int camellia_crypt_ctr_wrap( void *ctx, size_t length, - size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block, +static int camellia_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, const unsigned char *input, unsigned char *output ) { #if defined(POLARSSL_CIPHER_MODE_CTR) - return camellia_crypt_ctr( (camellia_context *) ctx, length, nc_off, nonce_counter, - stream_block, input, output ); + return camellia_crypt_ctr( (camellia_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output ); #else ((void) ctx); ((void) length); @@ -429,27 +525,38 @@ static int camellia_crypt_ctr_wrap( void *ctx, size_t length, ((void) input); ((void) output); - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; -#endif + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CTR */ } -static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length ) +static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) { return camellia_setkey_dec( (camellia_context *) ctx, key, key_length ); } -static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length ) +static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) { return camellia_setkey_enc( (camellia_context *) ctx, key, key_length ); } static void * camellia_ctx_alloc( void ) { - return polarssl_malloc( sizeof( camellia_context ) ); + camellia_context *ctx; + ctx = (camellia_context *) polarssl_malloc( sizeof( camellia_context ) ); + + if( ctx == NULL ) + return( NULL ); + + camellia_init( ctx ); + + return( ctx ); } static void camellia_ctx_free( void *ctx ) { + camellia_free( (camellia_context *) ctx ); polarssl_free( ctx ); } @@ -605,7 +712,8 @@ const cipher_info_t camellia_256_ctr_info = { #endif /* POLARSSL_CIPHER_MODE_CTR */ #if defined(POLARSSL_GCM_C) -static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key, unsigned int key_length ) +static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) { return gcm_init( (gcm_context *) ctx, POLARSSL_CIPHER_ID_CAMELLIA, key, key_length ); @@ -630,7 +738,7 @@ const cipher_info_t camellia_128_gcm_info = { 128, "CAMELLIA-128-GCM", 12, - 1, + POLARSSL_CIPHER_VARIABLE_IV_LEN, 16, &gcm_camellia_info }; @@ -641,7 +749,7 @@ const cipher_info_t camellia_192_gcm_info = { 192, "CAMELLIA-192-GCM", 12, - 1, + POLARSSL_CIPHER_VARIABLE_IV_LEN, 16, &gcm_camellia_info }; @@ -652,12 +760,67 @@ const cipher_info_t camellia_256_gcm_info = { 256, "CAMELLIA-256-GCM", 12, - 1, + POLARSSL_CIPHER_VARIABLE_IV_LEN, 16, &gcm_camellia_info }; #endif /* POLARSSL_GCM_C */ +#if defined(POLARSSL_CCM_C) +static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + return ccm_init( (ccm_context *) ctx, POLARSSL_CIPHER_ID_CAMELLIA, + key, key_length ); +} + +const cipher_base_t ccm_camellia_info = { + POLARSSL_CIPHER_ID_CAMELLIA, + NULL, + NULL, + NULL, + NULL, + NULL, + ccm_camellia_setkey_wrap, + ccm_camellia_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +const cipher_info_t camellia_128_ccm_info = { + POLARSSL_CIPHER_CAMELLIA_128_CCM, + POLARSSL_MODE_CCM, + 128, + "CAMELLIA-128-CCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; + +const cipher_info_t camellia_192_ccm_info = { + POLARSSL_CIPHER_CAMELLIA_192_CCM, + POLARSSL_MODE_CCM, + 192, + "CAMELLIA-192-CCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; + +const cipher_info_t camellia_256_ccm_info = { + POLARSSL_CIPHER_CAMELLIA_256_CCM, + POLARSSL_MODE_CCM, + 256, + "CAMELLIA-256-CCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; +#endif /* POLARSSL_CCM_C */ + #endif /* POLARSSL_CAMELLIA_C */ #if defined(POLARSSL_DES_C) @@ -680,7 +843,8 @@ static int des_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length, unsigned char *iv, const unsigned char *input, unsigned char *output ) { #if defined(POLARSSL_CIPHER_MODE_CBC) - return des_crypt_cbc( (des_context *) ctx, operation, length, iv, input, output ); + return des_crypt_cbc( (des_context *) ctx, operation, length, iv, input, + output ); #else ((void) ctx); ((void) operation); @@ -689,7 +853,7 @@ static int des_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length, ((void) input); ((void) output); - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); #endif /* POLARSSL_CIPHER_MODE_CBC */ } @@ -697,7 +861,8 @@ static int des3_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length, unsigned char *iv, const unsigned char *input, unsigned char *output ) { #if defined(POLARSSL_CIPHER_MODE_CBC) - return des3_crypt_cbc( (des3_context *) ctx, operation, length, iv, input, output ); + return des3_crypt_cbc( (des3_context *) ctx, operation, length, iv, input, + output ); #else ((void) ctx); ((void) operation); @@ -706,75 +871,52 @@ static int des3_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length, ((void) input); ((void) output); - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); #endif /* POLARSSL_CIPHER_MODE_CBC */ } -static int des_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t length, - size_t *iv_off, unsigned char *iv, const unsigned char *input, unsigned char *output ) -{ - ((void) ctx); - ((void) operation); - ((void) length); - ((void) iv_off); - ((void) iv); - ((void) input); - ((void) output); - - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; -} - -static int des_crypt_ctr_wrap( void *ctx, size_t length, - size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ) -{ - ((void) ctx); - ((void) length); - ((void) nc_off); - ((void) nonce_counter); - ((void) stream_block); - ((void) input); - ((void) output); - - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; -} - -static int des_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length ) +static int des_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) { ((void) key_length); return des_setkey_dec( (des_context *) ctx, key ); } -static int des_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length ) +static int des_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) { ((void) key_length); return des_setkey_enc( (des_context *) ctx, key ); } -static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length ) +static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) { ((void) key_length); return des3_set2key_dec( (des3_context *) ctx, key ); } -static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length ) +static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) { ((void) key_length); return des3_set2key_enc( (des3_context *) ctx, key ); } -static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length ) +static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) { ((void) key_length); return des3_set3key_dec( (des3_context *) ctx, key ); } -static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length ) +static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) { ((void) key_length); @@ -783,16 +925,38 @@ static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, unsigned static void * des_ctx_alloc( void ) { - return polarssl_malloc( sizeof( des_context ) ); + des_context *des = (des_context *) polarssl_malloc( sizeof( des_context ) ); + + if( des == NULL ) + return( NULL ); + + des_init( des ); + + return( des ); +} + +static void des_ctx_free( void *ctx ) +{ + des_free( (des_context *) ctx ); + polarssl_free( ctx ); } static void * des3_ctx_alloc( void ) { - return polarssl_malloc( sizeof( des3_context ) ); + des3_context *des3; + des3 = (des3_context *) polarssl_malloc( sizeof( des3_context ) ); + + if( des3 == NULL ) + return( NULL ); + + des3_init( des3 ); + + return( des3 ); } -static void des_ctx_free( void *ctx ) +static void des3_ctx_free( void *ctx ) { + des3_free( (des3_context *) ctx ); polarssl_free( ctx ); } @@ -800,8 +964,8 @@ const cipher_base_t des_info = { POLARSSL_CIPHER_ID_DES, des_crypt_ecb_wrap, des_crypt_cbc_wrap, - des_crypt_cfb128_wrap, - des_crypt_ctr_wrap, + NULL, + NULL, NULL, des_setkey_enc_wrap, des_setkey_dec_wrap, @@ -837,13 +1001,13 @@ const cipher_base_t des_ede_info = { POLARSSL_CIPHER_ID_DES, des3_crypt_ecb_wrap, des3_crypt_cbc_wrap, - des_crypt_cfb128_wrap, - des_crypt_ctr_wrap, + NULL, + NULL, NULL, des3_set2key_enc_wrap, des3_set2key_dec_wrap, des3_ctx_alloc, - des_ctx_free + des3_ctx_free }; const cipher_info_t des_ede_ecb_info = { @@ -874,13 +1038,13 @@ const cipher_base_t des_ede3_info = { POLARSSL_CIPHER_ID_DES, des3_crypt_ecb_wrap, des3_crypt_cbc_wrap, - des_crypt_cfb128_wrap, - des_crypt_ctr_wrap, + NULL, + NULL, NULL, des3_set3key_enc_wrap, des3_set3key_dec_wrap, des3_ctx_alloc, - des_ctx_free + des3_ctx_free }; const cipher_info_t des_ede3_ecb_info = { @@ -905,21 +1069,24 @@ const cipher_info_t des_ede3_cbc_info = { &des_ede3_info }; #endif /* POLARSSL_CIPHER_MODE_CBC */ -#endif +#endif /* POLARSSL_DES_C */ #if defined(POLARSSL_BLOWFISH_C) static int blowfish_crypt_ecb_wrap( void *ctx, operation_t operation, const unsigned char *input, unsigned char *output ) { - return blowfish_crypt_ecb( (blowfish_context *) ctx, operation, input, output ); + return blowfish_crypt_ecb( (blowfish_context *) ctx, operation, input, + output ); } -static int blowfish_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output ) +static int blowfish_crypt_cbc_wrap( void *ctx, operation_t operation, + size_t length, unsigned char *iv, const unsigned char *input, + unsigned char *output ) { #if defined(POLARSSL_CIPHER_MODE_CBC) - return blowfish_crypt_cbc( (blowfish_context *) ctx, operation, length, iv, input, output ); + return blowfish_crypt_cbc( (blowfish_context *) ctx, operation, length, iv, + input, output ); #else ((void) ctx); ((void) operation); @@ -928,15 +1095,17 @@ static int blowfish_crypt_cbc_wrap( void *ctx, operation_t operation, size_t len ((void) input); ((void) output); - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); #endif /* POLARSSL_CIPHER_MODE_CBC */ } -static int blowfish_crypt_cfb64_wrap( void *ctx, operation_t operation, size_t length, - size_t *iv_off, unsigned char *iv, const unsigned char *input, unsigned char *output ) +static int blowfish_crypt_cfb64_wrap( void *ctx, operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) { #if defined(POLARSSL_CIPHER_MODE_CFB) - return blowfish_crypt_cfb64( (blowfish_context *) ctx, operation, length, iv_off, iv, input, output ); + return blowfish_crypt_cfb64( (blowfish_context *) ctx, operation, length, + iv_off, iv, input, output ); #else ((void) ctx); ((void) operation); @@ -946,17 +1115,17 @@ static int blowfish_crypt_cfb64_wrap( void *ctx, operation_t operation, size_t l ((void) input); ((void) output); - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; -#endif + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CFB */ } -static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, - size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block, +static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, const unsigned char *input, unsigned char *output ) { #if defined(POLARSSL_CIPHER_MODE_CTR) - return blowfish_crypt_ctr( (blowfish_context *) ctx, length, nc_off, nonce_counter, - stream_block, input, output ); + return blowfish_crypt_ctr( (blowfish_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output ); #else ((void) ctx); ((void) length); @@ -966,22 +1135,32 @@ static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, ((void) input); ((void) output); - return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; -#endif + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CTR */ } -static int blowfish_setkey_wrap( void *ctx, const unsigned char *key, unsigned int key_length ) +static int blowfish_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) { return blowfish_setkey( (blowfish_context *) ctx, key, key_length ); } static void * blowfish_ctx_alloc( void ) { - return polarssl_malloc( sizeof( blowfish_context ) ); + blowfish_context *ctx; + ctx = (blowfish_context *) polarssl_malloc( sizeof( blowfish_context ) ); + + if( ctx == NULL ) + return( NULL ); + + blowfish_init( ctx ); + + return( ctx ); } static void blowfish_ctx_free( void *ctx ) { + blowfish_free( (blowfish_context *) ctx ); polarssl_free( ctx ); } @@ -1004,7 +1183,7 @@ const cipher_info_t blowfish_ecb_info = { 128, "BLOWFISH-ECB", 8, - 0, + POLARSSL_CIPHER_VARIABLE_KEY_LEN, 8, &blowfish_info }; @@ -1016,7 +1195,7 @@ const cipher_info_t blowfish_cbc_info = { 128, "BLOWFISH-CBC", 8, - 0, + POLARSSL_CIPHER_VARIABLE_KEY_LEN, 8, &blowfish_info }; @@ -1029,7 +1208,7 @@ const cipher_info_t blowfish_cfb64_info = { 128, "BLOWFISH-CFB64", 8, - 0, + POLARSSL_CIPHER_VARIABLE_KEY_LEN, 8, &blowfish_info }; @@ -1042,7 +1221,7 @@ const cipher_info_t blowfish_ctr_info = { 128, "BLOWFISH-CTR", 8, - 0, + POLARSSL_CIPHER_VARIABLE_KEY_LEN, 8, &blowfish_info }; @@ -1061,7 +1240,7 @@ static int arc4_setkey_wrap( void *ctx, const unsigned char *key, unsigned int key_length ) { /* we get key_length in bits, arc4 expects it in bytes */ - if( key_length % 8 != 0) + if( key_length % 8 != 0 ) return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); arc4_setup( (arc4_context *) ctx, key, key_length / 8 ); @@ -1070,11 +1249,20 @@ static int arc4_setkey_wrap( void *ctx, const unsigned char *key, static void * arc4_ctx_alloc( void ) { - return polarssl_malloc( sizeof( arc4_context ) ); + arc4_context *ctx; + ctx = (arc4_context *) polarssl_malloc( sizeof( arc4_context ) ); + + if( ctx == NULL ) + return( NULL ); + + arc4_init( ctx ); + + return( ctx ); } static void arc4_ctx_free( void *ctx ) { + arc4_free( (arc4_context *) ctx ); polarssl_free( ctx ); } @@ -1125,7 +1313,7 @@ static int null_setkey( void *ctx, const unsigned char *key, static void * null_ctx_alloc( void ) { - return (void *) 1; + return( (void *) 1 ) } static void null_ctx_free( void *ctx ) @@ -1184,6 +1372,11 @@ const cipher_definition_t cipher_definitions[] = { POLARSSL_CIPHER_AES_192_GCM, &aes_192_gcm_info }, { POLARSSL_CIPHER_AES_256_GCM, &aes_256_gcm_info }, #endif +#if defined(POLARSSL_CCM_C) + { POLARSSL_CIPHER_AES_128_CCM, &aes_128_ccm_info }, + { POLARSSL_CIPHER_AES_192_CCM, &aes_192_ccm_info }, + { POLARSSL_CIPHER_AES_256_CCM, &aes_256_ccm_info }, +#endif #endif /* POLARSSL_AES_C */ #if defined(POLARSSL_ARC4_C) @@ -1227,6 +1420,11 @@ const cipher_definition_t cipher_definitions[] = { POLARSSL_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info }, { POLARSSL_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info }, #endif +#if defined(POLARSSL_CCM_C) + { POLARSSL_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info }, + { POLARSSL_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info }, + { POLARSSL_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info }, +#endif #endif /* POLARSSL_CAMELLIA_C */ #if defined(POLARSSL_DES_C) @@ -1250,4 +1448,4 @@ const cipher_definition_t cipher_definitions[] = #define NUM_CIPHERS sizeof cipher_definitions / sizeof cipher_definitions[0] int supported_ciphers[NUM_CIPHERS]; -#endif +#endif /* POLARSSL_CIPHER_C */ diff --git a/pdns/ext/polarssl/library/ctr_drbg.c b/pdns/ext/polarssl/library/ctr_drbg.c index 53b8b54c3..96ee4f162 100644 --- a/pdns/ext/polarssl/library/ctr_drbg.c +++ b/pdns/ext/polarssl/library/ctr_drbg.c @@ -1,7 +1,7 @@ /* * CTR_DRBG implementation based on AES-256 (NIST SP 800-90) * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -28,7 +28,11 @@ * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_CTR_DRBG_C) @@ -38,6 +42,17 @@ #include #endif +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + /* * Non-public function wrapped by ctr_crbg_init(). Necessary to allow NIST * tests to succeed (which require known length fixed entropy) @@ -56,6 +71,8 @@ int ctr_drbg_init_entropy_len( memset( ctx, 0, sizeof(ctr_drbg_context) ); memset( key, 0, CTR_DRBG_KEYSIZE ); + aes_init( &ctx->aes_ctx ); + ctx->f_entropy = f_entropy; ctx->p_entropy = p_entropy; @@ -83,6 +100,15 @@ int ctr_drbg_init( ctr_drbg_context *ctx, CTR_DRBG_ENTROPY_LEN ) ); } +void ctr_drbg_free( ctr_drbg_context *ctx ) +{ + if( ctx == NULL ) + return; + + aes_free( &ctx->aes_ctx ); + polarssl_zeroize( ctx, sizeof( ctr_drbg_context ) ); +} + void ctr_drbg_set_prediction_resistance( ctr_drbg_context *ctx, int resistance ) { ctx->prediction_resistance = resistance; @@ -105,13 +131,14 @@ static int block_cipher_df( unsigned char *output, unsigned char tmp[CTR_DRBG_SEEDLEN]; unsigned char key[CTR_DRBG_KEYSIZE]; unsigned char chain[CTR_DRBG_BLOCKSIZE]; - unsigned char *p = buf, *iv; + unsigned char *p, *iv; aes_context aes_ctx; int i, j; size_t buf_len, use_len; memset( buf, 0, CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16 ); + aes_init( &aes_ctx ); /* * Construct IV (16 bytes) and S in buffer @@ -179,6 +206,8 @@ static int block_cipher_df( unsigned char *output, p += CTR_DRBG_BLOCKSIZE; } + aes_free( &aes_ctx ); + return( 0 ); } @@ -276,7 +305,7 @@ int ctr_drbg_reseed( ctr_drbg_context *ctx, return( 0 ); } - + int ctr_drbg_random_with_add( void *p_rng, unsigned char *output, size_t output_len, const unsigned char *additional, size_t add_len ) @@ -326,7 +355,8 @@ int ctr_drbg_random_with_add( void *p_rng, */ aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, tmp ); - use_len = (output_len > CTR_DRBG_BLOCKSIZE ) ? CTR_DRBG_BLOCKSIZE : output_len; + use_len = ( output_len > CTR_DRBG_BLOCKSIZE ) ? CTR_DRBG_BLOCKSIZE : + output_len; /* * Copy random block to destination */ @@ -410,7 +440,7 @@ int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path ) #include -unsigned char entropy_source_pr[96] = +static unsigned char entropy_source_pr[96] = { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16, 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02, 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b, @@ -424,7 +454,7 @@ unsigned char entropy_source_pr[96] = 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56, 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 }; -unsigned char entropy_source_nopr[64] = +static unsigned char entropy_source_nopr[64] = { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14, 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe, 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d, @@ -434,32 +464,39 @@ unsigned char entropy_source_nopr[64] = 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e, 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e }; -unsigned char nonce_pers_pr[16] = +static const unsigned char nonce_pers_pr[16] = { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2, 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c }; -unsigned char nonce_pers_nopr[16] = +static const unsigned char nonce_pers_nopr[16] = { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5, 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f }; -unsigned char result_pr[16] = +static const unsigned char result_pr[16] = { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f, 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 }; -unsigned char result_nopr[16] = +static const unsigned char result_nopr[16] = { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88, 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f }; -int test_offset; +static size_t test_offset; static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, size_t len ) { - unsigned char *p = data; + const unsigned char *p = data; memcpy( buf, p + test_offset, len ); - test_offset += 32; + test_offset += len; return( 0 ); } +#define CHK( c ) if( (c) != 0 ) \ + { \ + if( verbose != 0 ) \ + polarssl_printf( "failed\n" ); \ + return( 1 ); \ + } + /* * Checkup routine */ @@ -472,100 +509,41 @@ int ctr_drbg_self_test( int verbose ) * Based on a NIST CTR_DRBG test vector (PR = True) */ if( verbose != 0 ) - printf( " CTR_DRBG (PR = TRUE) : " ); + polarssl_printf( " CTR_DRBG (PR = TRUE) : " ); test_offset = 0; - if( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, entropy_source_pr, nonce_pers_pr, 16, 32 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } + CHK( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, + entropy_source_pr, nonce_pers_pr, 16, 32 ) ); ctr_drbg_set_prediction_resistance( &ctx, CTR_DRBG_PR_ON ); + CHK( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) ); + CHK( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) ); + CHK( memcmp( buf, result_pr, CTR_DRBG_BLOCKSIZE ) ); - if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( memcmp( buf, result_pr, CTR_DRBG_BLOCKSIZE ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); /* * Based on a NIST CTR_DRBG test vector (PR = FALSE) */ if( verbose != 0 ) - printf( " CTR_DRBG (PR = FALSE): " ); + polarssl_printf( " CTR_DRBG (PR = FALSE): " ); test_offset = 0; - if( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, entropy_source_nopr, nonce_pers_nopr, 16, 32 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( ctr_drbg_random( &ctx, buf, 16 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( ctr_drbg_reseed( &ctx, NULL, 0 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); + CHK( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, + entropy_source_nopr, nonce_pers_nopr, 16, 32 ) ); + CHK( ctr_drbg_random( &ctx, buf, 16 ) ); + CHK( ctr_drbg_reseed( &ctx, NULL, 0 ) ); + CHK( ctr_drbg_random( &ctx, buf, 16 ) ); + CHK( memcmp( buf, result_nopr, 16 ) ); - return( 1 ); - } - - if( ctr_drbg_random( &ctx, buf, 16 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( memcmp( buf, result_nopr, 16 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); return( 0 ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_CTR_DRBG_C */ diff --git a/pdns/ext/polarssl/library/debug.c b/pdns/ext/polarssl/library/debug.c index 371cbf95c..a81f502bf 100644 --- a/pdns/ext/polarssl/library/debug.c +++ b/pdns/ext/polarssl/library/debug.c @@ -1,7 +1,7 @@ /* * Debugging routines * - * Copyright (C) 2006-2010, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,7 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_DEBUG_C) @@ -46,6 +50,19 @@ #endif #endif /* _MSC_VER */ +static int debug_log_mode = POLARSSL_DEBUG_DFL_MODE; +static int debug_threshold = 0; + +void debug_set_log_mode( int log_mode ) +{ + debug_log_mode = log_mode; +} + +void debug_set_threshold( int threshold ) +{ + debug_threshold = threshold; +} + char *debug_fmt( const char *format, ... ) { va_list argp; @@ -66,8 +83,14 @@ void debug_print_msg( const ssl_context *ssl, int level, char str[512]; int maxlen = sizeof( str ) - 1; - if( ssl->f_dbg == NULL ) + if( ssl->f_dbg == NULL || level > debug_threshold ) + return; + + if( debug_log_mode == POLARSSL_DEBUG_LOG_RAW ) + { + ssl->f_dbg( ssl->p_dbg, level, text ); return; + } snprintf( str, maxlen, "%s(%04d): %s\n", file, line, text ); str[maxlen] = '\0'; @@ -80,12 +103,16 @@ void debug_print_ret( const ssl_context *ssl, int level, { char str[512]; int maxlen = sizeof( str ) - 1; + size_t idx = 0; - if( ssl->f_dbg == NULL ) + if( ssl->f_dbg == NULL || level > debug_threshold ) return; - snprintf( str, maxlen, "%s(%04d): %s() returned %d (0x%x)\n", - file, line, text, ret, ret ); + if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL ) + idx = snprintf( str, maxlen, "%s(%04d): ", file, line ); + + snprintf( str + idx, maxlen - idx, "%s() returned %d (-0x%04x)\n", + text, ret, -ret ); str[maxlen] = '\0'; ssl->f_dbg( ssl->p_dbg, level, str ); @@ -96,17 +123,21 @@ void debug_print_buf( const ssl_context *ssl, int level, unsigned char *buf, size_t len ) { char str[512]; - size_t i, maxlen = sizeof( str ) - 1; + size_t i, maxlen = sizeof( str ) - 1, idx = 0; - if( ssl->f_dbg == NULL ) + if( ssl->f_dbg == NULL || level > debug_threshold ) return; - snprintf( str, maxlen, "%s(%04d): dumping '%s' (%d bytes)\n", - file, line, text, (unsigned int) len ); + if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL ) + idx = snprintf( str, maxlen, "%s(%04d): ", file, line ); + + snprintf( str + idx, maxlen - idx, "dumping '%s' (%u bytes)\n", + text, (unsigned int) len ); str[maxlen] = '\0'; ssl->f_dbg( ssl->p_dbg, level, str ); + idx = 0; for( i = 0; i < len; i++ ) { if( i >= 4096 ) @@ -115,23 +146,29 @@ void debug_print_buf( const ssl_context *ssl, int level, if( i % 16 == 0 ) { if( i > 0 ) - ssl->f_dbg( ssl->p_dbg, level, "\n" ); + { + snprintf( str + idx, maxlen - idx, "\n" ); + ssl->f_dbg( ssl->p_dbg, level, str ); + idx = 0; + } - snprintf( str, maxlen, "%s(%04d): %04x: ", file, line, - (unsigned int) i ); + if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL ) + idx = snprintf( str, maxlen, "%s(%04d): ", file, line ); - str[maxlen] = '\0'; - ssl->f_dbg( ssl->p_dbg, level, str ); - } + idx += snprintf( str + idx, maxlen - idx, "%04x: ", + (unsigned int) i ); - snprintf( str, maxlen, " %02x", (unsigned int) buf[i] ); + } - str[maxlen] = '\0'; - ssl->f_dbg( ssl->p_dbg, level, str ); + idx += snprintf( str + idx, maxlen - idx, " %02x", + (unsigned int) buf[i] ); } if( len > 0 ) - ssl->f_dbg( ssl->p_dbg, level, "\n" ); + { + snprintf( str + idx, maxlen - idx, "\n" ); + ssl->f_dbg( ssl->p_dbg, level, str ); + } } #if defined(POLARSSL_ECP_C) @@ -142,6 +179,9 @@ void debug_print_ecp( const ssl_context *ssl, int level, char str[512]; int maxlen = sizeof( str ) - 1; + if( ssl->f_dbg == NULL || level > debug_threshold ) + return; + snprintf( str, maxlen, "%s(X)", text ); str[maxlen] = '\0'; debug_print_mpi( ssl, level, file, line, str, &X->X ); @@ -149,10 +189,6 @@ void debug_print_ecp( const ssl_context *ssl, int level, snprintf( str, maxlen, "%s(Y)", text ); str[maxlen] = '\0'; debug_print_mpi( ssl, level, file, line, str, &X->Y ); - - snprintf( str, maxlen, "%s(Z)", text ); - str[maxlen] = '\0'; - debug_print_mpi( ssl, level, file, line, str, &X->Z ); } #endif /* POLARSSL_ECP_C */ @@ -163,9 +199,9 @@ void debug_print_mpi( const ssl_context *ssl, int level, { char str[512]; int j, k, maxlen = sizeof( str ) - 1, zeros = 1; - size_t i, n; + size_t i, n, idx = 0; - if( ssl->f_dbg == NULL || X == NULL ) + if( ssl->f_dbg == NULL || X == NULL || level > debug_threshold ) return; for( n = X->n - 1; n > 0; n-- ) @@ -176,13 +212,16 @@ void debug_print_mpi( const ssl_context *ssl, int level, if( ( ( X->p[n] >> j ) & 1 ) != 0 ) break; - snprintf( str, maxlen, "%s(%04d): value of '%s' (%d bits) is:\n", - file, line, text, - (int) ( ( n * ( sizeof(t_uint) << 3 ) ) + j + 1 ) ); + if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL ) + idx = snprintf( str, maxlen, "%s(%04d): ", file, line ); + + snprintf( str + idx, maxlen - idx, "value of '%s' (%d bits) is:\n", + text, (int) ( ( n * ( sizeof(t_uint) << 3 ) ) + j + 1 ) ); str[maxlen] = '\0'; ssl->f_dbg( ssl->p_dbg, level, str ); + idx = 0; for( i = n + 1, j = 0; i > 0; i-- ) { if( zeros && X->p[i - 1] == 0 ) @@ -190,7 +229,7 @@ void debug_print_mpi( const ssl_context *ssl, int level, for( k = sizeof( t_uint ) - 1; k >= 0; k-- ) { - if( zeros && ( ( X->p[i - 1] >> (k << 3) ) & 0xFF ) == 0 ) + if( zeros && ( ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ) == 0 ) continue; else zeros = 0; @@ -198,19 +237,18 @@ void debug_print_mpi( const ssl_context *ssl, int level, if( j % 16 == 0 ) { if( j > 0 ) - ssl->f_dbg( ssl->p_dbg, level, "\n" ); - - snprintf( str, maxlen, "%s(%04d): ", file, line ); - - str[maxlen] = '\0'; - ssl->f_dbg( ssl->p_dbg, level, str ); + { + snprintf( str + idx, maxlen - idx, "\n" ); + ssl->f_dbg( ssl->p_dbg, level, str ); + idx = 0; + } + + if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL ) + idx = snprintf( str, maxlen, "%s(%04d): ", file, line ); } - snprintf( str, maxlen, " %02x", (unsigned int) - ( X->p[i - 1] >> (k << 3) ) & 0xFF ); - - str[maxlen] = '\0'; - ssl->f_dbg( ssl->p_dbg, level, str ); + idx += snprintf( str + idx, maxlen - idx, " %02x", (unsigned int) + ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ); j++; } @@ -219,14 +257,16 @@ void debug_print_mpi( const ssl_context *ssl, int level, if( zeros == 1 ) { - snprintf( str, maxlen, "%s(%04d): ", file, line ); + if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL ) + { + idx = snprintf( str, maxlen, "%s(%04d): ", file, line ); - str[maxlen] = '\0'; - ssl->f_dbg( ssl->p_dbg, level, str ); - ssl->f_dbg( ssl->p_dbg, level, " 00" ); + } + idx += snprintf( str + idx, maxlen - idx, " 00" ); } - ssl->f_dbg( ssl->p_dbg, level, "\n" ); + snprintf( str + idx, maxlen - idx, "\n" ); + ssl->f_dbg( ssl->p_dbg, level, str ); } #endif /* POLARSSL_BIGNUM_C */ @@ -247,7 +287,7 @@ static void debug_print_pk( const ssl_context *ssl, int level, return; } - for( i = 0; i < sizeof( items ); i++ ) + for( i = 0; i < POLARSSL_PK_DEBUG_MAX_ITEMS; i++ ) { if( items[i].type == POLARSSL_PK_DEBUG_NONE ) return; @@ -272,13 +312,19 @@ void debug_print_crt( const ssl_context *ssl, int level, const char *text, const x509_crt *crt ) { char str[1024], prefix[64]; - int i = 0, maxlen = sizeof( prefix ) - 1; + int i = 0, maxlen = sizeof( prefix ) - 1, idx = 0; - if( ssl->f_dbg == NULL || crt == NULL ) + if( ssl->f_dbg == NULL || crt == NULL || level > debug_threshold ) return; - snprintf( prefix, maxlen, "%s(%04d): ", file, line ); - prefix[maxlen] = '\0'; + if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL ) + { + snprintf( prefix, maxlen, "%s(%04d): ", file, line ); + prefix[maxlen] = '\0'; + } + else + prefix[0] = '\0'; + maxlen = sizeof( str ) - 1; while( crt != NULL ) @@ -286,8 +332,11 @@ void debug_print_crt( const ssl_context *ssl, int level, char buf[1024]; x509_crt_info( buf, sizeof( buf ) - 1, prefix, crt ); - snprintf( str, maxlen, "%s(%04d): %s #%d:\n%s", - file, line, text, ++i, buf ); + if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL ) + idx = snprintf( str, maxlen, "%s(%04d): ", file, line ); + + snprintf( str + idx, maxlen - idx, "%s #%d:\n%s", + text, ++i, buf ); str[maxlen] = '\0'; ssl->f_dbg( ssl->p_dbg, level, str ); @@ -299,4 +348,4 @@ void debug_print_crt( const ssl_context *ssl, int level, } #endif /* POLARSSL_X509_CRT_PARSE_C */ -#endif +#endif /* POLARSSL_DEBUG_C */ diff --git a/pdns/ext/polarssl/library/des.c b/pdns/ext/polarssl/library/des.c index 153810d72..12fe4f46a 100644 --- a/pdns/ext/polarssl/library/des.c +++ b/pdns/ext/polarssl/library/des.c @@ -1,7 +1,7 @@ /* * FIPS-46-3 compliant Triple-DES implementation * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -29,14 +29,29 @@ * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_DES_C) #include "polarssl/des.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + #if !defined(POLARSSL_DES_ALT) +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + /* * 32-bit integer manipulation macros (big endian) */ @@ -290,6 +305,32 @@ static const uint32_t RHs[16] = #define SWAP(a,b) { uint32_t t = a; a = b; b = t; t = 0; } +void des_init( des_context *ctx ) +{ + memset( ctx, 0, sizeof( des_context ) ); +} + +void des_free( des_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( des_context ) ); +} + +void des3_init( des3_context *ctx ) +{ + memset( ctx, 0, sizeof( des3_context ) ); +} + +void des3_free( des3_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( des3_context ) ); +} + static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8, 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44, 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81, @@ -317,7 +358,7 @@ int des_key_check_key_parity( const unsigned char key[DES_KEY_SIZE] ) int i; for( i = 0; i < DES_KEY_SIZE; i++ ) - if ( key[i] != odd_parity_table[key[i] / 2] ) + if( key[i] != odd_parity_table[key[i] / 2] ) return( 1 ); return( 0 ); @@ -372,7 +413,7 @@ int des_key_check_weak( const unsigned char key[DES_KEY_SIZE] ) int i; for( i = 0; i < WEAK_KEY_COUNT; i++ ) - if( memcmp( weak_key_table[i], key, DES_KEY_SIZE) == 0) + if( memcmp( weak_key_table[i], key, DES_KEY_SIZE) == 0 ) return( 1 ); return( 0 ); @@ -503,12 +544,13 @@ static void des3_set2key( uint32_t esk[96], /* * Triple-DES key schedule (112-bit, encryption) */ -int des3_set2key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] ) +int des3_set2key_enc( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 2] ) { uint32_t sk[96]; des3_set2key( ctx->sk, sk, key ); - memset( sk, 0, sizeof( sk ) ); + polarssl_zeroize( sk, sizeof( sk ) ); return( 0 ); } @@ -516,12 +558,13 @@ int des3_set2key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * /* * Triple-DES key schedule (112-bit, decryption) */ -int des3_set2key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] ) +int des3_set2key_dec( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 2] ) { uint32_t sk[96]; des3_set2key( sk, ctx->sk, key ); - memset( sk, 0, sizeof( sk ) ); + polarssl_zeroize( sk, sizeof( sk ) ); return( 0 ); } @@ -552,12 +595,13 @@ static void des3_set3key( uint32_t esk[96], /* * Triple-DES key schedule (168-bit, encryption) */ -int des3_set3key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] ) +int des3_set3key_enc( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 3] ) { uint32_t sk[96]; des3_set3key( ctx->sk, sk, key ); - memset( sk, 0, sizeof( sk ) ); + polarssl_zeroize( sk, sizeof( sk ) ); return( 0 ); } @@ -565,12 +609,13 @@ int des3_set3key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * /* * Triple-DES key schedule (168-bit, decryption) */ -int des3_set3key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] ) +int des3_set3key_dec( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 3] ) { uint32_t sk[96]; des3_set3key( sk, ctx->sk, key ); - memset( sk, 0, sizeof( sk ) ); + polarssl_zeroize( sk, sizeof( sk ) ); return( 0 ); } @@ -775,11 +820,6 @@ static const unsigned char des3_test_keys[24] = 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 }; -static const unsigned char des3_test_iv[8] = -{ - 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, -}; - static const unsigned char des3_test_buf[8] = { 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 @@ -799,6 +839,12 @@ static const unsigned char des3_test_ecb_enc[3][8] = { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 } }; +#if defined(POLARSSL_CIPHER_MODE_CBC) +static const unsigned char des3_test_iv[8] = +{ + 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, +}; + static const unsigned char des3_test_cbc_dec[3][8] = { { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 }, @@ -812,24 +858,24 @@ static const unsigned char des3_test_cbc_enc[3][8] = { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D }, { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 } }; +#endif /* POLARSSL_CIPHER_MODE_CBC */ /* * Checkup routine */ int des_self_test( int verbose ) { - int i, j, u, v; + int i, j, u, v, ret = 0; des_context ctx; des3_context ctx3; - unsigned char key[24]; unsigned char buf[8]; #if defined(POLARSSL_CIPHER_MODE_CBC) unsigned char prv[8]; unsigned char iv[8]; #endif - memset( key, 0, 24 ); - + des_init( &ctx ); + des3_init( &ctx3 ); /* * ECB mode */ @@ -839,9 +885,9 @@ int des_self_test( int verbose ) v = i & 1; if( verbose != 0 ) - printf( " DES%c-ECB-%3d (%s): ", - ( u == 0 ) ? ' ' : '3', 56 + u * 56, - ( v == DES_DECRYPT ) ? "dec" : "enc" ); + polarssl_printf( " DES%c-ECB-%3d (%s): ", + ( u == 0 ) ? ' ' : '3', 56 + u * 56, + ( v == DES_DECRYPT ) ? "dec" : "enc" ); memcpy( buf, des3_test_buf, 8 ); @@ -889,17 +935,18 @@ int des_self_test( int verbose ) memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); #if defined(POLARSSL_CIPHER_MODE_CBC) /* @@ -911,9 +958,9 @@ int des_self_test( int verbose ) v = i & 1; if( verbose != 0 ) - printf( " DES%c-CBC-%3d (%s): ", - ( u == 0 ) ? ' ' : '3', 56 + u * 56, - ( v == DES_DECRYPT ) ? "dec" : "enc" ); + polarssl_printf( " DES%c-CBC-%3d (%s): ", + ( u == 0 ) ? ' ' : '3', 56 + u * 56, + ( v == DES_DECRYPT ) ? "dec" : "enc" ); memcpy( iv, des3_test_iv, 8 ); memcpy( prv, des3_test_iv, 8 ); @@ -984,22 +1031,27 @@ int des_self_test( int verbose ) memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } #endif /* POLARSSL_CIPHER_MODE_CBC */ if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); - return( 0 ); +exit: + des_free( &ctx ); + des3_free( &ctx3 ); + + return( ret ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_DES_C */ diff --git a/pdns/ext/polarssl/library/dhm.c b/pdns/ext/polarssl/library/dhm.c index e8aa8191c..089c11b3d 100644 --- a/pdns/ext/polarssl/library/dhm.c +++ b/pdns/ext/polarssl/library/dhm.c @@ -1,7 +1,7 @@ /* * Diffie-Hellman-Merkle key exchange * - * Copyright (C) 2006-2010, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -28,7 +28,11 @@ * http://www.cacr.math.uwaterloo.ca/hac/ (chapter 12) */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_DHM_C) @@ -42,14 +46,20 @@ #include "polarssl/asn1.h" #endif -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else #include +#define polarssl_printf printf #define polarssl_malloc malloc #define polarssl_free free #endif +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + /* * helper to validate the mpi size and import it */ @@ -91,8 +101,9 @@ static int dhm_check_range( const mpi *param, const mpi *P ) int ret = POLARSSL_ERR_DHM_BAD_INPUT_DATA; mpi_init( &L ); mpi_init( &U ); - mpi_lset( &L, 2 ); - mpi_sub_int( &U, P, 2 ); + + MPI_CHK( mpi_lset( &L, 2 ) ); + MPI_CHK( mpi_sub_int( &U, P, 2 ) ); if( mpi_cmp_mpi( param, &L ) >= 0 && mpi_cmp_mpi( param, &U ) <= 0 ) @@ -100,11 +111,16 @@ static int dhm_check_range( const mpi *param, const mpi *P ) ret = 0; } +cleanup: mpi_free( &L ); mpi_free( &U ); - return( ret ); } +void dhm_init( dhm_context *ctx ) +{ + memset( ctx, 0, sizeof( dhm_context ) ); +} + /* * Parse the ServerKeyExchange parameters */ @@ -114,8 +130,6 @@ int dhm_read_params( dhm_context *ctx, { int ret; - dhm_free( ctx ); - if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 || ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 || ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 ) @@ -152,7 +166,7 @@ int dhm_make_params( dhm_context *ctx, int x_size, mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ); while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) - mpi_shift_r( &ctx->X, 1 ); + MPI_CHK( mpi_shift_r( &ctx->X, 1 ) ); if( count++ > 10 ) return( POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED ); @@ -238,7 +252,7 @@ int dhm_make_public( dhm_context *ctx, int x_size, mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ); while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) - mpi_shift_r( &ctx->X, 1 ); + MPI_CHK( mpi_shift_r( &ctx->X, 1 ) ); if( count++ > 10 ) return( POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED ); @@ -311,7 +325,7 @@ static int dhm_update_blinding( dhm_context *ctx, mpi_fill_random( &ctx->Vi, mpi_size( &ctx->P ), f_rng, p_rng ); while( mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 ) - mpi_shift_r( &ctx->Vi, 1 ); + MPI_CHK( mpi_shift_r( &ctx->Vi, 1 ) ); if( count++ > 10 ) return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); @@ -389,14 +403,15 @@ void dhm_free( dhm_context *ctx ) mpi_free( &ctx->GX ); mpi_free( &ctx->X ); mpi_free( &ctx->G ); mpi_free( &ctx->P ); - memset( ctx, 0, sizeof( dhm_context ) ); + polarssl_zeroize( ctx, sizeof( dhm_context ) ); } #if defined(POLARSSL_ASN1_PARSE_C) /* * Parse DHM parameters */ -int dhm_parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen ) +int dhm_parse_dhm( dhm_context *dhm, const unsigned char *dhmin, + size_t dhminlen ) { int ret; size_t len; @@ -405,7 +420,6 @@ int dhm_parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen pem_context pem; pem_init( &pem ); - memset( dhm, 0, sizeof( dhm_context ) ); ret = pem_read_buffer( &pem, "-----BEGIN DH PARAMETERS-----", @@ -425,7 +439,7 @@ int dhm_parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin; #else p = (unsigned char *) dhmin; -#endif +#endif /* POLARSSL_PEM_PARSE_C */ end = p + dhminlen; /* @@ -459,6 +473,8 @@ int dhm_parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen ret = 0; + dhm->len = mpi_size( &dhm->P ); + exit: #if defined(POLARSSL_PEM_PARSE_C) pem_free( &pem ); @@ -521,12 +537,12 @@ int dhm_parse_dhmfile( dhm_context *dhm, const char *path ) size_t n; unsigned char *buf; - if ( ( ret = load_file( path, &buf, &n ) ) != 0 ) + if( ( ret = load_file( path, &buf, &n ) ) != 0 ) return( ret ); ret = dhm_parse_dhm( dhm, buf, n ); - memset( buf, 0, n + 1 ); + polarssl_zeroize( buf, n + 1 ); polarssl_free( buf ); return( ret ); @@ -547,30 +563,36 @@ int dhm_self_test( int verbose ) int ret; dhm_context dhm; + dhm_init( &dhm ); + if( verbose != 0 ) - printf( " DHM parameter load: " ); + polarssl_printf( " DHM parameter load: " ); if( ( ret = dhm_parse_dhm( &dhm, (const unsigned char *) test_dhm_params, strlen( test_dhm_params ) ) ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( ret ); + ret = 1; + goto exit; } if( verbose != 0 ) - printf( "passed\n\n" ); + polarssl_printf( "passed\n\n" ); +exit: dhm_free( &dhm ); - return( 0 ); + return( ret ); #else - ((void) verbose); - return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); -#endif + if( verbose != 0 ) + polarssl_printf( " DHM parameter load: skipped\n" ); + + return( 0 ); +#endif /* POLARSSL_CERTS_C */ } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_DHM_C */ diff --git a/pdns/ext/polarssl/library/ecdh.c b/pdns/ext/polarssl/library/ecdh.c index 400e45fa2..b93d82ec6 100644 --- a/pdns/ext/polarssl/library/ecdh.c +++ b/pdns/ext/polarssl/library/ecdh.c @@ -1,7 +1,7 @@ /* * Elliptic curve Diffie-Hellman * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -30,7 +30,11 @@ * RFC 4492 */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_ECDH_C) @@ -97,13 +101,13 @@ void ecdh_free( ecdh_context *ctx ) return; ecp_group_free( &ctx->grp ); - mpi_free ( &ctx->d ); ecp_point_free( &ctx->Q ); ecp_point_free( &ctx->Qp ); - mpi_free ( &ctx->z ); ecp_point_free( &ctx->Vi ); ecp_point_free( &ctx->Vf ); - mpi_free ( &ctx->_d ); + mpi_free( &ctx->d ); + mpi_free( &ctx->z ); + mpi_free( &ctx->_d ); } /* @@ -140,7 +144,7 @@ int ecdh_make_params( ecdh_context *ctx, size_t *olen, return( ret ); *olen = grp_len + pt_len; - return 0; + return( 0 ); } /* @@ -162,7 +166,33 @@ int ecdh_read_params( ecdh_context *ctx, != 0 ) return( ret ); - return 0; + return( 0 ); +} + +/* + * Get parameters from a keypair + */ +int ecdh_get_params( ecdh_context *ctx, const ecp_keypair *key, + ecdh_side side ) +{ + int ret; + + if( ( ret = ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ) + return( ret ); + + /* If it's not our key, just import the public part as Qp */ + if( side == POLARSSL_ECDH_THEIRS ) + return( ecp_copy( &ctx->Qp, &key->Q ) ); + + /* Our key: import public (as Q) and private parts */ + if( side != POLARSSL_ECDH_OURS ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = ecp_copy( &ctx->Q, &key->Q ) ) != 0 || + ( ret = mpi_copy( &ctx->d, &key->d ) ) != 0 ) + return( ret ); + + return( 0 ); } /* @@ -192,10 +222,19 @@ int ecdh_make_public( ecdh_context *ctx, size_t *olen, int ecdh_read_public( ecdh_context *ctx, const unsigned char *buf, size_t blen ) { + int ret; + const unsigned char *p = buf; + if( ctx == NULL ) return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); - return ecp_tls_read_point( &ctx->grp, &ctx->Qp, &buf, blen ); + if( ( ret = ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p, blen ) ) != 0 ) + return( ret ); + + if( (size_t)( p - buf ) != blen ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + return( 0 ); } /* @@ -220,7 +259,7 @@ int ecdh_calc_secret( ecdh_context *ctx, size_t *olen, if( mpi_size( &ctx->z ) > blen ) return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); - *olen = ctx->grp.nbits / 8 + ( ( ctx->grp.nbits % 8 ) != 0 ); + *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 ); return mpi_write_binary( &ctx->z, buf, *olen ); } @@ -232,9 +271,10 @@ int ecdh_calc_secret( ecdh_context *ctx, size_t *olen, */ int ecdh_self_test( int verbose ) { - return( verbose++ ); + ((void) verbose ); + return( 0 ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif /* defined(POLARSSL_ECDH_C) */ +#endif /* POLARSSL_ECDH_C */ diff --git a/pdns/ext/polarssl/library/ecdsa.c b/pdns/ext/polarssl/library/ecdsa.c index 13f394bc8..5af7f6b53 100644 --- a/pdns/ext/polarssl/library/ecdsa.c +++ b/pdns/ext/polarssl/library/ecdsa.c @@ -1,7 +1,7 @@ /* * Elliptic curve DSA * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -29,13 +29,49 @@ * SEC1 http://www.secg.org/index.php?action=secg,docs_secg */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_ECDSA_C) #include "polarssl/ecdsa.h" #include "polarssl/asn1write.h" +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +#include "polarssl/hmac_drbg.h" +#endif + +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +/* + * This a hopefully temporary compatibility function. + * + * Since we can't ensure the caller will pass a valid md_alg before the next + * interface change, try to pick up a decent md by size. + * + * Argument is the minimum size in bytes of the MD output. + */ +static const md_info_t *md_info_by_size( size_t min_size ) +{ + const md_info_t *md_cur, *md_picked = NULL; + const int *md_alg; + + for( md_alg = md_list(); *md_alg != 0; md_alg++ ) + { + if( ( md_cur = md_info_from_type( *md_alg ) ) == NULL || + (size_t) md_cur->size < min_size || + ( md_picked != NULL && md_cur->size > md_picked->size ) ) + continue; + + md_picked = md_cur; + } + + return( md_picked ); +} +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ + /* * Derive a suitable integer for group grp from a buffer of length len * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3 @@ -43,8 +79,20 @@ static int derive_mpi( const ecp_group *grp, mpi *x, const unsigned char *buf, size_t blen ) { - size_t n_size = (grp->nbits + 7) / 8; - return( mpi_read_binary( x, buf, blen > n_size ? n_size : blen ) ); + int ret; + size_t n_size = ( grp->nbits + 7 ) / 8; + size_t use_size = blen > n_size ? n_size : blen; + + MPI_CHK( mpi_read_binary( x, buf, use_size ) ); + if( use_size * 8 > grp->nbits ) + MPI_CHK( mpi_shift_r( x, use_size * 8 - grp->nbits ) ); + + /* While at it, reduce modulo N */ + if( mpi_cmp_mpi( x, &grp->N ) >= 0 ) + MPI_CHK( mpi_sub_mpi( x, x, &grp->N ) ); + +cleanup: + return( ret ); } /* @@ -55,13 +103,16 @@ int ecdsa_sign( ecp_group *grp, mpi *r, mpi *s, const mpi *d, const unsigned char *buf, size_t blen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { - int ret, key_tries, sign_tries; + int ret, key_tries, sign_tries, blind_tries; ecp_point R; - mpi k, e; + mpi k, e, t; + + /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ + if( grp->N.p == NULL ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); ecp_point_init( &R ); - mpi_init( &k ); - mpi_init( &e ); + mpi_init( &k ); mpi_init( &e ); mpi_init( &t ); sign_tries = 0; do @@ -90,10 +141,30 @@ int ecdsa_sign( ecp_group *grp, mpi *r, mpi *s, MPI_CHK( derive_mpi( grp, &e, buf, blen ) ); /* - * Step 6: compute s = (e + r * d) / k mod n + * Generate a random value to blind inv_mod in next step, + * avoiding a potential timing leak. + */ + blind_tries = 0; + do + { + size_t n_size = ( grp->nbits + 7 ) / 8; + MPI_CHK( mpi_fill_random( &t, n_size, f_rng, p_rng ) ); + MPI_CHK( mpi_shift_r( &t, 8 * n_size - grp->nbits ) ); + + /* See ecp_gen_keypair() */ + if( ++blind_tries > 30 ) + return( POLARSSL_ERR_ECP_RANDOM_FAILED ); + } + while( mpi_cmp_int( &t, 1 ) < 0 || + mpi_cmp_mpi( &t, &grp->N ) >= 0 ); + + /* + * Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n */ MPI_CHK( mpi_mul_mpi( s, r, d ) ); MPI_CHK( mpi_add_mpi( &e, &e, s ) ); + MPI_CHK( mpi_mul_mpi( &e, &e, &t ) ); + MPI_CHK( mpi_mul_mpi( &k, &k, &t ) ); MPI_CHK( mpi_inv_mod( s, &k, &grp->N ) ); MPI_CHK( mpi_mul_mpi( s, s, &e ) ); MPI_CHK( mpi_mod_mpi( s, s, &grp->N ) ); @@ -108,12 +179,55 @@ int ecdsa_sign( ecp_group *grp, mpi *r, mpi *s, cleanup: ecp_point_free( &R ); - mpi_free( &k ); - mpi_free( &e ); + mpi_free( &k ); mpi_free( &e ); mpi_free( &t ); return( ret ); } +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +/* + * Deterministic signature wrapper + */ +int ecdsa_sign_det( ecp_group *grp, mpi *r, mpi *s, + const mpi *d, const unsigned char *buf, size_t blen, + md_type_t md_alg ) +{ + int ret; + hmac_drbg_context rng_ctx; + unsigned char data[2 * POLARSSL_ECP_MAX_BYTES]; + size_t grp_len = ( grp->nbits + 7 ) / 8; + const md_info_t *md_info; + mpi h; + + /* Temporary fallback */ + if( md_alg == POLARSSL_MD_NONE ) + md_info = md_info_by_size( blen ); + else + md_info = md_info_from_type( md_alg ); + + if( md_info == NULL ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + mpi_init( &h ); + memset( &rng_ctx, 0, sizeof( hmac_drbg_context ) ); + + /* Use private key and message hash (reduced) to initialize HMAC_DRBG */ + MPI_CHK( mpi_write_binary( d, data, grp_len ) ); + MPI_CHK( derive_mpi( grp, &h, buf, blen ) ); + MPI_CHK( mpi_write_binary( &h, data + grp_len, grp_len ) ); + hmac_drbg_init_buf( &rng_ctx, md_info, data, 2 * grp_len ); + + ret = ecdsa_sign( grp, r, s, d, buf, blen, + hmac_drbg_random, &rng_ctx ); + +cleanup: + hmac_drbg_free( &rng_ctx ); + mpi_free( &h ); + + return( ret ); +} +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ + /* * Verify ECDSA signature of hashed message (SEC1 4.1.4) * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message) @@ -129,6 +243,10 @@ int ecdsa_verify( ecp_group *grp, ecp_point_init( &R ); ecp_point_init( &P ); mpi_init( &e ); mpi_init( &s_inv ); mpi_init( &u1 ); mpi_init( &u2 ); + /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ + if( grp->N.p == NULL ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + /* * Step 1: make sure r and s are in range 1..n-1 */ @@ -217,6 +335,30 @@ cleanup: #endif #define MAX_SIG_LEN ( 3 + 2 * ( 2 + POLARSSL_ECP_MAX_BYTES ) ) +/* + * Convert a signature (given by context) to ASN.1 + */ +static int ecdsa_signature_to_asn1( ecdsa_context *ctx, + unsigned char *sig, size_t *slen ) +{ + int ret; + unsigned char buf[MAX_SIG_LEN]; + unsigned char *p = buf + sizeof( buf ); + size_t len = 0; + + ASN1_CHK_ADD( len, asn1_write_mpi( &p, buf, &ctx->s ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &p, buf, &ctx->r ) ); + + ASN1_CHK_ADD( len, asn1_write_len( &p, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &p, buf, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + + memcpy( sig, p, len ); + *slen = len; + + return( 0 ); +} + /* * Compute and write signature */ @@ -227,9 +369,6 @@ int ecdsa_write_signature( ecdsa_context *ctx, void *p_rng ) { int ret; - unsigned char buf[MAX_SIG_LEN]; - unsigned char *p = buf + sizeof( buf ); - size_t len = 0; if( ( ret = ecdsa_sign( &ctx->grp, &ctx->r, &ctx->s, &ctx->d, hash, hlen, f_rng, p_rng ) ) != 0 ) @@ -237,18 +376,29 @@ int ecdsa_write_signature( ecdsa_context *ctx, return( ret ); } - ASN1_CHK_ADD( len, asn1_write_mpi( &p, buf, &ctx->s ) ); - ASN1_CHK_ADD( len, asn1_write_mpi( &p, buf, &ctx->r ) ); + return( ecdsa_signature_to_asn1( ctx, sig, slen ) ); +} - ASN1_CHK_ADD( len, asn1_write_len( &p, buf, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &p, buf, - ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +/* + * Compute and write signature deterministically + */ +int ecdsa_write_signature_det( ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + md_type_t md_alg ) +{ + int ret; - memcpy( sig, p, len ); - *slen = len; + if( ( ret = ecdsa_sign_det( &ctx->grp, &ctx->r, &ctx->s, &ctx->d, + hash, hlen, md_alg ) ) != 0 ) + { + return( ret ); + } - return( 0 ); + return( ecdsa_signature_to_asn1( ctx, sig, slen ) ); } +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ /* * Read and check signature @@ -276,11 +426,14 @@ int ecdsa_read_signature( ecdsa_context *ctx, ( ret = asn1_get_mpi( &p, end, &ctx->s ) ) != 0 ) return( POLARSSL_ERR_ECP_BAD_INPUT_DATA + ret ); + if( ( ret = ecdsa_verify( &ctx->grp, hash, hlen, + &ctx->Q, &ctx->r, &ctx->s ) ) != 0 ) + return( ret ); + if( p != end ) - return( POLARSSL_ERR_ECP_BAD_INPUT_DATA + - POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + return( POLARSSL_ERR_ECP_SIG_LEN_MISMATCH ); - return( ecdsa_verify( &ctx->grp, hash, hlen, &ctx->Q, &ctx->r, &ctx->s ) ); + return( 0 ); } /* @@ -341,9 +494,10 @@ void ecdsa_free( ecdsa_context *ctx ) */ int ecdsa_self_test( int verbose ) { - return( verbose++ ); + ((void) verbose ); + return( 0 ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif /* defined(POLARSSL_ECDSA_C) */ +#endif /* POLARSSL_ECDSA_C */ diff --git a/pdns/ext/polarssl/library/ecp.c b/pdns/ext/polarssl/library/ecp.c index 3a075c403..afa795525 100644 --- a/pdns/ext/polarssl/library/ecp.c +++ b/pdns/ext/polarssl/library/ecp.c @@ -1,7 +1,7 @@ /* - * Elliptic curves over GF(p) + * Elliptic curves over GF(p): generic functions * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -31,34 +31,44 @@ * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf * RFC 4492 for the related TLS structures and constants * - * [1] OKEYA, Katsuyuki and TAKAGI, Tsuyoshi. The width-w NAF method provides - * small memory and fast elliptic scalar multiplications secure against - * side channel attacks. In : Topics in Cryptology—CT-RSA 2003. Springer - * Berlin Heidelberg, 2003. p. 328-343. - * . + * [M255] http://cr.yp.to/ecdh/curve25519-20060209.pdf * * [2] CORON, Jean-Sébastien. Resistance against differential power analysis * for elliptic curve cryptosystems. In : Cryptographic Hardware and * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302. * + * + * [3] HEDABOU, Mustapha, PINEL, Pierre, et BÉNÉTEAU, Lucien. A comb method to + * render ECC resistant against Side Channel Attacks. IACR Cryptology + * ePrint Archive, 2004, vol. 2004, p. 342. + * */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_ECP_C) #include "polarssl/ecp.h" -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else +#define polarssl_printf printf #define polarssl_malloc malloc #define polarssl_free free #endif -#include #include +#if defined(_MSC_VER) && !defined strcasecmp && !defined(EFIX64) && \ + !defined(EFI32) +#define strcasecmp _stricmp +#endif + #if defined(_MSC_VER) && !defined(inline) #define inline _inline #else @@ -67,60 +77,139 @@ #endif /* __ARMCC_VERSION */ #endif /*_MSC_VER */ +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + #if defined(POLARSSL_SELF_TEST) /* - * Counts of point addition and doubling operations. + * Counts of point addition and doubling, and field multiplications. * Used to test resistance of point multiplication to simple timing attacks. */ -unsigned long add_count, dbl_count; +static unsigned long add_count, dbl_count, mul_count; +#endif + +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_BP256R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_BP384R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_BP512R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) +#define POLARSSL_ECP_SHORT_WEIERSTRASS +#endif + +#if defined(POLARSSL_ECP_DP_M221_ENABLED) || \ + defined(POLARSSL_ECP_DP_M255_ENABLED) || \ + defined(POLARSSL_ECP_DP_M383_ENABLED) || \ + defined(POLARSSL_ECP_DP_M511_ENABLED) +#define POLARSSL_ECP_MONTGOMERY #endif +/* + * Curve types: internal for now, might be exposed later + */ +typedef enum +{ + POLARSSL_ECP_TYPE_NONE = 0, + POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */ + POLARSSL_ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */ +} ecp_curve_type; + /* * List of supported curves: * - internal ID * - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2) * - size in bits * - readable name + * + * Curves are listed in order: largest curves first, and for a given size, + * fastest curves first. This provides the default order for the SSL module. */ -const ecp_curve_info ecp_supported_curves[] = +static const ecp_curve_info ecp_supported_curves[] = { -#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) - { POLARSSL_ECP_DP_BP512R1, 28, 512, "brainpool512r1" }, -#endif -#if defined(POLARSSL_ECP_DP_BP384R1_ENABLED) - { POLARSSL_ECP_DP_BP384R1, 27, 384, "brainpool384r1" }, -#endif -#if defined(POLARSSL_ECP_DP_BP256R1_ENABLED) - { POLARSSL_ECP_DP_BP256R1, 26, 256, "brainpool256r1" }, -#endif #if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) { POLARSSL_ECP_DP_SECP521R1, 25, 521, "secp521r1" }, #endif +#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) + { POLARSSL_ECP_DP_BP512R1, 28, 512, "brainpoolP512r1" }, +#endif #if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) { POLARSSL_ECP_DP_SECP384R1, 24, 384, "secp384r1" }, #endif +#if defined(POLARSSL_ECP_DP_BP384R1_ENABLED) + { POLARSSL_ECP_DP_BP384R1, 27, 384, "brainpoolP384r1" }, +#endif #if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) { POLARSSL_ECP_DP_SECP256R1, 23, 256, "secp256r1" }, #endif +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) + { POLARSSL_ECP_DP_SECP256K1, 22, 256, "secp256k1" }, +#endif +#if defined(POLARSSL_ECP_DP_BP256R1_ENABLED) + { POLARSSL_ECP_DP_BP256R1, 26, 256, "brainpoolP256r1" }, +#endif #if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) { POLARSSL_ECP_DP_SECP224R1, 21, 224, "secp224r1" }, #endif +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) + { POLARSSL_ECP_DP_SECP224K1, 20, 224, "secp224k1" }, +#endif #if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) { POLARSSL_ECP_DP_SECP192R1, 19, 192, "secp192r1" }, +#endif +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) + { POLARSSL_ECP_DP_SECP192K1, 18, 192, "secp192k1" }, #endif { POLARSSL_ECP_DP_NONE, 0, 0, NULL }, }; +#define ECP_NB_CURVES sizeof( ecp_supported_curves ) / \ + sizeof( ecp_supported_curves[0] ) + +static ecp_group_id ecp_supported_grp_id[ECP_NB_CURVES]; + /* * List of supported curves and associated info */ const ecp_curve_info *ecp_curve_list( void ) { - return ecp_supported_curves; + return( ecp_supported_curves ); +} + +/* + * List of supported curves, group ID only + */ +const ecp_group_id *ecp_grp_id_list( void ) +{ + static int init_done = 0; + + if( ! init_done ) + { + size_t i = 0; + const ecp_curve_info *curve_info; + + for( curve_info = ecp_curve_list(); + curve_info->grp_id != POLARSSL_ECP_DP_NONE; + curve_info++ ) + { + ecp_supported_grp_id[i++] = curve_info->grp_id; + } + ecp_supported_grp_id[i] = POLARSSL_ECP_DP_NONE; + + init_done = 1; + } + + return( ecp_supported_grp_id ); } /* - * Get the curve info for the internal identifer + * Get the curve info for the internal identifier */ const ecp_curve_info *ecp_curve_info_from_grp_id( ecp_group_id grp_id ) { @@ -155,6 +244,38 @@ const ecp_curve_info *ecp_curve_info_from_tls_id( uint16_t tls_id ) return( NULL ); } +/* + * Get the curve info from the name + */ +const ecp_curve_info *ecp_curve_info_from_name( const char *name ) +{ + const ecp_curve_info *curve_info; + + for( curve_info = ecp_curve_list(); + curve_info->grp_id != POLARSSL_ECP_DP_NONE; + curve_info++ ) + { + if( strcasecmp( curve_info->name, name ) == 0 ) + return( curve_info ); + } + + return( NULL ); +} + +/* + * Get the type of a curve + */ +static inline ecp_curve_type ecp_get_type( const ecp_group *grp ) +{ + if( grp->G.X.p == NULL ) + return( POLARSSL_ECP_TYPE_NONE ); + + if( grp->G.Y.p == NULL ) + return( POLARSSL_ECP_TYPE_MONTGOMERY ); + else + return( POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ); +} + /* * Initialize (the components of) a point */ @@ -184,7 +305,7 @@ void ecp_group_init( ecp_group *grp ) */ void ecp_keypair_init( ecp_keypair *key ) { - if ( key == NULL ) + if( key == NULL ) return; ecp_group_init( &key->grp ); @@ -215,11 +336,14 @@ void ecp_group_free( ecp_group *grp ) if( grp == NULL ) return; - mpi_free( &grp->P ); - mpi_free( &grp->A ); - mpi_free( &grp->B ); - ecp_point_free( &grp->G ); - mpi_free( &grp->N ); + if( grp->h != 1 ) + { + mpi_free( &grp->P ); + mpi_free( &grp->A ); + mpi_free( &grp->B ); + ecp_point_free( &grp->G ); + mpi_free( &grp->N ); + } if( grp->T != NULL ) { @@ -228,7 +352,7 @@ void ecp_group_free( ecp_group *grp ) polarssl_free( grp->T ); } - memset( grp, 0, sizeof( ecp_group ) ); + polarssl_zeroize( grp, sizeof( ecp_group ) ); } /* @@ -236,7 +360,7 @@ void ecp_group_free( ecp_group *grp ) */ void ecp_keypair_free( ecp_keypair *key ) { - if ( key == NULL ) + if( key == NULL ) return; ecp_group_free( &key->grp ); @@ -366,16 +490,28 @@ cleanup: * Import a point from unsigned binary data (SEC1 2.3.4) */ int ecp_point_read_binary( const ecp_group *grp, ecp_point *pt, - const unsigned char *buf, size_t ilen ) { + const unsigned char *buf, size_t ilen ) +{ int ret; size_t plen; - if( ilen == 1 && buf[0] == 0x00 ) - return( ecp_set_zero( pt ) ); + if ( ilen < 1 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( buf[0] == 0x00 ) + { + if( ilen == 1 ) + return( ecp_set_zero( pt ) ); + else + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + } plen = mpi_size( &grp->P ); - if( ilen != 2 * plen + 1 || buf[0] != 0x04 ) + if( buf[0] != 0x04 ) + return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); + + if( ilen != 2 * plen + 1 ) return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); MPI_CHK( mpi_read_binary( &pt->X, buf + 1, plen ) ); @@ -399,7 +535,7 @@ int ecp_tls_read_point( const ecp_group *grp, ecp_point *pt, const unsigned char *buf_start; /* - * We must have at least two bytes (1 for length, at least of for data) + * We must have at least two bytes (1 for length, at least one for data) */ if( buf_len < 2 ) return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); @@ -445,20 +581,19 @@ int ecp_tls_write_point( const ecp_group *grp, const ecp_point *pt, buf[0] = (unsigned char) *olen; ++*olen; - return 0; + return( 0 ); } /* - * Import an ECP group from ASCII strings, general case (A used) + * Import an ECP group from ASCII strings, case A == -3 */ -static int ecp_group_read_string_gen( ecp_group *grp, int radix, - const char *p, const char *a, const char *b, +int ecp_group_read_string( ecp_group *grp, int radix, + const char *p, const char *b, const char *gx, const char *gy, const char *n) { int ret; MPI_CHK( mpi_read_string( &grp->P, radix, p ) ); - MPI_CHK( mpi_read_string( &grp->A, radix, a ) ); MPI_CHK( mpi_read_string( &grp->B, radix, b ) ); MPI_CHK( ecp_point_read_string( &grp->G, radix, gx, gy ) ); MPI_CHK( mpi_read_string( &grp->N, radix, n ) ); @@ -473,265 +608,6 @@ cleanup: return( ret ); } -/* - * Import an ECP group from ASCII strings, case A == -3 - */ -int ecp_group_read_string( ecp_group *grp, int radix, - const char *p, const char *b, - const char *gx, const char *gy, const char *n) -{ - int ret; - - MPI_CHK( ecp_group_read_string_gen( grp, radix, p, "00", b, gx, gy, n ) ); - MPI_CHK( mpi_add_int( &grp->A, &grp->P, -3 ) ); - -cleanup: - if( ret != 0 ) - ecp_group_free( grp ); - - return( ret ); -} - -/* - * Domain parameters for secp192r1 - */ -#define SECP192R1_P \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF" -#define SECP192R1_B \ - "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1" -#define SECP192R1_GX \ - "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012" -#define SECP192R1_GY \ - "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811" -#define SECP192R1_N \ - "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831" - -/* - * Domain parameters for secp224r1 - */ -#define SECP224R1_P \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001" -#define SECP224R1_B \ - "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4" -#define SECP224R1_GX \ - "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21" -#define SECP224R1_GY \ - "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34" -#define SECP224R1_N \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D" - -/* - * Domain parameters for secp256r1 - */ -#define SECP256R1_P \ - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF" -#define SECP256R1_B \ - "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B" -#define SECP256R1_GX \ - "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" -#define SECP256R1_GY \ - "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5" -#define SECP256R1_N \ - "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551" - -/* - * Domain parameters for secp384r1 - */ -#define SECP384R1_P \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ - "FFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF" -#define SECP384R1_B \ - "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE814112" \ - "0314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF" -#define SECP384R1_GX \ - "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B98" \ - "59F741E082542A385502F25DBF55296C3A545E3872760AB7" -#define SECP384R1_GY \ - "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147C" \ - "E9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F" -#define SECP384R1_N \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ - "C7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973" - -/* - * Domain parameters for secp521r1 - */ -#define SECP521R1_P \ - "000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" -#define SECP521R1_B \ - "00000051953EB9618E1C9A1F929A21A0B68540EEA2DA725B" \ - "99B315F3B8B489918EF109E156193951EC7E937B1652C0BD" \ - "3BB1BF073573DF883D2C34F1EF451FD46B503F00" -#define SECP521R1_GX \ - "000000C6858E06B70404E9CD9E3ECB662395B4429C648139" \ - "053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127" \ - "A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66" -#define SECP521R1_GY \ - "0000011839296A789A3BC0045C8A5FB42C7D1BD998F54449" \ - "579B446817AFBD17273E662C97EE72995EF42640C550B901" \ - "3FAD0761353C7086A272C24088BE94769FD16650" -#define SECP521R1_N \ - "000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ - "FFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148" \ - "F709A5D03BB5C9B8899C47AEBB6FB71E91386409" - -/* - * Domain parameters for brainpoolP256r1 (RFC 5639 3.4) - */ -#define BP256R1_P \ - "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377" -#define BP256R1_A \ - "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9" -#define BP256R1_B \ - "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6" -#define BP256R1_GX \ - "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262" -#define BP256R1_GY \ - "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997" -#define BP256R1_N \ - "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7" - -/* - * Domain parameters for brainpoolP384r1 (RFC 5639 3.6) - */ -#define BP384R1_P \ - "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB711" \ - "23ACD3A729901D1A71874700133107EC53" -#define BP384R1_A \ - "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F9" \ - "0F8AA5814A503AD4EB04A8C7DD22CE2826" -#define BP384R1_B \ - "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62" \ - "D57CB4390295DBC9943AB78696FA504C11" -#define BP384R1_GX \ - "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10" \ - "E8E826E03436D646AAEF87B2E247D4AF1E" -#define BP384R1_GY \ - "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129" \ - "280E4646217791811142820341263C5315" -#define BP384R1_N \ - "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425" \ - "A7CF3AB6AF6B7FC3103B883202E9046565" - -/* - * Domain parameters for brainpoolP512r1 (RFC 5639 3.7) - */ -#define BP512R1_P \ - "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308" \ - "717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3" -#define BP512R1_A \ - "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863" \ - "BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA" -#define BP512R1_B \ - "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117" \ - "A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723" -#define BP512R1_GX \ - "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D009" \ - "8EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822" -#define BP512R1_GY \ - "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F81" \ - "11B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892" -#define BP512R1_N \ - "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308" \ - "70553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069" - -#if defined(POLARSSL_ECP_NIST_OPTIM) -/* Forward declarations */ -static int ecp_mod_p192( mpi * ); -static int ecp_mod_p224( mpi * ); -static int ecp_mod_p256( mpi * ); -static int ecp_mod_p384( mpi * ); -static int ecp_mod_p521( mpi * ); -#endif - -/* - * Set a group using well-known domain parameters - */ -int ecp_use_known_dp( ecp_group *grp, ecp_group_id id ) -{ - grp->id = id; - - switch( id ) - { -#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) - case POLARSSL_ECP_DP_SECP192R1: -#if defined(POLARSSL_ECP_NIST_OPTIM) - grp->modp = ecp_mod_p192; -#endif - return( ecp_group_read_string( grp, 16, - SECP192R1_P, SECP192R1_B, - SECP192R1_GX, SECP192R1_GY, SECP192R1_N ) ); -#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) - case POLARSSL_ECP_DP_SECP224R1: -#if defined(POLARSSL_ECP_NIST_OPTIM) - grp->modp = ecp_mod_p224; -#endif - return( ecp_group_read_string( grp, 16, - SECP224R1_P, SECP224R1_B, - SECP224R1_GX, SECP224R1_GY, SECP224R1_N ) ); -#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) - case POLARSSL_ECP_DP_SECP256R1: -#if defined(POLARSSL_ECP_NIST_OPTIM) - grp->modp = ecp_mod_p256; -#endif - return( ecp_group_read_string( grp, 16, - SECP256R1_P, SECP256R1_B, - SECP256R1_GX, SECP256R1_GY, SECP256R1_N ) ); -#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) - case POLARSSL_ECP_DP_SECP384R1: -#if defined(POLARSSL_ECP_NIST_OPTIM) - grp->modp = ecp_mod_p384; -#endif - return( ecp_group_read_string( grp, 16, - SECP384R1_P, SECP384R1_B, - SECP384R1_GX, SECP384R1_GY, SECP384R1_N ) ); -#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) - case POLARSSL_ECP_DP_SECP521R1: -#if defined(POLARSSL_ECP_NIST_OPTIM) - grp->modp = ecp_mod_p521; -#endif - return( ecp_group_read_string( grp, 16, - SECP521R1_P, SECP521R1_B, - SECP521R1_GX, SECP521R1_GY, SECP521R1_N ) ); -#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_BP256R1_ENABLED) - case POLARSSL_ECP_DP_BP256R1: - return( ecp_group_read_string_gen( grp, 16, - BP256R1_P, BP256R1_A, BP256R1_B, - BP256R1_GX, BP256R1_GY, BP256R1_N ) ); -#endif /* POLARSSL_ECP_DP_BP256R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_BP384R1_ENABLED) - case POLARSSL_ECP_DP_BP384R1: - return( ecp_group_read_string_gen( grp, 16, - BP384R1_P, BP384R1_A, BP384R1_B, - BP384R1_GX, BP384R1_GY, BP384R1_N ) ); -#endif /* POLARSSL_ECP_DP_BP384R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) - case POLARSSL_ECP_DP_BP512R1: - return( ecp_group_read_string_gen( grp, 16, - BP512R1_P, BP512R1_A, BP512R1_B, - BP512R1_GX, BP512R1_GY, BP512R1_N ) ); -#endif /* POLARSSL_ECP_DP_BP512R1_ENABLED */ - - default: - ecp_group_free( grp ); - return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); - } -} - /* * Set a group from an ECParameters record (RFC 4492) */ @@ -794,7 +670,7 @@ int ecp_tls_write_group( const ecp_group *grp, size_t *olen, buf[0] = curve_info->tls_id >> 8; buf[1] = curve_info->tls_id & 0xFF; - return 0; + return( 0 ); } /* @@ -844,7 +720,14 @@ cleanup: /* * Reduce a mpi mod p in-place, general case, to use after mpi_mul_mpi */ -#define MOD_MUL( N ) MPI_CHK( ecp_modp( &N, grp ) ) +#if defined(POLARSSL_SELF_TEST) +#define INC_MUL_COUNT mul_count++; +#else +#define INC_MUL_COUNT +#endif + +#define MOD_MUL( N ) do { MPI_CHK( ecp_modp( &N, grp ) ); INC_MUL_COUNT } \ + while( 0 ) /* * Reduce a mpi mod p in-place, to use after mpi_sub_mpi @@ -863,10 +746,20 @@ cleanup: while( mpi_cmp_mpi( &N, &grp->P ) >= 0 ) \ MPI_CHK( mpi_sub_abs( &N, &N, &grp->P ) ) +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) +/* + * For curves in short Weierstrass form, we do all the internal operations in + * Jacobian coordinates. + * + * For multiplication, we'll use a comb method with coutermeasueres against + * SPA, hence timing attacks. + */ + /* * Normalize jacobian coordinates so that Z == 0 || Z == 1 (GECC 3.2.1) + * Cost: 1N := 1I + 3M + 1S */ -static int ecp_normalize( const ecp_group *grp, ecp_point *pt ) +static int ecp_normalize_jac( const ecp_group *grp, ecp_point *pt ) { int ret; mpi Zi, ZZi; @@ -902,23 +795,25 @@ cleanup: } /* - * Normalize jacobian coordinates of an array of points, + * Normalize jacobian coordinates of an array of (pointers to) points, * using Montgomery's trick to perform only one inversion mod P. * (See for example Cohen's "A Course in Computational Algebraic Number * Theory", Algorithm 10.3.4.) * * Warning: fails (returning an error) if one of the points is zero! - * This should never happen, see choice of w in ecp_mul(). + * This should never happen, see choice of w in ecp_mul_comb(). + * + * Cost: 1N(t) := 1I + (6t - 3)M + 1S */ -static int ecp_normalize_many( const ecp_group *grp, - ecp_point T[], size_t t_len ) +static int ecp_normalize_jac_many( const ecp_group *grp, + ecp_point *T[], size_t t_len ) { int ret; size_t i; mpi *c, u, Zi, ZZi; if( t_len < 2 ) - return( ecp_normalize( grp, T ) ); + return( ecp_normalize_jac( grp, *T ) ); if( ( c = (mpi *) polarssl_malloc( t_len * sizeof( mpi ) ) ) == NULL ) return( POLARSSL_ERR_ECP_MALLOC_FAILED ); @@ -930,10 +825,10 @@ static int ecp_normalize_many( const ecp_group *grp, /* * c[i] = Z_0 * ... * Z_i */ - MPI_CHK( mpi_copy( &c[0], &T[0].Z ) ); + MPI_CHK( mpi_copy( &c[0], &T[0]->Z ) ); for( i = 1; i < t_len; i++ ) { - MPI_CHK( mpi_mul_mpi( &c[i], &c[i-1], &T[i].Z ) ); + MPI_CHK( mpi_mul_mpi( &c[i], &c[i-1], &T[i]->Z ) ); MOD_MUL( c[i] ); } @@ -953,18 +848,27 @@ static int ecp_normalize_many( const ecp_group *grp, } else { - MPI_CHK( mpi_mul_mpi( &Zi, &u, &c[i-1] ) ); MOD_MUL( Zi ); - MPI_CHK( mpi_mul_mpi( &u, &u, &T[i].Z ) ); MOD_MUL( u ); + MPI_CHK( mpi_mul_mpi( &Zi, &u, &c[i-1] ) ); MOD_MUL( Zi ); + MPI_CHK( mpi_mul_mpi( &u, &u, &T[i]->Z ) ); MOD_MUL( u ); } /* * proceed as in normalize() */ - MPI_CHK( mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi ); - MPI_CHK( mpi_mul_mpi( &T[i].X, &T[i].X, &ZZi ) ); MOD_MUL( T[i].X ); - MPI_CHK( mpi_mul_mpi( &T[i].Y, &T[i].Y, &ZZi ) ); MOD_MUL( T[i].Y ); - MPI_CHK( mpi_mul_mpi( &T[i].Y, &T[i].Y, &Zi ) ); MOD_MUL( T[i].Y ); - MPI_CHK( mpi_lset( &T[i].Z, 1 ) ); + MPI_CHK( mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi ); + MPI_CHK( mpi_mul_mpi( &T[i]->X, &T[i]->X, &ZZi ) ); MOD_MUL( T[i]->X ); + MPI_CHK( mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &ZZi ) ); MOD_MUL( T[i]->Y ); + MPI_CHK( mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &Zi ) ); MOD_MUL( T[i]->Y ); + + /* + * Post-precessing: reclaim some memory by shrinking coordinates + * - not storing Z (always 1) + * - shrinking other coordinates, but still keeping the same number of + * limbs as P, as otherwise it will too likely be regrown too fast. + */ + MPI_CHK( mpi_shrink( &T[i]->X, grp->P.n ) ); + MPI_CHK( mpi_shrink( &T[i]->Y, grp->P.n ) ); + mpi_free( &T[i]->Z ); if( i == 0 ) break; @@ -980,6 +884,31 @@ cleanup: return( ret ); } +/* + * Conditional point inversion: Q -> -Q = (Q.X, -Q.Y, Q.Z) without leak. + * "inv" must be 0 (don't invert) or 1 (invert) or the result will be invalid + */ +static int ecp_safe_invert_jac( const ecp_group *grp, + ecp_point *Q, + unsigned char inv ) +{ + int ret; + unsigned char nonzero; + mpi mQY; + + mpi_init( &mQY ); + + /* Use the fact that -Q.Y mod P = P - Q.Y unless Q.Y == 0 */ + MPI_CHK( mpi_sub_mpi( &mQY, &grp->P, &Q->Y ) ); + nonzero = mpi_cmp_int( &Q->Y, 0 ) != 0; + MPI_CHK( mpi_safe_cond_assign( &Q->Y, &mQY, inv & nonzero ) ); + +cleanup: + mpi_free( &mQY ); + + return( ret ); +} + /* * Point doubling R = 2 P, Jacobian coordinates * @@ -987,6 +916,8 @@ cleanup: * with heavy variable renaming, some reordering and one minor modification * (a = 2 * b, c = d - 2a replaced with c = d, c = c - b, c = c - b) * in order to use a lot less intermediate variables (6 vs 25). + * + * Cost: 1D := 2M + 8S */ static int ecp_double_jac( const ecp_group *grp, ecp_point *R, const ecp_point *P ) @@ -1012,7 +943,17 @@ static int ecp_double_jac( const ecp_group *grp, ecp_point *R, MPI_CHK( mpi_mul_mpi( &Z3, &P->Z, &P->Z ) ); MOD_MUL( Z3 ); MPI_CHK( mpi_mul_mpi( &X3, &Z3, &Z3 ) ); MOD_MUL( X3 ); MPI_CHK( mpi_mul_int( &T3, &T3, 3 ) ); MOD_ADD( T3 ); - MPI_CHK( mpi_mul_mpi( &X3, &X3, &grp->A ) ); MOD_MUL( X3 ); + + /* Special case for A = -3 */ + if( grp->A.p == NULL ) + { + MPI_CHK( mpi_mul_int( &X3, &X3, 3 ) ); + X3.s = -1; /* mpi_mul_int doesn't handle negative numbers */ + MOD_SUB( X3 ); + } + else + MPI_CHK( mpi_mul_mpi( &X3, &X3, &grp->A ) ); MOD_MUL( X3 ); + MPI_CHK( mpi_add_mpi( &T3, &T3, &X3 ) ); MOD_ADD( T3 ); MPI_CHK( mpi_mul_mpi( &X3, &T3, &T3 ) ); MOD_MUL( X3 ); MPI_CHK( mpi_sub_mpi( &X3, &X3, &T1 ) ); MOD_SUB( X3 ); @@ -1038,19 +979,25 @@ cleanup: } /* - * Addition or subtraction: R = P + Q or R = P - Q, - * mixed affine-Jacobian coordinates (GECC 3.22) + * Addition: R = P + Q, mixed affine-Jacobian coordinates (GECC 3.22) * * The coordinates of Q must be normalized (= affine), * but those of P don't need to. R is not normalized. * - * If sign >= 0, perform addition, otherwise perform subtraction, - * taking advantage of the fact that, for Q != 0, we have - * -Q = (Q.X, -Q.Y, Q.Z) + * Special cases: (1) P or Q is zero, (2) R is zero, (3) P == Q. + * None of these cases can happen as intermediate step in ecp_mul_comb(): + * - at each step, P, Q and R are multiples of the base point, the factor + * being less than its order, so none of them is zero; + * - Q is an odd multiple of the base point, P an even multiple, + * due to the choice of precomputed points in the modified comb method. + * So branches for these cases do not leak secret information. + * + * We accept Q->Z being unset (saving memory in tables) as meaning 1. + * + * Cost: 1A := 8M + 3S */ static int ecp_add_mixed( const ecp_group *grp, ecp_point *R, - const ecp_point *P, const ecp_point *Q, - signed char sign ) + const ecp_point *P, const ecp_point *Q ) { int ret; mpi T1, T2, T3, T4, X, Y, Z; @@ -1060,30 +1007,18 @@ static int ecp_add_mixed( const ecp_group *grp, ecp_point *R, #endif /* - * Trivial cases: P == 0 or Q == 0 - * (Check Q first, so that we know Q != 0 when we compute -Q.) + * Trivial cases: P == 0 or Q == 0 (case 1) */ - if( mpi_cmp_int( &Q->Z, 0 ) == 0 ) - return( ecp_copy( R, P ) ); - if( mpi_cmp_int( &P->Z, 0 ) == 0 ) - { - ret = ecp_copy( R, Q ); - - /* - * -R.Y mod P = P - R.Y unless R.Y == 0 - */ - if( ret == 0 && sign < 0) - if( mpi_cmp_int( &R->Y, 0 ) != 0 ) - ret = mpi_sub_mpi( &R->Y, &grp->P, &R->Y ); + return( ecp_copy( R, Q ) ); - return( ret ); - } + if( Q->Z.p != NULL && mpi_cmp_int( &Q->Z, 0 ) == 0 ) + return( ecp_copy( R, P ) ); /* * Make sure Q coordinates are normalized */ - if( mpi_cmp_int( &Q->Z, 1 ) != 0 ) + if( Q->Z.p != NULL && mpi_cmp_int( &Q->Z, 1 ) != 0 ) return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); mpi_init( &T1 ); mpi_init( &T2 ); mpi_init( &T3 ); mpi_init( &T4 ); @@ -1093,20 +1028,10 @@ static int ecp_add_mixed( const ecp_group *grp, ecp_point *R, MPI_CHK( mpi_mul_mpi( &T2, &T1, &P->Z ) ); MOD_MUL( T2 ); MPI_CHK( mpi_mul_mpi( &T1, &T1, &Q->X ) ); MOD_MUL( T1 ); MPI_CHK( mpi_mul_mpi( &T2, &T2, &Q->Y ) ); MOD_MUL( T2 ); - - /* - * For subtraction, -Q.Y should have been used instead of Q.Y, - * so we replace T2 by -T2, which is P - T2 mod P - */ - if( sign < 0 ) - { - MPI_CHK( mpi_sub_mpi( &T2, &grp->P, &T2 ) ); - MOD_SUB( T2 ); - } - MPI_CHK( mpi_sub_mpi( &T1, &T1, &P->X ) ); MOD_SUB( T1 ); MPI_CHK( mpi_sub_mpi( &T2, &T2, &P->Y ) ); MOD_SUB( T2 ); + /* Special cases (2) and (3) */ if( mpi_cmp_int( &T1, 0 ) == 0 ) { if( mpi_cmp_int( &T2, 0 ) == 0 ) @@ -1154,8 +1079,11 @@ int ecp_add( const ecp_group *grp, ecp_point *R, { int ret; - MPI_CHK( ecp_add_mixed( grp, R, P, Q , 1 ) ); - MPI_CHK( ecp_normalize( grp, R ) ); + if( ecp_get_type( grp ) != POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); + + MPI_CHK( ecp_add_mixed( grp, R, P, Q ) ); + MPI_CHK( ecp_normalize_jac( grp, R ) ); cleanup: return( ret ); @@ -1168,106 +1096,23 @@ int ecp_sub( const ecp_group *grp, ecp_point *R, const ecp_point *P, const ecp_point *Q ) { int ret; + ecp_point mQ; - MPI_CHK( ecp_add_mixed( grp, R, P, Q, -1 ) ); - MPI_CHK( ecp_normalize( grp, R ) ); - -cleanup: - return( ret ); -} - -/* - * Compute a modified width-w non-adjacent form (NAF) of a number, - * with a fixed pattern for resistance to simple timing attacks (even SPA), - * see [1]. (The resulting multiplication algorithm can also been seen as a - * modification of 2^w-ary multiplication, with signed coefficients, all of - * them odd.) - * - * Input: - * m must be an odd positive mpi less than w * k bits long - * x must be an array of k elements - * w must be less than a certain maximum (currently 8) - * - * The result is a sequence x[0], ..., x[k-1] with x[i] in the range - * - 2^(width - 1) .. 2^(width - 1) - 1 such that - * m = (2 * x[0] + 1) + 2^width * (2 * x[1] + 1) + ... - * + 2^((k-1) * width) * (2 * x[k-1] + 1) - * - * Compared to "Algorithm SPA-resistant Width-w NAF with Odd Scalar" - * p. 335 of the cited reference, here we return only u, not d_w since - * it is known that the other d_w[j] will be 0. Moreover, the returned - * string doesn't actually store u_i but x_i = u_i / 2 since it is known - * that u_i is odd. Also, since we always select a positive value for d - * mod 2^w, we don't need to check the sign of u[i-1] when the reference - * does. Finally, there is an off-by-one error in the reference: the - * last index should be k-1, not k. - */ -static int ecp_w_naf_fixed( signed char x[], size_t k, - unsigned char w, const mpi *m ) -{ - int ret; - unsigned int i, u, mask, carry; - mpi M; - - mpi_init( &M ); - - MPI_CHK( mpi_copy( &M, m ) ); - mask = ( 1 << w ) - 1; - carry = 1 << ( w - 1 ); - - for( i = 0; i < k; i++ ) - { - u = M.p[0] & mask; - - if( ( u & 1 ) == 0 && i > 0 ) - x[i - 1] -= carry; - - x[i] = u >> 1; - mpi_shift_r( &M, w ); - } - - /* - * We should have consumed all bits, unless the input value was too big - */ - if( mpi_cmp_int( &M, 0 ) != 0 ) - ret = POLARSSL_ERR_ECP_BAD_INPUT_DATA; - -cleanup: - - mpi_free( &M ); - - return( ret ); -} - -/* - * Precompute odd multiples of P up to (2 * t_len - 1) P. - * The table is filled with T[i] = (2 * i + 1) P. - */ -static int ecp_precompute( const ecp_group *grp, - ecp_point T[], size_t t_len, - const ecp_point *P ) -{ - int ret; - size_t i; - ecp_point PP; - - ecp_point_init( &PP ); + ecp_point_init( &mQ ); - MPI_CHK( ecp_add( grp, &PP, P, P ) ); - - MPI_CHK( ecp_copy( &T[0], P ) ); + if( ecp_get_type( grp ) != POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); - for( i = 1; i < t_len; i++ ) - MPI_CHK( ecp_add_mixed( grp, &T[i], &T[i-1], &PP, +1 ) ); + /* mQ = - Q */ + MPI_CHK( ecp_copy( &mQ, Q ) ); + if( mpi_cmp_int( &mQ.Y, 0 ) != 0 ) + MPI_CHK( mpi_sub_mpi( &mQ.Y, &grp->P, &mQ.Y ) ); - /* - * T[0] = P already has normalized coordinates - */ - MPI_CHK( ecp_normalize_many( grp, T + 1, t_len - 1 ) ); + MPI_CHK( ecp_add_mixed( grp, R, P, &mQ ) ); + MPI_CHK( ecp_normalize_jac( grp, R ) ); cleanup: - - ecp_point_free( &PP ); + ecp_point_free( &mQ ); return( ret ); } @@ -1275,14 +1120,16 @@ cleanup: /* * Randomize jacobian coordinates: * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l - * This is sort of the reverse operation of ecp_normalize(). + * This is sort of the reverse operation of ecp_normalize_jac(). + * + * This countermeasure was first suggested in [2]. */ -static int ecp_randomize_coordinates( const ecp_group *grp, ecp_point *pt, +static int ecp_randomize_jac( const ecp_group *grp, ecp_point *pt, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret; mpi l, ll; - size_t p_size = (grp->pbits + 7) / 8; + size_t p_size = ( grp->pbits + 7 ) / 8; int count = 0; mpi_init( &l ); mpi_init( &ll ); @@ -1293,7 +1140,7 @@ static int ecp_randomize_coordinates( const ecp_group *grp, ecp_point *pt, mpi_fill_random( &l, p_size, f_rng, p_rng ); while( mpi_cmp_mpi( &l, &grp->P ) >= 0 ) - mpi_shift_r( &l, 1 ); + MPI_CHK( mpi_shift_r( &l, 1 ) ); if( count++ > 10 ) return( POLARSSL_ERR_ECP_RANDOM_FAILED ); @@ -1318,86 +1165,256 @@ cleanup: } /* - * Maximum length of the precomputed table + * Check and define parameters used by the comb method (see below for details) */ -#define MAX_PRE_LEN ( 1 << (POLARSSL_ECP_WINDOW_SIZE - 1) ) +#if POLARSSL_ECP_WINDOW_SIZE < 2 || POLARSSL_ECP_WINDOW_SIZE > 7 +#error "POLARSSL_ECP_WINDOW_SIZE out of bounds" +#endif -/* - * Maximum length of the NAF: ceil( grp->nbits + 1 ) / w - * (that is: grp->nbits / w + 1) - * Allow p_bits + 1 bits in case M = grp->N + 1 is one bit longer than N. - */ -#define MAX_NAF_LEN ( POLARSSL_ECP_MAX_BITS / 2 + 1 ) +/* d = ceil( n / w ) */ +#define COMB_MAX_D ( POLARSSL_ECP_MAX_BITS + 1 ) / 2 + +/* number of precomputed points */ +#define COMB_MAX_PRE ( 1 << ( POLARSSL_ECP_WINDOW_SIZE - 1 ) ) /* - * Integer multiplication: R = m * P + * Compute the representation of m that will be used with our comb method. * - * Based on fixed-pattern width-w NAF, see comments of ecp_w_naf_fixed(). + * The basic comb method is described in GECC 3.44 for example. We use a + * modified version that provides resistance to SPA by avoiding zero + * digits in the representation as in [3]. We modify the method further by + * requiring that all K_i be odd, which has the small cost that our + * representation uses one more K_i, due to carries. * - * This function executes a fixed number of operations for - * random m in the range 0 .. 2^nbits - 1. + * Also, for the sake of compactness, only the seven low-order bits of x[i] + * are used to represent K_i, and the msb of x[i] encodes the the sign (s_i in + * the paper): it is set if and only if if s_i == -1; * - * As an additional countermeasure against potential timing attacks, - * we randomize coordinates before each addition. This was suggested as a - * countermeasure against DPA in 5.3 of [2] (with the obvious adaptation that - * we use jacobian coordinates, not standard projective coordinates). + * Calling conventions: + * - x is an array of size d + 1 + * - w is the size, ie number of teeth, of the comb, and must be between + * 2 and 7 (in practice, between 2 and POLARSSL_ECP_WINDOW_SIZE) + * - m is the MPI, expected to be odd and such that bitlength(m) <= w * d + * (the result will be incorrect if these assumptions are not satisfied) + */ +static void ecp_comb_fixed( unsigned char x[], size_t d, + unsigned char w, const mpi *m ) +{ + size_t i, j; + unsigned char c, cc, adjust; + + memset( x, 0, d+1 ); + + /* First get the classical comb values (except for x_d = 0) */ + for( i = 0; i < d; i++ ) + for( j = 0; j < w; j++ ) + x[i] |= mpi_get_bit( m, i + d * j ) << j; + + /* Now make sure x_1 .. x_d are odd */ + c = 0; + for( i = 1; i <= d; i++ ) + { + /* Add carry and update it */ + cc = x[i] & c; + x[i] = x[i] ^ c; + c = cc; + + /* Adjust if needed, avoiding branches */ + adjust = 1 - ( x[i] & 0x01 ); + c |= x[i] & ( x[i-1] * adjust ); + x[i] = x[i] ^ ( x[i-1] * adjust ); + x[i-1] |= adjust << 7; + } +} + +/* + * Precompute points for the comb method + * + * If i = i_{w-1} ... i_1 is the binary representation of i, then + * T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P + * + * T must be able to hold 2^{w - 1} elements + * + * Cost: d(w-1) D + (2^{w-1} - 1) A + 1 N(w-1) + 1 N(2^{w-1} - 1) */ -int ecp_mul( ecp_group *grp, ecp_point *R, - const mpi *m, const ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +static int ecp_precompute_comb( const ecp_group *grp, + ecp_point T[], const ecp_point *P, + unsigned char w, size_t d ) { int ret; - unsigned char w, m_is_odd, p_eq_g; - size_t pre_len = 1, naf_len, i, j; - signed char naf[ MAX_NAF_LEN ]; - ecp_point Q, *T = NULL, S[2]; - mpi M; + unsigned char i, k; + size_t j; + ecp_point *cur, *TT[COMB_MAX_PRE - 1]; - if( mpi_cmp_int( m, 0 ) < 0 || mpi_msb( m ) > grp->nbits ) - return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + /* + * Set T[0] = P and + * T[2^{l-1}] = 2^{dl} P for l = 1 .. w-1 (this is not the final value) + */ + MPI_CHK( ecp_copy( &T[0], P ) ); + + k = 0; + for( i = 1; i < ( 1U << ( w - 1 ) ); i <<= 1 ) + { + cur = T + i; + MPI_CHK( ecp_copy( cur, T + ( i >> 1 ) ) ); + for( j = 0; j < d; j++ ) + MPI_CHK( ecp_double_jac( grp, cur, cur ) ); + + TT[k++] = cur; + } + + MPI_CHK( ecp_normalize_jac_many( grp, TT, k ) ); + + /* + * Compute the remaining ones using the minimal number of additions + * Be careful to update T[2^l] only after using it! + */ + k = 0; + for( i = 1; i < ( 1U << ( w - 1 ) ); i <<= 1 ) + { + j = i; + while( j-- ) + { + MPI_CHK( ecp_add_mixed( grp, &T[i + j], &T[j], &T[i] ) ); + TT[k++] = &T[i + j]; + } + } + + MPI_CHK( ecp_normalize_jac_many( grp, TT, k ) ); + +cleanup: + return( ret ); +} + +/* + * Select precomputed point: R = sign(i) * T[ abs(i) / 2 ] + */ +static int ecp_select_comb( const ecp_group *grp, ecp_point *R, + const ecp_point T[], unsigned char t_len, + unsigned char i ) +{ + int ret; + unsigned char ii, j; + + /* Ignore the "sign" bit and scale down */ + ii = ( i & 0x7Fu ) >> 1; + + /* Read the whole table to thwart cache-based timing attacks */ + for( j = 0; j < t_len; j++ ) + { + MPI_CHK( mpi_safe_cond_assign( &R->X, &T[j].X, j == ii ) ); + MPI_CHK( mpi_safe_cond_assign( &R->Y, &T[j].Y, j == ii ) ); + } + + /* Safely invert result if i is "negative" */ + MPI_CHK( ecp_safe_invert_jac( grp, R, i >> 7 ) ); + +cleanup: + return( ret ); +} + +/* + * Core multiplication algorithm for the (modified) comb method. + * This part is actually common with the basic comb method (GECC 3.44) + * + * Cost: d A + d D + 1 R + */ +static int ecp_mul_comb_core( const ecp_group *grp, ecp_point *R, + const ecp_point T[], unsigned char t_len, + const unsigned char x[], size_t d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + ecp_point Txi; + size_t i; + + ecp_point_init( &Txi ); + + /* Start with a non-zero point and randomize its coordinates */ + i = d; + MPI_CHK( ecp_select_comb( grp, R, T, t_len, x[i] ) ); + MPI_CHK( mpi_lset( &R->Z, 1 ) ); + if( f_rng != 0 ) + MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) ); + + while( i-- != 0 ) + { + MPI_CHK( ecp_double_jac( grp, R, R ) ); + MPI_CHK( ecp_select_comb( grp, &Txi, T, t_len, x[i] ) ); + MPI_CHK( ecp_add_mixed( grp, R, R, &Txi ) ); + } + +cleanup: + ecp_point_free( &Txi ); + + return( ret ); +} + +/* + * Multiplication using the comb method, + * for curves in short Weierstrass form + */ +static int ecp_mul_comb( ecp_group *grp, ecp_point *R, + const mpi *m, const ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char w, m_is_odd, p_eq_g, pre_len, i; + size_t d; + unsigned char k[COMB_MAX_D + 1]; + ecp_point *T; + mpi M, mm; mpi_init( &M ); - ecp_point_init( &Q ); - ecp_point_init( &S[0] ); - ecp_point_init( &S[1] ); + mpi_init( &mm ); + + /* we need N to be odd to trnaform m in an odd number, check now */ + if( mpi_get_bit( &grp->N, 0 ) != 1 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); /* - * Check if P == G + * Minimize the number of multiplications, that is minimize + * 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w ) + * (see costs of the various parts, with 1S = 1M) */ - p_eq_g = ( mpi_cmp_int( &P->Z, 1 ) == 0 && - mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 && - mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 ); + w = grp->nbits >= 384 ? 5 : 4; /* - * If P == G, pre-compute a lot of points: this will be re-used later, - * otherwise, choose window size depending on curve size + * If P == G, pre-compute a bit more, since this may be re-used later. + * Just adding one avoids upping the cost of the first mul too much, + * and the memory cost too. */ +#if POLARSSL_ECP_FIXED_POINT_OPTIM == 1 + p_eq_g = ( mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 && + mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 ); if( p_eq_g ) - w = POLARSSL_ECP_WINDOW_SIZE; - else - w = grp->nbits >= 512 ? 6 : - grp->nbits >= 224 ? 5 : - 4; + w++; +#else + p_eq_g = 0; +#endif /* - * Make sure w is within the limits. - * The last test ensures that none of the precomputed points is zero, - * which wouldn't be handled correctly by ecp_normalize_many(). - * It is only useful for very small curves as used in the test suite. + * Make sure w is within bounds. + * (The last test is useful only for very small curves in the test suite.) */ if( w > POLARSSL_ECP_WINDOW_SIZE ) w = POLARSSL_ECP_WINDOW_SIZE; - if( w < 2 || w >= grp->nbits ) + if( w >= grp->nbits ) w = 2; - pre_len <<= ( w - 1 ); - naf_len = grp->nbits / w + 1; + /* Other sizes that depend on w */ + pre_len = 1U << ( w - 1 ); + d = ( grp->nbits + w - 1 ) / w; /* * Prepare precomputed points: if P == G we want to - * use grp->T if already initialized, or initiliaze it. + * use grp->T if already initialized, or initialize it. */ - if( ! p_eq_g || grp->T == NULL ) + T = p_eq_g ? grp->T : NULL; + + if( T == NULL ) { T = (ecp_point *) polarssl_malloc( pre_len * sizeof( ecp_point ) ); if( T == NULL ) @@ -1409,7 +1426,7 @@ int ecp_mul( ecp_group *grp, ecp_point *R, for( i = 0; i < pre_len; i++ ) ecp_point_init( &T[i] ); - MPI_CHK( ecp_precompute( grp, T, pre_len, P ) ); + MPI_CHK( ecp_precompute_comb( grp, T, P, w, d ) ); if( p_eq_g ) { @@ -1417,74 +1434,27 @@ int ecp_mul( ecp_group *grp, ecp_point *R, grp->T_size = pre_len; } } - else - { - T = grp->T; - - /* Should never happen, but we want to be extra sure */ - if( pre_len != grp->T_size ) - { - ret = POLARSSL_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - } /* - * Make sure M is odd (M = m + 1 or M = m + 2) - * later we'll get m * P by subtracting P or 2 * P to M * P. + * Make sure M is odd (M = m or M = N - m, since N is odd) + * using the fact that m * P = - (N - m) * P */ m_is_odd = ( mpi_get_bit( m, 0 ) == 1 ); - MPI_CHK( mpi_copy( &M, m ) ); - MPI_CHK( mpi_add_int( &M, &M, 1 + m_is_odd ) ); + MPI_CHK( mpi_sub_mpi( &mm, &grp->N, m ) ); + MPI_CHK( mpi_safe_cond_assign( &M, &mm, ! m_is_odd ) ); /* - * Compute the fixed-pattern NAF of M + * Go for comb multiplication, R = M * P */ - MPI_CHK( ecp_w_naf_fixed( naf, naf_len, w, &M ) ); + ecp_comb_fixed( k, d, w, &M ); + MPI_CHK( ecp_mul_comb_core( grp, R, T, pre_len, k, d, f_rng, p_rng ) ); /* - * Compute M * P, using a variant of left-to-right 2^w-ary multiplication: - * at each step we add (2 * naf[i] + 1) P, then multiply by 2^w. - * - * If naf[i] >= 0, we have (2 * naf[i] + 1) P == T[ naf[i] ] - * Otherwise, (2 * naf[i] + 1) P == - ( 2 * ( - naf[i] - 1 ) + 1) P - * == T[ - naf[i] - 1 ] + * Now get m * P from M * P and normalize it */ - MPI_CHK( ecp_set_zero( &Q ) ); - i = naf_len - 1; - while( 1 ) - { - /* Countermeasure (see comments above) */ - if( f_rng != NULL ) - ecp_randomize_coordinates( grp, &Q, f_rng, p_rng ); - - if( naf[i] < 0 ) - { - MPI_CHK( ecp_add_mixed( grp, &Q, &Q, &T[ - naf[i] - 1 ], -1 ) ); - } - else - { - MPI_CHK( ecp_add_mixed( grp, &Q, &Q, &T[ naf[i] ], +1 ) ); - } - - if( i == 0 ) - break; - i--; - - for( j = 0; j < w; j++ ) - { - MPI_CHK( ecp_double_jac( grp, &Q, &Q ) ); - } - } - - /* - * Now get m * P from M * P - */ - MPI_CHK( ecp_copy( &S[0], P ) ); - MPI_CHK( ecp_add( grp, &S[1], P, P ) ); - MPI_CHK( ecp_sub( grp, R, &Q, &S[m_is_odd] ) ); - + MPI_CHK( ecp_safe_invert_jac( grp, R, ! m_is_odd ) ); + MPI_CHK( ecp_normalize_jac( grp, R ) ); cleanup: @@ -1495,501 +1465,435 @@ cleanup: polarssl_free( T ); } - ecp_point_free( &S[1] ); - ecp_point_free( &S[0] ); - ecp_point_free( &Q ); mpi_free( &M ); + mpi_free( &mm ); + + if( ret != 0 ) + ecp_point_free( R ); return( ret ); } +#endif /* POLARSSL_ECP_SHORT_WEIERSTRASS */ + +#if defined(POLARSSL_ECP_MONTGOMERY) /* - * Check that a point is valid as a public key (SEC1 3.2.3.1) + * For Montgomery curves, we do all the internal arithmetic in projective + * coordinates. Import/export of points uses only the x coordinates, which is + * internaly represented as X / Z. + * + * For scalar multiplication, we'll use a Montgomery ladder. */ -int ecp_check_pubkey( const ecp_group *grp, const ecp_point *pt ) + +/* + * Normalize Montgomery x/z coordinates: X = X/Z, Z = 1 + * Cost: 1M + 1I + */ +static int ecp_normalize_mxz( const ecp_group *grp, ecp_point *P ) { int ret; - mpi YY, RHS; - if( mpi_cmp_int( &pt->Z, 0 ) == 0 ) - return( POLARSSL_ERR_ECP_INVALID_KEY ); - - /* - * pt coordinates must be normalized for our checks - */ - if( mpi_cmp_int( &pt->Z, 1 ) != 0 ) - return( POLARSSL_ERR_ECP_INVALID_KEY ); - - if( mpi_cmp_int( &pt->X, 0 ) < 0 || - mpi_cmp_int( &pt->Y, 0 ) < 0 || - mpi_cmp_mpi( &pt->X, &grp->P ) >= 0 || - mpi_cmp_mpi( &pt->Y, &grp->P ) >= 0 ) - return( POLARSSL_ERR_ECP_INVALID_KEY ); - - mpi_init( &YY ); mpi_init( &RHS ); - - /* - * YY = Y^2 - * RHS = X (X^2 + A) + B = X^3 + A X + B - */ - MPI_CHK( mpi_mul_mpi( &YY, &pt->Y, &pt->Y ) ); MOD_MUL( YY ); - MPI_CHK( mpi_mul_mpi( &RHS, &pt->X, &pt->X ) ); MOD_MUL( RHS ); - MPI_CHK( mpi_add_mpi( &RHS, &RHS, &grp->A ) ); MOD_ADD( RHS ); - MPI_CHK( mpi_mul_mpi( &RHS, &RHS, &pt->X ) ); MOD_MUL( RHS ); - MPI_CHK( mpi_add_mpi( &RHS, &RHS, &grp->B ) ); MOD_ADD( RHS ); - - if( mpi_cmp_mpi( &YY, &RHS ) != 0 ) - ret = POLARSSL_ERR_ECP_INVALID_KEY; + MPI_CHK( mpi_inv_mod( &P->Z, &P->Z, &grp->P ) ); + MPI_CHK( mpi_mul_mpi( &P->X, &P->X, &P->Z ) ); MOD_MUL( P->X ); + MPI_CHK( mpi_lset( &P->Z, 1 ) ); cleanup: - - mpi_free( &YY ); mpi_free( &RHS ); - return( ret ); } /* - * Check that an mpi is valid as a private key (SEC1 3.2) - */ -int ecp_check_privkey( const ecp_group *grp, const mpi *d ) -{ - /* We want 1 <= d <= N-1 */ - if ( mpi_cmp_int( d, 1 ) < 0 || mpi_cmp_mpi( d, &grp->N ) >= 0 ) - return( POLARSSL_ERR_ECP_INVALID_KEY ); - - return( 0 ); -} - -/* - * Generate a keypair (SEC1 3.2.1) + * Randomize projective x/z coordinates: + * (X, Z) -> (l X, l Z) for random l + * This is sort of the reverse operation of ecp_normalize_mxz(). + * + * This countermeasure was first suggested in [2]. + * Cost: 2M */ -int ecp_gen_keypair( ecp_group *grp, mpi *d, ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) +static int ecp_randomize_mxz( const ecp_group *grp, ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { + int ret; + mpi l; + size_t p_size = ( grp->pbits + 7 ) / 8; int count = 0; - size_t n_size = (grp->nbits + 7) / 8; - /* - * Generate d such that 1 <= n < N - */ + mpi_init( &l ); + + /* Generate l such that 1 < l < p */ do { - mpi_fill_random( d, n_size, f_rng, p_rng ); + mpi_fill_random( &l, p_size, f_rng, p_rng ); - while( mpi_cmp_mpi( d, &grp->N ) >= 0 ) - mpi_shift_r( d, 1 ); + while( mpi_cmp_mpi( &l, &grp->P ) >= 0 ) + MPI_CHK( mpi_shift_r( &l, 1 ) ); if( count++ > 10 ) return( POLARSSL_ERR_ECP_RANDOM_FAILED ); } - while( mpi_cmp_int( d, 1 ) < 0 ); + while( mpi_cmp_int( &l, 1 ) <= 0 ); - return( ecp_mul( grp, Q, d, &grp->G, f_rng, p_rng ) ); + MPI_CHK( mpi_mul_mpi( &P->X, &P->X, &l ) ); MOD_MUL( P->X ); + MPI_CHK( mpi_mul_mpi( &P->Z, &P->Z, &l ) ); MOD_MUL( P->Z ); + +cleanup: + mpi_free( &l ); + + return( ret ); } -#if defined(POLARSSL_ECP_NIST_OPTIM) /* - * Fast reduction modulo the primes used by the NIST curves. + * Double-and-add: R = 2P, S = P + Q, with d = X(P - Q), + * for Montgomery curves in x/z coordinates. * - * These functions are: critical for speed, but not need for correct - * operations. So, we make the choice to heavily rely on the internals of our - * bignum library, which creates a tight coupling between these functions and - * our MPI implementation. However, the coupling between the ECP module and - * MPI remains loose, since these functions can be deactivated at will. - */ - -#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) -/* - * Compared to the way things are presented in FIPS 186-3 D.2, - * we proceed in columns, from right (least significant chunk) to left, - * adding chunks to N in place, and keeping a carry for the next chunk. - * This avoids moving things around in memory, and uselessly adding zeros, - * compared to the more straightforward, line-oriented approach. + * http://www.hyperelliptic.org/EFD/g1p/auto-code/montgom/xz/ladder/mladd-1987-m.op3 + * with + * d = X1 + * P = (X2, Z2) + * Q = (X3, Z3) + * R = (X4, Z4) + * S = (X5, Z5) + * and eliminating temporary variables tO, ..., t4. * - * For this prime we need to handle data in chunks of 64 bits. - * Since this is always a multiple of our basic t_uint, we can - * use a t_uint * to designate such a chunk, and small loops to handle it. + * Cost: 5M + 4S */ - -/* Add 64-bit chunks (dst += src) and update carry */ -static inline void add64( t_uint *dst, t_uint *src, t_uint *carry ) +static int ecp_double_add_mxz( const ecp_group *grp, + ecp_point *R, ecp_point *S, + const ecp_point *P, const ecp_point *Q, + const mpi *d ) { - unsigned char i; - t_uint c = 0; - for( i = 0; i < 8 / sizeof( t_uint ); i++, dst++, src++ ) - { - *dst += c; c = ( *dst < c ); - *dst += *src; c += ( *dst < *src ); - } - *carry += c; -} + int ret; + mpi A, AA, B, BB, E, C, D, DA, CB; + + mpi_init( &A ); mpi_init( &AA ); mpi_init( &B ); + mpi_init( &BB ); mpi_init( &E ); mpi_init( &C ); + mpi_init( &D ); mpi_init( &DA ); mpi_init( &CB ); + + MPI_CHK( mpi_add_mpi( &A, &P->X, &P->Z ) ); MOD_ADD( A ); + MPI_CHK( mpi_mul_mpi( &AA, &A, &A ) ); MOD_MUL( AA ); + MPI_CHK( mpi_sub_mpi( &B, &P->X, &P->Z ) ); MOD_SUB( B ); + MPI_CHK( mpi_mul_mpi( &BB, &B, &B ) ); MOD_MUL( BB ); + MPI_CHK( mpi_sub_mpi( &E, &AA, &BB ) ); MOD_SUB( E ); + MPI_CHK( mpi_add_mpi( &C, &Q->X, &Q->Z ) ); MOD_ADD( C ); + MPI_CHK( mpi_sub_mpi( &D, &Q->X, &Q->Z ) ); MOD_SUB( D ); + MPI_CHK( mpi_mul_mpi( &DA, &D, &A ) ); MOD_MUL( DA ); + MPI_CHK( mpi_mul_mpi( &CB, &C, &B ) ); MOD_MUL( CB ); + MPI_CHK( mpi_add_mpi( &S->X, &DA, &CB ) ); MOD_MUL( S->X ); + MPI_CHK( mpi_mul_mpi( &S->X, &S->X, &S->X ) ); MOD_MUL( S->X ); + MPI_CHK( mpi_sub_mpi( &S->Z, &DA, &CB ) ); MOD_SUB( S->Z ); + MPI_CHK( mpi_mul_mpi( &S->Z, &S->Z, &S->Z ) ); MOD_MUL( S->Z ); + MPI_CHK( mpi_mul_mpi( &S->Z, d, &S->Z ) ); MOD_MUL( S->Z ); + MPI_CHK( mpi_mul_mpi( &R->X, &AA, &BB ) ); MOD_MUL( R->X ); + MPI_CHK( mpi_mul_mpi( &R->Z, &grp->A, &E ) ); MOD_MUL( R->Z ); + MPI_CHK( mpi_add_mpi( &R->Z, &BB, &R->Z ) ); MOD_ADD( R->Z ); + MPI_CHK( mpi_mul_mpi( &R->Z, &E, &R->Z ) ); MOD_MUL( R->Z ); -/* Add carry to a 64-bit chunk and update carry */ -static inline void carry64( t_uint *dst, t_uint *carry ) -{ - unsigned char i; - for( i = 0; i < 8 / sizeof( t_uint ); i++, dst++ ) - { - *dst += *carry; - *carry = ( *dst < *carry ); - } -} +cleanup: + mpi_free( &A ); mpi_free( &AA ); mpi_free( &B ); + mpi_free( &BB ); mpi_free( &E ); mpi_free( &C ); + mpi_free( &D ); mpi_free( &DA ); mpi_free( &CB ); -#define WIDTH 8 / sizeof( t_uint ) -#define A( i ) N->p + i * WIDTH -#define ADD( i ) add64( p, A( i ), &c ) -#define NEXT p += WIDTH; carry64( p, &c ) -#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0 + return( ret ); +} /* - * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) + * Multiplication with Montgomery ladder in x/z coordinates, + * for curves in Montgomery form */ -static int ecp_mod_p192( mpi *N ) +static int ecp_mul_mxz( ecp_group *grp, ecp_point *R, + const mpi *m, const ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) { int ret; - t_uint c = 0; - t_uint *p, *end; + size_t i; + unsigned char b; + ecp_point RP; + mpi PX; - /* Make sure we have enough blocks so that A(5) is legal */ - MPI_CHK( mpi_grow( N, 6 * WIDTH ) ); + ecp_point_init( &RP ); mpi_init( &PX ); - p = N->p; - end = p + N->n; + /* Save PX and read from P before writing to R, in case P == R */ + MPI_CHK( mpi_copy( &PX, &P->X ) ); + MPI_CHK( ecp_copy( &RP, P ) ); - ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5 - ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5 - ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5 + /* Set R to zero in modified x/z coordinates */ + MPI_CHK( mpi_lset( &R->X, 1 ) ); + MPI_CHK( mpi_lset( &R->Z, 0 ) ); + mpi_free( &R->Y ); -cleanup: - return( ret ); -} + /* RP.X might be sligtly larger than P, so reduce it */ + MOD_ADD( RP.X ); -#undef WIDTH -#undef A -#undef ADD -#undef NEXT -#undef LAST -#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ + /* Randomize coordinates of the starting point */ + if( f_rng != NULL ) + MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) ); -#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) || \ - defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) || \ - defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) -/* - * The reader is advised to first understand ecp_mod_p192() since the same - * general structure is used here, but with additional complications: - * (1) chunks of 32 bits, and (2) subtractions. - */ - -/* - * For these primes, we need to handle data in chunks of 32 bits. - * This makes it more complicated if we use 64 bits limbs in MPI, - * which prevents us from using a uniform access method as for p192. - * - * So, we define a mini abstraction layer to access 32 bit chunks, - * load them in 'cur' for work, and store them back from 'cur' when done. - * - * While at it, also define the size of N in terms of 32-bit chunks. - */ -#define LOAD32 cur = A( i ); - -#if defined(POLARSSL_HAVE_INT8) /* 8 bit */ - -#define MAX32 N->n / 4 -#define A( j ) (uint32_t)( N->p[4*j+0] ) | \ - ( N->p[4*j+1] << 8 ) | \ - ( N->p[4*j+2] << 16 ) | \ - ( N->p[4*j+3] << 24 ) -#define STORE32 N->p[4*i+0] = (uint8_t)( cur ); \ - N->p[4*i+1] = (uint8_t)( cur >> 8 ); \ - N->p[4*i+2] = (uint8_t)( cur >> 16 ); \ - N->p[4*i+3] = (uint8_t)( cur >> 24 ); - -#elif defined(POLARSSL_HAVE_INT16) /* 16 bit */ - -#define MAX32 N->n / 2 -#define A( j ) (uint32_t)( N->p[2*j] ) | ( N->p[2*j+1] << 16 ) -#define STORE32 N->p[2*i+0] = (uint16_t)( cur ); \ - N->p[2*i+1] = (uint16_t)( cur >> 16 ); - -#elif defined(POLARSSL_HAVE_INT32) /* 32 bit */ - -#define MAX32 N->n -#define A( j ) N->p[j] -#define STORE32 N->p[i] = cur; - -#else /* 64-bit */ - -#define MAX32 N->n * 2 -#define A( j ) j % 2 ? (uint32_t)( N->p[j/2] >> 32 ) : (uint32_t)( N->p[j/2] ) -#define STORE32 \ - if( i % 2 ) { \ - N->p[i/2] &= 0x00000000FFFFFFFF; \ - N->p[i/2] |= ((uint64_t) cur) << 32; \ - } else { \ - N->p[i/2] &= 0xFFFFFFFF00000000; \ - N->p[i/2] |= (uint64_t) cur; \ + /* Loop invariant: R = result so far, RP = R + P */ + i = mpi_msb( m ); /* one past the (zero-based) most significant bit */ + while( i-- > 0 ) + { + b = mpi_get_bit( m, i ); + /* + * if (b) R = 2R + P else R = 2R, + * which is: + * if (b) double_add( RP, R, RP, R ) + * else double_add( R, RP, R, RP ) + * but using safe conditional swaps to avoid leaks + */ + MPI_CHK( mpi_safe_cond_swap( &R->X, &RP.X, b ) ); + MPI_CHK( mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); + MPI_CHK( ecp_double_add_mxz( grp, R, &RP, R, &RP, &PX ) ); + MPI_CHK( mpi_safe_cond_swap( &R->X, &RP.X, b ) ); + MPI_CHK( mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); } -#endif /* sizeof( t_uint ) */ + MPI_CHK( ecp_normalize_mxz( grp, R ) ); -/* - * Helpers for addition and subtraction of chunks, with signed carry. - */ -static inline void add32( uint32_t *dst, uint32_t src, signed char *carry ) -{ - *dst += src; - *carry += ( *dst < src ); -} +cleanup: + ecp_point_free( &RP ); mpi_free( &PX ); -static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry ) -{ - *carry -= ( *dst < src ); - *dst -= src; + return( ret ); } -#define ADD( j ) add32( &cur, A( j ), &c ); -#define SUB( j ) sub32( &cur, A( j ), &c ); - -/* - * Helpers for the main 'loop' - * (see fix_negative for the motivation of C) - */ -#define INIT( b ) \ - int ret; \ - signed char c = 0, cc; \ - uint32_t cur; \ - size_t i = 0, bits = b; \ - mpi C; \ - t_uint Cp[ b / 8 / sizeof( t_uint) + 1 ]; \ - \ - C.s = 1; \ - C.n = b / 8 / sizeof( t_uint) + 1; \ - C.p = Cp; \ - memset( Cp, 0, C.n * sizeof( t_uint ) ); \ - \ - MPI_CHK( mpi_grow( N, b * 2 / 8 / sizeof( t_uint ) ) ); \ - LOAD32; - -#define NEXT \ - STORE32; i++; LOAD32; \ - cc = c; c = 0; \ - if( cc < 0 ) \ - sub32( &cur, -cc, &c ); \ - else \ - add32( &cur, cc, &c ); \ - -#define LAST \ - STORE32; i++; \ - cur = c > 0 ? c : 0; STORE32; \ - cur = 0; while( ++i < MAX32 ) { STORE32; } \ - if( c < 0 ) fix_negative( N, c, &C, bits ); +#endif /* POLARSSL_ECP_MONTGOMERY */ /* - * If the result is negative, we get it in the form - * c * 2^(bits + 32) + N, with c negative and N positive shorter than 'bits' + * Multiplication R = m * P */ -static inline int fix_negative( mpi *N, signed char c, mpi *C, size_t bits ) +int ecp_mul( ecp_group *grp, ecp_point *R, + const mpi *m, const ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret; - /* C = - c * 2^(bits + 32) */ -#if !defined(POLARSSL_HAVE_INT64) - ((void) bits); -#else - if( bits == 224 ) - C->p[ C->n - 1 ] = ((t_uint) -c) << 32; - else -#endif - C->p[ C->n - 1 ] = (t_uint) -c; - - /* N = - ( C - N ) */ - MPI_CHK( mpi_sub_abs( N, C, N ) ); - N->s = -1; - -cleanup: - - return( ret ); -} - -#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) -/* - * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) - */ -static int ecp_mod_p224( mpi *N ) -{ - INIT( 224 ); + /* Common sanity checks */ + if( mpi_cmp_int( &P->Z, 1 ) != 0 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); - SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11 - SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12 - SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13 - SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11 - SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12 - SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13 - SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10 + if( ( ret = ecp_check_privkey( grp, m ) ) != 0 || + ( ret = ecp_check_pubkey( grp, P ) ) != 0 ) + return( ret ); -cleanup: - return( ret ); +#if defined(POLARSSL_ECP_MONTGOMERY) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_MONTGOMERY ) + return( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) ); +#endif +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + return( ecp_mul_comb( grp, R, m, P, f_rng, p_rng ) ); +#endif + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); } -#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ -#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) /* - * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) + * Check that an affine point is valid as a public key, + * short weierstrass curves (SEC1 3.2.3.1) */ -static int ecp_mod_p256( mpi *N ) +static int ecp_check_pubkey_sw( const ecp_group *grp, const ecp_point *pt ) { - INIT( 256 ); + int ret; + mpi YY, RHS; - ADD( 8 ); ADD( 9 ); - SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0 + /* pt coordinates must be normalized for our checks */ + if( mpi_cmp_int( &pt->X, 0 ) < 0 || + mpi_cmp_int( &pt->Y, 0 ) < 0 || + mpi_cmp_mpi( &pt->X, &grp->P ) >= 0 || + mpi_cmp_mpi( &pt->Y, &grp->P ) >= 0 ) + return( POLARSSL_ERR_ECP_INVALID_KEY ); - ADD( 9 ); ADD( 10 ); - SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1 + mpi_init( &YY ); mpi_init( &RHS ); - ADD( 10 ); ADD( 11 ); - SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2 + /* + * YY = Y^2 + * RHS = X (X^2 + A) + B = X^3 + A X + B + */ + MPI_CHK( mpi_mul_mpi( &YY, &pt->Y, &pt->Y ) ); MOD_MUL( YY ); + MPI_CHK( mpi_mul_mpi( &RHS, &pt->X, &pt->X ) ); MOD_MUL( RHS ); - ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 ); - SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3 + /* Special case for A = -3 */ + if( grp->A.p == NULL ) + { + MPI_CHK( mpi_sub_int( &RHS, &RHS, 3 ) ); MOD_SUB( RHS ); + } + else + { + MPI_CHK( mpi_add_mpi( &RHS, &RHS, &grp->A ) ); MOD_ADD( RHS ); + } - ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 ); - SUB( 9 ); SUB( 10 ); NEXT; // A4 + MPI_CHK( mpi_mul_mpi( &RHS, &RHS, &pt->X ) ); MOD_MUL( RHS ); + MPI_CHK( mpi_add_mpi( &RHS, &RHS, &grp->B ) ); MOD_ADD( RHS ); - ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 ); - SUB( 10 ); SUB( 11 ); NEXT; // A5 + if( mpi_cmp_mpi( &YY, &RHS ) != 0 ) + ret = POLARSSL_ERR_ECP_INVALID_KEY; - ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 ); - SUB( 8 ); SUB( 9 ); NEXT; // A6 +cleanup: - ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 ); - SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7 + mpi_free( &YY ); mpi_free( &RHS ); -cleanup: return( ret ); } -#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ +#endif /* POLARSSL_ECP_SHORT_WEIERSTRASS */ -#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) + +#if defined(POLARSSL_ECP_MONTGOMERY) /* - * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) + * Check validity of a public key for Montgomery curves with x-only schemes */ -static int ecp_mod_p384( mpi *N ) +static int ecp_check_pubkey_mx( const ecp_group *grp, const ecp_point *pt ) { - INIT( 384 ); - - ADD( 12 ); ADD( 21 ); ADD( 20 ); - SUB( 23 ); NEXT; // A0 - - ADD( 13 ); ADD( 22 ); ADD( 23 ); - SUB( 12 ); SUB( 20 ); NEXT; // A2 - - ADD( 14 ); ADD( 23 ); - SUB( 13 ); SUB( 21 ); NEXT; // A2 - - ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 ); - SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3 - - ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 ); - SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4 - - ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 ); - SUB( 16 ); NEXT; // A5 - - ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 ); - SUB( 17 ); NEXT; // A6 - - ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 ); - SUB( 18 ); NEXT; // A7 - - ADD( 20 ); ADD( 17 ); ADD( 16 ); - SUB( 19 ); NEXT; // A8 - - ADD( 21 ); ADD( 18 ); ADD( 17 ); - SUB( 20 ); NEXT; // A9 - - ADD( 22 ); ADD( 19 ); ADD( 18 ); - SUB( 21 ); NEXT; // A10 - - ADD( 23 ); ADD( 20 ); ADD( 19 ); - SUB( 22 ); LAST; // A11 + /* [M255 p. 5] Just check X is the correct number of bytes */ + if( mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 ) + return( POLARSSL_ERR_ECP_INVALID_KEY ); -cleanup: - return( ret ); + return( 0 ); } -#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ +#endif /* POLARSSL_ECP_MONTGOMERY */ -#undef A -#undef LOAD32 -#undef STORE32 -#undef MAX32 -#undef INIT -#undef NEXT -#undef LAST +/* + * Check that a point is valid as a public key + */ +int ecp_check_pubkey( const ecp_group *grp, const ecp_point *pt ) +{ + /* Must use affine coordinates */ + if( mpi_cmp_int( &pt->Z, 1 ) != 0 ) + return( POLARSSL_ERR_ECP_INVALID_KEY ); -#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED || - POLARSSL_ECP_DP_SECP256R1_ENABLED || - POLARSSL_ECP_DP_SECP384R1_ENABLED */ +#if defined(POLARSSL_ECP_MONTGOMERY) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_MONTGOMERY ) + return( ecp_check_pubkey_mx( grp, pt ) ); +#endif +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + return( ecp_check_pubkey_sw( grp, pt ) ); +#endif + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); +} -#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) /* - * Here we have an actual Mersenne prime, so things are more straightforward. - * However, chunks are aligned on a 'weird' boundary (521 bits). + * Check that an mpi is valid as a private key */ +int ecp_check_privkey( const ecp_group *grp, const mpi *d ) +{ +#if defined(POLARSSL_ECP_MONTGOMERY) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_MONTGOMERY ) + { + /* see [M255] page 5 */ + if( mpi_get_bit( d, 0 ) != 0 || + mpi_get_bit( d, 1 ) != 0 || + mpi_get_bit( d, 2 ) != 0 || + mpi_msb( d ) - 1 != grp->nbits ) /* mpi_msb is one-based! */ + return( POLARSSL_ERR_ECP_INVALID_KEY ); + else + return( 0 ); + } +#endif /* POLARSSL_ECP_MONTGOMERY */ +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + { + /* see SEC1 3.2 */ + if( mpi_cmp_int( d, 1 ) < 0 || + mpi_cmp_mpi( d, &grp->N ) >= 0 ) + return( POLARSSL_ERR_ECP_INVALID_KEY ); + else + return( 0 ); + } +#endif /* POLARSSL_ECP_SHORT_WEIERSTRASS */ -/* Size of p521 in terms of t_uint */ -#define P521_WIDTH ( 521 / 8 / sizeof( t_uint ) + 1 ) - -/* Bits to keep in the most significant t_uint */ -#if defined(POLARSSL_HAVE_INT8) -#define P521_MASK 0x01 -#else -#define P521_MASK 0x01FF -#endif + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); +} /* - * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5) - * Write N as A1 + 2^521 A0, return A0 + A1 + * Generate a keypair */ -static int ecp_mod_p521( mpi *N ) +int ecp_gen_keypair( ecp_group *grp, mpi *d, ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) { int ret; - size_t i; - mpi M; - t_uint Mp[P521_WIDTH + 1]; - /* Worst case for the size of M is when t_uint is 16 bits: - * we need to hold bits 513 to 1056, which is 34 limbs, that is - * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */ + size_t n_size = ( grp->nbits + 7 ) / 8; - if( N->n < P521_WIDTH ) - return( 0 ); +#if defined(POLARSSL_ECP_MONTGOMERY) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_MONTGOMERY ) + { + /* [M225] page 5 */ + size_t b; + + MPI_CHK( mpi_fill_random( d, n_size, f_rng, p_rng ) ); - /* M = A1 */ - M.s = 1; - M.n = N->n - ( P521_WIDTH - 1 ); - if( M.n > P521_WIDTH + 1 ) - M.n = P521_WIDTH + 1; - M.p = Mp; - memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( t_uint ) ); - MPI_CHK( mpi_shift_r( &M, 521 % ( 8 * sizeof( t_uint ) ) ) ); + /* Make sure the most significant bit is nbits */ + b = mpi_msb( d ) - 1; /* mpi_msb is one-based */ + if( b > grp->nbits ) + MPI_CHK( mpi_shift_r( d, b - grp->nbits ) ); + else + MPI_CHK( mpi_set_bit( d, grp->nbits, 1 ) ); - /* N = A0 */ - N->p[P521_WIDTH - 1] &= P521_MASK; - for( i = P521_WIDTH; i < N->n; i++ ) - N->p[i] = 0; + /* Make sure the last three bits are unset */ + MPI_CHK( mpi_set_bit( d, 0, 0 ) ); + MPI_CHK( mpi_set_bit( d, 1, 0 ) ); + MPI_CHK( mpi_set_bit( d, 2, 0 ) ); + } + else +#endif /* POLARSSL_ECP_MONTGOMERY */ +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + { + /* SEC1 3.2.1: Generate d such that 1 <= n < N */ + int count = 0; + unsigned char rnd[POLARSSL_ECP_MAX_BYTES]; - /* N = A0 + A1 */ - MPI_CHK( mpi_add_abs( N, N, &M ) ); + /* + * Match the procedure given in RFC 6979 (deterministic ECDSA): + * - use the same byte ordering; + * - keep the leftmost nbits bits of the generated octet string; + * - try until result is in the desired range. + * This also avoids any biais, which is especially important for ECDSA. + */ + do + { + MPI_CHK( f_rng( p_rng, rnd, n_size ) ); + MPI_CHK( mpi_read_binary( d, rnd, n_size ) ); + MPI_CHK( mpi_shift_r( d, 8 * n_size - grp->nbits ) ); + + /* + * Each try has at worst a probability 1/2 of failing (the msb has + * a probability 1/2 of being 0, and then the result will be < N), + * so after 30 tries failure probability is a most 2**(-30). + * + * For most curves, 1 try is enough with overwhelming probability, + * since N starts with a lot of 1s in binary, but some curves + * such as secp224k1 are actually very close to the worst case. + */ + if( ++count > 30 ) + return( POLARSSL_ERR_ECP_RANDOM_FAILED ); + } + while( mpi_cmp_int( d, 1 ) < 0 || + mpi_cmp_mpi( d, &grp->N ) >= 0 ); + } + else +#endif /* POLARSSL_ECP_SHORT_WEIERSTRASS */ + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); cleanup: - return( ret ); + if( ret != 0 ) + return( ret ); + + return( ecp_mul( grp, Q, d, &grp->G, f_rng, p_rng ) ); } -#undef P521_WIDTH -#undef P521_MASK -#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ +/* + * Generate a keypair, prettier wrapper + */ +int ecp_gen_key( ecp_group_id grp_id, ecp_keypair *key, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; -#endif /* POLARSSL_ECP_NIST_OPTIM */ + if( ( ret = ecp_use_known_dp( &key->grp, grp_id ) ) != 0 ) + return( ret ); + + return( ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) ); +} #if defined(POLARSSL_SELF_TEST) @@ -2003,17 +1907,16 @@ int ecp_self_test( int verbose ) ecp_group grp; ecp_point R, P; mpi m; - unsigned long add_c_prev, dbl_c_prev; + unsigned long add_c_prev, dbl_c_prev, mul_c_prev; /* exponents especially adapted for secp192r1 */ const char *exponents[] = { - "000000000000000000000000000000000000000000000000", /* zero */ "000000000000000000000000000000000000000000000001", /* one */ - "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* N */ + "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830", /* N - 1 */ "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */ - "400000000000000000000000000000000000000000000000", - "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - "555555555555555555555555555555555555555555555555", + "400000000000000000000000000000000000000000000000", /* one and zeros */ + "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */ + "555555555555555555555555555555555555555555555555", /* 101010... */ }; ecp_group_init( &grp ); @@ -2029,7 +1932,7 @@ int ecp_self_test( int verbose ) #endif if( verbose != 0 ) - printf( " ECP test #1 (constant op_count, base point G): " ); + polarssl_printf( " ECP test #1 (constant op_count, base point G): " ); /* Do a dummy multiplication first to trigger precomputation */ MPI_CHK( mpi_lset( &m, 2 ) ); @@ -2037,6 +1940,7 @@ int ecp_self_test( int verbose ) add_count = 0; dbl_count = 0; + mul_count = 0; MPI_CHK( mpi_read_string( &m, 16, exponents[0] ) ); MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) ); @@ -2044,16 +1948,20 @@ int ecp_self_test( int verbose ) { add_c_prev = add_count; dbl_c_prev = dbl_count; + mul_c_prev = mul_count; add_count = 0; dbl_count = 0; + mul_count = 0; MPI_CHK( mpi_read_string( &m, 16, exponents[i] ) ); MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) ); - if( add_count != add_c_prev || dbl_count != dbl_c_prev ) + if( add_count != add_c_prev || + dbl_count != dbl_c_prev || + mul_count != mul_c_prev ) { if( verbose != 0 ) - printf( "failed (%zu)\n", i ); + polarssl_printf( "failed (%u)\n", (unsigned int) i ); ret = 1; goto cleanup; @@ -2061,14 +1969,15 @@ int ecp_self_test( int verbose ) } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); if( verbose != 0 ) - printf( " ECP test #2 (constant op_count, other point): " ); + polarssl_printf( " ECP test #2 (constant op_count, other point): " ); /* We computed P = 2G last time, use it */ add_count = 0; dbl_count = 0; + mul_count = 0; MPI_CHK( mpi_read_string( &m, 16, exponents[0] ) ); MPI_CHK( ecp_mul( &grp, &R, &m, &P, NULL, NULL ) ); @@ -2076,16 +1985,20 @@ int ecp_self_test( int verbose ) { add_c_prev = add_count; dbl_c_prev = dbl_count; + mul_c_prev = mul_count; add_count = 0; dbl_count = 0; + mul_count = 0; MPI_CHK( mpi_read_string( &m, 16, exponents[i] ) ); MPI_CHK( ecp_mul( &grp, &R, &m, &P, NULL, NULL ) ); - if( add_count != add_c_prev || dbl_count != dbl_c_prev ) + if( add_count != add_c_prev || + dbl_count != dbl_c_prev || + mul_count != mul_c_prev ) { if( verbose != 0 ) - printf( "failed (%zu)\n", i ); + polarssl_printf( "failed (%u)\n", (unsigned int) i ); ret = 1; goto cleanup; @@ -2093,12 +2006,12 @@ int ecp_self_test( int verbose ) } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); cleanup: if( ret < 0 && verbose != 0 ) - printf( "Unexpected error, return code = %08X\n", ret ); + polarssl_printf( "Unexpected error, return code = %08X\n", ret ); ecp_group_free( &grp ); ecp_point_free( &R ); @@ -2106,11 +2019,11 @@ cleanup: mpi_free( &m ); if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); return( ret ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_ECP_C */ diff --git a/pdns/ext/polarssl/library/ecp_curves.c b/pdns/ext/polarssl/library/ecp_curves.c new file mode 100644 index 000000000..4c0018cc7 --- /dev/null +++ b/pdns/ext/polarssl/library/ecp_curves.c @@ -0,0 +1,1380 @@ +/* + * Elliptic curves over GF(p): curve-specific data and functions + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ECP_C) + +#include "polarssl/ecp.h" + +#if defined(_MSC_VER) && !defined(inline) +#define inline _inline +#else +#if defined(__ARMCC_VERSION) && !defined(inline) +#define inline __inline +#endif /* __ARMCC_VERSION */ +#endif /*_MSC_VER */ + +/* + * Conversion macros for embedded constants: + * build lists of t_uint's from lists of unsigned char's grouped by 8, 4 or 2 + */ +#if defined(POLARSSL_HAVE_INT8) + +#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ + a, b, c, d, e, f, g, h + +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + a, b, c, d + +#define BYTES_TO_T_UINT_2( a, b ) \ + a, b + +#elif defined(POLARSSL_HAVE_INT16) + +#define BYTES_TO_T_UINT_2( a, b ) \ + ( (t_uint) a << 0 ) | \ + ( (t_uint) b << 8 ) + +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + BYTES_TO_T_UINT_2( a, b ), \ + BYTES_TO_T_UINT_2( c, d ) + +#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ + BYTES_TO_T_UINT_2( a, b ), \ + BYTES_TO_T_UINT_2( c, d ), \ + BYTES_TO_T_UINT_2( e, f ), \ + BYTES_TO_T_UINT_2( g, h ) + +#elif defined(POLARSSL_HAVE_INT32) + +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + ( (t_uint) a << 0 ) | \ + ( (t_uint) b << 8 ) | \ + ( (t_uint) c << 16 ) | \ + ( (t_uint) d << 24 ) + +#define BYTES_TO_T_UINT_2( a, b ) \ + BYTES_TO_T_UINT_4( a, b, 0, 0 ) + +#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ + BYTES_TO_T_UINT_4( a, b, c, d ), \ + BYTES_TO_T_UINT_4( e, f, g, h ) + +#else /* 64-bits */ + +#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ + ( (t_uint) a << 0 ) | \ + ( (t_uint) b << 8 ) | \ + ( (t_uint) c << 16 ) | \ + ( (t_uint) d << 24 ) | \ + ( (t_uint) e << 32 ) | \ + ( (t_uint) f << 40 ) | \ + ( (t_uint) g << 48 ) | \ + ( (t_uint) h << 56 ) + +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 ) + +#define BYTES_TO_T_UINT_2( a, b ) \ + BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 ) + +#endif /* bits in t_uint */ + +/* + * Note: the constants are in little-endian order + * to be directly usable in MPIs + */ + +/* + * Domain parameters for secp192r1 + */ +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) +static const t_uint secp192r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const t_uint secp192r1_b[] = { + BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ), + BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ), + BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ), +}; +static const t_uint secp192r1_gx[] = { + BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ), + BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ), + BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ), +}; +static const t_uint secp192r1_gy[] = { + BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ), + BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ), + BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ), +}; +static const t_uint secp192r1_n[] = { + BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ), + BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ + +/* + * Domain parameters for secp224r1 + */ +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) +static const t_uint secp224r1_p[] = { + BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), +}; +static const t_uint secp224r1_b[] = { + BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ), + BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ), + BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ), + BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ), +}; +static const t_uint secp224r1_gx[] = { + BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ), + BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ), + BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ), + BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ), +}; +static const t_uint secp224r1_gy[] = { + BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ), + BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ), + BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ), + BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ), +}; +static const t_uint secp224r1_n[] = { + BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ), + BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ + +/* + * Domain parameters for secp256r1 + */ +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) +static const t_uint secp256r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const t_uint secp256r1_b[] = { + BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ), + BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ), + BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ), + BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ), +}; +static const t_uint secp256r1_gx[] = { + BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ), + BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ), + BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ), + BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ), +}; +static const t_uint secp256r1_gy[] = { + BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ), + BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ), + BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ), + BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ), +}; +static const t_uint secp256r1_n[] = { + BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ), + BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ + +/* + * Domain parameters for secp384r1 + */ +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) +static const t_uint secp384r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const t_uint secp384r1_b[] = { + BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ), + BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ), + BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ), + BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ), + BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ), + BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ), +}; +static const t_uint secp384r1_gx[] = { + BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ), + BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ), + BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ), + BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ), + BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ), + BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ), +}; +static const t_uint secp384r1_gy[] = { + BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ), + BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ), + BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ), + BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ), + BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ), + BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ), +}; +static const t_uint secp384r1_n[] = { + BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ), + BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ), + BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ + +/* + * Domain parameters for secp521r1 + */ +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) +static const t_uint secp521r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_2( 0xFF, 0x01 ), +}; +static const t_uint secp521r1_b[] = { + BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ), + BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ), + BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ), + BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ), + BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ), + BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ), + BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ), + BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ), + BYTES_TO_T_UINT_2( 0x51, 0x00 ), +}; +static const t_uint secp521r1_gx[] = { + BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ), + BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ), + BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ), + BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ), + BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ), + BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ), + BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ), + BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ), + BYTES_TO_T_UINT_2( 0xC6, 0x00 ), +}; +static const t_uint secp521r1_gy[] = { + BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ), + BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ), + BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ), + BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ), + BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ), + BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ), + BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ), + BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ), + BYTES_TO_T_UINT_2( 0x18, 0x01 ), +}; +static const t_uint secp521r1_n[] = { + BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ), + BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ), + BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ), + BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ), + BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_2( 0xFF, 0x01 ), +}; +#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) +static const t_uint secp192k1_p[] = { + BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const t_uint secp192k1_a[] = { + BYTES_TO_T_UINT_2( 0x00, 0x00 ), +}; +static const t_uint secp192k1_b[] = { + BYTES_TO_T_UINT_2( 0x03, 0x00 ), +}; +static const t_uint secp192k1_gx[] = { + BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ), + BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ), + BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ), +}; +static const t_uint secp192k1_gy[] = { + BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ), + BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ), + BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ), +}; +static const t_uint secp192k1_n[] = { + BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ), + BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) +static const t_uint secp224k1_p[] = { + BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const t_uint secp224k1_a[] = { + BYTES_TO_T_UINT_2( 0x00, 0x00 ), +}; +static const t_uint secp224k1_b[] = { + BYTES_TO_T_UINT_2( 0x05, 0x00 ), +}; +static const t_uint secp224k1_gx[] = { + BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ), + BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ), + BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ), + BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ), +}; +static const t_uint secp224k1_gy[] = { + BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ), + BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ), + BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ), + BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ), +}; +static const t_uint secp224k1_n[] = { + BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ), + BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ), +}; +#endif /* POLARSSL_ECP_DP_SECP224K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) +static const t_uint secp256k1_p[] = { + BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const t_uint secp256k1_a[] = { + BYTES_TO_T_UINT_2( 0x00, 0x00 ), +}; +static const t_uint secp256k1_b[] = { + BYTES_TO_T_UINT_2( 0x07, 0x00 ), +}; +static const t_uint secp256k1_gx[] = { + BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ), + BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ), + BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ), + BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ), +}; +static const t_uint secp256k1_gy[] = { + BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ), + BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ), + BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ), + BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ), +}; +static const t_uint secp256k1_n[] = { + BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ), + BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ), + BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP256K1_ENABLED */ + +/* + * Domain parameters for brainpoolP256r1 (RFC 5639 3.4) + */ +#if defined(POLARSSL_ECP_DP_BP256R1_ENABLED) +static const t_uint brainpoolP256r1_p[] = { + BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ), + BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ), + BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ), + BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ), +}; +static const t_uint brainpoolP256r1_a[] = { + BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ), + BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ), + BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ), + BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ), +}; +static const t_uint brainpoolP256r1_b[] = { + BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ), + BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ), + BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ), + BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ), +}; +static const t_uint brainpoolP256r1_gx[] = { + BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ), + BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ), + BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ), + BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ), +}; +static const t_uint brainpoolP256r1_gy[] = { + BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ), + BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ), + BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ), + BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ), +}; +static const t_uint brainpoolP256r1_n[] = { + BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ), + BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ), + BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ), + BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ), +}; +#endif /* POLARSSL_ECP_DP_BP256R1_ENABLED */ + +/* + * Domain parameters for brainpoolP384r1 (RFC 5639 3.6) + */ +#if defined(POLARSSL_ECP_DP_BP384R1_ENABLED) +static const t_uint brainpoolP384r1_p[] = { + BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ), + BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ), + BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ), + BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ), + BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ), + BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ), +}; +static const t_uint brainpoolP384r1_a[] = { + BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ), + BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ), + BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ), + BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ), + BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ), + BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ), +}; +static const t_uint brainpoolP384r1_b[] = { + BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ), + BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ), + BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ), + BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ), + BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ), + BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ), +}; +static const t_uint brainpoolP384r1_gx[] = { + BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ), + BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ), + BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ), + BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ), + BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ), + BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ), +}; +static const t_uint brainpoolP384r1_gy[] = { + BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ), + BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ), + BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ), + BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ), + BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ), + BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ), +}; +static const t_uint brainpoolP384r1_n[] = { + BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ), + BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ), + BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ), + BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ), + BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ), + BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ), +}; +#endif /* POLARSSL_ECP_DP_BP384R1_ENABLED */ + +/* + * Domain parameters for brainpoolP512r1 (RFC 5639 3.7) + */ +#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) +static const t_uint brainpoolP512r1_p[] = { + BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ), + BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ), + BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ), + BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ), + BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ), + BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ), + BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ), + BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ), +}; +static const t_uint brainpoolP512r1_a[] = { + BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ), + BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ), + BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ), + BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ), + BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ), + BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ), + BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ), + BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ), +}; +static const t_uint brainpoolP512r1_b[] = { + BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ), + BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ), + BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ), + BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ), + BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ), + BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ), + BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ), + BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ), +}; +static const t_uint brainpoolP512r1_gx[] = { + BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ), + BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ), + BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ), + BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ), + BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ), + BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ), + BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ), + BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ), +}; +static const t_uint brainpoolP512r1_gy[] = { + BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ), + BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ), + BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ), + BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ), + BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ), + BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ), + BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ), + BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ), +}; +static const t_uint brainpoolP512r1_n[] = { + BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ), + BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ), + BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ), + BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ), + BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ), + BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ), + BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ), + BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ), +}; +#endif /* POLARSSL_ECP_DP_BP512R1_ENABLED */ + +/* + * Create an MPI from embedded constants + * (assumes len is an exact multiple of sizeof t_uint) + */ +static inline void ecp_mpi_load( mpi *X, const t_uint *p, size_t len ) +{ + X->s = 1; + X->n = len / sizeof( t_uint ); + X->p = (t_uint *) p; +} + +/* + * Set an MPI to static value 1 + */ +static inline void ecp_mpi_set1( mpi *X ) +{ + static t_uint one[] = { 1 }; + X->s = 1; + X->n = 1; + X->p = one; +} + +/* + * Make group available from embedded constants + */ +static int ecp_group_load( ecp_group *grp, + const t_uint *p, size_t plen, + const t_uint *a, size_t alen, + const t_uint *b, size_t blen, + const t_uint *gx, size_t gxlen, + const t_uint *gy, size_t gylen, + const t_uint *n, size_t nlen) +{ + ecp_mpi_load( &grp->P, p, plen ); + if( a != NULL ) + ecp_mpi_load( &grp->A, a, alen ); + ecp_mpi_load( &grp->B, b, blen ); + ecp_mpi_load( &grp->N, n, nlen ); + + ecp_mpi_load( &grp->G.X, gx, gxlen ); + ecp_mpi_load( &grp->G.Y, gy, gylen ); + ecp_mpi_set1( &grp->G.Z ); + + grp->pbits = mpi_msb( &grp->P ); + grp->nbits = mpi_msb( &grp->N ); + + grp->h = 1; + + return( 0 ); +} + +#if defined(POLARSSL_ECP_NIST_OPTIM) +/* Forward declarations */ +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) +static int ecp_mod_p192( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) +static int ecp_mod_p224( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) +static int ecp_mod_p256( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) +static int ecp_mod_p384( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) +static int ecp_mod_p521( mpi * ); +#endif + +#define NIST_MODP( P ) grp->modp = ecp_mod_ ## P; +#else +#define NIST_MODP( P ) +#endif /* POLARSSL_ECP_NIST_OPTIM */ + +/* Additional forward declarations */ +#if defined(POLARSSL_ECP_DP_M255_ENABLED) +static int ecp_mod_p255( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) +static int ecp_mod_p192k1( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) +static int ecp_mod_p224k1( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) +static int ecp_mod_p256k1( mpi * ); +#endif + +#define LOAD_GROUP_A( G ) ecp_group_load( grp, \ + G ## _p, sizeof( G ## _p ), \ + G ## _a, sizeof( G ## _a ), \ + G ## _b, sizeof( G ## _b ), \ + G ## _gx, sizeof( G ## _gx ), \ + G ## _gy, sizeof( G ## _gy ), \ + G ## _n, sizeof( G ## _n ) ) + +#define LOAD_GROUP( G ) ecp_group_load( grp, \ + G ## _p, sizeof( G ## _p ), \ + NULL, 0, \ + G ## _b, sizeof( G ## _b ), \ + G ## _gx, sizeof( G ## _gx ), \ + G ## _gy, sizeof( G ## _gy ), \ + G ## _n, sizeof( G ## _n ) ) + +#if defined(POLARSSL_ECP_DP_M255_ENABLED) +/* + * Specialized function for creating the Curve25519 group + */ +static int ecp_use_curve25519( ecp_group *grp ) +{ + int ret; + + /* Actually ( A + 2 ) / 4 */ + MPI_CHK( mpi_read_string( &grp->A, 16, "01DB42" ) ); + + /* P = 2^255 - 19 */ + MPI_CHK( mpi_lset( &grp->P, 1 ) ); + MPI_CHK( mpi_shift_l( &grp->P, 255 ) ); + MPI_CHK( mpi_sub_int( &grp->P, &grp->P, 19 ) ); + grp->pbits = mpi_msb( &grp->P ); + + /* Y intentionaly not set, since we use x/z coordinates. + * This is used as a marker to identify Montgomery curves! */ + MPI_CHK( mpi_lset( &grp->G.X, 9 ) ); + MPI_CHK( mpi_lset( &grp->G.Z, 1 ) ); + mpi_free( &grp->G.Y ); + + /* Actually, the required msb for private keys */ + grp->nbits = 254; + +cleanup: + if( ret != 0 ) + ecp_group_free( grp ); + + return( ret ); +} +#endif /* POLARSSL_ECP_DP_M255_ENABLED */ + +/* + * Set a group using well-known domain parameters + */ +int ecp_use_known_dp( ecp_group *grp, ecp_group_id id ) +{ + ecp_group_free( grp ); + + grp->id = id; + + switch( id ) + { +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) + case POLARSSL_ECP_DP_SECP192R1: + NIST_MODP( p192 ); + return( LOAD_GROUP( secp192r1 ) ); +#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) + case POLARSSL_ECP_DP_SECP224R1: + NIST_MODP( p224 ); + return( LOAD_GROUP( secp224r1 ) ); +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) + case POLARSSL_ECP_DP_SECP256R1: + NIST_MODP( p256 ); + return( LOAD_GROUP( secp256r1 ) ); +#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) + case POLARSSL_ECP_DP_SECP384R1: + NIST_MODP( p384 ); + return( LOAD_GROUP( secp384r1 ) ); +#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) + case POLARSSL_ECP_DP_SECP521R1: + NIST_MODP( p521 ); + return( LOAD_GROUP( secp521r1 ) ); +#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) + case POLARSSL_ECP_DP_SECP192K1: + grp->modp = ecp_mod_p192k1; + return( LOAD_GROUP_A( secp192k1 ) ); +#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) + case POLARSSL_ECP_DP_SECP224K1: + grp->modp = ecp_mod_p224k1; + return( LOAD_GROUP_A( secp224k1 ) ); +#endif /* POLARSSL_ECP_DP_SECP224K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) + case POLARSSL_ECP_DP_SECP256K1: + grp->modp = ecp_mod_p256k1; + return( LOAD_GROUP_A( secp256k1 ) ); +#endif /* POLARSSL_ECP_DP_SECP256K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_BP256R1_ENABLED) + case POLARSSL_ECP_DP_BP256R1: + return( LOAD_GROUP_A( brainpoolP256r1 ) ); +#endif /* POLARSSL_ECP_DP_BP256R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_BP384R1_ENABLED) + case POLARSSL_ECP_DP_BP384R1: + return( LOAD_GROUP_A( brainpoolP384r1 ) ); +#endif /* POLARSSL_ECP_DP_BP384R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) + case POLARSSL_ECP_DP_BP512R1: + return( LOAD_GROUP_A( brainpoolP512r1 ) ); +#endif /* POLARSSL_ECP_DP_BP512R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_M255_ENABLED) + case POLARSSL_ECP_DP_M255: + grp->modp = ecp_mod_p255; + return( ecp_use_curve25519( grp ) ); +#endif /* POLARSSL_ECP_DP_M255_ENABLED */ + + default: + ecp_group_free( grp ); + return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); + } +} + +#if defined(POLARSSL_ECP_NIST_OPTIM) +/* + * Fast reduction modulo the primes used by the NIST curves. + * + * These functions are critical for speed, but not needed for correct + * operations. So, we make the choice to heavily rely on the internals of our + * bignum library, which creates a tight coupling between these functions and + * our MPI implementation. However, the coupling between the ECP module and + * MPI remains loose, since these functions can be deactivated at will. + */ + +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) +/* + * Compared to the way things are presented in FIPS 186-3 D.2, + * we proceed in columns, from right (least significant chunk) to left, + * adding chunks to N in place, and keeping a carry for the next chunk. + * This avoids moving things around in memory, and uselessly adding zeros, + * compared to the more straightforward, line-oriented approach. + * + * For this prime we need to handle data in chunks of 64 bits. + * Since this is always a multiple of our basic t_uint, we can + * use a t_uint * to designate such a chunk, and small loops to handle it. + */ + +/* Add 64-bit chunks (dst += src) and update carry */ +static inline void add64( t_uint *dst, t_uint *src, t_uint *carry ) +{ + unsigned char i; + t_uint c = 0; + for( i = 0; i < 8 / sizeof( t_uint ); i++, dst++, src++ ) + { + *dst += c; c = ( *dst < c ); + *dst += *src; c += ( *dst < *src ); + } + *carry += c; +} + +/* Add carry to a 64-bit chunk and update carry */ +static inline void carry64( t_uint *dst, t_uint *carry ) +{ + unsigned char i; + for( i = 0; i < 8 / sizeof( t_uint ); i++, dst++ ) + { + *dst += *carry; + *carry = ( *dst < *carry ); + } +} + +#define WIDTH 8 / sizeof( t_uint ) +#define A( i ) N->p + i * WIDTH +#define ADD( i ) add64( p, A( i ), &c ) +#define NEXT p += WIDTH; carry64( p, &c ) +#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0 + +/* + * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) + */ +static int ecp_mod_p192( mpi *N ) +{ + int ret; + t_uint c = 0; + t_uint *p, *end; + + /* Make sure we have enough blocks so that A(5) is legal */ + MPI_CHK( mpi_grow( N, 6 * WIDTH ) ); + + p = N->p; + end = p + N->n; + + ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5 + ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5 + ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5 + +cleanup: + return( ret ); +} + +#undef WIDTH +#undef A +#undef ADD +#undef NEXT +#undef LAST +#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) +/* + * The reader is advised to first understand ecp_mod_p192() since the same + * general structure is used here, but with additional complications: + * (1) chunks of 32 bits, and (2) subtractions. + */ + +/* + * For these primes, we need to handle data in chunks of 32 bits. + * This makes it more complicated if we use 64 bits limbs in MPI, + * which prevents us from using a uniform access method as for p192. + * + * So, we define a mini abstraction layer to access 32 bit chunks, + * load them in 'cur' for work, and store them back from 'cur' when done. + * + * While at it, also define the size of N in terms of 32-bit chunks. + */ +#define LOAD32 cur = A( i ); + +#if defined(POLARSSL_HAVE_INT8) /* 8 bit */ + +#define MAX32 N->n / 4 +#define A( j ) (uint32_t)( N->p[4*j+0] ) | \ + ( N->p[4*j+1] << 8 ) | \ + ( N->p[4*j+2] << 16 ) | \ + ( N->p[4*j+3] << 24 ) +#define STORE32 N->p[4*i+0] = (t_uint)( cur ); \ + N->p[4*i+1] = (t_uint)( cur >> 8 ); \ + N->p[4*i+2] = (t_uint)( cur >> 16 ); \ + N->p[4*i+3] = (t_uint)( cur >> 24 ); + +#elif defined(POLARSSL_HAVE_INT16) /* 16 bit */ + +#define MAX32 N->n / 2 +#define A( j ) (uint32_t)( N->p[2*j] ) | ( N->p[2*j+1] << 16 ) +#define STORE32 N->p[2*i+0] = (t_uint)( cur ); \ + N->p[2*i+1] = (t_uint)( cur >> 16 ); + +#elif defined(POLARSSL_HAVE_INT32) /* 32 bit */ + +#define MAX32 N->n +#define A( j ) N->p[j] +#define STORE32 N->p[i] = cur; + +#else /* 64-bit */ + +#define MAX32 N->n * 2 +#define A( j ) j % 2 ? (uint32_t)( N->p[j/2] >> 32 ) : (uint32_t)( N->p[j/2] ) +#define STORE32 \ + if( i % 2 ) { \ + N->p[i/2] &= 0x00000000FFFFFFFF; \ + N->p[i/2] |= ((t_uint) cur) << 32; \ + } else { \ + N->p[i/2] &= 0xFFFFFFFF00000000; \ + N->p[i/2] |= (t_uint) cur; \ + } + +#endif /* sizeof( t_uint ) */ + +/* + * Helpers for addition and subtraction of chunks, with signed carry. + */ +static inline void add32( uint32_t *dst, uint32_t src, signed char *carry ) +{ + *dst += src; + *carry += ( *dst < src ); +} + +static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry ) +{ + *carry -= ( *dst < src ); + *dst -= src; +} + +#define ADD( j ) add32( &cur, A( j ), &c ); +#define SUB( j ) sub32( &cur, A( j ), &c ); + +/* + * Helpers for the main 'loop' + * (see fix_negative for the motivation of C) + */ +#define INIT( b ) \ + int ret; \ + signed char c = 0, cc; \ + uint32_t cur; \ + size_t i = 0, bits = b; \ + mpi C; \ + t_uint Cp[ b / 8 / sizeof( t_uint) + 1 ]; \ + \ + C.s = 1; \ + C.n = b / 8 / sizeof( t_uint) + 1; \ + C.p = Cp; \ + memset( Cp, 0, C.n * sizeof( t_uint ) ); \ + \ + MPI_CHK( mpi_grow( N, b * 2 / 8 / sizeof( t_uint ) ) ); \ + LOAD32; + +#define NEXT \ + STORE32; i++; LOAD32; \ + cc = c; c = 0; \ + if( cc < 0 ) \ + sub32( &cur, -cc, &c ); \ + else \ + add32( &cur, cc, &c ); \ + +#define LAST \ + STORE32; i++; \ + cur = c > 0 ? c : 0; STORE32; \ + cur = 0; while( ++i < MAX32 ) { STORE32; } \ + if( c < 0 ) fix_negative( N, c, &C, bits ); + +/* + * If the result is negative, we get it in the form + * c * 2^(bits + 32) + N, with c negative and N positive shorter than 'bits' + */ +static inline int fix_negative( mpi *N, signed char c, mpi *C, size_t bits ) +{ + int ret; + + /* C = - c * 2^(bits + 32) */ +#if !defined(POLARSSL_HAVE_INT64) + ((void) bits); +#else + if( bits == 224 ) + C->p[ C->n - 1 ] = ((t_uint) -c) << 32; + else +#endif + C->p[ C->n - 1 ] = (t_uint) -c; + + /* N = - ( C - N ) */ + MPI_CHK( mpi_sub_abs( N, C, N ) ); + N->s = -1; + +cleanup: + + return( ret ); +} + +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) +/* + * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) + */ +static int ecp_mod_p224( mpi *N ) +{ + INIT( 224 ); + + SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11 + SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12 + SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13 + SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11 + SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12 + SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13 + SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10 + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) +/* + * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) + */ +static int ecp_mod_p256( mpi *N ) +{ + INIT( 256 ); + + ADD( 8 ); ADD( 9 ); + SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0 + + ADD( 9 ); ADD( 10 ); + SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1 + + ADD( 10 ); ADD( 11 ); + SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2 + + ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 ); + SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3 + + ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 ); + SUB( 9 ); SUB( 10 ); NEXT; // A4 + + ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 ); + SUB( 10 ); SUB( 11 ); NEXT; // A5 + + ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 ); + SUB( 8 ); SUB( 9 ); NEXT; // A6 + + ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 ); + SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7 + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) +/* + * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) + */ +static int ecp_mod_p384( mpi *N ) +{ + INIT( 384 ); + + ADD( 12 ); ADD( 21 ); ADD( 20 ); + SUB( 23 ); NEXT; // A0 + + ADD( 13 ); ADD( 22 ); ADD( 23 ); + SUB( 12 ); SUB( 20 ); NEXT; // A2 + + ADD( 14 ); ADD( 23 ); + SUB( 13 ); SUB( 21 ); NEXT; // A2 + + ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 ); + SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3 + + ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 ); + SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4 + + ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 ); + SUB( 16 ); NEXT; // A5 + + ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 ); + SUB( 17 ); NEXT; // A6 + + ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 ); + SUB( 18 ); NEXT; // A7 + + ADD( 20 ); ADD( 17 ); ADD( 16 ); + SUB( 19 ); NEXT; // A8 + + ADD( 21 ); ADD( 18 ); ADD( 17 ); + SUB( 20 ); NEXT; // A9 + + ADD( 22 ); ADD( 19 ); ADD( 18 ); + SUB( 21 ); NEXT; // A10 + + ADD( 23 ); ADD( 20 ); ADD( 19 ); + SUB( 22 ); LAST; // A11 + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ + +#undef A +#undef LOAD32 +#undef STORE32 +#undef MAX32 +#undef INIT +#undef NEXT +#undef LAST + +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED || + POLARSSL_ECP_DP_SECP256R1_ENABLED || + POLARSSL_ECP_DP_SECP384R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) +/* + * Here we have an actual Mersenne prime, so things are more straightforward. + * However, chunks are aligned on a 'weird' boundary (521 bits). + */ + +/* Size of p521 in terms of t_uint */ +#define P521_WIDTH ( 521 / 8 / sizeof( t_uint ) + 1 ) + +/* Bits to keep in the most significant t_uint */ +#if defined(POLARSSL_HAVE_INT8) +#define P521_MASK 0x01 +#else +#define P521_MASK 0x01FF +#endif + +/* + * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5) + * Write N as A1 + 2^521 A0, return A0 + A1 + */ +static int ecp_mod_p521( mpi *N ) +{ + int ret; + size_t i; + mpi M; + t_uint Mp[P521_WIDTH + 1]; + /* Worst case for the size of M is when t_uint is 16 bits: + * we need to hold bits 513 to 1056, which is 34 limbs, that is + * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */ + + if( N->n < P521_WIDTH ) + return( 0 ); + + /* M = A1 */ + M.s = 1; + M.n = N->n - ( P521_WIDTH - 1 ); + if( M.n > P521_WIDTH + 1 ) + M.n = P521_WIDTH + 1; + M.p = Mp; + memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( t_uint ) ); + MPI_CHK( mpi_shift_r( &M, 521 % ( 8 * sizeof( t_uint ) ) ) ); + + /* N = A0 */ + N->p[P521_WIDTH - 1] &= P521_MASK; + for( i = P521_WIDTH; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + A1 */ + MPI_CHK( mpi_add_abs( N, N, &M ) ); + +cleanup: + return( ret ); +} + +#undef P521_WIDTH +#undef P521_MASK +#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ + +#endif /* POLARSSL_ECP_NIST_OPTIM */ + +#if defined(POLARSSL_ECP_DP_M255_ENABLED) + +/* Size of p255 in terms of t_uint */ +#define P255_WIDTH ( 255 / 8 / sizeof( t_uint ) + 1 ) + +/* + * Fast quasi-reduction modulo p255 = 2^255 - 19 + * Write N as A0 + 2^255 A1, return A0 + 19 * A1 + */ +static int ecp_mod_p255( mpi *N ) +{ + int ret; + size_t i; + mpi M; + t_uint Mp[P255_WIDTH + 2]; + + if( N->n < P255_WIDTH ) + return( 0 ); + + /* M = A1 */ + M.s = 1; + M.n = N->n - ( P255_WIDTH - 1 ); + if( M.n > P255_WIDTH + 1 ) + M.n = P255_WIDTH + 1; + M.p = Mp; + memset( Mp, 0, sizeof Mp ); + memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( t_uint ) ); + MPI_CHK( mpi_shift_r( &M, 255 % ( 8 * sizeof( t_uint ) ) ) ); + M.n++; /* Make room for multiplication by 19 */ + + /* N = A0 */ + MPI_CHK( mpi_set_bit( N, 255, 0 ) ); + for( i = P255_WIDTH; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + 19 * A1 */ + MPI_CHK( mpi_mul_int( &M, &M, 19 ) ); + MPI_CHK( mpi_add_abs( N, N, &M ) ); + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_M255_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) +/* + * Fast quasi-reduction modulo P = 2^s - R, + * with R about 33 bits, used by the Koblitz curves. + * + * Write N as A0 + 2^224 A1, return A0 + R * A1. + * Actually do two passes, since R is big. + */ +#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( t_uint ) ) // Max limbs in P +#define P_KOBLITZ_R ( 8 / sizeof( t_uint ) ) // Limbs in R +static inline int ecp_mod_koblitz( mpi *N, t_uint *Rp, size_t p_limbs, + size_t adjust, size_t shift, t_uint mask ) +{ + int ret; + size_t i; + mpi M, R; + t_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R]; + + if( N->n < p_limbs ) + return( 0 ); + + /* Init R */ + R.s = 1; + R.p = Rp; + R.n = P_KOBLITZ_R; + + /* Common setup for M */ + M.s = 1; + M.p = Mp; + + /* M = A1 */ + M.n = N->n - ( p_limbs - adjust ); + if( M.n > p_limbs + adjust ) + M.n = p_limbs + adjust; + memset( Mp, 0, sizeof Mp ); + memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( t_uint ) ); + if( shift != 0 ) + MPI_CHK( mpi_shift_r( &M, shift ) ); + M.n += R.n - adjust; /* Make room for multiplication by R */ + + /* N = A0 */ + if( mask != 0 ) + N->p[p_limbs - 1] &= mask; + for( i = p_limbs; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + R * A1 */ + MPI_CHK( mpi_mul_mpi( &M, &M, &R ) ); + MPI_CHK( mpi_add_abs( N, N, &M ) ); + + /* Second pass */ + + /* M = A1 */ + M.n = N->n - ( p_limbs - adjust ); + if( M.n > p_limbs + adjust ) + M.n = p_limbs + adjust; + memset( Mp, 0, sizeof Mp ); + memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( t_uint ) ); + if( shift != 0 ) + MPI_CHK( mpi_shift_r( &M, shift ) ); + M.n += R.n - adjust; /* Make room for multiplication by R */ + + /* N = A0 */ + if( mask != 0 ) + N->p[p_limbs - 1] &= mask; + for( i = p_limbs; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + R * A1 */ + MPI_CHK( mpi_mul_mpi( &M, &M, &R ) ); + MPI_CHK( mpi_add_abs( N, N, &M ) ); + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED) || + POLARSSL_ECP_DP_SECP224K1_ENABLED) || + POLARSSL_ECP_DP_SECP256K1_ENABLED) */ + +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) +/* + * Fast quasi-reduction modulo p192k1 = 2^192 - R, + * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119 + */ +static int ecp_mod_p192k1( mpi *N ) +{ + static t_uint Rp[] = { + BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; + + return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( t_uint ), 0, 0, 0 ) ); +} +#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) +/* + * Fast quasi-reduction modulo p224k1 = 2^224 - R, + * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93 + */ +static int ecp_mod_p224k1( mpi *N ) +{ + static t_uint Rp[] = { + BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; + +#if defined(POLARSSL_HAVE_INT64) + return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) ); +#else + return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( t_uint ), 0, 0, 0 ) ); +#endif +} + +#endif /* POLARSSL_ECP_DP_SECP224K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) +/* + * Fast quasi-reduction modulo p256k1 = 2^256 - R, + * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1 + */ +static int ecp_mod_p256k1( mpi *N ) +{ + static t_uint Rp[] = { + BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; + return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( t_uint ), 0, 0, 0 ) ); +} +#endif /* POLARSSL_ECP_DP_SECP256K1_ENABLED */ + +#endif /* POLARSSL_ECP_C */ diff --git a/pdns/ext/polarssl/library/entropy.c b/pdns/ext/polarssl/library/entropy.c index c5fac26e9..bc7fb0fe4 100644 --- a/pdns/ext/polarssl/library/entropy.c +++ b/pdns/ext/polarssl/library/entropy.c @@ -1,7 +1,7 @@ /* * Entropy accumulator implementation * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,17 +23,30 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_ENTROPY_C) #include "polarssl/entropy.h" #include "polarssl/entropy_poll.h" +#if defined(POLARSSL_FS_IO) +#include +#endif + #if defined(POLARSSL_HAVEGE_C) #include "polarssl/havege.h" #endif +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + #define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */ void entropy_init( entropy_context *ctx ) @@ -70,7 +83,10 @@ void entropy_init( entropy_context *ctx ) void entropy_free( entropy_context *ctx ) { - ((void) ctx); +#if defined(POLARSSL_HAVEGE_C) + havege_free( &ctx->havege_data ); +#endif + polarssl_zeroize( ctx, sizeof( entropy_context ) ); #if defined(POLARSSL_THREADING_C) polarssl_mutex_free( &ctx->mutex ); #endif @@ -80,10 +96,19 @@ int entropy_add_source( entropy_context *ctx, f_source_ptr f_source, void *p_source, size_t threshold ) { - int index = ctx->source_count; + int index, ret = 0; + +#if defined(POLARSSL_THREADING_C) + if( ( ret = polarssl_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + index = ctx->source_count; if( index >= ENTROPY_MAX_SOURCES ) - return( POLARSSL_ERR_ENTROPY_MAX_SOURCES ); + { + ret = POLARSSL_ERR_ENTROPY_MAX_SOURCES; + goto exit; + } ctx->source[index].f_source = f_source; ctx->source[index].p_source = p_source; @@ -91,7 +116,13 @@ int entropy_add_source( entropy_context *ctx, ctx->source_count++; - return( 0 ); +exit: +#if defined(POLARSSL_THREADING_C) + if( polarssl_mutex_unlock( &ctx->mutex ) != 0 ) + return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); } /* @@ -133,18 +164,32 @@ static int entropy_update( entropy_context *ctx, unsigned char source_id, int entropy_update_manual( entropy_context *ctx, const unsigned char *data, size_t len ) { - return entropy_update( ctx, ENTROPY_SOURCE_MANUAL, data, len ); + int ret; + +#if defined(POLARSSL_THREADING_C) + if( ( ret = polarssl_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + ret = entropy_update( ctx, ENTROPY_SOURCE_MANUAL, data, len ); + +#if defined(POLARSSL_THREADING_C) + if( polarssl_mutex_unlock( &ctx->mutex ) != 0 ) + return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); } /* * Run through the different sources to add entropy to our accumulator */ -int entropy_gather( entropy_context *ctx ) +static int entropy_gather_internal( entropy_context *ctx ) { int ret, i; unsigned char buf[ENTROPY_MAX_GATHER]; size_t olen; - + if( ctx->source_count == 0 ) return( POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED ); @@ -154,7 +199,7 @@ int entropy_gather( entropy_context *ctx ) for( i = 0; i < ctx->source_count; i++ ) { olen = 0; - if ( ( ret = ctx->source[i].f_source( ctx->source[i].p_source, + if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source, buf, ENTROPY_MAX_GATHER, &olen ) ) != 0 ) { return( ret ); @@ -173,6 +218,28 @@ int entropy_gather( entropy_context *ctx ) return( 0 ); } +/* + * Thread-safe wrapper for entropy_gather_internal() + */ +int entropy_gather( entropy_context *ctx ) +{ + int ret; + +#if defined(POLARSSL_THREADING_C) + if( ( ret = polarssl_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + ret = entropy_gather_internal( ctx ); + +#if defined(POLARSSL_THREADING_C) + if( polarssl_mutex_unlock( &ctx->mutex ) != 0 ) + return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + int entropy_func( void *data, unsigned char *output, size_t len ) { int ret, count = 0, i, reached; @@ -198,7 +265,7 @@ int entropy_func( void *data, unsigned char *output, size_t len ) goto exit; } - if( ( ret = entropy_gather( ctx ) ) != 0 ) + if( ( ret = entropy_gather_internal( ctx ) ) != 0 ) goto exit; reached = 0; @@ -214,24 +281,19 @@ int entropy_func( void *data, unsigned char *output, size_t len ) #if defined(POLARSSL_ENTROPY_SHA512_ACCUMULATOR) sha512_finish( &ctx->accumulator, buf ); - /* - * Perform second SHA-512 on entropy - */ - sha512( buf, ENTROPY_BLOCK_SIZE, buf, 0 ); - /* * Reset accumulator and counters and recycle existing entropy */ memset( &ctx->accumulator, 0, sizeof( sha512_context ) ); sha512_starts( &ctx->accumulator, 0 ); sha512_update( &ctx->accumulator, buf, ENTROPY_BLOCK_SIZE ); -#else /* POLARSSL_ENTROPY_SHA512_ACCUMULATOR */ - sha256_finish( &ctx->accumulator, buf ); /* - * Perform second SHA-256 on entropy + * Perform second SHA-512 on entropy */ - sha256( buf, ENTROPY_BLOCK_SIZE, buf, 0 ); + sha512( buf, ENTROPY_BLOCK_SIZE, buf, 0 ); +#else /* POLARSSL_ENTROPY_SHA512_ACCUMULATOR */ + sha256_finish( &ctx->accumulator, buf ); /* * Reset accumulator and counters and recycle existing entropy @@ -239,6 +301,11 @@ int entropy_func( void *data, unsigned char *output, size_t len ) memset( &ctx->accumulator, 0, sizeof( sha256_context ) ); sha256_starts( &ctx->accumulator, 0 ); sha256_update( &ctx->accumulator, buf, ENTROPY_BLOCK_SIZE ); + + /* + * Perform second SHA-256 on entropy + */ + sha256( buf, ENTROPY_BLOCK_SIZE, buf, 0 ); #endif /* POLARSSL_ENTROPY_SHA512_ACCUMULATOR */ for( i = 0; i < ctx->source_count; i++ ) @@ -257,4 +324,154 @@ exit: return( ret ); } +#if defined(POLARSSL_FS_IO) +int entropy_write_seed_file( entropy_context *ctx, const char *path ) +{ + int ret = POLARSSL_ERR_ENTROPY_FILE_IO_ERROR; + FILE *f; + unsigned char buf[ENTROPY_BLOCK_SIZE]; + + if( ( f = fopen( path, "wb" ) ) == NULL ) + return( POLARSSL_ERR_ENTROPY_FILE_IO_ERROR ); + + if( ( ret = entropy_func( ctx, buf, ENTROPY_BLOCK_SIZE ) ) != 0 ) + goto exit; + + if( fwrite( buf, 1, ENTROPY_BLOCK_SIZE, f ) != ENTROPY_BLOCK_SIZE ) + { + ret = POLARSSL_ERR_ENTROPY_FILE_IO_ERROR; + goto exit; + } + + ret = 0; + +exit: + fclose( f ); + return( ret ); +} + +int entropy_update_seed_file( entropy_context *ctx, const char *path ) +{ + FILE *f; + size_t n; + unsigned char buf[ ENTROPY_MAX_SEED_SIZE ]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_ENTROPY_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + n = (size_t) ftell( f ); + fseek( f, 0, SEEK_SET ); + + if( n > ENTROPY_MAX_SEED_SIZE ) + n = ENTROPY_MAX_SEED_SIZE; + + if( fread( buf, 1, n, f ) != n ) + { + fclose( f ); + return( POLARSSL_ERR_ENTROPY_FILE_IO_ERROR ); + } + + fclose( f ); + + entropy_update_manual( ctx, buf, n ); + + return( entropy_write_seed_file( ctx, path ) ); +} +#endif /* POLARSSL_FS_IO */ + +#if defined(POLARSSL_SELF_TEST) + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_printf printf #endif + +/* + * Dummy source function + */ +static int entropy_dummy_source( void *data, unsigned char *output, + size_t len, size_t *olen ) +{ + ((void) data); + + memset( output, 0x2a, len ); + *olen = len; + + return( 0 ); +} + +/* + * The actual entropy quality is hard to test, but we can at least + * test that the functions don't cause errors and write the correct + * amount of data to buffers. + */ +int entropy_self_test( int verbose ) +{ + int ret = 0; + entropy_context ctx; + unsigned char buf[ENTROPY_BLOCK_SIZE] = { 0 }; + unsigned char acc[ENTROPY_BLOCK_SIZE] = { 0 }; + size_t i, j; + + if( verbose != 0 ) + polarssl_printf( " ENTROPY test: " ); + + entropy_init( &ctx ); + + ret = entropy_add_source( &ctx, entropy_dummy_source, NULL, 16 ); + if( ret != 0 ) + goto cleanup; + + if( ( ret = entropy_gather( &ctx ) ) != 0 ) + goto cleanup; + + if( ( ret = entropy_update_manual( &ctx, buf, sizeof buf ) ) != 0 ) + goto cleanup; + + /* + * To test that entropy_func writes correct number of bytes: + * - use the whole buffer and rely on ASan to detect overruns + * - collect entropy 8 times and OR the result in an accumulator: + * any byte should then be 0 with probably 2^(-64), so requiring + * each of the 32 or 64 bytes to be non-zero has a false failure rate + * of at most 2^(-58) which is acceptable. + */ + for( i = 0; i < 8; i++ ) + { + if( ( ret = entropy_func( &ctx, buf, sizeof( buf ) ) ) != 0 ) + goto cleanup; + + for( j = 0; j < sizeof( buf ); j++ ) + acc[j] |= buf[j]; + } + + for( j = 0; j < sizeof( buf ); j++ ) + { + if( acc[j] == 0 ) + { + ret = 1; + goto cleanup; + } + } + +cleanup: + entropy_free( &ctx ); + + if( verbose != 0 ) + { + if( ret != 0 ) + polarssl_printf( "failed\n" ); + else + polarssl_printf( "passed\n" ); + + polarssl_printf( "\n" ); + } + + return( ret != 0 ); +} +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_ENTROPY_C */ diff --git a/pdns/ext/polarssl/library/entropy_poll.c b/pdns/ext/polarssl/library/entropy_poll.c index badcfac5c..9ca9e9519 100644 --- a/pdns/ext/polarssl/library/entropy_poll.c +++ b/pdns/ext/polarssl/library/entropy_poll.c @@ -1,7 +1,7 @@ /* * Platform-specific and custom entropy polling functions * - * Copyright (C) 2006-2011, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,7 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_ENTROPY_C) @@ -56,18 +60,18 @@ int platform_entropy_poll( void *data, unsigned char *output, size_t len, if( CryptAcquireContext( &provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE ) { - return POLARSSL_ERR_ENTROPY_SOURCE_FAILED; + return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); } if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE ) - return POLARSSL_ERR_ENTROPY_SOURCE_FAILED; + return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); CryptReleaseContext( provider, 0 ); *olen = len; return( 0 ); } -#else +#else /* _WIN32 && !EFIX64 && !EFI32 */ #include @@ -82,13 +86,13 @@ int platform_entropy_poll( void *data, file = fopen( "/dev/urandom", "rb" ); if( file == NULL ) - return POLARSSL_ERR_ENTROPY_SOURCE_FAILED; - + return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); + ret = fread( output, 1, len, file ); if( ret != len ) { fclose( file ); - return POLARSSL_ERR_ENTROPY_SOURCE_FAILED; + return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); } fclose( file ); @@ -96,8 +100,8 @@ int platform_entropy_poll( void *data, return( 0 ); } -#endif -#endif +#endif /* _WIN32 && !EFIX64 && !EFI32 */ +#endif /* !POLARSSL_NO_PLATFORM_ENTROPY */ #if defined(POLARSSL_TIMING_C) int hardclock_poll( void *data, @@ -115,7 +119,7 @@ int hardclock_poll( void *data, return( 0 ); } -#endif +#endif /* POLARSSL_TIMING_C */ #if defined(POLARSSL_HAVEGE_C) int havege_poll( void *data, @@ -125,12 +129,12 @@ int havege_poll( void *data, *olen = 0; if( havege_random( hs, output, len ) != 0 ) - return POLARSSL_ERR_ENTROPY_SOURCE_FAILED; + return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); *olen = len; return( 0 ); } -#endif +#endif /* POLARSSL_HAVEGE_C */ #endif /* POLARSSL_ENTROPY_C */ diff --git a/pdns/ext/polarssl/library/error.c b/pdns/ext/polarssl/library/error.c index 9d76f194c..22234cf28 100644 --- a/pdns/ext/polarssl/library/error.c +++ b/pdns/ext/polarssl/library/error.c @@ -1,7 +1,7 @@ /* * Error message information * - * Copyright (C) 2006-2012, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,11 +23,17 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif -#if defined(POLARSSL_ERROR_C) - +#if defined(POLARSSL_ERROR_C) || defined(POLARSSL_ERROR_STRERROR_DUMMY) #include "polarssl/error.h" +#endif + +#if defined(POLARSSL_ERROR_C) #if defined(POLARSSL_AES_C) #include "polarssl/aes.h" @@ -49,6 +55,10 @@ #include "polarssl/camellia.h" #endif +#if defined(POLARSSL_CCM_C) +#include "polarssl/ccm.h" +#endif + #if defined(POLARSSL_CIPHER_C) #include "polarssl/cipher.h" #endif @@ -77,6 +87,10 @@ #include "polarssl/gcm.h" #endif +#if defined(POLARSSL_HMAC_DRBG_C) +#include "polarssl/hmac_drbg.h" +#endif + #if defined(POLARSSL_MD_C) #include "polarssl/md.h" #endif @@ -125,6 +139,10 @@ #include "polarssl/pkcs5.h" #endif +#if defined(POLARSSL_RIPEMD160_C) +#include "polarssl/ripemd160.h" +#endif + #if defined(POLARSSL_RSA_C) #include "polarssl/rsa.h" #endif @@ -186,6 +204,7 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) // High level error codes // + // BEGIN generated code #if defined(POLARSSL_CIPHER_C) if( use_ret == -(POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE) ) snprintf( buf, buflen, "CIPHER - The selected feature is not available" ); @@ -237,6 +256,8 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) snprintf( buf, buflen, "ECP - Generation of random value, such as (ephemeral) key, failed" ); if( use_ret == -(POLARSSL_ERR_ECP_INVALID_KEY) ) snprintf( buf, buflen, "ECP - Invalid private or public key" ); + if( use_ret == -(POLARSSL_ERR_ECP_SIG_LEN_MISMATCH) ) + snprintf( buf, buflen, "ECP - Signature is valid but shorter than the user-supplied length" ); #endif /* POLARSSL_ECP_C */ #if defined(POLARSSL_MD_C) @@ -298,6 +319,8 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) snprintf( buf, buflen, "PK - Elliptic curve is unsupported (only NIST curves are supported)" ); if( use_ret == -(POLARSSL_ERR_PK_FEATURE_UNAVAILABLE) ) snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" ); + if( use_ret == -(POLARSSL_ERR_PK_SIG_LEN_MISMATCH) ) + snprintf( buf, buflen, "PK - The signature is valid but its length is less than expected" ); #endif /* POLARSSL_PK_C */ #if defined(POLARSSL_PKCS12_C) @@ -358,8 +381,8 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) snprintf( buf, buflen, "SSL - An unknown cipher was received" ); if( use_ret == -(POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN) ) snprintf( buf, buflen, "SSL - The server has no ciphersuites in common with the client" ); - if( use_ret == -(POLARSSL_ERR_SSL_NO_SESSION_FOUND) ) - snprintf( buf, buflen, "SSL - No session to recover was found" ); + if( use_ret == -(POLARSSL_ERR_SSL_NO_RNG) ) + snprintf( buf, buflen, "SSL - No RNG was provided to the SSL module" ); if( use_ret == -(POLARSSL_ERR_SSL_NO_CLIENT_CERTIFICATE) ) snprintf( buf, buflen, "SSL - No client certification received from the client, but required by the authentication mode" ); if( use_ret == -(POLARSSL_ERR_SSL_CERTIFICATE_TOO_LARGE) ) @@ -422,9 +445,11 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) if( use_ret == -(POLARSSL_ERR_SSL_PK_TYPE_MISMATCH) ) snprintf( buf, buflen, "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" ); if( use_ret == -(POLARSSL_ERR_SSL_UNKNOWN_IDENTITY) ) - snprintf( buf, buflen, "SSL - Unkown identity received (eg, PSK identity)" ); + snprintf( buf, buflen, "SSL - Unknown identity received (eg, PSK identity)" ); if( use_ret == -(POLARSSL_ERR_SSL_INTERNAL_ERROR) ) snprintf( buf, buflen, "SSL - Internal error (eg, unexpected failure in lower-level module)" ); + if( use_ret == -(POLARSSL_ERR_SSL_COUNTER_WRAPPING) ) + snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" ); #endif /* POLARSSL_SSL_TLS_C */ #if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C) @@ -465,6 +490,7 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) if( use_ret == -(POLARSSL_ERR_X509_FILE_IO_ERROR) ) snprintf( buf, buflen, "X509 - Read/write of file failed" ); #endif /* POLARSSL_X509_USE,X509_CREATE_C */ + // END generated code if( strlen( buf ) == 0 ) snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret ); @@ -493,6 +519,7 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) // Low level error codes // + // BEGIN generated code #if defined(POLARSSL_AES_C) if( use_ret == -(POLARSSL_ERR_AES_INVALID_KEY_LENGTH) ) snprintf( buf, buflen, "AES - Invalid key length" ); @@ -557,6 +584,13 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) snprintf( buf, buflen, "CAMELLIA - Invalid data input length" ); #endif /* POLARSSL_CAMELLIA_C */ +#if defined(POLARSSL_CCM_C) + if( use_ret == -(POLARSSL_ERR_CCM_BAD_INPUT) ) + snprintf( buf, buflen, "CCM - Bad input parameters to function" ); + if( use_ret == -(POLARSSL_ERR_CCM_AUTH_FAILED) ) + snprintf( buf, buflen, "CCM - Authenticated decryption failed" ); +#endif /* POLARSSL_CCM_C */ + #if defined(POLARSSL_CTR_DRBG_C) if( use_ret == -(POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) ) snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" ); @@ -580,6 +614,8 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) snprintf( buf, buflen, "ENTROPY - No more sources can be added" ); if( use_ret == -(POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED) ) snprintf( buf, buflen, "ENTROPY - No sources have been added to poll" ); + if( use_ret == -(POLARSSL_ERR_ENTROPY_FILE_IO_ERROR) ) + snprintf( buf, buflen, "ENTROPY - Read/write error in file" ); #endif /* POLARSSL_ENTROPY_C */ #if defined(POLARSSL_GCM_C) @@ -589,6 +625,17 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) snprintf( buf, buflen, "GCM - Bad input parameters to function" ); #endif /* POLARSSL_GCM_C */ +#if defined(POLARSSL_HMAC_DRBG_C) + if( use_ret == -(POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG) ) + snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" ); + if( use_ret == -(POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG) ) + snprintf( buf, buflen, "HMAC_DRBG - Input too large (Entropy + additional)" ); + if( use_ret == -(POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR) ) + snprintf( buf, buflen, "HMAC_DRBG - Read/write error in file" ); + if( use_ret == -(POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED) ) + snprintf( buf, buflen, "HMAC_DRBG - The entropy source failed" ); +#endif /* POLARSSL_HMAC_DRBG_C */ + #if defined(POLARSSL_MD2_C) if( use_ret == -(POLARSSL_ERR_MD2_FILE_IO_ERROR) ) snprintf( buf, buflen, "MD2 - Read/write error in file" ); @@ -632,6 +679,8 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) #if defined(POLARSSL_OID_C) if( use_ret == -(POLARSSL_ERR_OID_NOT_FOUND) ) snprintf( buf, buflen, "OID - OID is not found" ); + if( use_ret == -(POLARSSL_ERR_OID_BUF_TOO_SMALL) ) + snprintf( buf, buflen, "OID - output buffer is too small" ); #endif /* POLARSSL_OID_C */ #if defined(POLARSSL_PADLOCK_C) @@ -644,6 +693,11 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) snprintf( buf, buflen, "PBKDF2 - Bad input parameters to function" ); #endif /* POLARSSL_PBKDF2_C */ +#if defined(POLARSSL_RIPEMD160_C) + if( use_ret == -(POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR) ) + snprintf( buf, buflen, "RIPEMD160 - Read/write error in file" ); +#endif /* POLARSSL_RIPEMD160_C */ + #if defined(POLARSSL_SHA1_C) if( use_ret == -(POLARSSL_ERR_SHA1_FILE_IO_ERROR) ) snprintf( buf, buflen, "SHA1 - Read/write error in file" ); @@ -672,6 +726,7 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) if( use_ret == -(POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH) ) snprintf( buf, buflen, "XTEA - The data input has an invalid length" ); #endif /* POLARSSL_XTEA_C */ + // END generated code if( strlen( buf ) != 0 ) return; diff --git a/pdns/ext/polarssl/library/gcm.c b/pdns/ext/polarssl/library/gcm.c index a9e18c89d..77b1e0fb6 100644 --- a/pdns/ext/polarssl/library/gcm.c +++ b/pdns/ext/polarssl/library/gcm.c @@ -1,7 +1,7 @@ /* * NIST SP800-38D compliant GCM implementation * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -22,15 +22,37 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + /* - * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf + * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf + * + * See also: + * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf + * + * We use the algorithm described as Shoup's method with 4-bit tables in + * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory. */ + +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_GCM_C) #include "polarssl/gcm.h" +#if defined(POLARSSL_AESNI_C) +#include "polarssl/aesni.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + /* * 32-bit integer manipulation macros (big endian) */ @@ -54,6 +76,19 @@ } #endif +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Precompute small multiples of H, that is set + * HH[i] || HL[i] = H times i, + * where i is seen as a field element as in [MGV], ie high-order bits + * correspond to low powers of P. The result is stored in the same way, that + * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL + * corresponds to P^127. + */ static int gcm_gen_table( gcm_context *ctx ) { int ret, i, j; @@ -66,9 +101,7 @@ static int gcm_gen_table( gcm_context *ctx ) if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 ) return( ret ); - ctx->HH[0] = 0; - ctx->HL[0] = 0; - + /* pack h as two 64-bits ints, big-endian */ GET_UINT32_BE( hi, h, 0 ); GET_UINT32_BE( lo, h, 4 ); vh = (uint64_t) hi << 32 | lo; @@ -77,9 +110,20 @@ static int gcm_gen_table( gcm_context *ctx ) GET_UINT32_BE( lo, h, 12 ); vl = (uint64_t) hi << 32 | lo; + /* 8 = 1000 corresponds to 1 in GF(2^128) */ ctx->HL[8] = vl; ctx->HH[8] = vh; +#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64) + /* With CLMUL support, we need only h, not the rest of the table */ + if( aesni_supports( POLARSSL_AESNI_CLMUL ) ) + return( 0 ); +#endif + + /* 0 corresponds to 0 in GF(2^128) */ + ctx->HH[0] = 0; + ctx->HL[0] = 0; + for( i = 4; i > 0; i >>= 1 ) { uint32_t T = ( vl & 1 ) * 0xe1000000U; @@ -90,7 +134,7 @@ static int gcm_gen_table( gcm_context *ctx ) ctx->HH[i] = vh; } - for (i = 2; i < 16; i <<= 1 ) + for( i = 2; i < 16; i <<= 1 ) { uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i; vh = *HiH; @@ -113,6 +157,8 @@ int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key, memset( ctx, 0, sizeof(gcm_context) ); + cipher_init( &ctx->cipher_ctx ); + cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB ); if( cipher_info == NULL ) return( POLARSSL_ERR_GCM_BAD_INPUT ); @@ -135,6 +181,11 @@ int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key, return( 0 ); } +/* + * Shoup's method for multiplication use this table with + * last4[x] = x times P^128 + * where x and last4[x] are seen as elements of GF(2^128) as in [MGV] + */ static const uint64_t last4[16] = { 0x0000, 0x1c20, 0x3840, 0x2460, @@ -143,15 +194,30 @@ static const uint64_t last4[16] = 0x9180, 0x8da0, 0xa9c0, 0xb5e0 }; +/* + * Sets output to x times H using the precomputed tables. + * x and output are seen as elements of GF(2^128) as in [MGV]. + */ static void gcm_mult( gcm_context *ctx, const unsigned char x[16], unsigned char output[16] ) { int i = 0; - unsigned char z[16]; unsigned char lo, hi, rem; uint64_t zh, zl; - memset( z, 0x00, 16 ); +#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64) + if( aesni_supports( POLARSSL_AESNI_CLMUL ) ) { + unsigned char h[16]; + + PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 ); + PUT_UINT32_BE( ctx->HH[8], h, 4 ); + PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 ); + PUT_UINT32_BE( ctx->HL[8], h, 12 ); + + aesni_gcm_mult( output, x, h ); + return; + } +#endif /* POLARSSL_AESNI_C && POLARSSL_HAVE_X86_64 */ lo = x[15] & 0xf; hi = x[15] >> 4; @@ -202,6 +268,13 @@ int gcm_starts( gcm_context *ctx, const unsigned char *p; size_t use_len, olen = 0; + /* IV and AD are limited to 2^64 bits, so 2^61 bytes */ + if( ( (uint64_t) iv_len ) >> 61 != 0 || + ( (uint64_t) add_len ) >> 61 != 0 ) + { + return( POLARSSL_ERR_GCM_BAD_INPUT ); + } + memset( ctx->y, 0x00, sizeof(ctx->y) ); memset( ctx->buf, 0x00, sizeof(ctx->buf) ); @@ -278,6 +351,14 @@ int gcm_update( gcm_context *ctx, if( output > input && (size_t) ( output - input ) < length ) return( POLARSSL_ERR_GCM_BAD_INPUT ); + /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes + * Also check for possible overflow */ + if( ctx->len + length < ctx->len || + (uint64_t) ctx->len + length > 0x03FFFFE0llu ) + { + return( POLARSSL_ERR_GCM_BAD_INPUT ); + } + ctx->len += length; p = input; @@ -323,7 +404,7 @@ int gcm_finish( gcm_context *ctx, uint64_t orig_len = ctx->len * 8; uint64_t orig_add_len = ctx->add_len * 8; - if( tag_len > 16 ) + if( tag_len > 16 || tag_len < 4 ) return( POLARSSL_ERR_GCM_BAD_INPUT ); if( tag_len != 0 ) @@ -387,11 +468,17 @@ int gcm_auth_decrypt( gcm_context *ctx, const unsigned char *input, unsigned char *output ) { + int ret; unsigned char check_tag[16]; size_t i; int diff; - gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag ); + if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, + iv, iv_len, add, add_len, + input, output, tag_len, check_tag ) ) != 0 ) + { + return( ret ); + } /* Check tag in "constant-time" */ for( diff = 0, i = 0; i < tag_len; i++ ) @@ -399,7 +486,7 @@ int gcm_auth_decrypt( gcm_context *ctx, if( diff != 0 ) { - memset( output, 0, length ); + polarssl_zeroize( output, length ); return( POLARSSL_ERR_GCM_AUTH_FAILED ); } @@ -408,8 +495,8 @@ int gcm_auth_decrypt( gcm_context *ctx, void gcm_free( gcm_context *ctx ) { - (void) cipher_free_ctx( &ctx->cipher_ctx ); - memset( ctx, 0, sizeof( gcm_context ) ); + cipher_free( &ctx->cipher_ctx ); + polarssl_zeroize( ctx, sizeof( gcm_context ) ); } #if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C) @@ -658,7 +745,8 @@ int gcm_self_test( int verbose ) for( i = 0; i < MAX_TESTS; i++ ) { if( verbose != 0 ) - printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" ); + polarssl_printf( " AES-GCM-%3d #%d (%s): ", + key_len, i, "enc" ); gcm_init( &ctx, cipher, key[key_index[i]], key_len ); @@ -673,7 +761,7 @@ int gcm_self_test( int verbose ) memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } @@ -681,10 +769,11 @@ int gcm_self_test( int verbose ) gcm_free( &ctx ); if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); if( verbose != 0 ) - printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" ); + polarssl_printf( " AES-GCM-%3d #%d (%s): ", + key_len, i, "dec" ); gcm_init( &ctx, cipher, key[key_index[i]], key_len ); @@ -699,7 +788,7 @@ int gcm_self_test( int verbose ) memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } @@ -707,10 +796,11 @@ int gcm_self_test( int verbose ) gcm_free( &ctx ); if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); if( verbose != 0 ) - printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" ); + polarssl_printf( " AES-GCM-%3d #%d split (%s): ", + key_len, i, "enc" ); gcm_init( &ctx, cipher, key[key_index[i]], key_len ); @@ -720,7 +810,7 @@ int gcm_self_test( int verbose ) if( ret != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } @@ -732,16 +822,17 @@ int gcm_self_test( int verbose ) if( ret != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } - ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, buf + 32 ); + ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, + buf + 32 ); if( ret != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } @@ -752,7 +843,7 @@ int gcm_self_test( int verbose ) if( ret != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } @@ -764,7 +855,7 @@ int gcm_self_test( int verbose ) memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } @@ -772,10 +863,11 @@ int gcm_self_test( int verbose ) gcm_free( &ctx ); if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); if( verbose != 0 ) - printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" ); + polarssl_printf( " AES-GCM-%3d #%d split (%s): ", + key_len, i, "dec" ); gcm_init( &ctx, cipher, key[key_index[i]], key_len ); @@ -785,7 +877,7 @@ int gcm_self_test( int verbose ) if( ret != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } @@ -797,16 +889,17 @@ int gcm_self_test( int verbose ) if( ret != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } - ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, buf + 32 ); + ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, + buf + 32 ); if( ret != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } @@ -817,7 +910,7 @@ int gcm_self_test( int verbose ) if( ret != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } @@ -829,7 +922,7 @@ int gcm_self_test( int verbose ) memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } @@ -837,13 +930,13 @@ int gcm_self_test( int verbose ) gcm_free( &ctx ); if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); return( 0 ); } @@ -852,4 +945,4 @@ int gcm_self_test( int verbose ) #endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */ -#endif +#endif /* POLARSSL_GCM_C */ diff --git a/pdns/ext/polarssl/library/havege.c b/pdns/ext/polarssl/library/havege.c index 4d6f418ec..3acd5bca1 100644 --- a/pdns/ext/polarssl/library/havege.c +++ b/pdns/ext/polarssl/library/havege.c @@ -1,7 +1,7 @@ /** * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion * - * Copyright (C) 2006-2010, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -30,7 +30,11 @@ * Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_HAVEGE_C) @@ -39,6 +43,11 @@ #include +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + /* ------------------------------------------------------------------------ * On average, one iteration accesses two 8-word blocks in the havege WALK * table, and generates 16 words in the RES array. @@ -145,7 +154,7 @@ *C = (*C >> (15)) ^ (*C << (17)) ^ CLK; \ *D = (*D >> (16)) ^ (*D << (16)) ^ CLK; \ \ - PT1 = ( RES[(i - 8) ^ PTX] ^ \ + PT1 = ( RES[( i - 8 ) ^ PTX] ^ \ WALK[PT1 ^ PTX ^ 7] ) & (~1); \ PT1 ^= (PT2 ^ 0x10) & 0x10; \ \ @@ -196,6 +205,14 @@ void havege_init( havege_state *hs ) havege_fill( hs ); } +void havege_free( havege_state *hs ) +{ + if( hs == NULL ) + return; + + polarssl_zeroize( hs, sizeof( havege_state ) ); +} + /* * HAVEGE rand function */ @@ -219,7 +236,7 @@ int havege_random( void *p_rng, unsigned char *buf, size_t len ) val ^= hs->pool[hs->offset[1]++]; memcpy( p, &val, use_len ); - + len -= use_len; p += use_len; } @@ -227,4 +244,4 @@ int havege_random( void *p_rng, unsigned char *buf, size_t len ) return( 0 ); } -#endif +#endif /* POLARSSL_HAVEGE_C */ diff --git a/pdns/ext/polarssl/library/hmac_drbg.c b/pdns/ext/polarssl/library/hmac_drbg.c new file mode 100644 index 000000000..d691be11f --- /dev/null +++ b/pdns/ext/polarssl/library/hmac_drbg.c @@ -0,0 +1,502 @@ +/* + * HMAC_DRBG implementation (NIST SP 800-90) + * + * Copyright (C) 2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * The NIST SP 800-90A DRBGs are described in the following publication. + * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf + * References below are based on rev. 1 (January 2012). + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_HMAC_DRBG_C) + +#include "polarssl/hmac_drbg.h" + +#if defined(POLARSSL_FS_IO) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * HMAC_DRBG update, using optional additional data (10.1.2.2) + */ +void hmac_drbg_update( hmac_drbg_context *ctx, + const unsigned char *additional, size_t add_len ) +{ + size_t md_len = ctx->md_ctx.md_info->size; + unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1; + unsigned char sep[1]; + unsigned char K[POLARSSL_MD_MAX_SIZE]; + + for( sep[0] = 0; sep[0] < rounds; sep[0]++ ) + { + /* Step 1 or 4 */ + md_hmac_reset( &ctx->md_ctx ); + md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); + md_hmac_update( &ctx->md_ctx, sep, 1 ); + if( rounds == 2 ) + md_hmac_update( &ctx->md_ctx, additional, add_len ); + md_hmac_finish( &ctx->md_ctx, K ); + + /* Step 2 or 5 */ + md_hmac_starts( &ctx->md_ctx, K, md_len ); + md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); + md_hmac_finish( &ctx->md_ctx, ctx->V ); + } +} + +/* + * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA) + */ +int hmac_drbg_init_buf( hmac_drbg_context *ctx, + const md_info_t * md_info, + const unsigned char *data, size_t data_len ) +{ + int ret; + + memset( ctx, 0, sizeof( hmac_drbg_context ) ); + + md_init( &ctx->md_ctx ); + + if( ( ret = md_init_ctx( &ctx->md_ctx, md_info ) ) != 0 ) + return( ret ); + + /* + * Set initial working state. + * Use the V memory location, which is currently all 0, to initialize the + * MD context with an all-zero key. Then set V to its initial value. + */ + md_hmac_starts( &ctx->md_ctx, ctx->V, md_info->size ); + memset( ctx->V, 0x01, md_info->size ); + + hmac_drbg_update( ctx, data, data_len ); + + return( 0 ); +} + +/* + * HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman) + */ +int hmac_drbg_reseed( hmac_drbg_context *ctx, + const unsigned char *additional, size_t len ) +{ + unsigned char seed[POLARSSL_HMAC_DRBG_MAX_SEED_INPUT]; + size_t seedlen; + + /* III. Check input length */ + if( len > POLARSSL_HMAC_DRBG_MAX_INPUT || + ctx->entropy_len + len > POLARSSL_HMAC_DRBG_MAX_SEED_INPUT ) + { + return( POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG ); + } + + memset( seed, 0, POLARSSL_HMAC_DRBG_MAX_SEED_INPUT ); + + /* IV. Gather entropy_len bytes of entropy for the seed */ + if( ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) != 0 ) + return( POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); + + seedlen = ctx->entropy_len; + + /* 1. Concatenate entropy and additional data if any */ + if( additional != NULL && len != 0 ) + { + memcpy( seed + seedlen, additional, len ); + seedlen += len; + } + + /* 2. Update state */ + hmac_drbg_update( ctx, seed, seedlen ); + + /* 3. Reset reseed_counter */ + ctx->reseed_counter = 1; + + /* 4. Done */ + return( 0 ); +} + +/* + * HMAC_DRBG initialisation (10.1.2.3 + 9.1) + */ +int hmac_drbg_init( hmac_drbg_context *ctx, + const md_info_t * md_info, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len ) +{ + int ret; + size_t entropy_len; + + memset( ctx, 0, sizeof( hmac_drbg_context ) ); + + md_init( &ctx->md_ctx ); + + if( ( ret = md_init_ctx( &ctx->md_ctx, md_info ) ) != 0 ) + return( ret ); + + /* + * Set initial working state. + * Use the V memory location, which is currently all 0, to initialize the + * MD context with an all-zero key. Then set V to its initial value. + */ + md_hmac_starts( &ctx->md_ctx, ctx->V, md_info->size ); + memset( ctx->V, 0x01, md_info->size ); + + ctx->f_entropy = f_entropy; + ctx->p_entropy = p_entropy; + + ctx->reseed_interval = POLARSSL_HMAC_DRBG_RESEED_INTERVAL; + + /* + * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by + * each hash function, then according to SP800-90A rev1 10.1 table 2, + * min_entropy_len (in bits) is security_strength. + * + * (This also matches the sizes used in the NIST test vectors.) + */ + entropy_len = md_info->size <= 20 ? 16 : /* 160-bits hash -> 128 bits */ + md_info->size <= 28 ? 24 : /* 224-bits hash -> 192 bits */ + 32; /* better (256+) -> 256 bits */ + + /* + * For initialisation, use more entropy to emulate a nonce + * (Again, matches test vectors.) + */ + ctx->entropy_len = entropy_len * 3 / 2; + + if( ( ret = hmac_drbg_reseed( ctx, custom, len ) ) != 0 ) + return( ret ); + + ctx->entropy_len = entropy_len; + + return( 0 ); +} + +/* + * Set prediction resistance + */ +void hmac_drbg_set_prediction_resistance( hmac_drbg_context *ctx, + int resistance ) +{ + ctx->prediction_resistance = resistance; +} + +/* + * Set entropy length grabbed for reseeds + */ +void hmac_drbg_set_entropy_len( hmac_drbg_context *ctx, size_t len ) +{ + ctx->entropy_len = len; +} + +/* + * Set reseed interval + */ +void hmac_drbg_set_reseed_interval( hmac_drbg_context *ctx, int interval ) +{ + ctx->reseed_interval = interval; +} + +/* + * HMAC_DRBG random function with optional additional data: + * 10.1.2.5 (arabic) + 9.3 (Roman) + */ +int hmac_drbg_random_with_add( void *p_rng, + unsigned char *output, size_t out_len, + const unsigned char *additional, size_t add_len ) +{ + int ret; + hmac_drbg_context *ctx = (hmac_drbg_context *) p_rng; + size_t md_len = md_get_size( ctx->md_ctx.md_info ); + size_t left = out_len; + unsigned char *out = output; + + /* II. Check request length */ + if( out_len > POLARSSL_HMAC_DRBG_MAX_REQUEST ) + return( POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG ); + + /* III. Check input length */ + if( add_len > POLARSSL_HMAC_DRBG_MAX_INPUT ) + return( POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG ); + + /* 1. (aka VII and IX) Check reseed counter and PR */ + if( ctx->f_entropy != NULL && /* For no-reseeding instances */ + ( ctx->prediction_resistance == POLARSSL_HMAC_DRBG_PR_ON || + ctx->reseed_counter > ctx->reseed_interval ) ) + { + if( ( ret = hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 ) + return( ret ); + + add_len = 0; /* VII.4 */ + } + + /* 2. Use additional data if any */ + if( additional != NULL && add_len != 0 ) + hmac_drbg_update( ctx, additional, add_len ); + + /* 3, 4, 5. Generate bytes */ + while( left != 0 ) + { + size_t use_len = left > md_len ? md_len : left; + + md_hmac_reset( &ctx->md_ctx ); + md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); + md_hmac_finish( &ctx->md_ctx, ctx->V ); + + memcpy( out, ctx->V, use_len ); + out += use_len; + left -= use_len; + } + + /* 6. Update */ + hmac_drbg_update( ctx, additional, add_len ); + + /* 7. Update reseed counter */ + ctx->reseed_counter++; + + /* 8. Done */ + return( 0 ); +} + +/* + * HMAC_DRBG random function + */ +int hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ) +{ + return( hmac_drbg_random_with_add( p_rng, output, out_len, NULL, 0 ) ); +} + +/* + * Free an HMAC_DRBG context + */ +void hmac_drbg_free( hmac_drbg_context *ctx ) +{ + if( ctx == NULL ) + return; + + md_free_ctx( &ctx->md_ctx ); + + polarssl_zeroize( ctx, sizeof( hmac_drbg_context ) ); +} + +#if defined(POLARSSL_FS_IO) +int hmac_drbg_write_seed_file( hmac_drbg_context *ctx, const char *path ) +{ + int ret; + FILE *f; + unsigned char buf[ POLARSSL_HMAC_DRBG_MAX_INPUT ]; + + if( ( f = fopen( path, "wb" ) ) == NULL ) + return( POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR ); + + if( ( ret = hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 ) + goto exit; + + if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) ) + { + ret = POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR; + goto exit; + } + + ret = 0; + +exit: + fclose( f ); + return( ret ); +} + +int hmac_drbg_update_seed_file( hmac_drbg_context *ctx, const char *path ) +{ + FILE *f; + size_t n; + unsigned char buf[ POLARSSL_HMAC_DRBG_MAX_INPUT ]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + n = (size_t) ftell( f ); + fseek( f, 0, SEEK_SET ); + + if( n > POLARSSL_HMAC_DRBG_MAX_INPUT ) + { + fclose( f ); + return( POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG ); + } + + if( fread( buf, 1, n, f ) != n ) + { + fclose( f ); + return( POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR ); + } + + fclose( f ); + + hmac_drbg_update( ctx, buf, n ); + + return( hmac_drbg_write_seed_file( ctx, path ) ); +} +#endif /* POLARSSL_FS_IO */ + + +#if defined(POLARSSL_SELF_TEST) + +#include + +#if !defined(POLARSSL_SHA1_C) +/* Dummy checkup routine */ +int hmac_drbg_self_test( int verbose ) +{ + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} +#else + +#define OUTPUT_LEN 80 + +/* From a NIST PR=true test vector */ +static unsigned char entropy_pr[] = { + 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f, + 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11, + 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42, + 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3, + 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 }; +static const unsigned char result_pr[OUTPUT_LEN] = { + 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39, + 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94, + 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54, + 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e, + 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab, + 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3, + 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 }; + +/* From a NIST PR=false test vector */ +static unsigned char entropy_nopr[] = { + 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66, + 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8, + 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3, + 0xe9, 0x9d, 0xfe, 0xdf }; +static const unsigned char result_nopr[OUTPUT_LEN] = { + 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f, + 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6, + 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a, + 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec, + 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd, + 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49, + 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 }; + +/* "Entropy" from buffer */ +static size_t test_offset; +static int hmac_drbg_self_test_entropy( void *data, + unsigned char *buf, size_t len ) +{ + const unsigned char *p = data; + memcpy( buf, p + test_offset, len ); + test_offset += len; + return( 0 ); +} + +#define CHK( c ) if( (c) != 0 ) \ + { \ + if( verbose != 0 ) \ + polarssl_printf( "failed\n" ); \ + return( 1 ); \ + } + +/* + * Checkup routine for HMAC_DRBG with SHA-1 + */ +int hmac_drbg_self_test( int verbose ) +{ + hmac_drbg_context ctx; + unsigned char buf[OUTPUT_LEN]; + const md_info_t *md_info = md_info_from_type( POLARSSL_MD_SHA1 ); + + /* + * PR = True + */ + if( verbose != 0 ) + polarssl_printf( " HMAC_DRBG (PR = True) : " ); + + test_offset = 0; + CHK( hmac_drbg_init( &ctx, md_info, + hmac_drbg_self_test_entropy, entropy_pr, + NULL, 0 ) ); + hmac_drbg_set_prediction_resistance( &ctx, POLARSSL_HMAC_DRBG_PR_ON ); + CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( memcmp( buf, result_pr, OUTPUT_LEN ) ); + hmac_drbg_free( &ctx ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + /* + * PR = False + */ + if( verbose != 0 ) + polarssl_printf( " HMAC_DRBG (PR = False) : " ); + + test_offset = 0; + CHK( hmac_drbg_init( &ctx, md_info, + hmac_drbg_self_test_entropy, entropy_nopr, + NULL, 0 ) ); + CHK( hmac_drbg_reseed( &ctx, NULL, 0 ) ); + CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) ); + hmac_drbg_free( &ctx ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_HMAC_DRBG_C */ diff --git a/pdns/ext/polarssl/library/md.c b/pdns/ext/polarssl/library/md.c index af6675661..7f9c5dc84 100644 --- a/pdns/ext/polarssl/library/md.c +++ b/pdns/ext/polarssl/library/md.c @@ -1,11 +1,11 @@ /** * \file md.c - * + * * \brief Generic message digest wrapper for PolarSSL * * \author Adriaan de Jong * - * Copyright (C) 2006-2010, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_MD_C) @@ -41,46 +45,55 @@ #define strcasecmp _stricmp #endif -static const int supported_digests[] = { +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} -#if defined(POLARSSL_MD2_C) - POLARSSL_MD_MD2, -#endif +static const int supported_digests[] = { -#if defined(POLARSSL_MD4_C) - POLARSSL_MD_MD4, +#if defined(POLARSSL_SHA512_C) + POLARSSL_MD_SHA384, + POLARSSL_MD_SHA512, #endif -#if defined(POLARSSL_MD5_C) - POLARSSL_MD_MD5, +#if defined(POLARSSL_SHA256_C) + POLARSSL_MD_SHA224, + POLARSSL_MD_SHA256, #endif #if defined(POLARSSL_SHA1_C) POLARSSL_MD_SHA1, #endif -#if defined(POLARSSL_SHA256_C) - POLARSSL_MD_SHA224, - POLARSSL_MD_SHA256, +#if defined(POLARSSL_RIPEMD160_C) + POLARSSL_MD_RIPEMD160, #endif -#if defined(POLARSSL_SHA512_C) - POLARSSL_MD_SHA384, - POLARSSL_MD_SHA512, +#if defined(POLARSSL_MD5_C) + POLARSSL_MD_MD5, #endif - 0 +#if defined(POLARSSL_MD4_C) + POLARSSL_MD_MD4, +#endif + +#if defined(POLARSSL_MD2_C) + POLARSSL_MD_MD2, +#endif + + POLARSSL_MD_NONE }; const int *md_list( void ) { - return supported_digests; + return( supported_digests ); } const md_info_t *md_info_from_string( const char *md_name ) { if( NULL == md_name ) - return NULL; + return( NULL ); /* Get the appropriate digest information */ #if defined(POLARSSL_MD2_C) @@ -95,6 +108,10 @@ const md_info_t *md_info_from_string( const char *md_name ) if( !strcasecmp( "MD5", md_name ) ) return md_info_from_type( POLARSSL_MD_MD5 ); #endif +#if defined(POLARSSL_RIPEMD160_C) + if( !strcasecmp( "RIPEMD160", md_name ) ) + return md_info_from_type( POLARSSL_MD_RIPEMD160 ); +#endif #if defined(POLARSSL_SHA1_C) if( !strcasecmp( "SHA1", md_name ) || !strcasecmp( "SHA", md_name ) ) return md_info_from_type( POLARSSL_MD_SHA1 ); @@ -111,7 +128,7 @@ const md_info_t *md_info_from_string( const char *md_name ) if( !strcasecmp( "SHA512", md_name ) ) return md_info_from_type( POLARSSL_MD_SHA512 ); #endif - return NULL; + return( NULL ); } const md_info_t *md_info_from_type( md_type_t md_type ) @@ -120,104 +137,120 @@ const md_info_t *md_info_from_type( md_type_t md_type ) { #if defined(POLARSSL_MD2_C) case POLARSSL_MD_MD2: - return &md2_info; + return( &md2_info ); #endif #if defined(POLARSSL_MD4_C) case POLARSSL_MD_MD4: - return &md4_info; + return( &md4_info ); #endif #if defined(POLARSSL_MD5_C) case POLARSSL_MD_MD5: - return &md5_info; + return( &md5_info ); +#endif +#if defined(POLARSSL_RIPEMD160_C) + case POLARSSL_MD_RIPEMD160: + return( &ripemd160_info ); #endif #if defined(POLARSSL_SHA1_C) case POLARSSL_MD_SHA1: - return &sha1_info; + return( &sha1_info ); #endif #if defined(POLARSSL_SHA256_C) case POLARSSL_MD_SHA224: - return &sha224_info; + return( &sha224_info ); case POLARSSL_MD_SHA256: - return &sha256_info; + return( &sha256_info ); #endif #if defined(POLARSSL_SHA512_C) case POLARSSL_MD_SHA384: - return &sha384_info; + return( &sha384_info ); case POLARSSL_MD_SHA512: - return &sha512_info; + return( &sha512_info ); #endif default: - return NULL; + return( NULL ); } } +void md_init( md_context_t *ctx ) +{ + memset( ctx, 0, sizeof( md_context_t ) ); +} + +void md_free( md_context_t *ctx ) +{ + if( ctx == NULL ) + return; + + if( ctx->md_ctx ) + ctx->md_info->ctx_free_func( ctx->md_ctx ); + + polarssl_zeroize( ctx, sizeof( md_context_t ) ); +} + int md_init_ctx( md_context_t *ctx, const md_info_t *md_info ) { if( md_info == NULL || ctx == NULL ) - return POLARSSL_ERR_MD_BAD_INPUT_DATA; + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); memset( ctx, 0, sizeof( md_context_t ) ); if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL ) - return POLARSSL_ERR_MD_ALLOC_FAILED; + return( POLARSSL_ERR_MD_ALLOC_FAILED ); ctx->md_info = md_info; md_info->starts_func( ctx->md_ctx ); - return 0; + return( 0 ); } int md_free_ctx( md_context_t *ctx ) { - if( ctx == NULL || ctx->md_info == NULL ) - return POLARSSL_ERR_MD_BAD_INPUT_DATA; - - ctx->md_info->ctx_free_func( ctx->md_ctx ); - ctx->md_ctx = NULL; + md_free( ctx ); - return 0; + return( 0 ); } int md_starts( md_context_t *ctx ) { if( ctx == NULL || ctx->md_info == NULL ) - return POLARSSL_ERR_MD_BAD_INPUT_DATA; + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); ctx->md_info->starts_func( ctx->md_ctx ); - return 0; + return( 0 ); } int md_update( md_context_t *ctx, const unsigned char *input, size_t ilen ) { if( ctx == NULL || ctx->md_info == NULL ) - return POLARSSL_ERR_MD_BAD_INPUT_DATA; + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); ctx->md_info->update_func( ctx->md_ctx, input, ilen ); - return 0; + return( 0 ); } int md_finish( md_context_t *ctx, unsigned char *output ) { if( ctx == NULL || ctx->md_info == NULL ) - return POLARSSL_ERR_MD_BAD_INPUT_DATA; + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); ctx->md_info->finish_func( ctx->md_ctx, output ); - return 0; + return( 0 ); } int md( const md_info_t *md_info, const unsigned char *input, size_t ilen, unsigned char *output ) { - if ( md_info == NULL ) - return POLARSSL_ERR_MD_BAD_INPUT_DATA; + if( md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); md_info->digest_func( input, ilen, output ); - return 0; + return( 0 ); } int md_file( const md_info_t *md_info, const char *path, unsigned char *output ) @@ -227,7 +260,7 @@ int md_file( const md_info_t *md_info, const char *path, unsigned char *output ) #endif if( md_info == NULL ) - return POLARSSL_ERR_MD_BAD_INPUT_DATA; + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); #if defined(POLARSSL_FS_IO) ret = md_info->file_func( path, output ); @@ -239,48 +272,48 @@ int md_file( const md_info_t *md_info, const char *path, unsigned char *output ) ((void) path); ((void) output); - return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE; -#endif + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_FS_IO */ } int md_hmac_starts( md_context_t *ctx, const unsigned char *key, size_t keylen ) { if( ctx == NULL || ctx->md_info == NULL ) - return POLARSSL_ERR_MD_BAD_INPUT_DATA; + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); - ctx->md_info->hmac_starts_func( ctx->md_ctx, key, keylen); + ctx->md_info->hmac_starts_func( ctx->md_ctx, key, keylen ); - return 0; + return( 0 ); } int md_hmac_update( md_context_t *ctx, const unsigned char *input, size_t ilen ) { if( ctx == NULL || ctx->md_info == NULL ) - return POLARSSL_ERR_MD_BAD_INPUT_DATA; + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); ctx->md_info->hmac_update_func( ctx->md_ctx, input, ilen ); - return 0; + return( 0 ); } -int md_hmac_finish( md_context_t *ctx, unsigned char *output) +int md_hmac_finish( md_context_t *ctx, unsigned char *output ) { if( ctx == NULL || ctx->md_info == NULL ) - return POLARSSL_ERR_MD_BAD_INPUT_DATA; + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); - ctx->md_info->hmac_finish_func( ctx->md_ctx, output); + ctx->md_info->hmac_finish_func( ctx->md_ctx, output ); - return 0; + return( 0 ); } int md_hmac_reset( md_context_t *ctx ) { if( ctx == NULL || ctx->md_info == NULL ) - return POLARSSL_ERR_MD_BAD_INPUT_DATA; + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); - ctx->md_info->hmac_reset_func( ctx->md_ctx); + ctx->md_info->hmac_reset_func( ctx->md_ctx ); - return 0; + return( 0 ); } int md_hmac( const md_info_t *md_info, const unsigned char *key, size_t keylen, @@ -288,21 +321,21 @@ int md_hmac( const md_info_t *md_info, const unsigned char *key, size_t keylen, unsigned char *output ) { if( md_info == NULL ) - return POLARSSL_ERR_MD_BAD_INPUT_DATA; + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); md_info->hmac_func( key, keylen, input, ilen, output ); - return 0; + return( 0 ); } int md_process( md_context_t *ctx, const unsigned char *data ) { if( ctx == NULL || ctx->md_info == NULL ) - return POLARSSL_ERR_MD_BAD_INPUT_DATA; + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); ctx->md_info->process_func( ctx->md_ctx, data ); - return 0; + return( 0 ); } -#endif +#endif /* POLARSSL_MD_C */ diff --git a/pdns/ext/polarssl/library/md2.c b/pdns/ext/polarssl/library/md2.c index 93e77d2f6..45bce371c 100644 --- a/pdns/ext/polarssl/library/md2.c +++ b/pdns/ext/polarssl/library/md2.c @@ -1,7 +1,7 @@ /* * RFC 1115/1319 compliant MD2 implementation * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -29,7 +29,11 @@ * http://www.ietf.org/rfc/rfc1319.txt */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_MD2_C) @@ -39,6 +43,17 @@ #include #endif +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + #if !defined(POLARSSL_MD2_ALT) static const unsigned char PI_SUBST[256] = @@ -71,6 +86,19 @@ static const unsigned char PI_SUBST[256] = 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14 }; +void md2_init( md2_context *ctx ) +{ + memset( ctx, 0, sizeof( md2_context ) ); +} + +void md2_free( md2_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( md2_context ) ); +} + /* * MD2 context setup */ @@ -174,11 +202,11 @@ void md2( const unsigned char *input, size_t ilen, unsigned char output[16] ) { md2_context ctx; + md2_init( &ctx ); md2_starts( &ctx ); md2_update( &ctx, input, ilen ); md2_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md2_context ) ); + md2_free( &ctx ); } #if defined(POLARSSL_FS_IO) @@ -195,14 +223,14 @@ int md2_file( const char *path, unsigned char output[16] ) if( ( f = fopen( path, "rb" ) ) == NULL ) return( POLARSSL_ERR_MD2_FILE_IO_ERROR ); + md2_init( &ctx ); md2_starts( &ctx ); while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) md2_update( &ctx, buf, n ); md2_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md2_context ) ); + md2_free( &ctx ); if( ferror( f ) != 0 ) { @@ -218,7 +246,8 @@ int md2_file( const char *path, unsigned char output[16] ) /* * MD2 HMAC context setup */ -void md2_hmac_starts( md2_context *ctx, const unsigned char *key, size_t keylen ) +void md2_hmac_starts( md2_context *ctx, const unsigned char *key, + size_t keylen ) { size_t i; unsigned char sum[16]; @@ -242,13 +271,14 @@ void md2_hmac_starts( md2_context *ctx, const unsigned char *key, size_t keylen md2_starts( ctx ); md2_update( ctx, ctx->ipad, 16 ); - memset( sum, 0, sizeof( sum ) ); + polarssl_zeroize( sum, sizeof( sum ) ); } /* * MD2 HMAC process buffer */ -void md2_hmac_update( md2_context *ctx, const unsigned char *input, size_t ilen ) +void md2_hmac_update( md2_context *ctx, const unsigned char *input, + size_t ilen ) { md2_update( ctx, input, ilen ); } @@ -266,7 +296,7 @@ void md2_hmac_finish( md2_context *ctx, unsigned char output[16] ) md2_update( ctx, tmpbuf, 16 ); md2_finish( ctx, output ); - memset( tmpbuf, 0, sizeof( tmpbuf ) ); + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); } /* @@ -287,11 +317,11 @@ void md2_hmac( const unsigned char *key, size_t keylen, { md2_context ctx; + md2_init( &ctx ); md2_hmac_starts( &ctx, key, keylen ); md2_hmac_update( &ctx, input, ilen ); md2_hmac_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md2_context ) ); + md2_free( &ctx ); } #if defined(POLARSSL_SELF_TEST) @@ -340,7 +370,7 @@ int md2_self_test( int verbose ) for( i = 0; i < 7; i++ ) { if( verbose != 0 ) - printf( " MD2 test #%d: ", i + 1 ); + polarssl_printf( " MD2 test #%d: ", i + 1 ); md2( (unsigned char *) md2_test_str[i], strlen( md2_test_str[i] ), md2sum ); @@ -348,21 +378,21 @@ int md2_self_test( int verbose ) if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); return( 0 ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_MD2_C */ diff --git a/pdns/ext/polarssl/library/md4.c b/pdns/ext/polarssl/library/md4.c index e14c83dc2..f6b71d56e 100644 --- a/pdns/ext/polarssl/library/md4.c +++ b/pdns/ext/polarssl/library/md4.c @@ -1,7 +1,7 @@ /* * RFC 1186/1320 compliant MD4 implementation * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -29,7 +29,11 @@ * http://www.ietf.org/rfc/rfc1320.txt */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_MD4_C) @@ -39,6 +43,17 @@ #include #endif +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + #if !defined(POLARSSL_MD4_ALT) /* @@ -64,6 +79,19 @@ } #endif +void md4_init( md4_context *ctx ) +{ + memset( ctx, 0, sizeof( md4_context ) ); +} + +void md4_free( md4_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( md4_context ) ); +} + /* * MD4 context setup */ @@ -189,7 +217,7 @@ void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen ) size_t fill; uint32_t left; - if( ilen <= 0 ) + if( ilen == 0 ) return; left = ctx->total[0] & 0x3F; @@ -270,11 +298,11 @@ void md4( const unsigned char *input, size_t ilen, unsigned char output[16] ) { md4_context ctx; + md4_init( &ctx ); md4_starts( &ctx ); md4_update( &ctx, input, ilen ); md4_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md4_context ) ); + md4_free( &ctx ); } #if defined(POLARSSL_FS_IO) @@ -291,14 +319,14 @@ int md4_file( const char *path, unsigned char output[16] ) if( ( f = fopen( path, "rb" ) ) == NULL ) return( POLARSSL_ERR_MD4_FILE_IO_ERROR ); + md4_init( &ctx ); md4_starts( &ctx ); while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) md4_update( &ctx, buf, n ); md4_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md4_context ) ); + md4_free( &ctx ); if( ferror( f ) != 0 ) { @@ -314,7 +342,8 @@ int md4_file( const char *path, unsigned char output[16] ) /* * MD4 HMAC context setup */ -void md4_hmac_starts( md4_context *ctx, const unsigned char *key, size_t keylen ) +void md4_hmac_starts( md4_context *ctx, const unsigned char *key, + size_t keylen ) { size_t i; unsigned char sum[16]; @@ -338,13 +367,14 @@ void md4_hmac_starts( md4_context *ctx, const unsigned char *key, size_t keylen md4_starts( ctx ); md4_update( ctx, ctx->ipad, 64 ); - memset( sum, 0, sizeof( sum ) ); + polarssl_zeroize( sum, sizeof( sum ) ); } /* * MD4 HMAC process buffer */ -void md4_hmac_update( md4_context *ctx, const unsigned char *input, size_t ilen ) +void md4_hmac_update( md4_context *ctx, const unsigned char *input, + size_t ilen ) { md4_update( ctx, input, ilen ); } @@ -362,7 +392,7 @@ void md4_hmac_finish( md4_context *ctx, unsigned char output[16] ) md4_update( ctx, tmpbuf, 16 ); md4_finish( ctx, output ); - memset( tmpbuf, 0, sizeof( tmpbuf ) ); + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); } /* @@ -383,11 +413,11 @@ void md4_hmac( const unsigned char *key, size_t keylen, { md4_context ctx; + md4_init( &ctx ); md4_hmac_starts( &ctx, key, keylen ); md4_hmac_update( &ctx, input, ilen ); md4_hmac_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md4_context ) ); + md4_free( &ctx ); } #if defined(POLARSSL_SELF_TEST) @@ -397,7 +427,7 @@ void md4_hmac( const unsigned char *key, size_t keylen, */ static const char md4_test_str[7][81] = { - { "" }, + { "" }, { "a" }, { "abc" }, { "message digest" }, @@ -436,7 +466,7 @@ int md4_self_test( int verbose ) for( i = 0; i < 7; i++ ) { if( verbose != 0 ) - printf( " MD4 test #%d: ", i + 1 ); + polarssl_printf( " MD4 test #%d: ", i + 1 ); md4( (unsigned char *) md4_test_str[i], strlen( md4_test_str[i] ), md4sum ); @@ -444,21 +474,21 @@ int md4_self_test( int verbose ) if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); return( 0 ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_MD4_C */ diff --git a/pdns/ext/polarssl/library/md5.c b/pdns/ext/polarssl/library/md5.c index b28461e9b..89354bc7d 100644 --- a/pdns/ext/polarssl/library/md5.c +++ b/pdns/ext/polarssl/library/md5.c @@ -1,7 +1,7 @@ /* * RFC 1321 compliant MD5 implementation * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -28,7 +28,11 @@ * http://www.ietf.org/rfc/rfc1321.txt */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_MD5_C) @@ -38,6 +42,17 @@ #include #endif +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + #if !defined(POLARSSL_MD5_ALT) /* @@ -63,6 +78,19 @@ } #endif +void md5_init( md5_context *ctx ) +{ + memset( ctx, 0, sizeof( md5_context ) ); +} + +void md5_free( md5_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( md5_context ) ); +} + /* * MD5 context setup */ @@ -151,7 +179,7 @@ void md5_process( md5_context *ctx, const unsigned char data[64] ) P( B, C, D, A, 12, 20, 0x8D2A4C8A ); #undef F - + #define F(x,y,z) (x ^ y ^ z) P( A, B, C, D, 5, 4, 0xFFFA3942 ); @@ -208,7 +236,7 @@ void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen ) size_t fill; uint32_t left; - if( ilen <= 0 ) + if( ilen == 0 ) return; left = ctx->total[0] & 0x3F; @@ -287,11 +315,11 @@ void md5( const unsigned char *input, size_t ilen, unsigned char output[16] ) { md5_context ctx; + md5_init( &ctx ); md5_starts( &ctx ); md5_update( &ctx, input, ilen ); md5_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md5_context ) ); + md5_free( &ctx ); } #if defined(POLARSSL_FS_IO) @@ -308,14 +336,14 @@ int md5_file( const char *path, unsigned char output[16] ) if( ( f = fopen( path, "rb" ) ) == NULL ) return( POLARSSL_ERR_MD5_FILE_IO_ERROR ); + md5_init( &ctx ); md5_starts( &ctx ); while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) md5_update( &ctx, buf, n ); md5_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md5_context ) ); + md5_free( &ctx ); if( ferror( f ) != 0 ) { @@ -331,7 +359,8 @@ int md5_file( const char *path, unsigned char output[16] ) /* * MD5 HMAC context setup */ -void md5_hmac_starts( md5_context *ctx, const unsigned char *key, size_t keylen ) +void md5_hmac_starts( md5_context *ctx, const unsigned char *key, + size_t keylen ) { size_t i; unsigned char sum[16]; @@ -355,13 +384,14 @@ void md5_hmac_starts( md5_context *ctx, const unsigned char *key, size_t keylen md5_starts( ctx ); md5_update( ctx, ctx->ipad, 64 ); - memset( sum, 0, sizeof( sum ) ); + polarssl_zeroize( sum, sizeof( sum ) ); } /* * MD5 HMAC process buffer */ -void md5_hmac_update( md5_context *ctx, const unsigned char *input, size_t ilen ) +void md5_hmac_update( md5_context *ctx, const unsigned char *input, + size_t ilen ) { md5_update( ctx, input, ilen ); } @@ -379,7 +409,7 @@ void md5_hmac_finish( md5_context *ctx, unsigned char output[16] ) md5_update( ctx, tmpbuf, 16 ); md5_finish( ctx, output ); - memset( tmpbuf, 0, sizeof( tmpbuf ) ); + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); } /* @@ -400,11 +430,11 @@ void md5_hmac( const unsigned char *key, size_t keylen, { md5_context ctx; + md5_init( &ctx ); md5_hmac_starts( &ctx, key, keylen ); md5_hmac_update( &ctx, input, ilen ); md5_hmac_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md5_context ) ); + md5_free( &ctx ); } #if defined(POLARSSL_SELF_TEST) @@ -413,7 +443,7 @@ void md5_hmac( const unsigned char *key, size_t keylen, */ static unsigned char md5_test_buf[7][81] = { - { "" }, + { "" }, { "a" }, { "abc" }, { "message digest" }, @@ -522,29 +552,29 @@ int md5_self_test( int verbose ) for( i = 0; i < 7; i++ ) { if( verbose != 0 ) - printf( " MD5 test #%d: ", i + 1 ); + polarssl_printf( " MD5 test #%d: ", i + 1 ); md5( md5_test_buf[i], md5_test_buflen[i], md5sum ); if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); for( i = 0; i < 7; i++ ) { if( verbose != 0 ) - printf( " HMAC-MD5 test #%d: ", i + 1 ); + polarssl_printf( " HMAC-MD5 test #%d: ", i + 1 ); if( i == 5 || i == 6 ) { @@ -565,21 +595,21 @@ int md5_self_test( int verbose ) if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); return( 0 ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_MD5_C */ diff --git a/pdns/ext/polarssl/library/md_wrap.c b/pdns/ext/polarssl/library/md_wrap.c index 038b13272..de701d319 100644 --- a/pdns/ext/polarssl/library/md_wrap.c +++ b/pdns/ext/polarssl/library/md_wrap.c @@ -5,7 +5,7 @@ * * \author Adriaan de Jong * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,7 +27,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_MD_C) @@ -45,6 +49,10 @@ #include "polarssl/md5.h" #endif +#if defined(POLARSSL_RIPEMD160_C) +#include "polarssl/ripemd160.h" +#endif + #if defined(POLARSSL_SHA1_C) #include "polarssl/sha1.h" #endif @@ -57,8 +65,8 @@ #include "polarssl/sha512.h" #endif -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else #define polarssl_malloc malloc #define polarssl_free free @@ -66,6 +74,11 @@ #include +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + #if defined(POLARSSL_MD2_C) static void md2_starts_wrap( void *ctx ) @@ -73,7 +86,8 @@ static void md2_starts_wrap( void *ctx ) md2_starts( (md2_context *) ctx ); } -static void md2_update_wrap( void *ctx, const unsigned char *input, size_t ilen ) +static void md2_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) { md2_update( (md2_context *) ctx, input, ilen ); } @@ -90,16 +104,18 @@ static int md2_file_wrap( const char *path, unsigned char *output ) #else ((void) path); ((void) output); - return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); #endif } -static void md2_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen ) +static void md2_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) { md2_hmac_starts( (md2_context *) ctx, key, keylen ); } -static void md2_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen ) +static void md2_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) { md2_hmac_update( (md2_context *) ctx, input, ilen ); } @@ -121,6 +137,7 @@ static void * md2_ctx_alloc( void ) static void md2_ctx_free( void *ctx ) { + polarssl_zeroize( ctx, sizeof( md2_context ) ); polarssl_free( ctx ); } @@ -150,7 +167,7 @@ const md_info_t md2_info = { md2_process_wrap, }; -#endif +#endif /* POLARSSL_MD2_C */ #if defined(POLARSSL_MD4_C) @@ -159,7 +176,8 @@ static void md4_starts_wrap( void *ctx ) md4_starts( (md4_context *) ctx ); } -static void md4_update_wrap( void *ctx, const unsigned char *input, size_t ilen ) +static void md4_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) { md4_update( (md4_context *) ctx, input, ilen ); } @@ -176,16 +194,18 @@ static int md4_file_wrap( const char *path, unsigned char *output ) #else ((void) path); ((void) output); - return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); #endif } -static void md4_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen ) +static void md4_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) { md4_hmac_starts( (md4_context *) ctx, key, keylen ); } -static void md4_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen ) +static void md4_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) { md4_hmac_update( (md4_context *) ctx, input, ilen ); } @@ -207,6 +227,7 @@ static void *md4_ctx_alloc( void ) static void md4_ctx_free( void *ctx ) { + polarssl_zeroize( ctx, sizeof( md4_context ) ); polarssl_free( ctx ); } @@ -234,7 +255,7 @@ const md_info_t md4_info = { md4_process_wrap, }; -#endif +#endif /* POLARSSL_MD4_C */ #if defined(POLARSSL_MD5_C) @@ -243,7 +264,8 @@ static void md5_starts_wrap( void *ctx ) md5_starts( (md5_context *) ctx ); } -static void md5_update_wrap( void *ctx, const unsigned char *input, size_t ilen ) +static void md5_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) { md5_update( (md5_context *) ctx, input, ilen ); } @@ -260,16 +282,18 @@ static int md5_file_wrap( const char *path, unsigned char *output ) #else ((void) path); ((void) output); - return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); #endif } -static void md5_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen ) +static void md5_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) { md5_hmac_starts( (md5_context *) ctx, key, keylen ); } -static void md5_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen ) +static void md5_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) { md5_hmac_update( (md5_context *) ctx, input, ilen ); } @@ -291,6 +315,7 @@ static void * md5_ctx_alloc( void ) static void md5_ctx_free( void *ctx ) { + polarssl_zeroize( ctx, sizeof( md5_context ) ); polarssl_free( ctx ); } @@ -318,7 +343,103 @@ const md_info_t md5_info = { md5_process_wrap, }; +#endif /* POLARSSL_MD5_C */ + +#if defined(POLARSSL_RIPEMD160_C) + +static void ripemd160_starts_wrap( void *ctx ) +{ + ripemd160_starts( (ripemd160_context *) ctx ); +} + +static void ripemd160_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + ripemd160_update( (ripemd160_context *) ctx, input, ilen ); +} + +static void ripemd160_finish_wrap( void *ctx, unsigned char *output ) +{ + ripemd160_finish( (ripemd160_context *) ctx, output ); +} + +static int ripemd160_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return ripemd160_file( path, output ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); #endif +} + +static void ripemd160_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + ripemd160_hmac_starts( (ripemd160_context *) ctx, key, keylen ); +} + +static void ripemd160_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + ripemd160_hmac_update( (ripemd160_context *) ctx, input, ilen ); +} + +static void ripemd160_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + ripemd160_hmac_finish( (ripemd160_context *) ctx, output ); +} + +static void ripemd160_hmac_reset_wrap( void *ctx ) +{ + ripemd160_hmac_reset( (ripemd160_context *) ctx ); +} + +static void * ripemd160_ctx_alloc( void ) +{ + ripemd160_context *ctx; + ctx = (ripemd160_context *) polarssl_malloc( sizeof( ripemd160_context ) ); + + if( ctx == NULL ) + return( NULL ); + + ripemd160_init( ctx ); + + return( ctx ); +} + +static void ripemd160_ctx_free( void *ctx ) +{ + ripemd160_free( (ripemd160_context *) ctx ); + polarssl_free( ctx ); +} + +static void ripemd160_process_wrap( void *ctx, const unsigned char *data ) +{ + ripemd160_process( (ripemd160_context *) ctx, data ); +} + +const md_info_t ripemd160_info = { + POLARSSL_MD_RIPEMD160, + "RIPEMD160", + 20, + ripemd160_starts_wrap, + ripemd160_update_wrap, + ripemd160_finish_wrap, + ripemd160, + ripemd160_file_wrap, + ripemd160_hmac_starts_wrap, + ripemd160_hmac_update_wrap, + ripemd160_hmac_finish_wrap, + ripemd160_hmac_reset_wrap, + ripemd160_hmac, + ripemd160_ctx_alloc, + ripemd160_ctx_free, + ripemd160_process_wrap, +}; + +#endif /* POLARSSL_RIPEMD160_C */ #if defined(POLARSSL_SHA1_C) @@ -327,7 +448,8 @@ static void sha1_starts_wrap( void *ctx ) sha1_starts( (sha1_context *) ctx ); } -static void sha1_update_wrap( void *ctx, const unsigned char *input, size_t ilen ) +static void sha1_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) { sha1_update( (sha1_context *) ctx, input, ilen ); } @@ -344,16 +466,18 @@ static int sha1_file_wrap( const char *path, unsigned char *output ) #else ((void) path); ((void) output); - return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); #endif } -static void sha1_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen ) +static void sha1_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) { sha1_hmac_starts( (sha1_context *) ctx, key, keylen ); } -static void sha1_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen ) +static void sha1_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) { sha1_hmac_update( (sha1_context *) ctx, input, ilen ); } @@ -370,11 +494,20 @@ static void sha1_hmac_reset_wrap( void *ctx ) static void * sha1_ctx_alloc( void ) { - return polarssl_malloc( sizeof( sha1_context ) ); + sha1_context *ctx; + ctx = (sha1_context *) polarssl_malloc( sizeof( sha1_context ) ); + + if( ctx == NULL ) + return( NULL ); + + sha1_init( ctx ); + + return( ctx ); } static void sha1_ctx_free( void *ctx ) { + sha1_free( (sha1_context *) ctx ); polarssl_free( ctx ); } @@ -402,7 +535,7 @@ const md_info_t sha1_info = { sha1_process_wrap, }; -#endif +#endif /* POLARSSL_SHA1_C */ /* * Wrappers for generic message digests @@ -414,7 +547,8 @@ static void sha224_starts_wrap( void *ctx ) sha256_starts( (sha256_context *) ctx, 1 ); } -static void sha224_update_wrap( void *ctx, const unsigned char *input, size_t ilen ) +static void sha224_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) { sha256_update( (sha256_context *) ctx, input, ilen ); } @@ -437,16 +571,18 @@ static int sha224_file_wrap( const char *path, unsigned char *output ) #else ((void) path); ((void) output); - return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); #endif } -static void sha224_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen ) +static void sha224_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) { sha256_hmac_starts( (sha256_context *) ctx, key, keylen, 1 ); } -static void sha224_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen ) +static void sha224_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) { sha256_hmac_update( (sha256_context *) ctx, input, ilen ); } @@ -475,6 +611,7 @@ static void * sha224_ctx_alloc( void ) static void sha224_ctx_free( void *ctx ) { + polarssl_zeroize( ctx, sizeof( sha256_context ) ); polarssl_free( ctx ); } @@ -507,7 +644,8 @@ static void sha256_starts_wrap( void *ctx ) sha256_starts( (sha256_context *) ctx, 0 ); } -static void sha256_update_wrap( void *ctx, const unsigned char *input, size_t ilen ) +static void sha256_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) { sha256_update( (sha256_context *) ctx, input, ilen ); } @@ -530,16 +668,18 @@ static int sha256_file_wrap( const char *path, unsigned char *output ) #else ((void) path); ((void) output); - return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); #endif } -static void sha256_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen ) +static void sha256_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) { sha256_hmac_starts( (sha256_context *) ctx, key, keylen, 0 ); } -static void sha256_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen ) +static void sha256_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) { sha256_hmac_update( (sha256_context *) ctx, input, ilen ); } @@ -563,11 +703,20 @@ static void sha256_hmac_wrap( const unsigned char *key, size_t keylen, static void * sha256_ctx_alloc( void ) { - return polarssl_malloc( sizeof( sha256_context ) ); + sha256_context *ctx; + ctx = (sha256_context *) polarssl_malloc( sizeof( sha256_context ) ); + + if( ctx == NULL ) + return( NULL ); + + sha256_init( ctx ); + + return( ctx ); } static void sha256_ctx_free( void *ctx ) { + sha256_free( (sha256_context *) ctx ); polarssl_free( ctx ); } @@ -595,7 +744,7 @@ const md_info_t sha256_info = { sha256_process_wrap, }; -#endif +#endif /* POLARSSL_SHA256_C */ #if defined(POLARSSL_SHA512_C) @@ -604,7 +753,8 @@ static void sha384_starts_wrap( void *ctx ) sha512_starts( (sha512_context *) ctx, 1 ); } -static void sha384_update_wrap( void *ctx, const unsigned char *input, size_t ilen ) +static void sha384_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) { sha512_update( (sha512_context *) ctx, input, ilen ); } @@ -627,16 +777,18 @@ static int sha384_file_wrap( const char *path, unsigned char *output ) #else ((void) path); ((void) output); - return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); #endif } -static void sha384_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen ) +static void sha384_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) { sha512_hmac_starts( (sha512_context *) ctx, key, keylen, 1 ); } -static void sha384_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen ) +static void sha384_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) { sha512_hmac_update( (sha512_context *) ctx, input, ilen ); } @@ -665,6 +817,7 @@ static void * sha384_ctx_alloc( void ) static void sha384_ctx_free( void *ctx ) { + polarssl_zeroize( ctx, sizeof( sha512_context ) ); polarssl_free( ctx ); } @@ -697,7 +850,8 @@ static void sha512_starts_wrap( void *ctx ) sha512_starts( (sha512_context *) ctx, 0 ); } -static void sha512_update_wrap( void *ctx, const unsigned char *input, size_t ilen ) +static void sha512_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) { sha512_update( (sha512_context *) ctx, input, ilen ); } @@ -720,16 +874,18 @@ static int sha512_file_wrap( const char *path, unsigned char *output ) #else ((void) path); ((void) output); - return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE; + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); #endif } -static void sha512_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen ) +static void sha512_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) { sha512_hmac_starts( (sha512_context *) ctx, key, keylen, 0 ); } -static void sha512_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen ) +static void sha512_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) { sha512_hmac_update( (sha512_context *) ctx, input, ilen ); } @@ -753,11 +909,20 @@ static void sha512_hmac_wrap( const unsigned char *key, size_t keylen, static void * sha512_ctx_alloc( void ) { - return polarssl_malloc( sizeof( sha512_context ) ); + sha512_context *ctx; + ctx = (sha512_context *) polarssl_malloc( sizeof( sha512_context ) ); + + if( ctx == NULL ) + return( NULL ); + + sha512_init( ctx ); + + return( ctx ); } static void sha512_ctx_free( void *ctx ) { + sha512_free( (sha512_context *) ctx ); polarssl_free( ctx ); } @@ -785,6 +950,6 @@ const md_info_t sha512_info = { sha512_process_wrap, }; -#endif +#endif /* POLARSSL_SHA512_C */ -#endif +#endif /* POLARSSL_MD_C */ diff --git a/pdns/ext/polarssl/library/memory_buffer_alloc.c b/pdns/ext/polarssl/library/memory_buffer_alloc.c index 7ec6498de..7710ba52b 100644 --- a/pdns/ext/polarssl/library/memory_buffer_alloc.c +++ b/pdns/ext/polarssl/library/memory_buffer_alloc.c @@ -1,7 +1,7 @@ /* * Buffer-based memory allocator * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,11 +23,15 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif -#if defined(POLARSSL_MEMORY_C) && defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) +#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) -#include "polarssl/memory.h" +#include "polarssl/memory_buffer_alloc.h" #include @@ -42,6 +46,17 @@ #include "polarssl/threading.h" #endif +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_fprintf fprintf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + #define MAGIC1 0xFF00AA55 #define MAGIC2 0xEE119966 #define MAX_BT 20 @@ -77,6 +92,7 @@ typedef struct size_t total_used; size_t maximum_used; size_t header_count; + size_t maximum_header_count; #endif #if defined(POLARSSL_THREADING_C) threading_mutex_t mutex; @@ -93,17 +109,18 @@ static void debug_header( memory_header *hdr ) size_t i; #endif - fprintf( stderr, "HDR: PTR(%10u), PREV(%10u), NEXT(%10u), ALLOC(%u), SIZE(%10u)\n", - (size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next, - hdr->alloc, hdr->size ); - fprintf( stderr, " FPREV(%10u), FNEXT(%10u)\n", - (size_t) hdr->prev_free, (size_t) hdr->next_free ); + polarssl_fprintf( stderr, "HDR: PTR(%10u), PREV(%10u), NEXT(%10u), " + "ALLOC(%u), SIZE(%10u)\n", + (size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next, + hdr->alloc, hdr->size ); + polarssl_fprintf( stderr, " FPREV(%10u), FNEXT(%10u)\n", + (size_t) hdr->prev_free, (size_t) hdr->next_free ); #if defined(POLARSSL_MEMORY_BACKTRACE) - fprintf( stderr, "TRACE: \n" ); + polarssl_fprintf( stderr, "TRACE: \n" ); for( i = 0; i < hdr->trace_count; i++ ) - fprintf( stderr, "%s\n", hdr->trace[i] ); - fprintf( stderr, "\n" ); + polarssl_fprintf( stderr, "%s\n", hdr->trace[i] ); + polarssl_fprintf( stderr, "\n" ); #endif } @@ -111,14 +128,14 @@ static void debug_chain() { memory_header *cur = heap.first; - fprintf( stderr, "\nBlock list\n" ); + polarssl_fprintf( stderr, "\nBlock list\n" ); while( cur != NULL ) { debug_header( cur ); cur = cur->next; } - fprintf( stderr, "Free list\n" ); + polarssl_fprintf( stderr, "Free list\n" ); cur = heap.first_free; while( cur != NULL ) @@ -134,7 +151,7 @@ static int verify_header( memory_header *hdr ) if( hdr->magic1 != MAGIC1 ) { #if defined(POLARSSL_MEMORY_DEBUG) - fprintf( stderr, "FATAL: MAGIC1 mismatch\n" ); + polarssl_fprintf( stderr, "FATAL: MAGIC1 mismatch\n" ); #endif return( 1 ); } @@ -142,7 +159,7 @@ static int verify_header( memory_header *hdr ) if( hdr->magic2 != MAGIC2 ) { #if defined(POLARSSL_MEMORY_DEBUG) - fprintf( stderr, "FATAL: MAGIC2 mismatch\n" ); + polarssl_fprintf( stderr, "FATAL: MAGIC2 mismatch\n" ); #endif return( 1 ); } @@ -150,7 +167,7 @@ static int verify_header( memory_header *hdr ) if( hdr->alloc > 1 ) { #if defined(POLARSSL_MEMORY_DEBUG) - fprintf( stderr, "FATAL: alloc has illegal value\n" ); + polarssl_fprintf( stderr, "FATAL: alloc has illegal value\n" ); #endif return( 1 ); } @@ -158,7 +175,7 @@ static int verify_header( memory_header *hdr ) if( hdr->prev != NULL && hdr->prev == hdr->next ) { #if defined(POLARSSL_MEMORY_DEBUG) - fprintf( stderr, "FATAL: prev == next\n" ); + polarssl_fprintf( stderr, "FATAL: prev == next\n" ); #endif return( 1 ); } @@ -166,7 +183,7 @@ static int verify_header( memory_header *hdr ) if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free ) { #if defined(POLARSSL_MEMORY_DEBUG) - fprintf( stderr, "FATAL: prev_free == next_free\n" ); + polarssl_fprintf( stderr, "FATAL: prev_free == next_free\n" ); #endif return( 1 ); } @@ -181,7 +198,8 @@ static int verify_chain() if( verify_header( heap.first ) != 0 ) { #if defined(POLARSSL_MEMORY_DEBUG) - fprintf( stderr, "FATAL: verification of first header failed\n" ); + polarssl_fprintf( stderr, "FATAL: verification of first header " + "failed\n" ); #endif return( 1 ); } @@ -189,7 +207,8 @@ static int verify_chain() if( heap.first->prev != NULL ) { #if defined(POLARSSL_MEMORY_DEBUG) - fprintf( stderr, "FATAL: verification failed: first->prev != NULL\n" ); + polarssl_fprintf( stderr, "FATAL: verification failed: " + "first->prev != NULL\n" ); #endif return( 1 ); } @@ -199,7 +218,8 @@ static int verify_chain() if( verify_header( cur ) != 0 ) { #if defined(POLARSSL_MEMORY_DEBUG) - fprintf( stderr, "FATAL: verification of header failed\n" ); + polarssl_fprintf( stderr, "FATAL: verification of header " + "failed\n" ); #endif return( 1 ); } @@ -207,7 +227,8 @@ static int verify_chain() if( cur->prev != prv ) { #if defined(POLARSSL_MEMORY_DEBUG) - fprintf( stderr, "FATAL: verification failed: cur->prev != prv\n" ); + polarssl_fprintf( stderr, "FATAL: verification failed: " + "cur->prev != prv\n" ); #endif return( 1 ); } @@ -253,7 +274,8 @@ static void *buffer_alloc_malloc( size_t len ) if( cur->alloc != 0 ) { #if defined(POLARSSL_MEMORY_DEBUG) - fprintf( stderr, "FATAL: block in free_list but allocated data\n" ); + polarssl_fprintf( stderr, "FATAL: block in free_list but allocated " + "data\n" ); #endif exit( 1 ); } @@ -264,7 +286,8 @@ static void *buffer_alloc_malloc( size_t len ) // Found location, split block if > memory_header + 4 room left // - if( cur->size - len < sizeof(memory_header) + POLARSSL_MEMORY_ALIGN_MULTIPLE ) + if( cur->size - len < sizeof(memory_header) + + POLARSSL_MEMORY_ALIGN_MULTIPLE ) { cur->alloc = 1; @@ -283,7 +306,7 @@ static void *buffer_alloc_malloc( size_t len ) #if defined(POLARSSL_MEMORY_DEBUG) heap.total_used += cur->size; - if( heap.total_used > heap.maximum_used) + if( heap.total_used > heap.maximum_used ) heap.maximum_used = heap.total_used; #endif #if defined(POLARSSL_MEMORY_BACKTRACE) @@ -295,7 +318,7 @@ static void *buffer_alloc_malloc( size_t len ) if( ( heap.verify & MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 ) exit( 1 ); - return ( (unsigned char *) cur ) + sizeof(memory_header); + return( ( (unsigned char *) cur ) + sizeof(memory_header) ); } p = ( (unsigned char *) cur ) + sizeof(memory_header) + len; @@ -335,8 +358,10 @@ static void *buffer_alloc_malloc( size_t len ) #if defined(POLARSSL_MEMORY_DEBUG) heap.header_count++; + if( heap.header_count > heap.maximum_header_count ) + heap.maximum_header_count = heap.header_count; heap.total_used += cur->size; - if( heap.total_used > heap.maximum_used) + if( heap.total_used > heap.maximum_used ) heap.maximum_used = heap.total_used; #endif #if defined(POLARSSL_MEMORY_BACKTRACE) @@ -348,7 +373,7 @@ static void *buffer_alloc_malloc( size_t len ) if( ( heap.verify & MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 ) exit( 1 ); - return ( (unsigned char *) cur ) + sizeof(memory_header); + return( ( (unsigned char *) cur ) + sizeof(memory_header) ); } static void buffer_alloc_free( void *ptr ) @@ -362,7 +387,8 @@ static void buffer_alloc_free( void *ptr ) if( p < heap.buf || p > heap.buf + heap.len ) { #if defined(POLARSSL_MEMORY_DEBUG) - fprintf( stderr, "FATAL: polarssl_free() outside of managed space\n" ); + polarssl_fprintf( stderr, "FATAL: polarssl_free() outside of managed " + "space\n" ); #endif exit( 1 ); } @@ -376,7 +402,8 @@ static void buffer_alloc_free( void *ptr ) if( hdr->alloc != 1 ) { #if defined(POLARSSL_MEMORY_DEBUG) - fprintf( stderr, "FATAL: polarssl_free() on unallocated data\n" ); + polarssl_fprintf( stderr, "FATAL: polarssl_free() on unallocated " + "data\n" ); #endif exit( 1 ); } @@ -483,20 +510,24 @@ int memory_buffer_alloc_verify() #if defined(POLARSSL_MEMORY_DEBUG) void memory_buffer_alloc_status() { - fprintf( stderr, - "Current use: %u blocks / %u bytes, max: %u bytes, malloc / free: %u / %u\n", - heap.header_count, heap.total_used, heap.maximum_used, - heap.malloc_count, heap.free_count ); + polarssl_fprintf( stderr, + "Current use: %u blocks / %u bytes, max: %u blocks / " + "%u bytes (total %u bytes), malloc / free: %u / %u\n", + heap.header_count, heap.total_used, + heap.maximum_header_count, heap.maximum_used, + heap.maximum_header_count * sizeof( memory_header ) + + heap.maximum_used, + heap.malloc_count, heap.free_count ); if( heap.first->next == NULL ) - fprintf( stderr, "All memory de-allocated in stack buffer\n" ); + polarssl_fprintf( stderr, "All memory de-allocated in stack buffer\n" ); else { - fprintf( stderr, "Memory currently allocated:\n" ); + polarssl_fprintf( stderr, "Memory currently allocated:\n" ); debug_chain(); } } -#endif /* POLARSSL_MEMORY_BUFFER_ALLOC_DEBUG */ +#endif /* POLARSSL_MEMORY_DEBUG */ #if defined(POLARSSL_THREADING_C) static void *buffer_alloc_malloc_mutexed( size_t len ) @@ -514,7 +545,7 @@ static void buffer_alloc_free_mutexed( void *ptr ) buffer_alloc_free( ptr ); polarssl_mutex_unlock( &heap.mutex ); } -#endif +#endif /* POLARSSL_THREADING_C */ int memory_buffer_alloc_init( unsigned char *buf, size_t len ) { @@ -523,13 +554,19 @@ int memory_buffer_alloc_init( unsigned char *buf, size_t len ) #if defined(POLARSSL_THREADING_C) polarssl_mutex_init( &heap.mutex ); - polarssl_malloc = buffer_alloc_malloc_mutexed; - polarssl_free = buffer_alloc_free_mutexed; + platform_set_malloc_free( buffer_alloc_malloc_mutexed, + buffer_alloc_free_mutexed ); #else - polarssl_malloc = buffer_alloc_malloc; - polarssl_free = buffer_alloc_free; + platform_set_malloc_free( buffer_alloc_malloc, buffer_alloc_free ); #endif + if( (size_t) buf % POLARSSL_MEMORY_ALIGN_MULTIPLE ) + { + buf += POLARSSL_MEMORY_ALIGN_MULTIPLE + - (size_t) buf % POLARSSL_MEMORY_ALIGN_MULTIPLE; + len -= (size_t) buf % POLARSSL_MEMORY_ALIGN_MULTIPLE; + } + heap.buf = buf; heap.len = len; @@ -546,7 +583,7 @@ void memory_buffer_alloc_free() #if defined(POLARSSL_THREADING_C) polarssl_mutex_free( &heap.mutex ); #endif - memset( &heap, 0, sizeof(buffer_alloc_ctx) ); + polarssl_zeroize( &heap, sizeof(buffer_alloc_ctx) ); } -#endif /* POLARSSL_MEMORY_C && POLARSSL_MEMORY_BUFFER_ALLOC_C */ +#endif /* POLARSSL_MEMORY_BUFFER_ALLOC_C */ diff --git a/pdns/ext/polarssl/library/net.c b/pdns/ext/polarssl/library/net.c index be2785d98..ad4b8921c 100644 --- a/pdns/ext/polarssl/library/net.c +++ b/pdns/ext/polarssl/library/net.c @@ -1,7 +1,7 @@ /* * TCP networking functions * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,7 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_NET_C) @@ -32,14 +36,25 @@ #if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ !defined(EFI32) +#if defined(POLARSSL_HAVE_IPV6) +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +/* Enables getaddrinfo() & Co */ +#define _WIN32_WINNT 0x0501 +#include +#endif + #include #include +#if defined(_MSC_VER) #if defined(_WIN32_WCE) #pragma comment( lib, "ws2.lib" ) #else #pragma comment( lib, "ws2_32.lib" ) #endif +#endif /* _MSC_VER */ #define read(fd,buf,len) recv(fd,(char*)buf,(int) len,0) #define write(fd,buf,len) send(fd,(char*)buf,(int) len,0) @@ -47,7 +62,7 @@ static int wsa_init_done = 0; -#else +#else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ #include #include @@ -63,7 +78,7 @@ static int wsa_init_done = 0; #include #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \ - defined(__DragonflyBSD__) + defined(__DragonFly__) #include #elif defined(__APPLE__) || defined(HAVE_MACHINE_ENDIAN_H) || \ defined(EFIX64) || defined(EFI32) @@ -76,11 +91,16 @@ static int wsa_init_done = 0; #include #endif -#endif +#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ #include #include +#if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \ + !defined(EFI32) +#define snprintf _snprintf +#endif + #if defined(POLARSSL_HAVE_TIME) #include #endif @@ -94,10 +114,11 @@ typedef UINT32 uint32_t; /* * htons() is not always available. - * By default go for LITTLE_ENDIAN variant. Otherwise hope for _BYTE_ORDER and __BIG_ENDIAN - * to help determine endianness. + * By default go for LITTLE_ENDIAN variant. Otherwise hope for _BYTE_ORDER and + * __BIG_ENDIAN to help determine endianness. */ -#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN +#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ + __BYTE_ORDER == __BIG_ENDIAN #define POLARSSL_HTONS(n) (n) #define POLARSSL_HTONL(n) (n) #else @@ -109,27 +130,23 @@ typedef UINT32 uint32_t; (((unsigned long )(n) & 0xFF000000) >> 24)) #endif -unsigned short net_htons(unsigned short n); -unsigned long net_htonl(unsigned long n); +unsigned short net_htons( unsigned short n ); +unsigned long net_htonl( unsigned long n ); #define net_htons(n) POLARSSL_HTONS(n) #define net_htonl(n) POLARSSL_HTONL(n) /* - * Initiate a TCP connection with host:port + * Prepare for using the sockets interface */ -int net_connect( int *fd, const char *host, int port ) +static int net_prepare( void ) { - struct sockaddr_in server_addr; - struct hostent *server_host; - #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ !defined(EFI32) - WSADATA wsaData; if( wsa_init_done == 0 ) { - if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR ) + if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 ) return( POLARSSL_ERR_NET_SOCKET_FAILED ); wsa_init_done = 1; @@ -139,6 +156,70 @@ int net_connect( int *fd, const char *host, int port ) signal( SIGPIPE, SIG_IGN ); #endif #endif + return( 0 ); +} + +/* + * Initiate a TCP connection with host:port + */ +int net_connect( int *fd, const char *host, int port ) +{ +#if defined(POLARSSL_HAVE_IPV6) + int ret; + struct addrinfo hints, *addr_list, *cur; + char port_str[6]; + + if( ( ret = net_prepare() ) != 0 ) + return( ret ); + + /* getaddrinfo expects port as a string */ + memset( port_str, 0, sizeof( port_str ) ); + snprintf( port_str, sizeof( port_str ), "%d", port ); + + /* Do name resolution with both IPv6 and IPv4, but only TCP */ + memset( &hints, 0, sizeof( hints ) ); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + if( getaddrinfo( host, port_str, &hints, &addr_list ) != 0 ) + return( POLARSSL_ERR_NET_UNKNOWN_HOST ); + + /* Try the sockaddrs until a connection succeeds */ + ret = POLARSSL_ERR_NET_UNKNOWN_HOST; + for( cur = addr_list; cur != NULL; cur = cur->ai_next ) + { + *fd = (int) socket( cur->ai_family, cur->ai_socktype, + cur->ai_protocol ); + if( *fd < 0 ) + { + ret = POLARSSL_ERR_NET_SOCKET_FAILED; + continue; + } + + if( connect( *fd, cur->ai_addr, cur->ai_addrlen ) == 0 ) + { + ret = 0; + break; + } + + close( *fd ); + ret = POLARSSL_ERR_NET_CONNECT_FAILED; + } + + freeaddrinfo( addr_list ); + + return( ret ); + +#else + /* Legacy IPv4-only version */ + + int ret; + struct sockaddr_in server_addr; + struct hostent *server_host; + + if( ( ret = net_prepare() ) != 0 ) + return( ret ); if( ( server_host = gethostbyname( host ) ) == NULL ) return( POLARSSL_ERR_NET_UNKNOWN_HOST ); @@ -161,6 +242,7 @@ int net_connect( int *fd, const char *host, int port ) } return( 0 ); +#endif /* POLARSSL_HAVE_IPV6 */ } /* @@ -168,25 +250,81 @@ int net_connect( int *fd, const char *host, int port ) */ int net_bind( int *fd, const char *bind_ip, int port ) { - int n, c[4]; - struct sockaddr_in server_addr; - -#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ - !defined(EFI32) - WSADATA wsaData; +#if defined(POLARSSL_HAVE_IPV6) + int n, ret; + struct addrinfo hints, *addr_list, *cur; + char port_str[6]; + + if( ( ret = net_prepare() ) != 0 ) + return( ret ); + + /* getaddrinfo expects port as a string */ + memset( port_str, 0, sizeof( port_str ) ); + snprintf( port_str, sizeof( port_str ), "%d", port ); + + /* Bind to IPv6 and/or IPv4, but only in TCP */ + memset( &hints, 0, sizeof( hints ) ); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + if( bind_ip == NULL ) + hints.ai_flags = AI_PASSIVE; + + if( getaddrinfo( bind_ip, port_str, &hints, &addr_list ) != 0 ) + return( POLARSSL_ERR_NET_UNKNOWN_HOST ); - if( wsa_init_done == 0 ) + /* Try the sockaddrs until a binding succeeds */ + ret = POLARSSL_ERR_NET_UNKNOWN_HOST; + for( cur = addr_list; cur != NULL; cur = cur->ai_next ) { - if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR ) - return( POLARSSL_ERR_NET_SOCKET_FAILED ); - - wsa_init_done = 1; + *fd = (int) socket( cur->ai_family, cur->ai_socktype, + cur->ai_protocol ); + if( *fd < 0 ) + { + ret = POLARSSL_ERR_NET_SOCKET_FAILED; + continue; + } + + n = 1; + if( setsockopt( *fd, SOL_SOCKET, SO_REUSEADDR, + (const char *) &n, sizeof( n ) ) != 0 ) + { + close( *fd ); + ret = POLARSSL_ERR_NET_SOCKET_FAILED; + continue; + } + + if( bind( *fd, cur->ai_addr, cur->ai_addrlen ) != 0 ) + { + close( *fd ); + ret = POLARSSL_ERR_NET_BIND_FAILED; + continue; + } + + if( listen( *fd, POLARSSL_NET_LISTEN_BACKLOG ) != 0 ) + { + close( *fd ); + ret = POLARSSL_ERR_NET_LISTEN_FAILED; + continue; + } + + /* I we ever get there, it's a success */ + ret = 0; + break; } + + freeaddrinfo( addr_list ); + + return( ret ); + #else -#if !defined(EFIX64) && !defined(EFI32) - signal( SIGPIPE, SIG_IGN ); -#endif -#endif + /* Legacy IPv4-only version */ + + int ret, n, c[4]; + struct sockaddr_in server_addr; + + if( ( ret = net_prepare() ) != 0 ) + return( ret ); if( ( *fd = (int) socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 ) return( POLARSSL_ERR_NET_SOCKET_FAILED ); @@ -230,17 +368,35 @@ int net_bind( int *fd, const char *bind_ip, int port ) } return( 0 ); +#endif /* POLARSSL_HAVE_IPV6 */ } +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) /* - * Check if the current operation is blocking + * Check if the requested operation would be blocking on a non-blocking socket + * and thus 'failed' with a negative return value. */ -static int net_is_blocking( void ) +static int net_would_block( int fd ) { -#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ - !defined(EFI32) + ((void) fd); return( WSAGetLastError() == WSAEWOULDBLOCK ); +} #else +/* + * Check if the requested operation would be blocking on a non-blocking socket + * and thus 'failed' with a negative return value. + * + * Note: on a blocking socket this function always returns 0! + */ +static int net_would_block( int fd ) +{ + /* + * Never return 'WOULD BLOCK' on a non-blocking socket + */ + if( ( fcntl( fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK ) + return( 0 ); + switch( errno ) { #if defined EAGAIN @@ -252,15 +408,19 @@ static int net_is_blocking( void ) return( 1 ); } return( 0 ); -#endif } +#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ /* * Accept a connection from a remote client */ int net_accept( int bind_fd, int *client_fd, void *client_ip ) { +#if defined(POLARSSL_HAVE_IPV6) + struct sockaddr_storage client_addr; +#else struct sockaddr_in client_addr; +#endif #if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \ defined(_SOCKLEN_T_DECLARED) @@ -274,15 +434,32 @@ int net_accept( int bind_fd, int *client_fd, void *client_ip ) if( *client_fd < 0 ) { - if( net_is_blocking() != 0 ) + if( net_would_block( *client_fd ) != 0 ) return( POLARSSL_ERR_NET_WANT_READ ); return( POLARSSL_ERR_NET_ACCEPT_FAILED ); } if( client_ip != NULL ) + { +#if defined(POLARSSL_HAVE_IPV6) + if( client_addr.ss_family == AF_INET ) + { + struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr; + memcpy( client_ip, &addr4->sin_addr.s_addr, + sizeof( addr4->sin_addr.s_addr ) ); + } + else + { + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr; + memcpy( client_ip, &addr6->sin6_addr.s6_addr, + sizeof( addr6->sin6_addr.s6_addr ) ); + } +#else memcpy( client_ip, &client_addr.sin_addr.s_addr, sizeof( client_addr.sin_addr.s_addr ) ); +#endif /* POLARSSL_HAVE_IPV6 */ + } return( 0 ); } @@ -330,11 +507,12 @@ void net_usleep( unsigned long usec ) */ int net_recv( void *ctx, unsigned char *buf, size_t len ) { - int ret = read( *((int *) ctx), buf, len ); + int fd = *((int *) ctx); + int ret = read( fd, buf, len ); if( ret < 0 ) { - if( net_is_blocking() != 0 ) + if( net_would_block( fd ) != 0 ) return( POLARSSL_ERR_NET_WANT_READ ); #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ @@ -360,11 +538,12 @@ int net_recv( void *ctx, unsigned char *buf, size_t len ) */ int net_send( void *ctx, const unsigned char *buf, size_t len ) { - int ret = write( *((int *) ctx), buf, len ); + int fd = *((int *) ctx); + int ret = write( fd, buf, len ); if( ret < 0 ) { - if( net_is_blocking() != 0 ) + if( net_would_block( fd ) != 0 ) return( POLARSSL_ERR_NET_WANT_WRITE ); #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ @@ -394,4 +573,4 @@ void net_close( int fd ) close( fd ); } -#endif +#endif /* POLARSSL_NET_C */ diff --git a/pdns/ext/polarssl/library/oid.c b/pdns/ext/polarssl/library/oid.c index b0b551dea..7b54054de 100644 --- a/pdns/ext/polarssl/library/oid.c +++ b/pdns/ext/polarssl/library/oid.c @@ -3,7 +3,7 @@ * * \brief Object Identifier (OID) database * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -25,7 +25,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_OID_C) @@ -72,7 +76,7 @@ static const TYPE_T * oid_ ## NAME ## _from_asn1( const asn1_buf *oid ) \ int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \ { \ const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ - if( data == NULL ) return ( POLARSSL_ERR_OID_NOT_FOUND ); \ + if( data == NULL ) return( POLARSSL_ERR_OID_NOT_FOUND ); \ *ATTR1 = data->descriptor.ATTR1; \ return( 0 ); \ } @@ -85,7 +89,7 @@ int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \ int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \ { \ const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ - if( data == NULL ) return ( POLARSSL_ERR_OID_NOT_FOUND ); \ + if( data == NULL ) return( POLARSSL_ERR_OID_NOT_FOUND ); \ *ATTR1 = data->ATTR1; \ return( 0 ); \ } @@ -99,7 +103,7 @@ int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \ int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1, ATTR2_TYPE * ATTR2 ) \ { \ const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ - if( data == NULL ) return ( POLARSSL_ERR_OID_NOT_FOUND ); \ + if( data == NULL ) return( POLARSSL_ERR_OID_NOT_FOUND ); \ *ATTR1 = data->ATTR1; \ *ATTR2 = data->ATTR2; \ return( 0 ); \ @@ -195,6 +199,38 @@ static const oid_x520_attr_t oid_x520_attr_type[] = { ADD_LEN( OID_AT_POSTAL_CODE ), "id-at-postalCode", "Postal code" }, "postalCode", }, + { + { ADD_LEN( OID_AT_SUR_NAME ), "id-at-surName", "Surname" }, + "SN", + }, + { + { ADD_LEN( OID_AT_GIVEN_NAME ), "id-at-givenName", "Given name" }, + "GN", + }, + { + { ADD_LEN( OID_AT_INITIALS ), "id-at-initials", "Initials" }, + "initials", + }, + { + { ADD_LEN( OID_AT_GENERATION_QUALIFIER ), "id-at-generationQualifier", "Generation qualifier" }, + "generationQualifier", + }, + { + { ADD_LEN( OID_AT_TITLE ), "id-at-title", "Title" }, + "title", + }, + { + { ADD_LEN( OID_AT_DN_QUALIFIER ),"id-at-dnQualifier", "Distinguished Name qualifier" }, + "dnQualifier", + }, + { + { ADD_LEN( OID_AT_PSEUDONYM ), "id-at-pseudonym", "Pseudonym" }, + "pseudonym", + }, + { + { ADD_LEN( OID_DOMAIN_COMPONENT ), "id-domainComponent", "Domain component" }, + "DC", + }, { { NULL, 0, NULL, NULL }, NULL, @@ -327,6 +363,10 @@ static const oid_sig_alg_t oid_sig_alg[] = { ADD_LEN( OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" }, POLARSSL_MD_SHA512, POLARSSL_PK_ECDSA, }, + { + { ADD_LEN( OID_RSASSA_PSS ), "RSASSA-PSS", "RSASSA-PSS" }, + POLARSSL_MD_NONE, POLARSSL_PK_RSASSA_PSS, + }, { { NULL, 0, NULL, NULL }, 0, 0, @@ -402,6 +442,18 @@ static const oid_ecp_grp_t oid_ecp_grp[] = { ADD_LEN( OID_EC_GRP_SECP521R1 ), "secp521r1", "secp521r1" }, POLARSSL_ECP_DP_SECP521R1, }, + { + { ADD_LEN( OID_EC_GRP_SECP192K1 ), "secp192k1", "secp192k1" }, + POLARSSL_ECP_DP_SECP192K1, + }, + { + { ADD_LEN( OID_EC_GRP_SECP224K1 ), "secp224k1", "secp224k1" }, + POLARSSL_ECP_DP_SECP224K1, + }, + { + { ADD_LEN( OID_EC_GRP_SECP256K1 ), "secp256k1", "secp256k1" }, + POLARSSL_ECP_DP_SECP256K1, + }, { { ADD_LEN( OID_EC_GRP_BP256R1 ), "brainpoolP256r1","brainpool256r1" }, POLARSSL_ECP_DP_BP256R1, @@ -481,10 +533,6 @@ static const oid_md_alg_t oid_md_alg[] = { ADD_LEN( OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" }, POLARSSL_MD_SHA1, }, - { - { ADD_LEN( OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" }, - POLARSSL_MD_SHA1, - }, { { ADD_LEN( OID_DIGEST_ALG_SHA224 ), "id-sha224", "SHA-224" }, POLARSSL_MD_SHA224, @@ -557,7 +605,7 @@ FN_OID_GET_ATTR2(oid_get_pkcs12_pbe_alg, oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, m * This fuction tries to 'fix' this by at least suggesting enlarging the * size by 20. */ -static int compat_snprintf(char *str, size_t size, const char *format, ...) +static int compat_snprintf( char *str, size_t size, const char *format, ... ) { va_list ap; int res = -1; @@ -569,29 +617,27 @@ static int compat_snprintf(char *str, size_t size, const char *format, ...) va_end( ap ); // No quick fix possible - if ( res < 0 ) + if( res < 0 ) return( (int) size + 20 ); - return res; + return( res ); } #define snprintf compat_snprintf -#endif - -#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2 - -#define SAFE_SNPRINTF() \ -{ \ - if( ret == -1 ) \ - return( -1 ); \ - \ - if ( (unsigned int) ret > n ) { \ - p[n - 1] = '\0'; \ - return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\ - } \ - \ - n -= (unsigned int) ret; \ - p += (unsigned int) ret; \ +#endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */ + +#define SAFE_SNPRINTF() \ +{ \ + if( ret == -1 ) \ + return( POLARSSL_ERR_OID_BUF_TOO_SMALL ); \ + \ + if( (unsigned int) ret >= n ) { \ + p[n - 1] = '\0'; \ + return( POLARSSL_ERR_OID_BUF_TOO_SMALL ); \ + } \ + \ + n -= (unsigned int) ret; \ + p += (unsigned int) ret; \ } /* Return the x.y.z.... style numeric string for the given OID */ @@ -617,8 +663,8 @@ int oid_get_numeric_string( char *buf, size_t size, for( i = 1; i < oid->len; i++ ) { /* Prevent overflow in value. */ - if ( ( ( value << 7 ) >> 7 ) != value ) - return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); + if( ( ( value << 7 ) >> 7 ) != value ) + return( POLARSSL_ERR_OID_BUF_TOO_SMALL ); value <<= 7; value += oid->p[i] & 0x7F; diff --git a/pdns/ext/polarssl/library/padlock.c b/pdns/ext/polarssl/library/padlock.c index a7b4c0c77..5d06390ca 100644 --- a/pdns/ext/polarssl/library/padlock.c +++ b/pdns/ext/polarssl/library/padlock.c @@ -1,7 +1,7 @@ /* * VIA PadLock support functions * - * Copyright (C) 2006-2010, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -29,7 +29,11 @@ * programming_guide.pdf */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_PADLOCK_C) @@ -43,21 +47,21 @@ int padlock_supports( int feature ) { static int flags = -1; - int ebx, edx; + int ebx = 0, edx = 0; if( flags == -1 ) { - asm( "movl %%ebx, %0 \n" \ - "movl $0xC0000000, %%eax \n" \ - "cpuid \n" \ - "cmpl $0xC0000001, %%eax \n" \ - "movl $0, %%edx \n" \ - "jb unsupported \n" \ - "movl $0xC0000001, %%eax \n" \ - "cpuid \n" \ - "unsupported: \n" \ - "movl %%edx, %1 \n" \ - "movl %2, %%ebx \n" + asm( "movl %%ebx, %0 \n\t" + "movl $0xC0000000, %%eax \n\t" + "cpuid \n\t" + "cmpl $0xC0000001, %%eax \n\t" + "movl $0, %%edx \n\t" + "jb unsupported \n\t" + "movl $0xC0000001, %%eax \n\t" + "cpuid \n\t" + "unsupported: \n\t" + "movl %%edx, %1 \n\t" + "movl %2, %%ebx \n\t" : "=m" (ebx), "=m" (edx) : "m" (ebx) : "eax", "ecx", "edx" ); @@ -76,7 +80,7 @@ int padlock_xcryptecb( aes_context *ctx, const unsigned char input[16], unsigned char output[16] ) { - int ebx; + int ebx = 0; uint32_t *rk; uint32_t *blk; uint32_t *ctrl; @@ -89,15 +93,16 @@ int padlock_xcryptecb( aes_context *ctx, ctrl = blk + 4; *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 ); - asm( "pushfl; popfl \n" \ - "movl %%ebx, %0 \n" \ - "movl $1, %%ecx \n" \ - "movl %2, %%edx \n" \ - "movl %3, %%ebx \n" \ - "movl %4, %%esi \n" \ - "movl %4, %%edi \n" \ - ".byte 0xf3,0x0f,0xa7,0xc8\n" \ - "movl %1, %%ebx \n" + asm( "pushfl \n\t" + "popfl \n\t" + "movl %%ebx, %0 \n\t" + "movl $1, %%ecx \n\t" + "movl %2, %%edx \n\t" + "movl %3, %%ebx \n\t" + "movl %4, %%esi \n\t" + "movl %4, %%edi \n\t" + ".byte 0xf3,0x0f,0xa7,0xc8 \n\t" + "movl %1, %%ebx \n\t" : "=m" (ebx) : "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk) : "ecx", "edx", "esi", "edi" ); @@ -117,7 +122,7 @@ int padlock_xcryptcbc( aes_context *ctx, const unsigned char *input, unsigned char *output ) { - int ebx; + int ebx = 0; size_t count; uint32_t *rk; uint32_t *iw; @@ -133,20 +138,21 @@ int padlock_xcryptcbc( aes_context *ctx, memcpy( iw, iv, 16 ); ctrl = iw + 4; - *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + (mode^1) - 10 ) << 9 ); - - count = (length + 15) >> 4; - - asm( "pushfl; popfl \n" \ - "movl %%ebx, %0 \n" \ - "movl %2, %%ecx \n" \ - "movl %3, %%edx \n" \ - "movl %4, %%ebx \n" \ - "movl %5, %%esi \n" \ - "movl %6, %%edi \n" \ - "movl %7, %%eax \n" \ - ".byte 0xf3,0x0f,0xa7,0xd0\n" \ - "movl %1, %%ebx \n" + *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode ^ 1 ) - 10 ) << 9 ); + + count = ( length + 15 ) >> 4; + + asm( "pushfl \n\t" + "popfl \n\t" + "movl %%ebx, %0 \n\t" + "movl %2, %%ecx \n\t" + "movl %3, %%edx \n\t" + "movl %4, %%ebx \n\t" + "movl %5, %%esi \n\t" + "movl %6, %%edi \n\t" + "movl %7, %%eax \n\t" + ".byte 0xf3,0x0f,0xa7,0xd0 \n\t" + "movl %1, %%ebx \n\t" : "=m" (ebx) : "m" (ebx), "m" (count), "m" (ctrl), "m" (rk), "m" (input), "m" (output), "m" (iw) @@ -157,6 +163,6 @@ int padlock_xcryptcbc( aes_context *ctx, return( 0 ); } -#endif +#endif /* POLARSSL_HAVE_X86 */ -#endif +#endif /* POLARSSL_PADLOCK_C */ diff --git a/pdns/ext/polarssl/library/pbkdf2.c b/pdns/ext/polarssl/library/pbkdf2.c index 09e56dfa3..e76f06642 100644 --- a/pdns/ext/polarssl/library/pbkdf2.c +++ b/pdns/ext/polarssl/library/pbkdf2.c @@ -6,7 +6,7 @@ * * \author Mathias Olsson * - * Copyright (C) 2006-2012, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -34,7 +34,11 @@ * http://tools.ietf.org/html/rfc6070 (Test vectors) */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_PBKDF2_C) diff --git a/pdns/ext/polarssl/library/pem.c b/pdns/ext/polarssl/library/pem.c index d602d8aa2..485d829c0 100644 --- a/pdns/ext/polarssl/library/pem.c +++ b/pdns/ext/polarssl/library/pem.c @@ -1,7 +1,7 @@ /* * Privacy Enhanced Mail (PEM) decoding * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,7 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_PEM_PARSE_C) || defined(POLARSSL_PEM_WRITE_C) #include "polarssl/pem.h" @@ -33,8 +37,8 @@ #include "polarssl/md5.h" #include "polarssl/cipher.h" -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else #define polarssl_malloc malloc #define polarssl_free free @@ -42,6 +46,11 @@ #include +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + #if defined(POLARSSL_PEM_PARSE_C) void pem_init( pem_context *ctx ) { @@ -53,7 +62,8 @@ void pem_init( pem_context *ctx ) /* * Read a 16-byte hex string and convert it to binary */ -static int pem_get_iv( const unsigned char *s, unsigned char *iv, size_t iv_len ) +static int pem_get_iv( const unsigned char *s, unsigned char *iv, + size_t iv_len ) { size_t i, j, k; @@ -82,6 +92,8 @@ static void pem_pbkdf1( unsigned char *key, size_t keylen, unsigned char md5sum[16]; size_t use_len; + md5_init( &md5_ctx ); + /* * key[ 0..15] = MD5(pwd || IV) */ @@ -94,8 +106,8 @@ static void pem_pbkdf1( unsigned char *key, size_t keylen, { memcpy( key, md5sum, keylen ); - memset( &md5_ctx, 0, sizeof( md5_ctx ) ); - memset( md5sum, 0, 16 ); + md5_free( &md5_ctx ); + polarssl_zeroize( md5sum, 16 ); return; } @@ -116,8 +128,8 @@ static void pem_pbkdf1( unsigned char *key, size_t keylen, memcpy( key + 16, md5sum, use_len ); - memset( &md5_ctx, 0, sizeof( md5_ctx ) ); - memset( md5sum, 0, 16 ); + md5_free( &md5_ctx ); + polarssl_zeroize( md5sum, 16 ); } #if defined(POLARSSL_DES_C) @@ -131,14 +143,16 @@ static void pem_des_decrypt( unsigned char des_iv[8], des_context des_ctx; unsigned char des_key[8]; + des_init( &des_ctx ); + pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen ); des_setkey_dec( &des_ctx, des_key ); des_crypt_cbc( &des_ctx, DES_DECRYPT, buflen, des_iv, buf, buf ); - memset( &des_ctx, 0, sizeof( des_ctx ) ); - memset( des_key, 0, 8 ); + des_free( &des_ctx ); + polarssl_zeroize( des_key, 8 ); } /* @@ -151,14 +165,16 @@ static void pem_des3_decrypt( unsigned char des3_iv[8], des3_context des3_ctx; unsigned char des3_key[24]; + des3_init( &des3_ctx ); + pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen ); des3_set3key_dec( &des3_ctx, des3_key ); des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen, des3_iv, buf, buf ); - memset( &des3_ctx, 0, sizeof( des3_ctx ) ); - memset( des3_key, 0, 24 ); + des3_free( &des3_ctx ); + polarssl_zeroize( des3_key, 24 ); } #endif /* POLARSSL_DES_C */ @@ -173,14 +189,16 @@ static void pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen, aes_context aes_ctx; unsigned char aes_key[32]; + aes_init( &aes_ctx ); + pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen ); aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 ); aes_crypt_cbc( &aes_ctx, AES_DECRYPT, buflen, aes_iv, buf, buf ); - memset( &aes_ctx, 0, sizeof( aes_ctx ) ); - memset( aes_key, 0, keylen ); + aes_free( &aes_ctx ); + polarssl_zeroize( aes_key, keylen ); } #endif /* POLARSSL_AES_C */ @@ -365,13 +383,10 @@ int pem_read_buffer( pem_context *ctx, const char *header, const char *footer, void pem_free( pem_context *ctx ) { - if( ctx->buf ) - polarssl_free( ctx->buf ); - - if( ctx->info ) - polarssl_free( ctx->info ); + polarssl_free( ctx->buf ); + polarssl_free( ctx->info ); - memset( ctx, 0, sizeof( pem_context ) ); + polarssl_zeroize( ctx, sizeof( pem_context ) ); } #endif /* POLARSSL_PEM_PARSE_C */ @@ -382,10 +397,11 @@ int pem_write_buffer( const char *header, const char *footer, { int ret; unsigned char *encode_buf, *c, *p = buf; - size_t len = 0, use_len = 0; - size_t add_len = strlen( header ) + strlen( footer ) + ( use_len / 64 ) + 1; + size_t len = 0, use_len = 0, add_len = 0; base64_encode( NULL, &use_len, der_data, der_len ); + add_len = strlen( header ) + strlen( footer ) + ( use_len / 64 ) + 1; + if( use_len + add_len > buf_len ) { *olen = use_len + add_len; diff --git a/pdns/ext/polarssl/library/pk.c b/pdns/ext/polarssl/library/pk.c index 80eccc911..11faf3c8d 100644 --- a/pdns/ext/polarssl/library/pk.c +++ b/pdns/ext/polarssl/library/pk.c @@ -1,7 +1,7 @@ /* * Public Key abstraction layer * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,7 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_PK_C) @@ -40,6 +44,11 @@ #include "polarssl/ecdsa.h" #endif +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + /* * Initialise a pk_context */ @@ -57,13 +66,12 @@ void pk_init( pk_context *ctx ) */ void pk_free( pk_context *ctx ) { - if( ctx == NULL || ctx->pk_info == NULL) + if( ctx == NULL || ctx->pk_info == NULL ) return; ctx->pk_info->ctx_free_func( ctx->pk_ctx ); - ctx->pk_ctx = NULL; - ctx->pk_info = NULL; + polarssl_zeroize( ctx, sizeof( pk_context ) ); } /* @@ -74,21 +82,21 @@ const pk_info_t * pk_info_from_type( pk_type_t pk_type ) switch( pk_type ) { #if defined(POLARSSL_RSA_C) case POLARSSL_PK_RSA: - return &rsa_info; + return( &rsa_info ); #endif #if defined(POLARSSL_ECP_C) case POLARSSL_PK_ECKEY: - return &eckey_info; + return( &eckey_info ); case POLARSSL_PK_ECKEY_DH: - return &eckeydh_info; + return( &eckeydh_info ); #endif #if defined(POLARSSL_ECDSA_C) case POLARSSL_PK_ECDSA: - return &ecdsa_info; + return( &ecdsa_info ); #endif - /* POLARSSL_PK_RSA_ALT ommited on purpose */ + /* POLARSSL_PK_RSA_ALT omitted on purpose */ default: - return NULL; + return( NULL ); } } @@ -184,6 +192,59 @@ int pk_verify( pk_context *ctx, md_type_t md_alg, sig, sig_len ) ); } +/* + * Verify a signature with options + */ +int pk_verify_ext( pk_type_t type, const void *options, + pk_context *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ! pk_can_do( ctx, type ) ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + + if( type == POLARSSL_PK_RSASSA_PSS ) + { +#if defined(POLARSSL_RSA_C) && defined(POLARSSL_PKCS1_V21) + int ret; + const pk_rsassa_pss_options *pss_opts; + + if( options == NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + pss_opts = (const pk_rsassa_pss_options *) options; + + if( sig_len < pk_get_len( ctx ) ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + ret = rsa_rsassa_pss_verify_ext( pk_rsa( *ctx ), + NULL, NULL, RSA_PUBLIC, + md_alg, hash_len, hash, + pss_opts->mgf1_hash_id, + pss_opts->expected_salt_len, + sig ); + if( ret != 0 ) + return( ret ); + + if( sig_len > pk_get_len( ctx ) ) + return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH ); + + return( 0 ); +#else + return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); +#endif + } + + /* General case: no options */ + if( options != NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + return( pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) ); +} + /* * Make a signature */ @@ -258,6 +319,9 @@ int pk_debug( const pk_context *ctx, pk_debug_item *items ) if( ctx == NULL || ctx->pk_info == NULL ) return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + if( ctx->pk_info->debug_func == NULL ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + ctx->pk_info->debug_func( ctx->pk_ctx, items ); return( 0 ); } diff --git a/pdns/ext/polarssl/library/pk_wrap.c b/pdns/ext/polarssl/library/pk_wrap.c index 6f22b095f..5e9ff605e 100644 --- a/pdns/ext/polarssl/library/pk_wrap.c +++ b/pdns/ext/polarssl/library/pk_wrap.c @@ -1,7 +1,7 @@ /* * Public Key abstraction layer: wrapper functions * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,7 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_PK_C) @@ -40,35 +44,49 @@ #include "polarssl/ecdsa.h" #endif -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else #include #define polarssl_malloc malloc #define polarssl_free free #endif -/* Used by RSA-alt too */ +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if defined(POLARSSL_RSA_C) static int rsa_can_do( pk_type_t type ) { - return( type == POLARSSL_PK_RSA ); + return( type == POLARSSL_PK_RSA || + type == POLARSSL_PK_RSASSA_PSS ); } -#if defined(POLARSSL_RSA_C) static size_t rsa_get_size( const void *ctx ) { - return( 8 * ((rsa_context *) ctx)->len ); + return( 8 * ((const rsa_context *) ctx)->len ); } static int rsa_verify_wrap( void *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len ) { - if( sig_len != ((rsa_context *) ctx)->len ) + int ret; + + if( sig_len < ((rsa_context *) ctx)->len ) return( POLARSSL_ERR_RSA_VERIFY_FAILED ); - return( rsa_pkcs1_verify( (rsa_context *) ctx, NULL, NULL, - RSA_PUBLIC, md_alg, (unsigned int) hash_len, hash, sig ) ); + if( ( ret = rsa_pkcs1_verify( (rsa_context *) ctx, NULL, NULL, + RSA_PUBLIC, md_alg, + (unsigned int) hash_len, hash, sig ) ) != 0 ) + return( ret ); + + if( sig_len > ((rsa_context *) ctx)->len ) + return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH ); + + return( 0 ); } static int rsa_sign_wrap( void *ctx, md_type_t md_alg, @@ -114,7 +132,7 @@ static void *rsa_alloc_wrap( void ) if( ctx != NULL ) rsa_init( (rsa_context *) ctx, 0, 0 ); - return ctx; + return( ctx ); } static void rsa_free_wrap( void *ctx ) @@ -259,7 +277,7 @@ const pk_info_t eckey_info = { }; /* - * EC key resticted to ECDH + * EC key restricted to ECDH */ static int eckeydh_can_do( pk_type_t type ) { @@ -292,10 +310,16 @@ static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len ) { + int ret; ((void) md_alg); - return( ecdsa_read_signature( (ecdsa_context *) ctx, - hash, hash_len, sig, sig_len ) ); + ret = ecdsa_read_signature( (ecdsa_context *) ctx, + hash, hash_len, sig, sig_len ); + + if( ret == POLARSSL_ERR_ECP_SIG_LEN_MISMATCH ) + return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH ); + + return( ret ); } static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg, @@ -303,10 +327,19 @@ static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg, unsigned char *sig, size_t *sig_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { + /* Use deterministic ECDSA by default if available */ +#if defined(POLARSSL_ECDSA_DETERMINISTIC) + ((void) f_rng); + ((void) p_rng); + + return( ecdsa_write_signature_det( (ecdsa_context *) ctx, + hash, hash_len, sig, sig_len, md_alg ) ); +#else ((void) md_alg); return( ecdsa_write_signature( (ecdsa_context *) ctx, hash, hash_len, sig, sig_len, f_rng, p_rng ) ); +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ } static void *ecdsa_alloc_wrap( void ) @@ -344,11 +377,16 @@ const pk_info_t ecdsa_info = { * Support for alternative RSA-private implementations */ +static int rsa_alt_can_do( pk_type_t type ) +{ + return( type == POLARSSL_PK_RSA ); +} + static size_t rsa_alt_get_size( const void *ctx ) { - rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx; + const rsa_alt_context *rsa_alt = (const rsa_alt_context *) ctx; - return( rsa_alt->key_len_func( rsa_alt->key ) ); + return( 8 * rsa_alt->key_len_func( rsa_alt->key ) ); } static int rsa_alt_sign_wrap( void *ctx, md_type_t md_alg, @@ -388,11 +426,12 @@ static void *rsa_alt_alloc_wrap( void ) if( ctx != NULL ) memset( ctx, 0, sizeof( rsa_alt_context ) ); - return ctx; + return( ctx ); } static void rsa_alt_free_wrap( void *ctx ) { + polarssl_zeroize( ctx, sizeof( rsa_alt_context ) ); polarssl_free( ctx ); } @@ -400,7 +439,7 @@ const pk_info_t rsa_alt_info = { POLARSSL_PK_RSA_ALT, "RSA-alt", rsa_alt_get_size, - rsa_can_do, + rsa_alt_can_do, NULL, rsa_alt_sign_wrap, rsa_alt_decrypt_wrap, diff --git a/pdns/ext/polarssl/library/pkcs11.c b/pdns/ext/polarssl/library/pkcs11.c index 9f68d782a..64e7ce379 100644 --- a/pdns/ext/polarssl/library/pkcs11.c +++ b/pdns/ext/polarssl/library/pkcs11.c @@ -5,7 +5,7 @@ * * \author Adriaan de Jong * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -30,16 +30,18 @@ #include "polarssl/pkcs11.h" #if defined(POLARSSL_PKCS11_C) +#include "polarssl/md.h" +#include "polarssl/oid.h" +#include "polarssl/x509_crt.h" -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else +#include #define polarssl_malloc malloc #define polarssl_free free #endif -#include - int pkcs11_x509_cert_init( x509_crt *cert, pkcs11h_certificate_t pkcs11_cert ) { int ret = 1; @@ -52,7 +54,8 @@ int pkcs11_x509_cert_init( x509_crt *cert, pkcs11h_certificate_t pkcs11_cert ) goto cleanup; } - if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL, &cert_blob_size ) != CKR_OK ) + if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL, + &cert_blob_size ) != CKR_OK ) { ret = 3; goto cleanup; @@ -65,13 +68,14 @@ int pkcs11_x509_cert_init( x509_crt *cert, pkcs11h_certificate_t pkcs11_cert ) goto cleanup; } - if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob, &cert_blob_size ) != CKR_OK ) + if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob, + &cert_blob_size ) != CKR_OK ) { ret = 5; goto cleanup; } - if( 0 != x509_crt_parse(cert, cert_blob, cert_blob_size ) ) + if( 0 != x509_crt_parse( cert, cert_blob, cert_blob_size ) ) { ret = 6; goto cleanup; @@ -83,7 +87,7 @@ cleanup: if( NULL != cert_blob ) polarssl_free( cert_blob ); - return ret; + return( ret ); } @@ -101,7 +105,7 @@ int pkcs11_priv_key_init( pkcs11_context *priv_key, if( 0 != pkcs11_x509_cert_init( &cert, pkcs11_cert ) ) goto cleanup; - priv_key->len = cert.rsa.len; + priv_key->len = pk_get_len( &cert.pk ); priv_key->pkcs11h_cert = pkcs11_cert; ret = 0; @@ -109,7 +113,7 @@ int pkcs11_priv_key_init( pkcs11_context *priv_key, cleanup: x509_crt_free( &cert ); - return ret; + return( ret ); } void pkcs11_priv_key_free( pkcs11_context *priv_key ) @@ -129,7 +133,7 @@ int pkcs11_decrypt( pkcs11_context *ctx, if( NULL == ctx ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); - if( RSA_PUBLIC == mode ) + if( RSA_PRIVATE != mode ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); output_len = input_len = ctx->len; @@ -158,83 +162,70 @@ int pkcs11_decrypt( pkcs11_context *ctx, int pkcs11_sign( pkcs11_context *ctx, int mode, - int hash_id, + md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, unsigned char *sig ) { - size_t olen, asn_len; + size_t sig_len = 0, asn_len = 0, oid_size = 0; unsigned char *p = sig; + const char *oid; if( NULL == ctx ) - return POLARSSL_ERR_RSA_BAD_INPUT_DATA; - - if( RSA_PUBLIC == mode ) - return POLARSSL_ERR_RSA_BAD_INPUT_DATA; + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); - olen = ctx->len; + if( RSA_PRIVATE != mode ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); - switch( hash_id ) + if( md_alg != POLARSSL_MD_NONE ) { - case SIG_RSA_RAW: - asn_len = 0; - memcpy( p, hash, hashlen ); - break; - - case SIG_RSA_MD2: - asn_len = OID_SIZE(ASN1_HASH_MDX); - memcpy( p, ASN1_HASH_MDX, asn_len ); - memcpy( p + asn_len, hash, hashlen ); - p[13] = 2; break; - - case SIG_RSA_MD4: - asn_len = OID_SIZE(ASN1_HASH_MDX); - memcpy( p, ASN1_HASH_MDX, asn_len ); - memcpy( p + asn_len, hash, hashlen ); - p[13] = 4; break; - - case SIG_RSA_MD5: - asn_len = OID_SIZE(ASN1_HASH_MDX); - memcpy( p, ASN1_HASH_MDX, asn_len ); - memcpy( p + asn_len, hash, hashlen ); - p[13] = 5; break; - - case SIG_RSA_SHA1: - asn_len = OID_SIZE(ASN1_HASH_SHA1); - memcpy( p, ASN1_HASH_SHA1, asn_len ); - memcpy( p + 15, hash, hashlen ); - break; - - case SIG_RSA_SHA224: - asn_len = OID_SIZE(ASN1_HASH_SHA2X); - memcpy( p, ASN1_HASH_SHA2X, asn_len ); - memcpy( p + asn_len, hash, hashlen ); - p[1] += hashlen; p[14] = 4; p[18] += hashlen; break; - - case SIG_RSA_SHA256: - asn_len = OID_SIZE(ASN1_HASH_SHA2X); - memcpy( p, ASN1_HASH_SHA2X, asn_len ); - memcpy( p + asn_len, hash, hashlen ); - p[1] += hashlen; p[14] = 1; p[18] += hashlen; break; - - case SIG_RSA_SHA384: - asn_len = OID_SIZE(ASN1_HASH_SHA2X); - memcpy( p, ASN1_HASH_SHA2X, asn_len ); - memcpy( p + asn_len, hash, hashlen ); - p[1] += hashlen; p[14] = 2; p[18] += hashlen; break; - - case SIG_RSA_SHA512: - asn_len = OID_SIZE(ASN1_HASH_SHA2X); - memcpy( p, ASN1_HASH_SHA2X, asn_len ); - memcpy( p + asn_len, hash, hashlen ); - p[1] += hashlen; p[14] = 3; p[18] += hashlen; break; - - default: + const md_info_t *md_info = md_info_from_type( md_alg ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + hashlen = md_get_size( md_info ); + asn_len = 10 + oid_size; } + sig_len = ctx->len; + if( hashlen > sig_len || asn_len > sig_len || + hashlen + asn_len > sig_len ) + { + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + } + + if( md_alg != POLARSSL_MD_NONE ) + { + /* + * DigestInfo ::= SEQUENCE { + * digestAlgorithm DigestAlgorithmIdentifier, + * digest Digest } + * + * DigestAlgorithmIdentifier ::= AlgorithmIdentifier + * + * Digest ::= OCTET STRING + */ + *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED; + *p++ = (unsigned char) ( 0x08 + oid_size + hashlen ); + *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED; + *p++ = (unsigned char) ( 0x04 + oid_size ); + *p++ = ASN1_OID; + *p++ = oid_size & 0xFF; + memcpy( p, oid, oid_size ); + p += oid_size; + *p++ = ASN1_NULL; + *p++ = 0x00; + *p++ = ASN1_OCTET_STRING; + *p++ = hashlen; + } + + memcpy( p, hash, hashlen ); + if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig, - asn_len + hashlen, sig, &olen ) != CKR_OK ) + asn_len + hashlen, sig, &sig_len ) != CKR_OK ) { return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); } diff --git a/pdns/ext/polarssl/library/pkcs12.c b/pdns/ext/polarssl/library/pkcs12.c index 16821b03b..0cf2edf10 100644 --- a/pdns/ext/polarssl/library/pkcs12.c +++ b/pdns/ext/polarssl/library/pkcs12.c @@ -1,7 +1,7 @@ /* * PKCS#12 Personal Information Exchange Syntax * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -29,7 +29,11 @@ * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_PKCS12_C) @@ -45,6 +49,11 @@ #include "polarssl/des.h" #endif +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + static int pkcs12_parse_pbe_params( asn1_buf *params, asn1_buf *salt, int *iterations ) { @@ -89,13 +98,14 @@ static int pkcs12_pbe_derive_key_iv( asn1_buf *pbe_params, md_type_t md_type, size_t i; unsigned char unipwd[258]; - memset(&salt, 0, sizeof(asn1_buf)); - memset(&unipwd, 0, sizeof(unipwd)); + memset( &salt, 0, sizeof(asn1_buf) ); + memset( &unipwd, 0, sizeof(unipwd) ); - if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt, &iterations ) ) != 0 ) + if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt, + &iterations ) ) != 0 ) return( ret ); - for(i = 0; i < pwdlen; i++) + for( i = 0; i < pwdlen; i++ ) unipwd[i * 2 + 1] = pwd[i]; if( ( ret = pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2, @@ -137,6 +147,8 @@ int pkcs12_pbe_sha1_rc4_128( asn1_buf *pbe_params, int mode, arc4_context ctx; ((void) mode); + arc4_init( &ctx ); + if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, POLARSSL_MD_SHA1, pwd, pwdlen, key, 16, NULL, 0 ) ) != 0 ) @@ -146,9 +158,13 @@ int pkcs12_pbe_sha1_rc4_128( asn1_buf *pbe_params, int mode, arc4_setup( &ctx, key, 16 ); if( ( ret = arc4_crypt( &ctx, len, data, output ) ) != 0 ) - return( ret ); + goto exit; - return( 0 ); +exit: + polarssl_zeroize( key, sizeof( key ) ); + arc4_free( &ctx ); + + return( ret ); #endif /* POLARSSL_ARC4_C */ } @@ -178,6 +194,8 @@ int pkcs12_pbe( asn1_buf *pbe_params, int mode, return( ret ); } + cipher_init( &cipher_ctx ); + if( ( ret = cipher_init_ctx( &cipher_ctx, cipher_info ) ) != 0 ) goto exit; @@ -200,7 +218,9 @@ int pkcs12_pbe( asn1_buf *pbe_params, int mode, ret = POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH; exit: - cipher_free_ctx( &cipher_ctx ); + polarssl_zeroize( key, sizeof( key ) ); + polarssl_zeroize( iv, sizeof( iv ) ); + cipher_free( &cipher_ctx ); return( ret ); } @@ -247,7 +267,9 @@ int pkcs12_derivation( unsigned char *data, size_t datalen, if( md_info == NULL ) return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE ); - if ( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 ) + md_init( &md_ctx ); + + if( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 ) return( ret ); hlen = md_get_size( md_info ); @@ -325,7 +347,12 @@ int pkcs12_derivation( unsigned char *data, size_t datalen, ret = 0; exit: - md_free_ctx( &md_ctx ); + polarssl_zeroize( salt_block, sizeof( salt_block ) ); + polarssl_zeroize( pwd_block, sizeof( pwd_block ) ); + polarssl_zeroize( hash_block, sizeof( hash_block ) ); + polarssl_zeroize( hash_output, sizeof( hash_output ) ); + + md_free( &md_ctx ); return( ret ); } diff --git a/pdns/ext/polarssl/library/pkcs5.c b/pdns/ext/polarssl/library/pkcs5.c index 39aa5b96e..e769783ee 100644 --- a/pdns/ext/polarssl/library/pkcs5.c +++ b/pdns/ext/polarssl/library/pkcs5.c @@ -5,7 +5,7 @@ * * \author Mathias Olsson * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -33,7 +33,11 @@ * http://tools.ietf.org/html/rfc6070 (Test vectors) */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_PKCS5_C) @@ -42,13 +46,19 @@ #include "polarssl/cipher.h" #include "polarssl/oid.h" -static int pkcs5_parse_pbkdf2_params( asn1_buf *params, +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +static int pkcs5_parse_pbkdf2_params( const asn1_buf *params, asn1_buf *salt, int *iterations, int *keylen, md_type_t *md_type ) { int ret; asn1_buf prf_alg_oid; - unsigned char **p = ¶ms->p; + unsigned char *p = params->p; const unsigned char *end = params->p + params->len; if( params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) @@ -63,28 +73,28 @@ static int pkcs5_parse_pbkdf2_params( asn1_buf *params, * } * */ - if( ( ret = asn1_get_tag( p, end, &salt->len, ASN1_OCTET_STRING ) ) != 0 ) + if( ( ret = asn1_get_tag( &p, end, &salt->len, ASN1_OCTET_STRING ) ) != 0 ) return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret ); - salt->p = *p; - *p += salt->len; + salt->p = p; + p += salt->len; - if( ( ret = asn1_get_int( p, end, iterations ) ) != 0 ) + if( ( ret = asn1_get_int( &p, end, iterations ) ) != 0 ) return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret ); - if( *p == end ) + if( p == end ) return( 0 ); - if( ( ret = asn1_get_int( p, end, keylen ) ) != 0 ) + if( ( ret = asn1_get_int( &p, end, keylen ) ) != 0 ) { if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret ); } - if( *p == end ) + if( p == end ) return( 0 ); - if( ( ret = asn1_get_alg_null( p, end, &prf_alg_oid ) ) != 0 ) + if( ( ret = asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 ) return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret ); if( !OID_CMP( OID_HMAC_SHA1, &prf_alg_oid ) ) @@ -92,7 +102,7 @@ static int pkcs5_parse_pbkdf2_params( asn1_buf *params, *md_type = POLARSSL_MD_SHA1; - if( *p != end ) + if( p != end ) return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); @@ -120,9 +130,6 @@ int pkcs5_pbes2( asn1_buf *pbe_params, int mode, p = pbe_params->p; end = p + pbe_params->len; - memset( &md_ctx, 0, sizeof(md_context_t) ); - memset( &cipher_ctx, 0, sizeof(cipher_context_t) ); - /* * PBES2-params ::= SEQUENCE { * keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, @@ -152,16 +159,23 @@ int pkcs5_pbes2( asn1_buf *pbe_params, int mode, if( md_info == NULL ) return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE ); - if( ( ret = asn1_get_alg( &p, end, &enc_scheme_oid, &enc_scheme_params ) ) != 0 ) + if( ( ret = asn1_get_alg( &p, end, &enc_scheme_oid, + &enc_scheme_params ) ) != 0 ) + { return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret ); + } - if ( oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 ) + if( oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 ) return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE ); cipher_info = cipher_info_from_type( cipher_alg ); if( cipher_info == NULL ) return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE ); + /* + * The value of keylen from pkcs5_parse_pbkdf2_params() is ignored + * since it is optional and we don't know if it was set or not + */ keylen = cipher_info->key_length / 8; if( enc_scheme_params.tag != ASN1_OCTET_STRING || @@ -170,13 +184,16 @@ int pkcs5_pbes2( asn1_buf *pbe_params, int mode, return( POLARSSL_ERR_PKCS5_INVALID_FORMAT ); } + md_init( &md_ctx ); + cipher_init( &cipher_ctx ); + memcpy( iv, enc_scheme_params.p, enc_scheme_params.len ); if( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 ) goto exit; - if ( ( ret = pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len, - iterations, keylen, key ) ) != 0 ) + if( ( ret = pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len, + iterations, keylen, key ) ) != 0 ) { goto exit; } @@ -187,24 +204,13 @@ int pkcs5_pbes2( asn1_buf *pbe_params, int mode, if( ( ret = cipher_setkey( &cipher_ctx, key, 8 * keylen, mode ) ) != 0 ) goto exit; - if( ( ret = cipher_set_iv( &cipher_ctx, iv, enc_scheme_params.len ) ) != 0 ) - goto exit; - - if( ( ret = cipher_reset( &cipher_ctx ) ) != 0 ) - goto exit; - - if( ( ret = cipher_update( &cipher_ctx, data, datalen, - output, &olen ) ) != 0 ) - { - goto exit; - } - - if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 ) + if( ( ret = cipher_crypt( &cipher_ctx, iv, enc_scheme_params.len, + data, datalen, output, &olen ) ) != 0 ) ret = POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH; exit: - md_free_ctx( &md_ctx ); - cipher_free_ctx( &cipher_ctx ); + md_free( &md_ctx ); + cipher_free( &cipher_ctx ); return( ret ); } @@ -247,7 +253,7 @@ int pkcs5_pbkdf2_hmac( md_context_t *ctx, const unsigned char *password, memcpy( md1, work, md_size ); - for ( i = 1; i < iteration_count; i++ ) + for( i = 1; i < iteration_count; i++ ) { // U2 ends up in md1 // @@ -282,6 +288,16 @@ int pkcs5_pbkdf2_hmac( md_context_t *ctx, const unsigned char *password, #if defined(POLARSSL_SELF_TEST) +#if !defined(POLARSSL_SHA1_C) +int pkcs5_self_test( int verbose ) +{ + if( verbose != 0 ) + polarssl_printf( " PBKDF2 (SHA1): skipped\n\n" ); + + return( 0 ); +} +#else + #include #define MAX_TESTS 6 @@ -319,7 +335,7 @@ uint32_t key_len[MAX_TESTS] = { 20, 20, 20, 20, 25, 16 }; -unsigned char result_key[MAX_TESTS][32] = +unsigned char result_key[MAX_TESTS][32] = { { 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71, 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06, @@ -348,16 +364,28 @@ int pkcs5_self_test( int verbose ) int ret, i; unsigned char key[64]; + md_init( &sha1_ctx ); + info_sha1 = md_info_from_type( POLARSSL_MD_SHA1 ); if( info_sha1 == NULL ) - return( 1 ); + { + ret = 1; + goto exit; + } if( ( ret = md_init_ctx( &sha1_ctx, info_sha1 ) ) != 0 ) - return( 1 ); + { + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( " PBKDF2 note: test #3 may be slow!\n" ); for( i = 0; i < MAX_TESTS; i++ ) { - printf( " PBKDF2 (SHA1) #%d: ", i ); + if( verbose != 0 ) + polarssl_printf( " PBKDF2 (SHA1) #%d: ", i ); ret = pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i], slen[i], it_cnt[i], key_len[i], key ); @@ -365,22 +393,24 @@ int pkcs5_self_test( int verbose ) memcmp( result_key[i], key, key_len[i] ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } - printf( "\n" ); + polarssl_printf( "\n" ); - if( ( ret = md_free_ctx( &sha1_ctx ) ) != 0 ) - return( 1 ); +exit: + md_free( &sha1_ctx ); return( 0 ); } +#endif /* POLARSSL_SHA1_C */ #endif /* POLARSSL_SELF_TEST */ diff --git a/pdns/ext/polarssl/library/pkparse.c b/pdns/ext/polarssl/library/pkparse.c index a5de20b9f..29217a28a 100644 --- a/pdns/ext/polarssl/library/pkparse.c +++ b/pdns/ext/polarssl/library/pkparse.c @@ -1,7 +1,7 @@ /* * Public Key layer for parsing key files and structures * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,7 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_PK_PARSE_C) @@ -50,8 +54,8 @@ #include "polarssl/pkcs12.h" #endif -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else #include #define polarssl_malloc malloc @@ -59,6 +63,11 @@ #endif #if defined(POLARSSL_FS_IO) +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + /* * Load all data from a file into a given buffer. */ @@ -111,7 +120,7 @@ int pk_parse_keyfile( pk_context *ctx, size_t n; unsigned char *buf; - if ( (ret = load_file( path, &buf, &n ) ) != 0 ) + if( ( ret = load_file( path, &buf, &n ) ) != 0 ) return( ret ); if( pwd == NULL ) @@ -120,7 +129,7 @@ int pk_parse_keyfile( pk_context *ctx, ret = pk_parse_key( ctx, buf, n, (const unsigned char *) pwd, strlen( pwd ) ); - memset( buf, 0, n + 1 ); + polarssl_zeroize( buf, n + 1 ); polarssl_free( buf ); return( ret ); @@ -135,12 +144,12 @@ int pk_parse_public_keyfile( pk_context *ctx, const char *path ) size_t n; unsigned char *buf; - if ( (ret = load_file( path, &buf, &n ) ) != 0 ) + if( ( ret = load_file( path, &buf, &n ) ) != 0 ) return( ret ); ret = pk_parse_public_key( ctx, buf, n ); - memset( buf, 0, n + 1 ); + polarssl_zeroize( buf, n + 1 ); polarssl_free( buf ); return( ret ); @@ -148,12 +157,12 @@ int pk_parse_public_keyfile( pk_context *ctx, const char *path ) #endif /* POLARSSL_FS_IO */ #if defined(POLARSSL_ECP_C) -/* Get an EC group id from an ECParameters buffer +/* Minimally parse an ECParameters buffer to and asn1_buf * * ECParameters ::= CHOICE { * namedCurve OBJECT IDENTIFIER + * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... } * -- implicitCurve NULL - * -- specifiedCurve SpecifiedECDomain * } */ static int pk_get_ecparams( unsigned char **p, const unsigned char *end, @@ -161,10 +170,22 @@ static int pk_get_ecparams( unsigned char **p, const unsigned char *end, { int ret; + /* Tag may be either OID or SEQUENCE */ params->tag = **p; + if( params->tag != ASN1_OID +#if defined(POLARSSL_PK_PARSE_EC_EXTENDED) + && params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) +#endif + ) + { + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); + } - if( ( ret = asn1_get_tag( p, end, ¶ms->len, ASN1_OID ) ) != 0 ) + if( ( ret = asn1_get_tag( p, end, ¶ms->len, params->tag ) ) != 0 ) + { return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } params->p = *p; *p += params->len; @@ -176,16 +197,262 @@ static int pk_get_ecparams( unsigned char **p, const unsigned char *end, return( 0 ); } +#if defined(POLARSSL_PK_PARSE_EC_EXTENDED) +/* + * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it. + * WARNING: the resulting group should only be used with + * pk_group_id_from_specified(), since its base point may not be set correctly + * if it was encoded compressed. + * + * SpecifiedECDomain ::= SEQUENCE { + * version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...), + * fieldID FieldID {{FieldTypes}}, + * curve Curve, + * base ECPoint, + * order INTEGER, + * cofactor INTEGER OPTIONAL, + * hash HashAlgorithm OPTIONAL, + * ... + * } + * + * We only support prime-field as field type, and ignore hash and cofactor. + */ +static int pk_group_from_specified( const asn1_buf *params, ecp_group *grp ) +{ + int ret; + unsigned char *p = params->p; + const unsigned char * const end = params->p + params->len; + const unsigned char *end_field, *end_curve; + size_t len; + int ver; + + /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */ + if( ( ret = asn1_get_int( &p, end, &ver ) ) != 0 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( ver < 1 || ver > 3 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT ); + + /* + * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field + * fieldType FIELD-ID.&id({IOSet}), + * parameters FIELD-ID.&Type({IOSet}{@fieldType}) + * } + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( ret ); + + end_field = p + len; + + /* + * FIELD-ID ::= TYPE-IDENTIFIER + * FieldTypes FIELD-ID ::= { + * { Prime-p IDENTIFIED BY prime-field } | + * { Characteristic-two IDENTIFIED BY characteristic-two-field } + * } + * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } + */ + if( ( ret = asn1_get_tag( &p, end_field, &len, ASN1_OID ) ) != 0 ) + return( ret ); + + if( len != OID_SIZE( OID_ANSI_X9_62_PRIME_FIELD ) || + memcmp( p, OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 ) + { + return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); + } + + p += len; + + /* Prime-p ::= INTEGER -- Field of size p. */ + if( ( ret = asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + grp->pbits = mpi_msb( &grp->P ); + + if( p != end_field ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + /* + * Curve ::= SEQUENCE { + * a FieldElement, + * b FieldElement, + * seed BIT STRING OPTIONAL + * -- Shall be present if used in SpecifiedECDomain + * -- with version equal to ecdpVer2 or ecdpVer3 + * } + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( ret ); + + end_curve = p + len; + + /* + * FieldElement ::= OCTET STRING + * containing an integer in the case of a prime field + */ + if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_OCTET_STRING ) ) != 0 || + ( ret = mpi_read_binary( &grp->A, p, len ) ) != 0 ) + { + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + p += len; + + if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_OCTET_STRING ) ) != 0 || + ( ret = mpi_read_binary( &grp->B, p, len ) ) != 0 ) + { + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + p += len; + + /* Ignore seed BIT STRING OPTIONAL */ + if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_BIT_STRING ) ) == 0 ) + p += len; + + if( p != end_curve ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + /* + * ECPoint ::= OCTET STRING + */ + if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( ( ret = ecp_point_read_binary( grp, &grp->G, + ( const unsigned char *) p, len ) ) != 0 ) + { + /* + * If we can't read the point because it's compressed, cheat by + * reading only the X coordinate and the parity bit of Y. + */ + if( ret != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE || + ( p[0] != 0x02 && p[0] != 0x03 ) || + len != mpi_size( &grp->P ) + 1 || + mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 || + mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 || + mpi_lset( &grp->G.Z, 1 ) != 0 ) + { + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT ); + } + } + + p += len; + + /* + * order INTEGER + */ + if( ( ret = asn1_get_mpi( &p, end, &grp->N ) ) ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + grp->nbits = mpi_msb( &grp->N ); + + /* + * Allow optional elements by purposefully not enforcing p == end here. + */ + + return( 0 ); +} + +/* + * Find the group id associated with an (almost filled) group as generated by + * pk_group_from_specified(), or return an error if unknown. + */ +static int pk_group_id_from_group( const ecp_group *grp, ecp_group_id *grp_id ) +{ + int ret = 0; + ecp_group ref; + const ecp_group_id *id; + + ecp_group_init( &ref ); + + for( id = ecp_grp_id_list(); *id != POLARSSL_ECP_DP_NONE; id++ ) + { + /* Load the group associated to that id */ + ecp_group_free( &ref ); + MPI_CHK( ecp_use_known_dp( &ref, *id ) ); + + /* Compare to the group we were given, starting with easy tests */ + if( grp->pbits == ref.pbits && grp->nbits == ref.nbits && + mpi_cmp_mpi( &grp->P, &ref.P ) == 0 && + mpi_cmp_mpi( &grp->A, &ref.A ) == 0 && + mpi_cmp_mpi( &grp->B, &ref.B ) == 0 && + mpi_cmp_mpi( &grp->N, &ref.N ) == 0 && + mpi_cmp_mpi( &grp->G.X, &ref.G.X ) == 0 && + mpi_cmp_mpi( &grp->G.Z, &ref.G.Z ) == 0 && + /* For Y we may only know the parity bit, so compare only that */ + mpi_get_bit( &grp->G.Y, 0 ) == mpi_get_bit( &ref.G.Y, 0 ) ) + { + break; + } + + } + +cleanup: + ecp_group_free( &ref ); + + *grp_id = *id; + + if( ret == 0 && *id == POLARSSL_ECP_DP_NONE ) + ret = POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE; + + return( ret ); +} + +/* + * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID + */ +static int pk_group_id_from_specified( const asn1_buf *params, + ecp_group_id *grp_id ) +{ + int ret; + ecp_group grp; + + ecp_group_init( &grp ); + + if( ( ret = pk_group_from_specified( params, &grp ) ) != 0 ) + goto cleanup; + + ret = pk_group_id_from_group( &grp, grp_id ); + +cleanup: + ecp_group_free( &grp ); + + return( ret ); +} +#endif /* POLARSSL_PK_PARSE_EC_EXTENDED */ + /* * Use EC parameters to initialise an EC group + * + * ECParameters ::= CHOICE { + * namedCurve OBJECT IDENTIFIER + * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... } + * -- implicitCurve NULL */ static int pk_use_ecparams( const asn1_buf *params, ecp_group *grp ) { int ret; ecp_group_id grp_id; - if( oid_get_ec_grp( params, &grp_id ) != 0 ) - return( POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE ); + if( params->tag == ASN1_OID ) + { + if( oid_get_ec_grp( params, &grp_id ) != 0 ) + return( POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE ); + } + else + { +#if defined(POLARSSL_PK_PARSE_EC_EXTENDED) + if( ( ret = pk_group_id_from_specified( params, &grp_id ) ) != 0 ) + return( ret ); +#else + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT ); +#endif + } /* * grp may already be initilialized; if so, make sure IDs match @@ -201,6 +468,10 @@ static int pk_use_ecparams( const asn1_buf *params, ecp_group *grp ) /* * EC public key is an EC point + * + * The caller is responsible for clearing the structure upon failure if + * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE + * return code of ecp_point_read_binary() and leave p in a usable state. */ static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end, ecp_keypair *key ) @@ -208,19 +479,17 @@ static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end, int ret; if( ( ret = ecp_point_read_binary( &key->grp, &key->Q, - (const unsigned char *) *p, end - *p ) ) != 0 || - ( ret = ecp_check_pubkey( &key->grp, &key->Q ) ) != 0 ) + (const unsigned char *) *p, end - *p ) ) == 0 ) { - ecp_keypair_free( key ); - return( POLARSSL_ERR_PK_INVALID_PUBKEY ); + ret = ecp_check_pubkey( &key->grp, &key->Q ); } /* - * We know ecp_point_read_binary consumed all bytes + * We know ecp_point_read_binary consumed all bytes or failed */ *p = (unsigned char *) end; - return( 0 ); + return( ret ); } #endif /* POLARSSL_ECP_C */ @@ -451,7 +720,7 @@ static int pk_parse_key_sec1_der( ecp_keypair *eck, size_t keylen ) { int ret; - int version; + int version, pubkey_done; size_t len; asn1_buf params; unsigned char *p = (unsigned char *) key; @@ -513,8 +782,10 @@ static int pk_parse_key_sec1_der( ecp_keypair *eck, } /* - * Is 'publickey' present? If not, create it from the private key. + * Is 'publickey' present? If not, or if we can't read it (eg because it + * is compressed), create it from the private key. */ + pubkey_done = 0; if( ( ret = asn1_get_tag( &p, end, &len, ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 ) { @@ -527,16 +798,27 @@ static int pk_parse_key_sec1_der( ecp_keypair *eck, return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); - if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) != 0 ) - return( ret ); + if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 ) + pubkey_done = 1; + else + { + /* + * The only acceptable failure mode of pk_get_ecpubkey() above + * is if the point format is not recognized. + */ + if( ret != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT ); + } } - else if ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) { ecp_keypair_free( eck ); return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); } - else if( ( ret = ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G, - NULL, NULL ) ) != 0 ) + + if( ! pubkey_done && + ( ret = ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G, + NULL, NULL ) ) != 0 ) { ecp_keypair_free( eck ); return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); @@ -548,7 +830,7 @@ static int pk_parse_key_sec1_der( ecp_keypair *eck, return( ret ); } - return 0; + return( 0 ); } #endif /* POLARSSL_ECP_C */ @@ -637,7 +919,7 @@ static int pk_parse_key_pkcs8_unencrypted_der( #endif /* POLARSSL_ECP_C */ return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG ); - return 0; + return( 0 ); } /* @@ -648,7 +930,7 @@ static int pk_parse_key_pkcs8_encrypted_der( const unsigned char *key, size_t keylen, const unsigned char *pwd, size_t pwdlen ) { - int ret; + int ret, decrypted = 0; size_t len; unsigned char buf[2048]; unsigned char *p, *end; @@ -712,6 +994,8 @@ static int pk_parse_key_pkcs8_encrypted_der( return( ret ); } + + decrypted = 1; } else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) ) { @@ -728,6 +1012,8 @@ static int pk_parse_key_pkcs8_encrypted_der( // if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) return( POLARSSL_ERR_PK_PASSWORD_MISMATCH ); + + decrypted = 1; } else #endif /* POLARSSL_PKCS12_C */ @@ -742,14 +1028,18 @@ static int pk_parse_key_pkcs8_encrypted_der( return( ret ); } + + decrypted = 1; } else #endif /* POLARSSL_PKCS5_C */ { ((void) pwd); - return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); } + if( decrypted == 0 ) + return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); + return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) ); } @@ -951,7 +1241,7 @@ int pk_parse_public_key( pk_context *ctx, pem_free( &pem ); return( ret ); } -#endif +#endif /* POLARSSL_PEM_PARSE_C */ p = (unsigned char *) key; ret = pk_parse_subpubkey( &p, p + keylen, ctx ); diff --git a/pdns/ext/polarssl/library/pkwrite.c b/pdns/ext/polarssl/library/pkwrite.c index 8b6d7356e..3b0bbdb4e 100644 --- a/pdns/ext/polarssl/library/pkwrite.c +++ b/pdns/ext/polarssl/library/pkwrite.c @@ -1,7 +1,7 @@ /* * Public Key layer for writing key files and structures * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,7 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_PK_WRITE_C) @@ -44,8 +48,8 @@ #include "polarssl/pem.h" #endif -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else #include #define polarssl_malloc malloc @@ -69,7 +73,8 @@ static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start, ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->N ) ); ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); return( (int) len ); } @@ -187,7 +192,8 @@ int pk_write_pubkey_der( pk_context *key, unsigned char *buf, size_t size ) par_len ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); return( (int) len ); } @@ -214,10 +220,11 @@ int pk_write_key_der( pk_context *key, unsigned char *buf, size_t size ) ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 0 ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); } else -#endif +#endif /* POLARSSL_RSA_C */ #if defined(POLARSSL_ECP_C) if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) { @@ -267,10 +274,11 @@ int pk_write_key_der( pk_context *key, unsigned char *buf, size_t size ) ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 1 ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); } else -#endif +#endif /* POLARSSL_ECP_C */ return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); return( (int) len ); diff --git a/pdns/ext/polarssl/library/platform.c b/pdns/ext/polarssl/library/platform.c new file mode 100644 index 000000000..d57cbc828 --- /dev/null +++ b/pdns/ext/polarssl/library/platform.c @@ -0,0 +1,116 @@ +/* + * Platform abstraction layer + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_PLATFORM_C) + +#include "polarssl/platform.h" + +#if defined(POLARSSL_PLATFORM_MEMORY) +#if !defined(POLARSSL_PLATFORM_STD_MALLOC) +static void *platform_malloc_uninit( size_t len ) +{ + ((void) len); + return( NULL ); +} + +#define POLARSSL_PLATFORM_STD_MALLOC platform_malloc_uninit +#endif /* !POLARSSL_PLATFORM_STD_MALLOC */ + +#if !defined(POLARSSL_PLATFORM_STD_FREE) +static void platform_free_uninit( void *ptr ) +{ + ((void) ptr); +} + +#define POLARSSL_PLATFORM_STD_FREE platform_free_uninit +#endif /* !POLARSSL_PLATFORM_STD_FREE */ + +void * (*polarssl_malloc)( size_t ) = POLARSSL_PLATFORM_STD_MALLOC; +void (*polarssl_free)( void * ) = POLARSSL_PLATFORM_STD_FREE; + +int platform_set_malloc_free( void * (*malloc_func)( size_t ), + void (*free_func)( void * ) ) +{ + polarssl_malloc = malloc_func; + polarssl_free = free_func; + return( 0 ); +} +#endif /* POLARSSL_PLATFORM_MEMORY */ + +#if defined(POLARSSL_PLATFORM_PRINTF_ALT) +#if !defined(POLARSSL_PLATFORM_STD_PRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_printf_uninit( const char *format, ... ) +{ + ((void) format); + return( 0 ); +} + +#define POLARSSL_PLATFORM_STD_PRINTF platform_printf_uninit +#endif /* !POLARSSL_PLATFORM_STD_PRINTF */ + +int (*polarssl_printf)( const char *, ... ) = POLARSSL_PLATFORM_STD_PRINTF; + +int platform_set_printf( int (*printf_func)( const char *, ... ) ) +{ + polarssl_printf = printf_func; + return( 0 ); +} +#endif /* POLARSSL_PLATFORM_PRINTF_ALT */ + +#if defined(POLARSSL_PLATFORM_FPRINTF_ALT) +#if !defined(POLARSSL_PLATFORM_STD_FPRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_fprintf_uninit( FILE *stream, const char *format, ... ) +{ + ((void) stream); + ((void) format); + return( 0 ); +} + +#define POLARSSL_PLATFORM_STD_FPRINTF platform_fprintf_uninit +#endif /* !POLARSSL_PLATFORM_STD_FPRINTF */ + +int (*polarssl_fprintf)( FILE *, const char *, ... ) = + POLARSSL_PLATFORM_STD_FPRINTF; + +int platform_set_fprintf( int (*fprintf_func)( FILE *, const char *, ... ) ) +{ + polarssl_fprintf = fprintf_func; + return( 0 ); +} +#endif /* POLARSSL_PLATFORM_FPRINTF_ALT */ + +#endif /* POLARSSL_PLATFORM_C */ diff --git a/pdns/ext/polarssl/library/ripemd160.c b/pdns/ext/polarssl/library/ripemd160.c new file mode 100644 index 000000000..fcd77609f --- /dev/null +++ b/pdns/ext/polarssl/library/ripemd160.c @@ -0,0 +1,653 @@ +/* + * RIPE MD-160 implementation + * + * Copyright (C) 2014-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * The RIPEMD-160 algorithm was designed by RIPE in 1996 + * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html + * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160 + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_RIPEMD160_C) + +#include "polarssl/ripemd160.h" + +#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST) +#include +#endif + +#if defined(POLARSSL_SELF_TEST) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ +} +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +void ripemd160_init( ripemd160_context *ctx ) +{ + memset( ctx, 0, sizeof( ripemd160_context ) ); +} + +void ripemd160_free( ripemd160_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( ripemd160_context ) ); +} + +/* + * RIPEMD-160 context setup + */ +void ripemd160_starts( ripemd160_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +/* + * Process one block + */ +void ripemd160_process( ripemd160_context *ctx, const unsigned char data[64] ) +{ + uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16]; + + GET_UINT32_LE( X[ 0], data, 0 ); + GET_UINT32_LE( X[ 1], data, 4 ); + GET_UINT32_LE( X[ 2], data, 8 ); + GET_UINT32_LE( X[ 3], data, 12 ); + GET_UINT32_LE( X[ 4], data, 16 ); + GET_UINT32_LE( X[ 5], data, 20 ); + GET_UINT32_LE( X[ 6], data, 24 ); + GET_UINT32_LE( X[ 7], data, 28 ); + GET_UINT32_LE( X[ 8], data, 32 ); + GET_UINT32_LE( X[ 9], data, 36 ); + GET_UINT32_LE( X[10], data, 40 ); + GET_UINT32_LE( X[11], data, 44 ); + GET_UINT32_LE( X[12], data, 48 ); + GET_UINT32_LE( X[13], data, 52 ); + GET_UINT32_LE( X[14], data, 56 ); + GET_UINT32_LE( X[15], data, 60 ); + + A = Ap = ctx->state[0]; + B = Bp = ctx->state[1]; + C = Cp = ctx->state[2]; + D = Dp = ctx->state[3]; + E = Ep = ctx->state[4]; + +#define F1( x, y, z ) ( x ^ y ^ z ) +#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) ) +#define F3( x, y, z ) ( ( x | ~y ) ^ z ) +#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) ) +#define F5( x, y, z ) ( x ^ ( y | ~z ) ) + +#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) ) + +#define P( a, b, c, d, e, r, s, f, k ) \ + a += f( b, c, d ) + X[r] + k; \ + a = S( a, s ) + e; \ + c = S( c, 10 ); + +#define P2( a, b, c, d, e, r, s, rp, sp ) \ + P( a, b, c, d, e, r, s, F, K ); \ + P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp ); + +#define F F1 +#define K 0x00000000 +#define Fp F5 +#define Kp 0x50A28BE6 + P2( A, B, C, D, E, 0, 11, 5, 8 ); + P2( E, A, B, C, D, 1, 14, 14, 9 ); + P2( D, E, A, B, C, 2, 15, 7, 9 ); + P2( C, D, E, A, B, 3, 12, 0, 11 ); + P2( B, C, D, E, A, 4, 5, 9, 13 ); + P2( A, B, C, D, E, 5, 8, 2, 15 ); + P2( E, A, B, C, D, 6, 7, 11, 15 ); + P2( D, E, A, B, C, 7, 9, 4, 5 ); + P2( C, D, E, A, B, 8, 11, 13, 7 ); + P2( B, C, D, E, A, 9, 13, 6, 7 ); + P2( A, B, C, D, E, 10, 14, 15, 8 ); + P2( E, A, B, C, D, 11, 15, 8, 11 ); + P2( D, E, A, B, C, 12, 6, 1, 14 ); + P2( C, D, E, A, B, 13, 7, 10, 14 ); + P2( B, C, D, E, A, 14, 9, 3, 12 ); + P2( A, B, C, D, E, 15, 8, 12, 6 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F2 +#define K 0x5A827999 +#define Fp F4 +#define Kp 0x5C4DD124 + P2( E, A, B, C, D, 7, 7, 6, 9 ); + P2( D, E, A, B, C, 4, 6, 11, 13 ); + P2( C, D, E, A, B, 13, 8, 3, 15 ); + P2( B, C, D, E, A, 1, 13, 7, 7 ); + P2( A, B, C, D, E, 10, 11, 0, 12 ); + P2( E, A, B, C, D, 6, 9, 13, 8 ); + P2( D, E, A, B, C, 15, 7, 5, 9 ); + P2( C, D, E, A, B, 3, 15, 10, 11 ); + P2( B, C, D, E, A, 12, 7, 14, 7 ); + P2( A, B, C, D, E, 0, 12, 15, 7 ); + P2( E, A, B, C, D, 9, 15, 8, 12 ); + P2( D, E, A, B, C, 5, 9, 12, 7 ); + P2( C, D, E, A, B, 2, 11, 4, 6 ); + P2( B, C, D, E, A, 14, 7, 9, 15 ); + P2( A, B, C, D, E, 11, 13, 1, 13 ); + P2( E, A, B, C, D, 8, 12, 2, 11 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F3 +#define K 0x6ED9EBA1 +#define Fp F3 +#define Kp 0x6D703EF3 + P2( D, E, A, B, C, 3, 11, 15, 9 ); + P2( C, D, E, A, B, 10, 13, 5, 7 ); + P2( B, C, D, E, A, 14, 6, 1, 15 ); + P2( A, B, C, D, E, 4, 7, 3, 11 ); + P2( E, A, B, C, D, 9, 14, 7, 8 ); + P2( D, E, A, B, C, 15, 9, 14, 6 ); + P2( C, D, E, A, B, 8, 13, 6, 6 ); + P2( B, C, D, E, A, 1, 15, 9, 14 ); + P2( A, B, C, D, E, 2, 14, 11, 12 ); + P2( E, A, B, C, D, 7, 8, 8, 13 ); + P2( D, E, A, B, C, 0, 13, 12, 5 ); + P2( C, D, E, A, B, 6, 6, 2, 14 ); + P2( B, C, D, E, A, 13, 5, 10, 13 ); + P2( A, B, C, D, E, 11, 12, 0, 13 ); + P2( E, A, B, C, D, 5, 7, 4, 7 ); + P2( D, E, A, B, C, 12, 5, 13, 5 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F4 +#define K 0x8F1BBCDC +#define Fp F2 +#define Kp 0x7A6D76E9 + P2( C, D, E, A, B, 1, 11, 8, 15 ); + P2( B, C, D, E, A, 9, 12, 6, 5 ); + P2( A, B, C, D, E, 11, 14, 4, 8 ); + P2( E, A, B, C, D, 10, 15, 1, 11 ); + P2( D, E, A, B, C, 0, 14, 3, 14 ); + P2( C, D, E, A, B, 8, 15, 11, 14 ); + P2( B, C, D, E, A, 12, 9, 15, 6 ); + P2( A, B, C, D, E, 4, 8, 0, 14 ); + P2( E, A, B, C, D, 13, 9, 5, 6 ); + P2( D, E, A, B, C, 3, 14, 12, 9 ); + P2( C, D, E, A, B, 7, 5, 2, 12 ); + P2( B, C, D, E, A, 15, 6, 13, 9 ); + P2( A, B, C, D, E, 14, 8, 9, 12 ); + P2( E, A, B, C, D, 5, 6, 7, 5 ); + P2( D, E, A, B, C, 6, 5, 10, 15 ); + P2( C, D, E, A, B, 2, 12, 14, 8 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F5 +#define K 0xA953FD4E +#define Fp F1 +#define Kp 0x00000000 + P2( B, C, D, E, A, 4, 9, 12, 8 ); + P2( A, B, C, D, E, 0, 15, 15, 5 ); + P2( E, A, B, C, D, 5, 5, 10, 12 ); + P2( D, E, A, B, C, 9, 11, 4, 9 ); + P2( C, D, E, A, B, 7, 6, 1, 12 ); + P2( B, C, D, E, A, 12, 8, 5, 5 ); + P2( A, B, C, D, E, 2, 13, 8, 14 ); + P2( E, A, B, C, D, 10, 12, 7, 6 ); + P2( D, E, A, B, C, 14, 5, 6, 8 ); + P2( C, D, E, A, B, 1, 12, 2, 13 ); + P2( B, C, D, E, A, 3, 13, 13, 6 ); + P2( A, B, C, D, E, 8, 14, 14, 5 ); + P2( E, A, B, C, D, 11, 11, 0, 15 ); + P2( D, E, A, B, C, 6, 8, 3, 13 ); + P2( C, D, E, A, B, 15, 5, 9, 11 ); + P2( B, C, D, E, A, 13, 6, 11, 11 ); +#undef F +#undef K +#undef Fp +#undef Kp + + C = ctx->state[1] + C + Dp; + ctx->state[1] = ctx->state[2] + D + Ep; + ctx->state[2] = ctx->state[3] + E + Ap; + ctx->state[3] = ctx->state[4] + A + Bp; + ctx->state[4] = ctx->state[0] + B + Cp; + ctx->state[0] = C; +} + +/* + * RIPEMD-160 process buffer + */ +void ripemd160_update( ripemd160_context *ctx, + const unsigned char *input, size_t ilen ) +{ + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + ripemd160_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + ripemd160_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), input, ilen ); + } +} + +static const unsigned char ripemd160_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * RIPEMD-160 final digest + */ +void ripemd160_finish( ripemd160_context *ctx, unsigned char output[20] ) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_LE( low, msglen, 0 ); + PUT_UINT32_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + ripemd160_update( ctx, ripemd160_padding, padn ); + ripemd160_update( ctx, msglen, 8 ); + + PUT_UINT32_LE( ctx->state[0], output, 0 ); + PUT_UINT32_LE( ctx->state[1], output, 4 ); + PUT_UINT32_LE( ctx->state[2], output, 8 ); + PUT_UINT32_LE( ctx->state[3], output, 12 ); + PUT_UINT32_LE( ctx->state[4], output, 16 ); +} + +/* + * output = RIPEMD-160( input buffer ) + */ +void ripemd160( const unsigned char *input, size_t ilen, + unsigned char output[20] ) +{ + ripemd160_context ctx; + + ripemd160_init( &ctx ); + ripemd160_starts( &ctx ); + ripemd160_update( &ctx, input, ilen ); + ripemd160_finish( &ctx, output ); + ripemd160_free( &ctx ); +} + +#if defined(POLARSSL_FS_IO) +/* + * output = RIPEMD-160( file contents ) + */ +int ripemd160_file( const char *path, unsigned char output[20] ) +{ + FILE *f; + size_t n; + ripemd160_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR ); + + ripemd160_init( &ctx ); + ripemd160_starts( &ctx ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + ripemd160_update( &ctx, buf, n ); + + ripemd160_finish( &ctx, output ); + ripemd160_free( &ctx ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR ); + } + + fclose( f ); + return( 0 ); +} +#endif /* POLARSSL_FS_IO */ + +/* + * RIPEMD-160 HMAC context setup + */ +void ripemd160_hmac_starts( ripemd160_context *ctx, + const unsigned char *key, size_t keylen ) +{ + size_t i; + unsigned char sum[20]; + + if( keylen > 64 ) + { + ripemd160( key, keylen, sum ); + keylen = 20; + key = sum; + } + + memset( ctx->ipad, 0x36, 64 ); + memset( ctx->opad, 0x5C, 64 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + ripemd160_starts( ctx ); + ripemd160_update( ctx, ctx->ipad, 64 ); + + polarssl_zeroize( sum, sizeof( sum ) ); +} + +/* + * RIPEMD-160 HMAC process buffer + */ +void ripemd160_hmac_update( ripemd160_context *ctx, + const unsigned char *input, size_t ilen ) +{ + ripemd160_update( ctx, input, ilen ); +} + +/* + * RIPEMD-160 HMAC final digest + */ +void ripemd160_hmac_finish( ripemd160_context *ctx, unsigned char output[20] ) +{ + unsigned char tmpbuf[20]; + + ripemd160_finish( ctx, tmpbuf ); + ripemd160_starts( ctx ); + ripemd160_update( ctx, ctx->opad, 64 ); + ripemd160_update( ctx, tmpbuf, 20 ); + ripemd160_finish( ctx, output ); + + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); +} + +/* + * RIPEMD-160 HMAC context reset + */ +void ripemd160_hmac_reset( ripemd160_context *ctx ) +{ + ripemd160_starts( ctx ); + ripemd160_update( ctx, ctx->ipad, 64 ); +} + +/* + * output = HMAC-RIPEMD-160( hmac key, input buffer ) + */ +void ripemd160_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[20] ) +{ + ripemd160_context ctx; + + ripemd160_init( &ctx ); + ripemd160_hmac_starts( &ctx, key, keylen ); + ripemd160_hmac_update( &ctx, input, ilen ); + ripemd160_hmac_finish( &ctx, output ); + ripemd160_free( &ctx ); +} + + +#if defined(POLARSSL_SELF_TEST) +/* + * Test vectors from the RIPEMD-160 paper and + * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html#HMAC + */ +#define TESTS 8 +#define KEYS 2 +static const char *ripemd160_test_input[TESTS] = +{ + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", +}; + +static const unsigned char ripemd160_test_md[TESTS][20] = +{ + { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, + 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }, + { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, + 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }, + { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, + 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }, + { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, + 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }, + { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, + 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }, + { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, + 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }, + { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed, + 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 }, + { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb, + 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb }, +}; + +static const unsigned char ripemd160_test_hmac[KEYS][TESTS][20] = +{ + { + { 0xcf, 0x38, 0x76, 0x77, 0xbf, 0xda, 0x84, 0x83, 0xe6, 0x3b, + 0x57, 0xe0, 0x6c, 0x3b, 0x5e, 0xcd, 0x8b, 0x7f, 0xc0, 0x55 }, + { 0x0d, 0x35, 0x1d, 0x71, 0xb7, 0x8e, 0x36, 0xdb, 0xb7, 0x39, + 0x1c, 0x81, 0x0a, 0x0d, 0x2b, 0x62, 0x40, 0xdd, 0xba, 0xfc }, + { 0xf7, 0xef, 0x28, 0x8c, 0xb1, 0xbb, 0xcc, 0x61, 0x60, 0xd7, + 0x65, 0x07, 0xe0, 0xa3, 0xbb, 0xf7, 0x12, 0xfb, 0x67, 0xd6 }, + { 0xf8, 0x36, 0x62, 0xcc, 0x8d, 0x33, 0x9c, 0x22, 0x7e, 0x60, + 0x0f, 0xcd, 0x63, 0x6c, 0x57, 0xd2, 0x57, 0x1b, 0x1c, 0x34 }, + { 0x84, 0x3d, 0x1c, 0x4e, 0xb8, 0x80, 0xac, 0x8a, 0xc0, 0xc9, + 0xc9, 0x56, 0x96, 0x50, 0x79, 0x57, 0xd0, 0x15, 0x5d, 0xdb }, + { 0x60, 0xf5, 0xef, 0x19, 0x8a, 0x2d, 0xd5, 0x74, 0x55, 0x45, + 0xc1, 0xf0, 0xc4, 0x7a, 0xa3, 0xfb, 0x57, 0x76, 0xf8, 0x81 }, + { 0xe4, 0x9c, 0x13, 0x6a, 0x9e, 0x56, 0x27, 0xe0, 0x68, 0x1b, + 0x80, 0x8a, 0x3b, 0x97, 0xe6, 0xa6, 0xe6, 0x61, 0xae, 0x79 }, + { 0x31, 0xbe, 0x3c, 0xc9, 0x8c, 0xee, 0x37, 0xb7, 0x9b, 0x06, + 0x19, 0xe3, 0xe1, 0xc2, 0xbe, 0x4f, 0x1a, 0xa5, 0x6e, 0x6c }, + }, + { + { 0xfe, 0x69, 0xa6, 0x6c, 0x74, 0x23, 0xee, 0xa9, 0xc8, 0xfa, + 0x2e, 0xff, 0x8d, 0x9d, 0xaf, 0xb4, 0xf1, 0x7a, 0x62, 0xf5 }, + { 0x85, 0x74, 0x3e, 0x89, 0x9b, 0xc8, 0x2d, 0xbf, 0xa3, 0x6f, + 0xaa, 0xa7, 0xa2, 0x5b, 0x7c, 0xfd, 0x37, 0x24, 0x32, 0xcd }, + { 0x6e, 0x4a, 0xfd, 0x50, 0x1f, 0xa6, 0xb4, 0xa1, 0x82, 0x3c, + 0xa3, 0xb1, 0x0b, 0xd9, 0xaa, 0x0b, 0xa9, 0x7b, 0xa1, 0x82 }, + { 0x2e, 0x06, 0x6e, 0x62, 0x4b, 0xad, 0xb7, 0x6a, 0x18, 0x4c, + 0x8f, 0x90, 0xfb, 0xa0, 0x53, 0x33, 0x0e, 0x65, 0x0e, 0x92 }, + { 0x07, 0xe9, 0x42, 0xaa, 0x4e, 0x3c, 0xd7, 0xc0, 0x4d, 0xed, + 0xc1, 0xd4, 0x6e, 0x2e, 0x8c, 0xc4, 0xc7, 0x41, 0xb3, 0xd9 }, + { 0xb6, 0x58, 0x23, 0x18, 0xdd, 0xcf, 0xb6, 0x7a, 0x53, 0xa6, + 0x7d, 0x67, 0x6b, 0x8a, 0xd8, 0x69, 0xad, 0xed, 0x62, 0x9a }, + { 0xf1, 0xbe, 0x3e, 0xe8, 0x77, 0x70, 0x31, 0x40, 0xd3, 0x4f, + 0x97, 0xea, 0x1a, 0xb3, 0xa0, 0x7c, 0x14, 0x13, 0x33, 0xe2 }, + { 0x85, 0xf1, 0x64, 0x70, 0x3e, 0x61, 0xa6, 0x31, 0x31, 0xbe, + 0x7e, 0x45, 0x95, 0x8e, 0x07, 0x94, 0x12, 0x39, 0x04, 0xf9 }, + }, +}; + +static const unsigned char ripemd160_test_key[KEYS][20] = +{ + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, + 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01, 0x23, 0x45, 0x67 }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, + 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33 }, +}; + +/* + * Checkup routine + */ +int ripemd160_self_test( int verbose ) +{ + int i, j; + unsigned char output[20]; + + memset( output, 0, sizeof output ); + + for( i = 0; i < TESTS; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " RIPEMD-160 test #%d: ", i + 1 ); + + ripemd160( (const unsigned char *) ripemd160_test_input[i], + strlen( ripemd160_test_input[i] ), + output ); + + if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + for( j = 0; j < KEYS; j++ ) + { + if( verbose != 0 ) + polarssl_printf( " HMAC-RIPEMD-160 test #%d, key #%d: ", + i + 1, j + 1 ); + + ripemd160_hmac( ripemd160_test_key[j], 20, + (const unsigned char *) ripemd160_test_input[i], + strlen( ripemd160_test_input[i] ), + output ); + + if( memcmp( output, ripemd160_test_hmac[j][i], 20 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + } + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_RIPEMD160_C */ diff --git a/pdns/ext/polarssl/library/rsa.c b/pdns/ext/polarssl/library/rsa.c index 210ea46e3..0fd5199b2 100644 --- a/pdns/ext/polarssl/library/rsa.c +++ b/pdns/ext/polarssl/library/rsa.c @@ -1,7 +1,7 @@ /* * The RSA public-key cryptosystem * - * Copyright (C) 2006-2011, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -29,7 +29,11 @@ * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_RSA_C) @@ -43,6 +47,12 @@ #include #include +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + /* * Initialize an RSA context */ @@ -52,14 +62,22 @@ void rsa_init( rsa_context *ctx, { memset( ctx, 0, sizeof( rsa_context ) ); - ctx->padding = padding; - ctx->hash_id = hash_id; + rsa_set_padding( ctx, padding, hash_id ); #if defined(POLARSSL_THREADING_C) polarssl_mutex_init( &ctx->mutex ); #endif } +/* + * Set padding for an existing RSA context + */ +void rsa_set_padding( rsa_context *ctx, int padding, int hash_id ) +{ + ctx->padding = padding; + ctx->hash_id = hash_id; +} + #if defined(POLARSSL_GENPRIME) /* @@ -86,7 +104,7 @@ int rsa_gen_key( rsa_context *ctx, do { - MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0, + MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0, f_rng, p_rng ) ); MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0, @@ -135,7 +153,7 @@ cleanup: return( 0 ); } -#endif +#endif /* POLARSSL_GENPRIME */ /* * Check a public RSA key @@ -154,7 +172,7 @@ int rsa_check_pubkey( const rsa_context *ctx ) return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); if( mpi_msb( &ctx->E ) < 2 || - mpi_msb( &ctx->E ) > 64 ) + mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 ) return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); return( 0 ); @@ -311,7 +329,7 @@ cleanup: return( ret ); } -#endif +#endif /* !POLARSSL_RSA_NO_CRT */ /* * Do an RSA private key operation @@ -343,7 +361,7 @@ int rsa_private( rsa_context *ctx, Vi = &ctx->Vi; Vf = &ctx->Vf; #endif -#endif +#endif /* !POLARSSL_RSA_NO_CRT */ mpi_init( &T ); mpi_init( &T1 ); mpi_init( &T2 ); @@ -401,7 +419,7 @@ int rsa_private( rsa_context *ctx, MPI_CHK( mpi_mul_mpi( &T, &T, Vf ) ); MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) ); } -#endif +#endif /* POLARSSL_RSA_NO_CRT */ olen = ctx->len; MPI_CHK( mpi_write_binary( &T, output, olen ) ); @@ -465,7 +483,7 @@ static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, dlen -= use_len; } } -#endif +#endif /* POLARSSL_PKCS1_V21 */ #if defined(POLARSSL_PKCS1_V21) /* @@ -487,7 +505,10 @@ int rsa_rsaes_oaep_encrypt( rsa_context *ctx, const md_info_t *md_info; md_context_t md_ctx; - if( ctx->padding != RSA_PKCS_V21 || f_rng == NULL ) + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( f_rng == NULL ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); md_info = md_info_from_type( ctx->hash_id ); @@ -497,7 +518,7 @@ int rsa_rsaes_oaep_encrypt( rsa_context *ctx, olen = ctx->len; hlen = md_get_size( md_info ); - if( olen < ilen + 2 * hlen + 2 || f_rng == NULL ) + if( olen < ilen + 2 * hlen + 2 ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); memset( output, 0, olen ); @@ -519,6 +540,7 @@ int rsa_rsaes_oaep_encrypt( rsa_context *ctx, *p++ = 1; memcpy( p, input, ilen ); + md_init( &md_ctx ); md_init_ctx( &md_ctx, md_info ); // maskedDB: Apply dbMask to DB @@ -531,7 +553,7 @@ int rsa_rsaes_oaep_encrypt( rsa_context *ctx, mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1, &md_ctx ); - md_free_ctx( &md_ctx ); + md_free( &md_ctx ); return( ( mode == RSA_PUBLIC ) ? rsa_public( ctx, output, output ) @@ -554,7 +576,10 @@ int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx, int ret; unsigned char *p = output; - if( ctx->padding != RSA_PKCS_V15 || f_rng == NULL ) + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( f_rng == NULL ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); olen = ctx->len; @@ -579,8 +604,8 @@ int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx, // Check if RNG failed to generate data // - if( rng_dl == 0 || ret != 0) - return POLARSSL_ERR_RSA_RNG_FAILED + ret; + if( rng_dl == 0 || ret != 0 ) + return( POLARSSL_ERR_RSA_RNG_FAILED + ret ); p++; } @@ -646,15 +671,18 @@ int rsa_rsaes_oaep_decrypt( rsa_context *ctx, size_t output_max_len ) { int ret; - size_t ilen; - unsigned char *p; + size_t ilen, i, pad_len; + unsigned char *p, bad, pad_done; unsigned char buf[POLARSSL_MPI_MAX_SIZE]; unsigned char lhash[POLARSSL_MD_MAX_SIZE]; unsigned int hlen; const md_info_t *md_info; md_context_t md_ctx; - if( ctx->padding != RSA_PKCS_V21 ) + /* + * Parameters sanity checks + */ + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); ilen = ctx->len; @@ -662,6 +690,13 @@ int rsa_rsaes_oaep_decrypt( rsa_context *ctx, if( ilen < 16 || ilen > sizeof( buf ) ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + md_info = md_info_from_type( ctx->hash_id ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + /* + * RSA operation + */ ret = ( mode == RSA_PUBLIC ) ? rsa_public( ctx, input, buf ) : rsa_private( ctx, f_rng, p_rng, input, buf ); @@ -669,53 +704,64 @@ int rsa_rsaes_oaep_decrypt( rsa_context *ctx, if( ret != 0 ) return( ret ); - p = buf; - - if( *p++ != 0 ) - return( POLARSSL_ERR_RSA_INVALID_PADDING ); - - md_info = md_info_from_type( ctx->hash_id ); - if( md_info == NULL ) - return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); - + /* + * Unmask data and generate lHash + */ hlen = md_get_size( md_info ); + md_init( &md_ctx ); md_init_ctx( &md_ctx, md_info ); - // Generate lHash - // + /* Generate lHash */ md( md_info, label, label_len, lhash ); - // seed: Apply seedMask to maskedSeed - // + /* seed: Apply seedMask to maskedSeed */ mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1, &md_ctx ); - // DB: Apply dbMask to maskedDB - // + /* DB: Apply dbMask to maskedDB */ mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen, &md_ctx ); - p += hlen; - md_free_ctx( &md_ctx ); + md_free( &md_ctx ); - // Check validity - // - if( memcmp( lhash, p, hlen ) != 0 ) - return( POLARSSL_ERR_RSA_INVALID_PADDING ); + /* + * Check contents, in "constant-time" + */ + p = buf; + bad = 0; - p += hlen; + bad |= *p++; /* First byte must be 0 */ - while( *p == 0 && p < buf + ilen ) - p++; + p += hlen; /* Skip seed */ - if( p == buf + ilen ) - return( POLARSSL_ERR_RSA_INVALID_PADDING ); + /* Check lHash */ + for( i = 0; i < hlen; i++ ) + bad |= lhash[i] ^ *p++; + + /* Get zero-padding len, but always read till end of buffer + * (minus one, for the 01 byte) */ + pad_len = 0; + pad_done = 0; + for( i = 0; i < ilen - 2 * hlen - 2; i++ ) + { + pad_done |= p[i]; + pad_len += ( pad_done == 0 ); + } - if( *p++ != 0x01 ) + p += pad_len; + bad |= *p++ ^ 0x01; + + /* + * The only information "leaked" is whether the padding was correct or not + * (eg, no data is copied if it was not correct). This meets the + * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between + * the different error conditions. + */ + if( bad != 0 ) return( POLARSSL_ERR_RSA_INVALID_PADDING ); - if (ilen - (p - buf) > output_max_len) + if( ilen - ( p - buf ) > output_max_len ) return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE ); *olen = ilen - (p - buf); @@ -737,13 +783,12 @@ int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx, unsigned char *output, size_t output_max_len) { - int ret, correct = 1; - size_t ilen, pad_count = 0; - unsigned char *p, *q; - unsigned char bt; + int ret; + size_t ilen, pad_count = 0, i; + unsigned char *p, bad, pad_done = 0; unsigned char buf[POLARSSL_MPI_MAX_SIZE]; - if( ctx->padding != RSA_PKCS_V15 ) + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); ilen = ctx->len; @@ -759,60 +804,49 @@ int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx, return( ret ); p = buf; + bad = 0; - if( *p++ != 0 ) - correct = 0; - - bt = *p++; - if( ( bt != RSA_CRYPT && mode == RSA_PRIVATE ) || - ( bt != RSA_SIGN && mode == RSA_PUBLIC ) ) - { - correct = 0; - } + /* + * Check and get padding len in "constant-time" + */ + bad |= *p++; /* First byte must be 0 */ - if( bt == RSA_CRYPT ) + /* This test does not depend on secret data */ + if( mode == RSA_PRIVATE ) { - while( *p != 0 && p < buf + ilen - 1 ) - pad_count += ( *p++ != 0 ); - - correct &= ( *p == 0 && p < buf + ilen - 1 ); - - q = p; + bad |= *p++ ^ RSA_CRYPT; - // Also pass over all other bytes to reduce timing differences - // - while ( q < buf + ilen - 1 ) - pad_count += ( *q++ != 0 ); + /* Get padding len, but always read till end of buffer + * (minus one, for the 00 byte) */ + for( i = 0; i < ilen - 3; i++ ) + { + pad_done |= ( p[i] == 0 ); + pad_count += ( pad_done == 0 ); + } - // Prevent compiler optimization of pad_count - // - correct |= pad_count & 0x100000; /* Always 0 unless 1M bit keys */ - p++; + p += pad_count; + bad |= *p++; /* Must be zero */ } else { - while( *p == 0xFF && p < buf + ilen - 1 ) - pad_count += ( *p++ == 0xFF ); - - correct &= ( *p == 0 && p < buf + ilen - 1 ); + bad |= *p++ ^ RSA_SIGN; - q = p; - - // Also pass over all other bytes to reduce timing differences - // - while ( q < buf + ilen - 1 ) - pad_count += ( *q++ != 0 ); + /* Get padding len, but always read till end of buffer + * (minus one, for the 00 byte) */ + for( i = 0; i < ilen - 3; i++ ) + { + pad_done |= ( p[i] != 0xFF ); + pad_count += ( pad_done == 0 ); + } - // Prevent compiler optimization of pad_count - // - correct |= pad_count & 0x100000; /* Always 0 unless 1M bit keys */ - p++; + p += pad_count; + bad |= *p++; /* Must be zero */ } - if( correct == 0 ) + if( bad ) return( POLARSSL_ERR_RSA_INVALID_PADDING ); - if (ilen - (p - buf) > output_max_len) + if( ilen - ( p - buf ) > output_max_len ) return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE ); *olen = ilen - (p - buf); @@ -875,7 +909,10 @@ int rsa_rsassa_pss_sign( rsa_context *ctx, const md_info_t *md_info; md_context_t md_ctx; - if( ctx->padding != RSA_PKCS_V21 || f_rng == NULL ) + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( f_rng == NULL ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); olen = ctx->len; @@ -903,8 +940,6 @@ int rsa_rsassa_pss_sign( rsa_context *ctx, memset( sig, 0, olen ); - msb = mpi_msb( &ctx->N ) - 1; - // Generate salt of length slen // if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 ) @@ -918,6 +953,7 @@ int rsa_rsassa_pss_sign( rsa_context *ctx, memcpy( p, salt, slen ); p += slen; + md_init( &md_ctx ); md_init_ctx( &md_ctx, md_info ); // Generate H = Hash( M' ) @@ -937,7 +973,7 @@ int rsa_rsassa_pss_sign( rsa_context *ctx, // mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx ); - md_free_ctx( &md_ctx ); + md_free( &md_ctx ); msb = mpi_msb( &ctx->N ) - 1; sig[0] &= 0xFF >> ( olen * 8 - msb ); @@ -971,7 +1007,7 @@ int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx, unsigned char *p = sig; const char *oid; - if( ctx->padding != RSA_PKCS_V15 ) + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); olen = ctx->len; @@ -1073,14 +1109,16 @@ int rsa_pkcs1_sign( rsa_context *ctx, /* * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function */ -int rsa_rsassa_pss_verify( rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - const unsigned char *sig ) +int rsa_rsassa_pss_verify_ext( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + md_type_t mgf1_hash_id, + int expected_salt_len, + const unsigned char *sig ) { int ret; size_t siglen; @@ -1093,7 +1131,7 @@ int rsa_rsassa_pss_verify( rsa_context *ctx, const md_info_t *md_info; md_context_t md_ctx; - if( ctx->padding != RSA_PKCS_V21 ) + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); siglen = ctx->len; @@ -1124,12 +1162,12 @@ int rsa_rsassa_pss_verify( rsa_context *ctx, hashlen = md_get_size( md_info ); } - md_info = md_info_from_type( ctx->hash_id ); + md_info = md_info_from_type( mgf1_hash_id ); if( md_info == NULL ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); hlen = md_get_size( md_info ); - slen = siglen - hlen - 1; + slen = siglen - hlen - 1; /* Currently length of salt + padding */ memset( zeros, 0, 8 ); @@ -1147,24 +1185,33 @@ int rsa_rsassa_pss_verify( rsa_context *ctx, if( buf[0] >> ( 8 - siglen * 8 + msb ) ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + md_init( &md_ctx ); md_init_ctx( &md_ctx, md_info ); mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx ); buf[0] &= 0xFF >> ( siglen * 8 - msb ); - while( *p == 0 && p < buf + siglen ) + while( p < buf + siglen && *p == 0 ) p++; if( p == buf + siglen || *p++ != 0x01 ) { - md_free_ctx( &md_ctx ); + md_free( &md_ctx ); return( POLARSSL_ERR_RSA_INVALID_PADDING ); } + /* Actual salt len */ slen -= p - buf; + if( expected_salt_len != RSA_SALT_LEN_ANY && + slen != (size_t) expected_salt_len ) + { + md_free( &md_ctx ); + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + } + // Generate H = Hash( M' ) // md_starts( &md_ctx ); @@ -1173,13 +1220,36 @@ int rsa_rsassa_pss_verify( rsa_context *ctx, md_update( &md_ctx, p, slen ); md_finish( &md_ctx, result ); - md_free_ctx( &md_ctx ); + md_free( &md_ctx ); if( memcmp( p + slen, result, hlen ) == 0 ) return( 0 ); else return( POLARSSL_ERR_RSA_VERIFY_FAILED ); } + +/* + * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function + */ +int rsa_rsassa_pss_verify( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig ) +{ + md_type_t mgf1_hash_id = ( ctx->hash_id != POLARSSL_MD_NONE ) + ? (md_type_t) ctx->hash_id + : md_alg; + + return( rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode, + md_alg, hashlen, hash, + mgf1_hash_id, RSA_SALT_LEN_ANY, + sig ) ); + +} #endif /* POLARSSL_PKCS1_V21 */ #if defined(POLARSSL_PKCS1_V15) @@ -1203,7 +1273,7 @@ int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx, const md_info_t *md_info; asn1_buf oid; - if( ctx->padding != RSA_PKCS_V15 ) + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); siglen = ctx->len; @@ -1361,7 +1431,7 @@ int rsa_copy( rsa_context *dst, const rsa_context *src ) #endif dst->padding = src->padding; - dst->hash_id = src->padding; + dst->hash_id = src->hash_id; cleanup: if( ret != 0 ) @@ -1446,9 +1516,10 @@ void rsa_free( rsa_context *ctx ) #define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \ "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD" -#if defined(POLARSSL_PCKS1_V15) +#if defined(POLARSSL_PKCS1_V15) static int myrand( void *rng_state, unsigned char *output, size_t len ) { +#if !defined(__OpenBSD__) size_t i; if( rng_state != NULL ) @@ -1456,17 +1527,24 @@ static int myrand( void *rng_state, unsigned char *output, size_t len ) for( i = 0; i < len; ++i ) output[i] = rand(); +#else + if( rng_state != NULL ) + rng_state = NULL; + + arc4random_buf( output, len ); +#endif /* !OpenBSD */ return( 0 ); } -#endif +#endif /* POLARSSL_PKCS1_V15 */ /* * Checkup routine */ int rsa_self_test( int verbose ) { -#if defined(POLARSSL_PCKS1_V15) + int ret = 0; +#if defined(POLARSSL_PKCS1_V15) size_t len; rsa_context rsa; unsigned char rsa_plaintext[PT_LEN]; @@ -1479,29 +1557,29 @@ int rsa_self_test( int verbose ) rsa_init( &rsa, RSA_PKCS_V15, 0 ); rsa.len = KEY_LEN; - mpi_read_string( &rsa.N , 16, RSA_N ); - mpi_read_string( &rsa.E , 16, RSA_E ); - mpi_read_string( &rsa.D , 16, RSA_D ); - mpi_read_string( &rsa.P , 16, RSA_P ); - mpi_read_string( &rsa.Q , 16, RSA_Q ); - mpi_read_string( &rsa.DP, 16, RSA_DP ); - mpi_read_string( &rsa.DQ, 16, RSA_DQ ); - mpi_read_string( &rsa.QP, 16, RSA_QP ); + MPI_CHK( mpi_read_string( &rsa.N , 16, RSA_N ) ); + MPI_CHK( mpi_read_string( &rsa.E , 16, RSA_E ) ); + MPI_CHK( mpi_read_string( &rsa.D , 16, RSA_D ) ); + MPI_CHK( mpi_read_string( &rsa.P , 16, RSA_P ) ); + MPI_CHK( mpi_read_string( &rsa.Q , 16, RSA_Q ) ); + MPI_CHK( mpi_read_string( &rsa.DP, 16, RSA_DP ) ); + MPI_CHK( mpi_read_string( &rsa.DQ, 16, RSA_DQ ) ); + MPI_CHK( mpi_read_string( &rsa.QP, 16, RSA_QP ) ); if( verbose != 0 ) - printf( " RSA key validation: " ); + polarssl_printf( " RSA key validation: " ); if( rsa_check_pubkey( &rsa ) != 0 || rsa_check_privkey( &rsa ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) - printf( "passed\n PKCS#1 encryption : " ); + polarssl_printf( "passed\n PKCS#1 encryption : " ); memcpy( rsa_plaintext, RSA_PT, PT_LEN ); @@ -1509,20 +1587,20 @@ int rsa_self_test( int verbose ) rsa_plaintext, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) - printf( "passed\n PKCS#1 decryption : " ); + polarssl_printf( "passed\n PKCS#1 decryption : " ); if( rsa_pkcs1_decrypt( &rsa, myrand, NULL, RSA_PRIVATE, &len, rsa_ciphertext, rsa_decrypted, sizeof(rsa_decrypted) ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } @@ -1530,14 +1608,14 @@ int rsa_self_test( int verbose ) if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } #if defined(POLARSSL_SHA1_C) if( verbose != 0 ) - printf( "passed\n PKCS#1 data sign : " ); + polarssl_printf( "passed\n PKCS#1 data sign : " ); sha1( rsa_plaintext, PT_LEN, sha1sum ); @@ -1545,34 +1623,35 @@ int rsa_self_test( int verbose ) sha1sum, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) - printf( "passed\n PKCS#1 sig. verify: " ); + polarssl_printf( "passed\n PKCS#1 sig. verify: " ); if( rsa_pkcs1_verify( &rsa, NULL, NULL, RSA_PUBLIC, POLARSSL_MD_SHA1, 0, sha1sum, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) - printf( "passed\n\n" ); + polarssl_printf( "passed\n\n" ); #endif /* POLARSSL_SHA1_C */ +cleanup: rsa_free( &rsa ); #else /* POLARSSL_PKCS1_V15 */ ((void) verbose); #endif /* POLARSSL_PKCS1_V15 */ - return( 0 ); + return( ret ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_RSA_C */ diff --git a/pdns/ext/polarssl/library/sha1.c b/pdns/ext/polarssl/library/sha1.c index b301b0979..20408c742 100644 --- a/pdns/ext/polarssl/library/sha1.c +++ b/pdns/ext/polarssl/library/sha1.c @@ -1,7 +1,7 @@ /* * FIPS-180-1 compliant SHA-1 implementation * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -28,7 +28,11 @@ * http://www.itl.nist.gov/fipspubs/fip180-1.htm */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_SHA1_C) @@ -38,6 +42,17 @@ #include #endif +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + #if !defined(POLARSSL_SHA1_ALT) /* @@ -63,6 +78,19 @@ } #endif +void sha1_init( sha1_context *ctx ) +{ + memset( ctx, 0, sizeof( sha1_context ) ); +} + +void sha1_free( sha1_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( sha1_context ) ); +} + /* * SHA-1 context setup */ @@ -103,8 +131,8 @@ void sha1_process( sha1_context *ctx, const unsigned char data[64] ) #define R(t) \ ( \ - temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ - W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ + temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \ + W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \ ( W[t & 0x0F] = S(temp,1) ) \ ) @@ -242,7 +270,7 @@ void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen ) size_t fill; uint32_t left; - if( ilen <= 0 ) + if( ilen == 0 ) return; left = ctx->total[0] & 0x3F; @@ -320,11 +348,11 @@ void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ) { sha1_context ctx; + sha1_init( &ctx ); sha1_starts( &ctx ); sha1_update( &ctx, input, ilen ); sha1_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( sha1_context ) ); + sha1_free( &ctx ); } #if defined(POLARSSL_FS_IO) @@ -341,14 +369,14 @@ int sha1_file( const char *path, unsigned char output[20] ) if( ( f = fopen( path, "rb" ) ) == NULL ) return( POLARSSL_ERR_SHA1_FILE_IO_ERROR ); + sha1_init( &ctx ); sha1_starts( &ctx ); while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) sha1_update( &ctx, buf, n ); sha1_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( sha1_context ) ); + sha1_free( &ctx ); if( ferror( f ) != 0 ) { @@ -364,7 +392,8 @@ int sha1_file( const char *path, unsigned char output[20] ) /* * SHA-1 HMAC context setup */ -void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, size_t keylen ) +void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, + size_t keylen ) { size_t i; unsigned char sum[20]; @@ -388,13 +417,14 @@ void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, size_t keyle sha1_starts( ctx ); sha1_update( ctx, ctx->ipad, 64 ); - memset( sum, 0, sizeof( sum ) ); + polarssl_zeroize( sum, sizeof( sum ) ); } /* * SHA-1 HMAC process buffer */ -void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, size_t ilen ) +void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, + size_t ilen ) { sha1_update( ctx, input, ilen ); } @@ -412,7 +442,7 @@ void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ) sha1_update( ctx, tmpbuf, 20 ); sha1_finish( ctx, output ); - memset( tmpbuf, 0, sizeof( tmpbuf ) ); + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); } /* @@ -433,18 +463,18 @@ void sha1_hmac( const unsigned char *key, size_t keylen, { sha1_context ctx; + sha1_init( &ctx ); sha1_hmac_starts( &ctx, key, keylen ); sha1_hmac_update( &ctx, input, ilen ); sha1_hmac_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( sha1_context ) ); + sha1_free( &ctx ); } #if defined(POLARSSL_SELF_TEST) /* * FIPS-180-1 test vectors */ -static unsigned char sha1_test_buf[3][57] = +static unsigned char sha1_test_buf[3][57] = { { "abc" }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, @@ -537,18 +567,20 @@ static const unsigned char sha1_hmac_test_sum[7][20] = */ int sha1_self_test( int verbose ) { - int i, j, buflen; + int i, j, buflen, ret = 0; unsigned char buf[1024]; unsigned char sha1sum[20]; sha1_context ctx; + sha1_init( &ctx ); + /* * SHA-1 */ for( i = 0; i < 3; i++ ) { if( verbose != 0 ) - printf( " SHA-1 test #%d: ", i + 1 ); + polarssl_printf( " SHA-1 test #%d: ", i + 1 ); sha1_starts( &ctx ); @@ -568,22 +600,23 @@ int sha1_self_test( int verbose ) if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); for( i = 0; i < 7; i++ ) { if( verbose != 0 ) - printf( " HMAC-SHA-1 test #%d: ", i + 1 ); + polarssl_printf( " HMAC-SHA-1 test #%d: ", i + 1 ); if( i == 5 || i == 6 ) { @@ -604,21 +637,25 @@ int sha1_self_test( int verbose ) if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); - return( 0 ); +exit: + sha1_free( &ctx ); + + return( ret ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_SHA1_C */ diff --git a/pdns/ext/polarssl/library/sha256.c b/pdns/ext/polarssl/library/sha256.c index e4d48427d..4fc66982f 100644 --- a/pdns/ext/polarssl/library/sha256.c +++ b/pdns/ext/polarssl/library/sha256.c @@ -1,7 +1,7 @@ /* * FIPS-180-2 compliant SHA-256 implementation * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -28,7 +28,11 @@ * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_SHA256_C) @@ -38,6 +42,17 @@ #include #endif +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + #if !defined(POLARSSL_SHA256_ALT) /* @@ -63,6 +78,19 @@ } #endif +void sha256_init( sha256_context *ctx ) +{ + memset( ctx, 0, sizeof( sha256_context ) ); +} + +void sha256_free( sha256_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( sha256_context ) ); +} + /* * SHA-256 context setup */ @@ -233,12 +261,13 @@ void sha256_process( sha256_context *ctx, const unsigned char data[64] ) /* * SHA-256 process buffer */ -void sha256_update( sha256_context *ctx, const unsigned char *input, size_t ilen ) +void sha256_update( sha256_context *ctx, const unsigned char *input, + size_t ilen ) { size_t fill; uint32_t left; - if( ilen <= 0 ) + if( ilen == 0 ) return; left = ctx->total[0] & 0x3F; @@ -322,11 +351,11 @@ void sha256( const unsigned char *input, size_t ilen, { sha256_context ctx; + sha256_init( &ctx ); sha256_starts( &ctx, is224 ); sha256_update( &ctx, input, ilen ); sha256_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( sha256_context ) ); + sha256_free( &ctx ); } #if defined(POLARSSL_FS_IO) @@ -343,14 +372,14 @@ int sha256_file( const char *path, unsigned char output[32], int is224 ) if( ( f = fopen( path, "rb" ) ) == NULL ) return( POLARSSL_ERR_SHA256_FILE_IO_ERROR ); + sha256_init( &ctx ); sha256_starts( &ctx, is224 ); while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) sha256_update( &ctx, buf, n ); sha256_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( sha256_context ) ); + sha256_free( &ctx ); if( ferror( f ) != 0 ) { @@ -391,13 +420,14 @@ void sha256_hmac_starts( sha256_context *ctx, const unsigned char *key, sha256_starts( ctx, is224 ); sha256_update( ctx, ctx->ipad, 64 ); - memset( sum, 0, sizeof( sum ) ); + polarssl_zeroize( sum, sizeof( sum ) ); } /* * SHA-256 HMAC process buffer */ -void sha256_hmac_update( sha256_context *ctx, const unsigned char *input, size_t ilen ) +void sha256_hmac_update( sha256_context *ctx, const unsigned char *input, + size_t ilen ) { sha256_update( ctx, input, ilen ); } @@ -419,7 +449,7 @@ void sha256_hmac_finish( sha256_context *ctx, unsigned char output[32] ) sha256_update( ctx, tmpbuf, hlen ); sha256_finish( ctx, output ); - memset( tmpbuf, 0, sizeof( tmpbuf ) ); + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); } /* @@ -440,18 +470,18 @@ void sha256_hmac( const unsigned char *key, size_t keylen, { sha256_context ctx; + sha256_init( &ctx ); sha256_hmac_starts( &ctx, key, keylen, is224 ); sha256_hmac_update( &ctx, input, ilen ); sha256_hmac_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( sha256_context ) ); + sha256_free( &ctx ); } #if defined(POLARSSL_SELF_TEST) /* * FIPS-180-2 test vectors */ -static unsigned char sha256_test_buf[3][57] = +static unsigned char sha256_test_buf[3][57] = { { "abc" }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, @@ -615,18 +645,20 @@ static const unsigned char sha256_hmac_test_sum[14][32] = */ int sha256_self_test( int verbose ) { - int i, j, k, buflen; + int i, j, k, buflen, ret = 0; unsigned char buf[1024]; unsigned char sha256sum[32]; sha256_context ctx; + sha256_init( &ctx ); + for( i = 0; i < 6; i++ ) { j = i % 3; k = i < 3; if( verbose != 0 ) - printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 ); + polarssl_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 ); sha256_starts( &ctx, k ); @@ -646,17 +678,18 @@ int sha256_self_test( int verbose ) if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); for( i = 0; i < 14; i++ ) { @@ -664,7 +697,7 @@ int sha256_self_test( int verbose ) k = i < 7; if( verbose != 0 ) - printf( " HMAC-SHA-%d test #%d: ", 256 - k * 32, j + 1 ); + polarssl_printf( " HMAC-SHA-%d test #%d: ", 256 - k * 32, j + 1 ); if( j == 5 || j == 6 ) { @@ -685,21 +718,25 @@ int sha256_self_test( int verbose ) if( memcmp( sha256sum, sha256_hmac_test_sum[i], buflen ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); - return( 0 ); +exit: + sha256_free( &ctx ); + + return( ret ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_SHA256_C */ diff --git a/pdns/ext/polarssl/library/sha512.c b/pdns/ext/polarssl/library/sha512.c index 2366e7c2c..f1d15256f 100644 --- a/pdns/ext/polarssl/library/sha512.c +++ b/pdns/ext/polarssl/library/sha512.c @@ -1,7 +1,7 @@ /* * FIPS-180-2 compliant SHA-384/512 implementation * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -28,7 +28,11 @@ * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_SHA512_C) @@ -38,6 +42,17 @@ #include #endif +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + #if !defined(POLARSSL_SHA512_ALT) /* @@ -55,7 +70,7 @@ | ( (uint64_t) (b)[(i) + 6] << 8 ) \ | ( (uint64_t) (b)[(i) + 7] ); \ } -#endif +#endif /* GET_UINT64_BE */ #ifndef PUT_UINT64_BE #define PUT_UINT64_BE(n,b,i) \ @@ -69,7 +84,7 @@ (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \ (b)[(i) + 7] = (unsigned char) ( (n) ); \ } -#endif +#endif /* PUT_UINT64_BE */ /* * Round constants @@ -118,6 +133,19 @@ static const uint64_t K[80] = UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) }; +void sha512_init( sha512_context *ctx ) +{ + memset( ctx, 0, sizeof( sha512_context ) ); +} + +void sha512_free( sha512_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( sha512_context ) ); +} + /* * SHA-512 context setup */ @@ -226,12 +254,13 @@ void sha512_process( sha512_context *ctx, const unsigned char data[128] ) /* * SHA-512 process buffer */ -void sha512_update( sha512_context *ctx, const unsigned char *input, size_t ilen ) +void sha512_update( sha512_context *ctx, const unsigned char *input, + size_t ilen ) { size_t fill; unsigned int left; - if( ilen <= 0 ) + if( ilen == 0 ) return; left = (unsigned int) (ctx->total[0] & 0x7F); @@ -320,11 +349,11 @@ void sha512( const unsigned char *input, size_t ilen, { sha512_context ctx; + sha512_init( &ctx ); sha512_starts( &ctx, is384 ); sha512_update( &ctx, input, ilen ); sha512_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( sha512_context ) ); + sha512_free( &ctx ); } #if defined(POLARSSL_FS_IO) @@ -341,14 +370,14 @@ int sha512_file( const char *path, unsigned char output[64], int is384 ) if( ( f = fopen( path, "rb" ) ) == NULL ) return( POLARSSL_ERR_SHA512_FILE_IO_ERROR ); + sha512_init( &ctx ); sha512_starts( &ctx, is384 ); while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) sha512_update( &ctx, buf, n ); sha512_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( sha512_context ) ); + sha512_free( &ctx ); if( ferror( f ) != 0 ) { @@ -389,7 +418,7 @@ void sha512_hmac_starts( sha512_context *ctx, const unsigned char *key, sha512_starts( ctx, is384 ); sha512_update( ctx, ctx->ipad, 128 ); - memset( sum, 0, sizeof( sum ) ); + polarssl_zeroize( sum, sizeof( sum ) ); } /* @@ -418,7 +447,7 @@ void sha512_hmac_finish( sha512_context *ctx, unsigned char output[64] ) sha512_update( ctx, tmpbuf, hlen ); sha512_finish( ctx, output ); - memset( tmpbuf, 0, sizeof( tmpbuf ) ); + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); } /* @@ -439,11 +468,11 @@ void sha512_hmac( const unsigned char *key, size_t keylen, { sha512_context ctx; + sha512_init( &ctx ); sha512_hmac_starts( &ctx, key, keylen, is384 ); sha512_hmac_update( &ctx, input, ilen ); sha512_hmac_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( sha512_context ) ); + sha512_free( &ctx ); } #if defined(POLARSSL_SELF_TEST) @@ -451,7 +480,7 @@ void sha512_hmac( const unsigned char *key, size_t keylen, /* * FIPS-180-2 test vectors */ -static unsigned char sha512_test_buf[3][113] = +static unsigned char sha512_test_buf[3][113] = { { "abc" }, { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" @@ -670,18 +699,20 @@ static const unsigned char sha512_hmac_test_sum[14][64] = */ int sha512_self_test( int verbose ) { - int i, j, k, buflen; + int i, j, k, buflen, ret = 0; unsigned char buf[1024]; unsigned char sha512sum[64]; sha512_context ctx; + sha512_init( &ctx ); + for( i = 0; i < 6; i++ ) { j = i % 3; k = i < 3; if( verbose != 0 ) - printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 ); + polarssl_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 ); sha512_starts( &ctx, k ); @@ -701,17 +732,18 @@ int sha512_self_test( int verbose ) if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); for( i = 0; i < 14; i++ ) { @@ -719,7 +751,7 @@ int sha512_self_test( int verbose ) k = i < 7; if( verbose != 0 ) - printf( " HMAC-SHA-%d test #%d: ", 512 - k * 128, j + 1 ); + polarssl_printf( " HMAC-SHA-%d test #%d: ", 512 - k * 128, j + 1 ); if( j == 5 || j == 6 ) { @@ -740,21 +772,25 @@ int sha512_self_test( int verbose ) if( memcmp( sha512sum, sha512_hmac_test_sum[i], buflen ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); - return( 0 ); +exit: + sha512_free( &ctx ); + + return( ret ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_SHA512_C */ diff --git a/pdns/ext/polarssl/library/ssl_cache.c b/pdns/ext/polarssl/library/ssl_cache.c index e0847b6dc..836b68511 100644 --- a/pdns/ext/polarssl/library/ssl_cache.c +++ b/pdns/ext/polarssl/library/ssl_cache.c @@ -1,7 +1,7 @@ /* * SSL session cache implementation * - * Copyright (C) 2006-2012, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -27,14 +27,18 @@ * to store and retrieve the session information. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_SSL_CACHE_C) #include "polarssl/ssl_cache.h" -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else #define polarssl_malloc malloc #define polarssl_free free @@ -101,7 +105,9 @@ int ssl_cache_get( void *data, ssl_session *session ) */ if( entry->peer_cert.p != NULL ) { - session->peer_cert = (x509_crt *) polarssl_malloc( sizeof(x509_crt) ); + session->peer_cert = + (x509_crt *) polarssl_malloc( sizeof(x509_crt) ); + if( session->peer_cert == NULL ) { ret = 1; @@ -186,17 +192,15 @@ int ssl_cache_set( void *data, const ssl_session *session ) /* * Reuse oldest entry if max_entries reached */ - if( old != NULL && count >= cache->max_entries ) + if( count >= cache->max_entries ) { - cur = old; - memset( &cur->session, 0, sizeof(ssl_session) ); -#if defined(POLARSSL_X509_CRT_PARSE_C) - if( cur->peer_cert.p != NULL ) + if( old == NULL ) { - polarssl_free( cur->peer_cert.p ); - memset( &cur->peer_cert, 0, sizeof(x509_buf) ); + ret = 1; + goto exit; } -#endif /* POLARSSL_X509_CRT_PARSE_C */ + + cur = old; } #else /* POLARSSL_HAVE_TIME */ /* @@ -213,22 +217,17 @@ int ssl_cache_set( void *data, const ssl_session *session ) cur = cache->chain; cache->chain = cur->next; - -#if defined(POLARSSL_X509_CRT_PARSE_C) - if( cur->peer_cert.p != NULL ) - { - polarssl_free( cur->peer_cert.p ); - memset( &cur->peer_cert, 0, sizeof(x509_buf) ); - } -#endif /* POLARSSL_X509_CRT_PARSE_C */ - - memset( cur, 0, sizeof(ssl_cache_entry) ); + cur->next = NULL; prv->next = cur; } #endif /* POLARSSL_HAVE_TIME */ else { - cur = (ssl_cache_entry *) polarssl_malloc( sizeof(ssl_cache_entry) ); + /* + * max_entries not reached, create new entry + */ + cur = (ssl_cache_entry *) + polarssl_malloc( sizeof(ssl_cache_entry) ); if( cur == NULL ) { ret = 1; @@ -251,12 +250,22 @@ int ssl_cache_set( void *data, const ssl_session *session ) memcpy( &cur->session, session, sizeof( ssl_session ) ); #if defined(POLARSSL_X509_CRT_PARSE_C) + /* + * If we're reusing an entry, free its certificate first + */ + if( cur->peer_cert.p != NULL ) + { + polarssl_free( cur->peer_cert.p ); + memset( &cur->peer_cert, 0, sizeof(x509_buf) ); + } + /* * Store peer certificate */ if( session->peer_cert != NULL ) { - cur->peer_cert.p = (unsigned char *) polarssl_malloc( session->peer_cert->raw.len ); + cur->peer_cert.p = (unsigned char *) + polarssl_malloc( session->peer_cert->raw.len ); if( cur->peer_cert.p == NULL ) { ret = 1; @@ -312,8 +321,7 @@ void ssl_cache_free( ssl_cache_context *cache ) ssl_session_free( &prv->session ); #if defined(POLARSSL_X509_CRT_PARSE_C) - if( prv->peer_cert.p != NULL ) - polarssl_free( prv->peer_cert.p ); + polarssl_free( prv->peer_cert.p ); #endif /* POLARSSL_X509_CRT_PARSE_C */ polarssl_free( prv ); diff --git a/pdns/ext/polarssl/library/ssl_ciphersuites.c b/pdns/ext/polarssl/library/ssl_ciphersuites.c index 615e96715..df838e260 100644 --- a/pdns/ext/polarssl/library/ssl_ciphersuites.c +++ b/pdns/ext/polarssl/library/ssl_ciphersuites.c @@ -3,7 +3,7 @@ * * \brief SSL ciphersuites for PolarSSL * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -25,7 +25,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_SSL_TLS_C) @@ -42,27 +46,34 @@ /* * Ordered from most preferred to least preferred in terms of security. * - * Current rule (except weak and null which come last): + * Current rule (except rc4, weak and null which come last): * 1. By key exchange: * Forward-secure non-PSK > forward-secure PSK > other non-PSK > other PSK * 2. By key length and cipher: - * AES-256 > Camellia-256 > AES-128 > Camellia-128 > 3DES > RC4 - * 3. By cipher mode when relevant GCM > CBC - * 4. By hash function used + * AES-256 > Camellia-256 > AES-128 > Camellia-128 > 3DES + * 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8 + * 4. By hash function used when relevant * 5. By key exchange/auth again: EC > non-EC */ static const int ciphersuite_preference[] = { +#if defined(SSL_CIPHERSUITES) + SSL_CIPHERSUITES, +#else /* All AES-256 ephemeral suites */ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_256_CCM, + TLS_DHE_RSA_WITH_AES_256_CCM, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, + TLS_DHE_RSA_WITH_AES_256_CCM_8, /* All CAMELLIA-256 ephemeral suites */ TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, @@ -77,12 +88,16 @@ static const int ciphersuite_preference[] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_128_CCM, + TLS_DHE_RSA_WITH_AES_128_CCM, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, + TLS_DHE_RSA_WITH_AES_128_CCM_8, /* All CAMELLIA-128 ephemeral suites */ TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, @@ -97,11 +112,10 @@ static const int ciphersuite_preference[] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, - TLS_ECDHE_RSA_WITH_RC4_128_SHA, /* The PSK ephemeral suites */ TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, + TLS_DHE_PSK_WITH_AES_256_CCM, TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, @@ -109,8 +123,10 @@ static const int ciphersuite_preference[] = TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, + TLS_DHE_PSK_WITH_AES_256_CCM_8, TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, + TLS_DHE_PSK_WITH_AES_128_CCM, TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, @@ -118,36 +134,59 @@ static const int ciphersuite_preference[] = TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, + TLS_DHE_PSK_WITH_AES_128_CCM_8, TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, - TLS_ECDHE_PSK_WITH_RC4_128_SHA, - TLS_DHE_PSK_WITH_RC4_128_SHA, /* All AES-256 suites */ TLS_RSA_WITH_AES_256_GCM_SHA384, + TLS_RSA_WITH_AES_256_CCM, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + TLS_RSA_WITH_AES_256_CCM_8, /* All CAMELLIA-256 suites */ TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, + TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, + TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, /* All AES-128 suites */ TLS_RSA_WITH_AES_128_GCM_SHA256, + TLS_RSA_WITH_AES_128_CCM, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + TLS_RSA_WITH_AES_128_CCM_8, /* All CAMELLIA-128 suites */ TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, + TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, + TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, /* All remaining >= 128-bit suites */ TLS_RSA_WITH_3DES_EDE_CBC_SHA, - TLS_RSA_WITH_RC4_128_SHA, - TLS_RSA_WITH_RC4_128_MD5, + TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, /* The RSA PSK suites */ TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, @@ -163,22 +202,36 @@ static const int ciphersuite_preference[] = TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, - TLS_RSA_PSK_WITH_RC4_128_SHA, /* The PSK suites */ TLS_PSK_WITH_AES_256_GCM_SHA384, + TLS_PSK_WITH_AES_256_CCM, TLS_PSK_WITH_AES_256_CBC_SHA384, TLS_PSK_WITH_AES_256_CBC_SHA, TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, + TLS_PSK_WITH_AES_256_CCM_8, TLS_PSK_WITH_AES_128_GCM_SHA256, + TLS_PSK_WITH_AES_128_CCM, TLS_PSK_WITH_AES_128_CBC_SHA256, TLS_PSK_WITH_AES_128_CBC_SHA, TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, + TLS_PSK_WITH_AES_128_CCM_8, TLS_PSK_WITH_3DES_EDE_CBC_SHA, + + /* RC4 suites */ + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + TLS_ECDHE_RSA_WITH_RC4_128_SHA, + TLS_ECDHE_PSK_WITH_RC4_128_SHA, + TLS_DHE_PSK_WITH_RC4_128_SHA, + TLS_RSA_WITH_RC4_128_SHA, + TLS_RSA_WITH_RC4_128_MD5, + TLS_ECDH_RSA_WITH_RC4_128_SHA, + TLS_ECDH_ECDSA_WITH_RC4_128_SHA, + TLS_RSA_PSK_WITH_RC4_128_SHA, TLS_PSK_WITH_RC4_128_SHA, /* Weak suites */ @@ -198,6 +251,8 @@ static const int ciphersuite_preference[] = TLS_RSA_WITH_NULL_SHA256, TLS_RSA_WITH_NULL_SHA, TLS_RSA_WITH_NULL_MD5, + TLS_ECDH_RSA_WITH_NULL_SHA, + TLS_ECDH_ECDSA_WITH_NULL_SHA, TLS_RSA_PSK_WITH_NULL_SHA384, TLS_RSA_PSK_WITH_NULL_SHA256, TLS_RSA_PSK_WITH_NULL_SHA, @@ -205,13 +260,10 @@ static const int ciphersuite_preference[] = TLS_PSK_WITH_NULL_SHA256, TLS_PSK_WITH_NULL_SHA, +#endif 0 }; -#define MAX_CIPHERSUITES 128 -static int supported_ciphersuites[MAX_CIPHERSUITES]; -static int supported_init = 0; - static const ssl_ciphersuite_t ciphersuite_definitions[] = { #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) @@ -262,6 +314,28 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = 0 }, #endif /* POLARSSL_GCM_C */ #endif /* POLARSSL_SHA512_C */ +#if defined(POLARSSL_CCM_C) + { TLS_ECDHE_ECDSA_WITH_AES_256_CCM, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, + { TLS_ECDHE_ECDSA_WITH_AES_128_CCM, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, +#endif /* POLARSSL_CCM_C */ #endif /* POLARSSL_AES_C */ #if defined(POLARSSL_CAMELLIA_C) @@ -269,14 +343,14 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA256_C) { TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA256_C */ #if defined(POLARSSL_SHA512_C) { TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA512_C */ @@ -388,14 +462,14 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA256_C) { TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256", POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_RSA, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA256_C */ #if defined(POLARSSL_SHA512_C) { TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384", POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDHE_RSA, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA512_C */ @@ -501,6 +575,28 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = 0 }, #endif /* POLARSSL_SHA1_C */ #endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_CCM_C) + { TLS_DHE_RSA_WITH_AES_256_CCM, "TLS-DHE-RSA-WITH-AES-256-CCM", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_DHE_RSA_WITH_AES_256_CCM_8, "TLS-DHE-RSA-WITH-AES-256-CCM-8", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, + { TLS_DHE_RSA_WITH_AES_128_CCM, "TLS-DHE-RSA-WITH-AES-128-CCM", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_DHE_RSA_WITH_AES_128_CCM_8, "TLS-DHE-RSA-WITH-AES-128-CCM-8", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, +#endif /* POLARSSL_CCM_C */ #endif /* POLARSSL_AES_C */ #if defined(POLARSSL_CAMELLIA_C) @@ -614,6 +710,28 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = 0 }, #endif /* POLARSSL_CIPHER_MODE_CBC */ #endif /* POLARSSL_SHA1_C */ +#if defined(POLARSSL_CCM_C) + { TLS_RSA_WITH_AES_256_CCM, "TLS-RSA-WITH-AES-256-CCM", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_RSA_WITH_AES_256_CCM_8, "TLS-RSA-WITH-AES-256-CCM-8", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, + { TLS_RSA_WITH_AES_128_CCM, "TLS-RSA-WITH-AES-128-CCM", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_RSA_WITH_AES_128_CCM_8, "TLS-RSA-WITH-AES-128-CCM-8", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, +#endif /* POLARSSL_CCM_C */ #endif /* POLARSSL_AES_C */ #if defined(POLARSSL_CAMELLIA_C) @@ -697,6 +815,244 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #endif /* POLARSSL_ARC4_C */ #endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) +#if defined(POLARSSL_AES_C) +#if defined(POLARSSL_SHA1_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_SHA1_C */ +#if defined(POLARSSL_SHA256_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_GCM_C) + { TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256", + POLARSSL_CIPHER_AES_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_GCM_C) + { TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384", + POLARSSL_CIPHER_AES_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_AES_C */ + +#if defined(POLARSSL_CAMELLIA_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA256_C) + { TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) + { TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_GCM_C) +#if defined(POLARSSL_SHA256_C) + { TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-GCM-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) + { TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-GCM-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_CAMELLIA_C */ + +#if defined(POLARSSL_DES_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-RSA-WITH-3DES-EDE-CBC-SHA", + POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_ARC4_C) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDH_RSA_WITH_RC4_128_SHA, "TLS-ECDH-RSA-WITH-RC4-128-SHA", + POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_ARC4_C */ + +#if defined(POLARSSL_CIPHER_NULL_CIPHER) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDH_RSA_WITH_NULL_SHA, "TLS-ECDH-RSA-WITH-NULL-SHA", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_NULL_CIPHER */ +#endif /* POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +#if defined(POLARSSL_AES_C) +#if defined(POLARSSL_SHA1_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_SHA1_C */ +#if defined(POLARSSL_SHA256_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_GCM_C) + { TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256", + POLARSSL_CIPHER_AES_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_GCM_C) + { TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384", + POLARSSL_CIPHER_AES_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_AES_C */ + +#if defined(POLARSSL_CAMELLIA_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA256_C) + { TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) + { TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_GCM_C) +#if defined(POLARSSL_SHA256_C) + { TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) + { TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_CAMELLIA_C */ + +#if defined(POLARSSL_DES_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA", + POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_ARC4_C) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDH_ECDSA_WITH_RC4_128_SHA, "TLS-ECDH-ECDSA-WITH-RC4-128-SHA", + POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_ARC4_C */ + +#if defined(POLARSSL_CIPHER_NULL_CIPHER) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS-ECDH-ECDSA-WITH-NULL-SHA", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_NULL_CIPHER */ +#endif /* POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + #if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) #if defined(POLARSSL_AES_C) #if defined(POLARSSL_GCM_C) @@ -721,7 +1077,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA256_C) { TLS_PSK_WITH_AES_128_CBC_SHA256, "TLS-PSK-WITH-AES-128-CBC-SHA256", POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA256_C */ @@ -729,7 +1085,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA512_C) { TLS_PSK_WITH_AES_256_CBC_SHA384, "TLS-PSK-WITH-AES-256-CBC-SHA384", POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA512_C */ @@ -748,6 +1104,28 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = 0 }, #endif /* POLARSSL_SHA1_C */ #endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_CCM_C) + { TLS_PSK_WITH_AES_256_CCM, "TLS-PSK-WITH-AES-256-CCM", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_PSK_WITH_AES_256_CCM_8, "TLS-PSK-WITH-AES-256-CCM-8", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, + { TLS_PSK_WITH_AES_128_CCM, "TLS-PSK-WITH-AES-128-CCM", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_PSK_WITH_AES_128_CCM_8, "TLS-PSK-WITH-AES-128-CCM-8", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, +#endif /* POLARSSL_CCM_C */ #endif /* POLARSSL_AES_C */ #if defined(POLARSSL_CAMELLIA_C) @@ -755,7 +1133,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA256_C) { TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256", POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA256_C */ @@ -763,7 +1141,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA512_C) { TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384", POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA512_C */ @@ -835,7 +1213,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA256_C) { TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA256", POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA256_C */ @@ -843,7 +1221,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA512_C) { TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA384", POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_DHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA512_C */ @@ -862,6 +1240,28 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = 0 }, #endif /* POLARSSL_SHA1_C */ #endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_CCM_C) + { TLS_DHE_PSK_WITH_AES_256_CCM, "TLS-DHE-PSK-WITH-AES-256-CCM", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_DHE_PSK_WITH_AES_256_CCM_8, "TLS-DHE-PSK-WITH-AES-256-CCM-8", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, + { TLS_DHE_PSK_WITH_AES_128_CCM, "TLS-DHE-PSK-WITH-AES-128-CCM", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_DHE_PSK_WITH_AES_128_CCM_8, "TLS-DHE-PSK-WITH-AES-128-CCM-8", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, +#endif /* POLARSSL_CCM_C */ #endif /* POLARSSL_AES_C */ #if defined(POLARSSL_CAMELLIA_C) @@ -869,7 +1269,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA256_C) { TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA256_C */ @@ -877,7 +1277,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA512_C) { TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_DHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA512_C */ @@ -932,7 +1332,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA256_C) { TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256", POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA256_C */ @@ -940,7 +1340,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA512_C) { TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384", POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA512_C */ @@ -948,13 +1348,13 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA1_C) { TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA", POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, { TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA", POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA1_C */ @@ -966,7 +1366,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA256_C) { TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA256_C */ @@ -974,7 +1374,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA512_C) { TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA512_C */ @@ -986,7 +1386,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA1_C) { TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA", POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA1_C */ @@ -997,7 +1397,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA1_C) { TLS_ECDHE_PSK_WITH_RC4_128_SHA, "TLS-ECDHE-PSK-WITH-RC4-128-SHA", POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA1_C */ @@ -1028,7 +1428,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA256_C) { TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA256", POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA256_C */ @@ -1036,7 +1436,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA512_C) { TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384", POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_RSA_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA512_C */ @@ -1062,7 +1462,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA256_C) { TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256", POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA256_C */ @@ -1070,7 +1470,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA512_C) { TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384", POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_RSA_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, 0 }, #endif /* POLARSSL_SHA512_C */ @@ -1158,7 +1558,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA256_C) { TLS_PSK_WITH_NULL_SHA256, "TLS-PSK-WITH-NULL-SHA256", POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, POLARSSL_CIPHERSUITE_WEAK }, #endif @@ -1166,7 +1566,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA512_C) { TLS_PSK_WITH_NULL_SHA384, "TLS-PSK-WITH-NULL-SHA384", POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, POLARSSL_CIPHERSUITE_WEAK }, #endif @@ -1184,7 +1584,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA256_C) { TLS_DHE_PSK_WITH_NULL_SHA256, "TLS-DHE-PSK-WITH-NULL-SHA256", POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, POLARSSL_CIPHERSUITE_WEAK }, #endif @@ -1192,7 +1592,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA512_C) { TLS_DHE_PSK_WITH_NULL_SHA384, "TLS-DHE-PSK-WITH-NULL-SHA384", POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_DHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, POLARSSL_CIPHERSUITE_WEAK }, #endif @@ -1202,7 +1602,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA1_C) { TLS_ECDHE_PSK_WITH_NULL_SHA, "TLS-ECDHE-PSK-WITH-NULL-SHA", POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, POLARSSL_CIPHERSUITE_WEAK }, #endif /* POLARSSL_SHA1_C */ @@ -1210,7 +1610,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA256_C) { TLS_ECDHE_PSK_WITH_NULL_SHA256, "TLS-ECDHE-PSK-WITH-NULL-SHA256", POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, POLARSSL_CIPHERSUITE_WEAK }, #endif @@ -1218,7 +1618,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA512_C) { TLS_ECDHE_PSK_WITH_NULL_SHA384, "TLS-ECDHE-PSK-WITH-NULL-SHA384", POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, POLARSSL_CIPHERSUITE_WEAK }, #endif @@ -1236,7 +1636,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA256_C) { TLS_RSA_PSK_WITH_NULL_SHA256, "TLS-RSA-PSK-WITH-NULL-SHA256", POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, POLARSSL_CIPHERSUITE_WEAK }, #endif @@ -1244,7 +1644,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = #if defined(POLARSSL_SHA512_C) { TLS_RSA_PSK_WITH_NULL_SHA384, "TLS-RSA-PSK-WITH-NULL-SHA384", POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_RSA_PSK, - SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, POLARSSL_CIPHERSUITE_WEAK }, #endif @@ -1279,6 +1679,17 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] = { 0, "", 0, 0, 0, 0, 0, 0, 0, 0 } }; +#if defined(SSL_CIPHERSUITES) +const int *ssl_list_ciphersuites( void ) +{ + return( ciphersuite_preference ); +} +#else +#define MAX_CIPHERSUITES sizeof( ciphersuite_definitions ) / \ + sizeof( ciphersuite_definitions[0] ) +static int supported_ciphersuites[MAX_CIPHERSUITES]; +static int supported_init = 0; + const int *ssl_list_ciphersuites( void ) { /* @@ -1287,25 +1698,33 @@ const int *ssl_list_ciphersuites( void ) */ if( supported_init == 0 ) { - const int *p = ciphersuite_preference; - int *q = supported_ciphersuites; - size_t i; - size_t max = sizeof(supported_ciphersuites) / sizeof(int); + const int *p; + int *q; - for( i = 0; i < max - 1 && p[i] != 0; i++ ) + for( p = ciphersuite_preference, q = supported_ciphersuites; + *p != 0 && q < supported_ciphersuites + MAX_CIPHERSUITES - 1; + p++ ) { - if( ssl_ciphersuite_from_id( p[i] ) != NULL ) - *(q++) = p[i]; +#if defined(POLARSSL_REMOVE_ARC4_CIPHERSUITES) + const ssl_ciphersuite_t *cs_info; + if( ( cs_info = ssl_ciphersuite_from_id( *p ) ) != NULL && + cs_info->cipher != POLARSSL_CIPHER_ARC4_128 ) +#else + if( ssl_ciphersuite_from_id( *p ) != NULL ) +#endif + *(q++) = *p; } *q = 0; supported_init = 1; } - return supported_ciphersuites; + return( supported_ciphersuites ); }; +#endif /* SSL_CIPHERSUITES */ -const ssl_ciphersuite_t *ssl_ciphersuite_from_string( const char *ciphersuite_name ) +const ssl_ciphersuite_t *ssl_ciphersuite_from_string( + const char *ciphersuite_name ) { const ssl_ciphersuite_t *cur = ciphersuite_definitions; @@ -1376,12 +1795,17 @@ pk_type_t ssl_get_ciphersuite_sig_pk_alg( const ssl_ciphersuite_t *info ) case POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA: return( POLARSSL_PK_ECDSA ); + case POLARSSL_KEY_EXCHANGE_ECDH_RSA: + case POLARSSL_KEY_EXCHANGE_ECDH_ECDSA: + return( POLARSSL_PK_ECKEY ); + default: return( POLARSSL_PK_NONE ); } } -#endif +#endif /* POLARSSL_PK_C */ +#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) int ssl_ciphersuite_uses_ec( const ssl_ciphersuite_t *info ) { switch( info->key_exchange ) @@ -1389,13 +1813,17 @@ int ssl_ciphersuite_uses_ec( const ssl_ciphersuite_t *info ) case POLARSSL_KEY_EXCHANGE_ECDHE_RSA: case POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA: case POLARSSL_KEY_EXCHANGE_ECDHE_PSK: + case POLARSSL_KEY_EXCHANGE_ECDH_RSA: + case POLARSSL_KEY_EXCHANGE_ECDH_ECDSA: return( 1 ); default: return( 0 ); } } +#endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */ +#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) int ssl_ciphersuite_uses_psk( const ssl_ciphersuite_t *info ) { switch( info->key_exchange ) @@ -1410,5 +1838,6 @@ int ssl_ciphersuite_uses_psk( const ssl_ciphersuite_t *info ) return( 0 ); } } +#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */ -#endif +#endif /* POLARSSL_SSL_TLS_C */ diff --git a/pdns/ext/polarssl/library/ssl_cli.c b/pdns/ext/polarssl/library/ssl_cli.c index 0eaa531fc..d38d76955 100644 --- a/pdns/ext/polarssl/library/ssl_cli.c +++ b/pdns/ext/polarssl/library/ssl_cli.c @@ -1,7 +1,7 @@ /* * SSLv3/TLSv1 client-side functions * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,15 +23,19 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_SSL_CLI_C) #include "polarssl/debug.h" #include "polarssl/ssl.h" -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else #define polarssl_malloc malloc #define polarssl_free free @@ -51,6 +55,13 @@ typedef UINT32 uint32_t; #include #endif +#if defined(POLARSSL_SSL_SESSION_TICKETS) +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} +#endif + #if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) static void ssl_write_hostname_ext( ssl_context *ssl, unsigned char *buf, @@ -60,7 +71,7 @@ static void ssl_write_hostname_ext( ssl_context *ssl, *olen = 0; - if ( ssl->hostname == NULL ) + if( ssl->hostname == NULL ) return; SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s", @@ -137,8 +148,10 @@ static void ssl_write_signature_algorithms_ext( ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; - unsigned char *sig_alg_list = buf + 6; size_t sig_alg_len = 0; +#if defined(POLARSSL_RSA_C) || defined(POLARSSL_ECDSA_C) + unsigned char *sig_alg_list = buf + 6; +#endif *olen = 0; @@ -231,21 +244,30 @@ static void ssl_write_supported_elliptic_curves_ext( ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; - unsigned char elliptic_curve_list[20]; + unsigned char *elliptic_curve_list = p + 6; size_t elliptic_curve_len = 0; - const ecp_curve_info *curve; + const ecp_curve_info *info; +#if defined(POLARSSL_SSL_SET_CURVES) + const ecp_group_id *grp_id; +#else ((void) ssl); +#endif *olen = 0; SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) ); - for( curve = ecp_curve_list(); - curve->grp_id != POLARSSL_ECP_DP_NONE; - curve++ ) +#if defined(POLARSSL_SSL_SET_CURVES) + for( grp_id = ssl->curve_list; *grp_id != POLARSSL_ECP_DP_NONE; grp_id++ ) + { + info = ecp_curve_info_from_grp_id( *grp_id ); +#else + for( info = ecp_curve_list(); info->grp_id != POLARSSL_ECP_DP_NONE; info++ ) { - elliptic_curve_list[elliptic_curve_len++] = curve->tls_id >> 8; - elliptic_curve_list[elliptic_curve_len++] = curve->tls_id & 0xFF; +#endif + + elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8; + elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF; } if( elliptic_curve_len == 0 ) @@ -260,8 +282,6 @@ static void ssl_write_supported_elliptic_curves_ext( ssl_context *ssl, *p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF ); - memcpy( p, elliptic_curve_list, elliptic_curve_len ); - *olen = 6 + elliptic_curve_len; } @@ -376,6 +396,54 @@ static void ssl_write_session_ticket_ext( ssl_context *ssl, } #endif /* POLARSSL_SSL_SESSION_TICKETS */ +#if defined(POLARSSL_SSL_ALPN) +static void ssl_write_alpn_ext( ssl_context *ssl, + unsigned char *buf, size_t *olen ) +{ + unsigned char *p = buf; + const char **cur; + + if( ssl->alpn_list == NULL ) + { + *olen = 0; + return; + } + + SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) ); + + *p++ = (unsigned char)( ( TLS_EXT_ALPN >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_ALPN ) & 0xFF ); + + /* + * opaque ProtocolName<1..2^8-1>; + * + * struct { + * ProtocolName protocol_name_list<2..2^16-1> + * } ProtocolNameList; + */ + + /* Skip writing extension and list length for now */ + p += 4; + + for( cur = ssl->alpn_list; *cur != NULL; cur++ ) + { + *p = (unsigned char)( strlen( *cur ) & 0xFF ); + memcpy( p + 1, *cur, *p ); + p += 1 + *p; + } + + *olen = p - buf; + + /* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */ + buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF ); + buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF ); + + /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */ + buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF ); + buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF ); +} +#endif /* POLARSSL_SSL_ALPN */ + static int ssl_write_client_hello( ssl_context *ssl ) { int ret; @@ -390,6 +458,12 @@ static int ssl_write_client_hello( ssl_context *ssl ) SSL_DEBUG_MSG( 2, ( "=> write client hello" ) ); + if( ssl->f_rng == NULL ) + { + SSL_DEBUG_MSG( 1, ( "no RNG provided") ); + return( POLARSSL_ERR_SSL_NO_RNG ); + } + if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE ) { ssl->major_ver = ssl->min_major_ver; @@ -431,7 +505,7 @@ static int ssl_write_client_hello( ssl_context *ssl ) return( ret ); p += 4; -#endif +#endif /* POLARSSL_HAVE_TIME */ if( ( ret = ssl->f_rng( ssl->p_rng, p, 28 ) ) != 0 ) return( ret ); @@ -542,7 +616,7 @@ static int ssl_write_client_hello( ssl_context *ssl ) *p++ = 1; *p++ = SSL_COMPRESS_NULL; -#endif +#endif /* POLARSSL_ZLIB_SUPPORT */ // First write extensions, then the total length // @@ -582,12 +656,20 @@ static int ssl_write_client_hello( ssl_context *ssl ) ext_len += olen; #endif +#if defined(POLARSSL_SSL_ALPN) + ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d", ext_len ) ); - *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( ext_len ) & 0xFF ); - p += ext_len; + if( ext_len > 0 ) + { + *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ext_len ) & 0xFF ); + p += ext_len; + } ssl->out_msglen = p - buf; ssl->out_msgtype = SSL_MSG_HANDSHAKE; @@ -721,7 +803,7 @@ static int ssl_parse_supported_point_formats_ext( ssl_context *ssl, return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); } - p = buf + 2; + p = buf + 1; while( list_size > 0 ) { if( p[0] == POLARSSL_ECP_PF_UNCOMPRESSED || @@ -736,10 +818,59 @@ static int ssl_parse_supported_point_formats_ext( ssl_context *ssl, p++; } - return( 0 ); + SSL_DEBUG_MSG( 1, ( "no point format in common" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); } #endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */ +#if defined(POLARSSL_SSL_ALPN) +static int ssl_parse_alpn_ext( ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + size_t list_len, name_len; + const char **p; + + /* If we didn't send it, the server shouldn't send it */ + if( ssl->alpn_list == NULL ) + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + + /* + * opaque ProtocolName<1..2^8-1>; + * + * struct { + * ProtocolName protocol_name_list<2..2^16-1> + * } ProtocolNameList; + * + * the "ProtocolNameList" MUST contain exactly one "ProtocolName" + */ + + /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ + if( len < 4 ) + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + + list_len = ( buf[0] << 8 ) | buf[1]; + if( list_len != len - 2 ) + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + + name_len = buf[2]; + if( name_len != list_len - 1 ) + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + + /* Check that the server chosen protocol was in our list and save it */ + for( p = ssl->alpn_list; *p != NULL; p++ ) + { + if( name_len == strlen( *p ) && + memcmp( buf + 3, *p, name_len ) == 0 ) + { + ssl->alpn_chosen = *p; + return( 0 ); + } + } + + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); +} +#endif /* POLARSSL_SSL_ALPN */ + static int ssl_parse_server_hello( ssl_context *ssl ) { int ret, i, comp; @@ -797,8 +928,8 @@ static int ssl_parse_server_hello( ssl_context *ssl ) if( ssl->minor_ver < ssl->min_minor_ver ) { SSL_DEBUG_MSG( 1, ( "server only supports ssl smaller than minimum" - " [%d:%d] < [%d:%d]", ssl->major_ver, ssl->minor_ver, - buf[4], buf[5] ) ); + " [%d:%d] < [%d:%d]", ssl->major_ver, + ssl->minor_ver, buf[4], buf[5] ) ); ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL, SSL_ALERT_MSG_PROTOCOL_VERSION ); @@ -854,15 +985,15 @@ static int ssl_parse_server_hello( ssl_context *ssl ) * Initialize update checksum functions */ ssl->transform_negotiate->ciphersuite_info = ssl_ciphersuite_from_id( i ); - ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info ); if( ssl->transform_negotiate->ciphersuite_info == NULL ) { - SSL_DEBUG_MSG( 1, ( "ciphersuite info for %02x not found", - ssl->ciphersuite_list[ssl->minor_ver][i] ) ); + SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) ); return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); } + ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info ); + SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n ); @@ -953,7 +1084,8 @@ static int ssl_parse_server_hello( ssl_context *ssl ) SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); renegotiation_info_seen = 1; - if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size ) ) != 0 ) + if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4, + ext_size ) ) != 0 ) return( ret ); break; @@ -1010,6 +1142,16 @@ static int ssl_parse_server_hello( ssl_context *ssl ) break; #endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */ +#if defined(POLARSSL_SSL_ALPN) + case TLS_EXT_ALPN: + SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); + + if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 ) + return( ret ); + + break; +#endif /* POLARSSL_SSL_ALPN */ + default: SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", ext_id ) ); @@ -1107,6 +1249,42 @@ static int ssl_parse_server_dh_params( ssl_context *ssl, unsigned char **p, #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED || POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +static int ssl_check_server_ecdh_params( const ssl_context *ssl ) +{ + const ecp_curve_info *curve_info; + + curve_info = ecp_curve_info_from_grp_id( ssl->handshake->ecdh_ctx.grp.id ); + if( curve_info == NULL ) + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) ); + +#if defined(POLARSSL_SSL_ECP_SET_CURVES) + if( ! ssl_curve_is_acceptable( ssl, ssl->handshake->ecdh_ctx.grp.id ) ) +#else + if( ssl->handshake->ecdh_ctx.grp.nbits < 163 || + ssl->handshake->ecdh_ctx.grp.nbits > 521 ) +#endif + return( -1 ); + + SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp ); + + return( 0 ); +} +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) @@ -1131,18 +1309,12 @@ static int ssl_parse_server_ecdh_params( ssl_context *ssl, return( ret ); } - SSL_DEBUG_MSG( 2, ( "ECDH curve size: %d", - (int) ssl->handshake->ecdh_ctx.grp.nbits ) ); - - if( ssl->handshake->ecdh_ctx.grp.nbits < 163 || - ssl->handshake->ecdh_ctx.grp.nbits > 521 ) + if( ssl_check_server_ecdh_params( ssl ) != 0 ) { - SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDH length)" ) ); + SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDHE curve)" ) ); return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } - SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp ); - return( ret ); } #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED || @@ -1301,6 +1473,41 @@ static int ssl_parse_signature_algorithm( ssl_context *ssl, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ #endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +static int ssl_get_ecdh_params_from_cert( ssl_context *ssl ) +{ + int ret; + const ecp_keypair *peer_key; + + if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk, + POLARSSL_PK_ECKEY ) ) + { + SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) ); + return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH ); + } + + peer_key = pk_ec( ssl->session_negotiate->peer_cert->pk ); + + if( ( ret = ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key, + POLARSSL_ECDH_THEIRS ) ) != 0 ) + { + SSL_DEBUG_RET( 1, ( "ecdh_get_params" ), ret ); + return( ret ); + } + + if( ssl_check_server_ecdh_params( ssl ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE ); + } + + return( ret ); +} +#endif /* POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || + POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + static int ssl_parse_server_key_exchange( ssl_context *ssl ) { int ret; @@ -1329,6 +1536,26 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) ((void) end); #endif +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_ECDSA ) + { + if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret ); + return( ret ); + } + + SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) ); + ssl->state++; + return( 0 ); + } + ((void) p); + ((void) end); +#endif /* POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + if( ( ret = ssl_read_record( ssl ) ) != 0 ) { SSL_DEBUG_RET( 1, "ssl_read_record", ret ); @@ -1417,7 +1644,7 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ @@ -1449,7 +1676,7 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) } } else -#endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ #if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ defined(POLARSSL_SSL_PROTO_TLS1_1) if( ssl->minor_ver < SSL_MINOR_VERSION_3 ) @@ -1464,7 +1691,7 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) #endif { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } /* @@ -1491,6 +1718,9 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) md5_context md5; sha1_context sha1; + md5_init( &md5 ); + sha1_init( &sha1 ); + hashlen = 36; /* @@ -1515,6 +1745,9 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) sha1_update( &sha1, ssl->handshake->randbytes, 64 ); sha1_update( &sha1, ssl->in_msg + 4, params_len ); sha1_finish( &sha1, hash + 16 ); + + md5_free( &md5 ); + sha1_free( &sha1 ); } else #endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 || \ @@ -1525,6 +1758,8 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) { md_context_t ctx; + md_init( &ctx ); + /* Info from md_alg will be used instead */ hashlen = 0; @@ -1535,7 +1770,8 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) * ServerDHParams params; * }; */ - if( ( ret = md_init_ctx( &ctx, md_info_from_type( md_alg ) ) ) != 0 ) + if( ( ret = md_init_ctx( &ctx, + md_info_from_type( md_alg ) ) ) != 0 ) { SSL_DEBUG_RET( 1, "md_init_ctx", ret ); return( ret ); @@ -1545,14 +1781,14 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) md_update( &ctx, ssl->handshake->randbytes, 64 ); md_update( &ctx, ssl->in_msg + 4, params_len ); md_finish( &ctx, hash ); - md_free_ctx( &ctx ); + md_free( &ctx ); } else #endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \ POLARSSL_SSL_PROTO_TLS1_2 */ { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen : @@ -1586,15 +1822,50 @@ exit: return( 0 ); } +#if !defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +static int ssl_parse_certificate_request( ssl_context *ssl ) +{ + const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); + + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); + ssl->state++; + return( 0 ); + } + + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); +} +#else static int ssl_parse_certificate_request( ssl_context *ssl ) { int ret; unsigned char *buf, *p; size_t n = 0, m = 0; size_t cert_type_len = 0, dn_len = 0; + const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); + ssl->state++; + return( 0 ); + } + /* * 0 . 0 handshake type * 1 . 3 handshake length @@ -1720,6 +1991,10 @@ exit: return( 0 ); } +#endif /* !POLARSSL_KEY_EXCHANGE_RSA_ENABLED && + !POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED && + !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ static int ssl_parse_server_hello_done( ssl_context *ssl ) { @@ -1790,7 +2065,7 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X ); SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); - ssl->handshake->pmslen = ssl->handshake->dhm_ctx.len; + ssl->handshake->pmslen = POLARSSL_PREMASTER_SIZE; if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx, ssl->handshake->premaster, @@ -1806,9 +2081,13 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) else #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED */ #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA || - ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA ) + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_ECDSA ) { /* * ECDH key exchange -- send client public value @@ -1841,7 +2120,9 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) } else #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || @@ -1920,7 +2201,7 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } if( ( ret = ssl_psk_derive_premaster( ssl, @@ -1944,7 +2225,7 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) { ((void) ciphersuite_info); SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } if( ( ret = ssl_derive_keys( ssl ) ) != 0 ) @@ -1976,12 +2257,12 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) static int ssl_write_certificate_verify( ssl_context *ssl ) { - int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ) { @@ -1990,8 +2271,8 @@ static int ssl_write_certificate_verify( ssl_context *ssl ) return( 0 ); } - SSL_DEBUG_MSG( 1, ( "should not happen" ) ); - return( ret ); + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } #else static int ssl_write_certificate_verify( ssl_context *ssl ) @@ -2007,6 +2288,7 @@ static int ssl_write_certificate_verify( ssl_context *ssl ) SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ) { @@ -2104,7 +2386,7 @@ static int ssl_write_certificate_verify( ssl_context *ssl ) #endif /* POLARSSL_SSL_PROTO_TLS1_2 */ { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } if( ( ret = pk_sign( ssl_own_key( ssl ), md_alg, hash_start, hashlen, @@ -2199,9 +2481,11 @@ static int ssl_parse_new_session_ticket( ssl_context *ssl ) * Zero-length ticket means the server changed his mind and doesn't want * to send a ticket after all, so just forget it */ - if( ticket_len == 0) + if( ticket_len == 0 ) return( 0 ); + polarssl_zeroize( ssl->session_negotiate->ticket, + ssl->session_negotiate->ticket_len ); polarssl_free( ssl->session_negotiate->ticket ); ssl->session_negotiate->ticket = NULL; ssl->session_negotiate->ticket_len = 0; @@ -2348,4 +2632,4 @@ int ssl_handshake_client_step( ssl_context *ssl ) return( ret ); } -#endif +#endif /* POLARSSL_SSL_CLI_C */ diff --git a/pdns/ext/polarssl/library/ssl_srv.c b/pdns/ext/polarssl/library/ssl_srv.c index e44bf7212..25be98826 100644 --- a/pdns/ext/polarssl/library/ssl_srv.c +++ b/pdns/ext/polarssl/library/ssl_srv.c @@ -1,7 +1,7 @@ /* * SSLv3/TLSv1 server-side functions * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,7 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_SSL_SRV_C) @@ -33,8 +37,8 @@ #include "polarssl/ecp.h" #endif -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else #define polarssl_malloc malloc #define polarssl_free free @@ -48,6 +52,11 @@ #endif #if defined(POLARSSL_SSL_SESSION_TICKETS) +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + /* * Serialize a session in the following format: * 0 . n-1 session structure, n = sizeof(ssl_session) @@ -140,7 +149,8 @@ static int ssl_load_session( ssl_session *session, x509_crt_init( session->peer_cert ); - if( ( ret = x509_crt_parse( session->peer_cert, p, cert_len ) ) != 0 ) + if( ( ret = x509_crt_parse_der( session->peer_cert, + p, cert_len ) ) != 0 ) { x509_crt_free( session->peer_cert ); polarssl_free( session->peer_cert ); @@ -202,7 +212,7 @@ static int ssl_write_ticket( ssl_context *ssl, size_t *tlen ) */ state = p + 2; if( ssl_save_session( ssl->session_negotiate, state, - SSL_MAX_CONTENT_LEN - (state - ssl->out_ctr) - 48, + SSL_MAX_CONTENT_LEN - ( state - ssl->out_ctr ) - 48, &clear_len ) != 0 ) { return( POLARSSL_ERR_SSL_CERTIFICATE_TOO_LARGE ); @@ -310,7 +320,7 @@ static int ssl_parse_ticket( ssl_context *ssl, if( ( ret = ssl_load_session( &session, ticket, clear_len ) ) != 0 ) { SSL_DEBUG_MSG( 1, ( "failed to parse ticket content" ) ); - memset( &session, 0, sizeof( ssl_session ) ); + ssl_session_free( &session ); return( ret ); } @@ -319,7 +329,7 @@ static int ssl_parse_ticket( ssl_context *ssl, if( (int) ( time( NULL) - session.start ) > ssl->ticket_lifetime ) { SSL_DEBUG_MSG( 1, ( "session ticket expired" ) ); - memset( &session, 0, sizeof( ssl_session ) ); + ssl_session_free( &session ); return( POLARSSL_ERR_SSL_SESSION_TICKET_EXPIRED ); } #endif @@ -333,7 +343,9 @@ static int ssl_parse_ticket( ssl_context *ssl, ssl_session_free( ssl->session_negotiate ); memcpy( ssl->session_negotiate, &session, sizeof( ssl_session ) ); - memset( &session, 0, sizeof( ssl_session ) ); + + /* Zeroize instead of free as we copied the content */ + polarssl_zeroize( &session, sizeof( ssl_session ) ); return( 0 ); } @@ -367,6 +379,8 @@ static int ssl_parse_servername_ext( ssl_context *ssl, size_t servername_list_size, hostname_len; const unsigned char *p; + SSL_DEBUG_MSG( 3, ( "parse ServerName extension" ) ); + servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); if( servername_list_size + 2 != len ) { @@ -389,6 +403,7 @@ static int ssl_parse_servername_ext( ssl_context *ssl, ret = ssl_sni_wrapper( ssl, p + 3, hostname_len ); if( ret != 0 ) { + SSL_DEBUG_RET( 1, "ssl_sni_wrapper", ret ); ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL, SSL_ALERT_MSG_UNRECOGNIZED_NAME ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); @@ -457,59 +472,31 @@ static int ssl_parse_signature_algorithms_ext( ssl_context *ssl, { size_t sig_alg_list_size; const unsigned char *p; + const unsigned char *end = buf + len; + const int *md_cur; + sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); if( sig_alg_list_size + 2 != len || - sig_alg_list_size %2 != 0 ) + sig_alg_list_size % 2 != 0 ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } - p = buf + 2; - while( sig_alg_list_size > 0 ) - { - /* - * For now, just ignore signature algorithm and rely on offered - * ciphersuites only. To be fixed later. - */ -#if defined(POLARSSL_SHA512_C) - if( p[0] == SSL_HASH_SHA512 ) - { - ssl->handshake->sig_alg = SSL_HASH_SHA512; - break; - } - if( p[0] == SSL_HASH_SHA384 ) - { - ssl->handshake->sig_alg = SSL_HASH_SHA384; - break; - } -#endif -#if defined(POLARSSL_SHA256_C) - if( p[0] == SSL_HASH_SHA256 ) - { - ssl->handshake->sig_alg = SSL_HASH_SHA256; - break; - } - if( p[0] == SSL_HASH_SHA224 ) - { - ssl->handshake->sig_alg = SSL_HASH_SHA224; - break; - } -#endif - if( p[0] == SSL_HASH_SHA1 ) - { - ssl->handshake->sig_alg = SSL_HASH_SHA1; - break; - } - if( p[0] == SSL_HASH_MD5 ) - { - ssl->handshake->sig_alg = SSL_HASH_MD5; - break; + /* + * For now, ignore the SignatureAlgorithm part and rely on offered + * ciphersuites only for that part. To be fixed later. + * + * So, just look at the HashAlgorithm part. + */ + for( md_cur = md_list(); *md_cur != POLARSSL_MD_NONE; md_cur++ ) { + for( p = buf + 2; p < end; p += 2 ) { + if( *md_cur == (int) ssl_md_alg_from_hash( p[0] ) ) { + ssl->handshake->sig_alg = p[0]; + break; + } } - - sig_alg_list_size -= 2; - p += 2; } SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d", @@ -536,7 +523,7 @@ static int ssl_parse_supported_elliptic_curves( ssl_context *ssl, return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } - /* Don't allow our peer to make use allocated too much memory, + /* Don't allow our peer to make us allocate too much memory, * and leave room for a final 0 */ our_size = list_size / 2 + 1; if( our_size > POLARSSL_ECP_DP_MAX ) @@ -545,7 +532,7 @@ static int ssl_parse_supported_elliptic_curves( ssl_context *ssl, if( ( curves = polarssl_malloc( our_size * sizeof( *curves ) ) ) == NULL ) return( POLARSSL_ERR_SSL_MALLOC_FAILED ); - /* explicit void pointer cast for buggy MS compiler */ + /* explicit void pointer cast for buggy MS compiler */ memset( (void *) curves, 0, our_size * sizeof( *curves ) ); ssl->handshake->curves = curves; @@ -680,6 +667,207 @@ static int ssl_parse_session_ticket_ext( ssl_context *ssl, } #endif /* POLARSSL_SSL_SESSION_TICKETS */ +#if defined(POLARSSL_SSL_ALPN) +static int ssl_parse_alpn_ext( ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + size_t list_len, cur_len, ours_len; + const unsigned char *theirs, *start, *end; + const char **ours; + + /* If ALPN not configured, just ignore the extension */ + if( ssl->alpn_list == NULL ) + return( 0 ); + + /* + * opaque ProtocolName<1..2^8-1>; + * + * struct { + * ProtocolName protocol_name_list<2..2^16-1> + * } ProtocolNameList; + */ + + /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ + if( len < 4 ) + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + + list_len = ( buf[0] << 8 ) | buf[1]; + if( list_len != len - 2 ) + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + + /* + * Use our order of preference + */ + start = buf + 2; + end = buf + len; + for( ours = ssl->alpn_list; *ours != NULL; ours++ ) + { + ours_len = strlen( *ours ); + for( theirs = start; theirs != end; theirs += cur_len ) + { + /* If the list is well formed, we should get equality first */ + if( theirs > end ) + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + + cur_len = *theirs++; + + /* Empty strings MUST NOT be included */ + if( cur_len == 0 ) + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + + if( cur_len == ours_len && + memcmp( theirs, *ours, cur_len ) == 0 ) + { + ssl->alpn_chosen = *ours; + return( 0 ); + } + } + } + + /* If we get there, no match was found */ + ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL, + SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); +} +#endif /* POLARSSL_SSL_ALPN */ + +/* + * Auxiliary functions for ServerHello parsing and related actions + */ + +#if defined(POLARSSL_X509_CRT_PARSE_C) +/* + * Return 1 if the given EC key uses the given curve, 0 otherwise + */ +#if defined(POLARSSL_ECDSA_C) +static int ssl_key_matches_curves( pk_context *pk, + const ecp_curve_info **curves ) +{ + const ecp_curve_info **crv = curves; + ecp_group_id grp_id = pk_ec( *pk )->grp.id; + + while( *crv != NULL ) + { + if( (*crv)->grp_id == grp_id ) + return( 1 ); + crv++; + } + + return( 0 ); +} +#endif /* POLARSSL_ECDSA_C */ + +/* + * Try picking a certificate for this ciphersuite, + * return 0 on success and -1 on failure. + */ +static int ssl_pick_cert( ssl_context *ssl, + const ssl_ciphersuite_t * ciphersuite_info ) +{ + ssl_key_cert *cur, *list; + pk_type_t pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); + +#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) + if( ssl->handshake->sni_key_cert != NULL ) + list = ssl->handshake->sni_key_cert; + else +#endif + list = ssl->handshake->key_cert; + + if( pk_alg == POLARSSL_PK_NONE ) + return( 0 ); + + for( cur = list; cur != NULL; cur = cur->next ) + { + if( ! pk_can_do( cur->key, pk_alg ) ) + continue; + + /* + * This avoids sending the client a cert it'll reject based on + * keyUsage or other extensions. + * + * It also allows the user to provision different certificates for + * different uses based on keyUsage, eg if they want to avoid signing + * and decrypting with the same RSA key. + */ + if( ssl_check_cert_usage( cur->cert, ciphersuite_info, + SSL_IS_SERVER ) != 0 ) + { + continue; + } + +#if defined(POLARSSL_ECDSA_C) + if( pk_alg == POLARSSL_PK_ECDSA ) + { + if( ssl_key_matches_curves( cur->key, ssl->handshake->curves ) ) + break; + } + else +#endif + break; + } + + if( cur == NULL ) + return( -1 ); + + ssl->handshake->key_cert = cur; + return( 0 ); +} +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +/* + * Check if a given ciphersuite is suitable for use with our config/keys/etc + * Sets ciphersuite_info only if the suite matches. + */ +static int ssl_ciphersuite_match( ssl_context *ssl, int suite_id, + const ssl_ciphersuite_t **ciphersuite_info ) +{ + const ssl_ciphersuite_t *suite_info; + + suite_info = ssl_ciphersuite_from_id( suite_id ); + if( suite_info == NULL ) + { + SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", suite_id ) ); + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + + if( suite_info->min_minor_ver > ssl->minor_ver || + suite_info->max_minor_ver < ssl->minor_ver ) + return( 0 ); + +#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) + if( ssl_ciphersuite_uses_ec( suite_info ) && + ( ssl->handshake->curves == NULL || + ssl->handshake->curves[0] == NULL ) ) + return( 0 ); +#endif + +#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) + /* If the ciphersuite requires a pre-shared key and we don't + * have one, skip it now rather than failing later */ + if( ssl_ciphersuite_uses_psk( suite_info ) && + ssl->f_psk == NULL && + ( ssl->psk == NULL || ssl->psk_identity == NULL || + ssl->psk_identity_len == 0 || ssl->psk_len == 0 ) ) + return( 0 ); +#endif + +#if defined(POLARSSL_X509_CRT_PARSE_C) + /* + * Final check: if ciphersuite requires us to have a + * certificate/key of a particular type: + * - select the appropriate certificate if we have one, or + * - try the next ciphersuite if we don't + * This must be done last since we modify the key_cert list. + */ + if( ssl_pick_cert( ssl, suite_info ) != 0 ) + return( 0 ); +#endif + + *ciphersuite_info = suite_info; + return( 0 ); +} + #if defined(POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) static int ssl_parse_client_hello_v2( ssl_context *ssl ) { @@ -746,7 +934,8 @@ static int ssl_parse_client_hello_v2( ssl_context *ssl ) if( ssl->minor_ver < ssl->min_minor_ver ) { SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" - " [%d:%d] < [%d:%d]", ssl->major_ver, ssl->minor_ver, + " [%d:%d] < [%d:%d]", + ssl->major_ver, ssl->minor_ver, ssl->min_major_ver, ssl->min_minor_ver ) ); ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL, @@ -821,7 +1010,8 @@ static int ssl_parse_client_hello_v2( ssl_context *ssl ) p = buf + 6 + ciph_len; ssl->session_negotiate->length = sess_len; - memset( ssl->session_negotiate->id, 0, sizeof( ssl->session_negotiate->id ) ); + memset( ssl->session_negotiate->id, 0, + sizeof( ssl->session_negotiate->id ) ); memcpy( ssl->session_negotiate->id, p, ssl->session_negotiate->length ); p += sess_len; @@ -851,31 +1041,28 @@ static int ssl_parse_client_hello_v2( ssl_context *ssl ) } ciphersuites = ssl->ciphersuite_list[ssl->minor_ver]; + ciphersuite_info = NULL; +#if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE) + for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) + { + for( i = 0; ciphersuites[i] != 0; i++ ) +#else for( i = 0; ciphersuites[i] != 0; i++ ) { for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) +#endif { - // Only allow non-ECC ciphersuites as we do not have extensions - // - if( p[0] == 0 && p[1] == 0 && - ( ( ciphersuites[i] >> 8 ) & 0xFF ) == 0 && - p[2] == ( ciphersuites[i] & 0xFF ) ) - { - ciphersuite_info = ssl_ciphersuite_from_id( ciphersuites[i] ); + if( p[0] != 0 || + p[1] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || + p[2] != ( ( ciphersuites[i] ) & 0xFF ) ) + continue; - if( ciphersuite_info == NULL ) - { - SSL_DEBUG_MSG( 1, ( "ciphersuite info for %02x not found", - ciphersuites[i] ) ); - return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); - } - - if( ciphersuite_info->min_minor_ver > ssl->minor_ver || - ciphersuite_info->max_minor_ver < ssl->minor_ver ) - continue; + if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], + &ciphersuite_info ) ) != 0 ) + return( ret ); + if( ciphersuite_info != NULL ) goto have_ciphersuite_v2; - } } } @@ -911,69 +1098,6 @@ have_ciphersuite_v2: } #endif /* POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ -#if defined(POLARSSL_X509_CRT_PARSE_C) -#if defined(POLARSSL_ECDSA_C) -static int ssl_key_matches_curves( pk_context *pk, - const ecp_curve_info **curves ) -{ - const ecp_curve_info **crv = curves; - ecp_group_id grp_id = pk_ec( *pk )->grp.id; - - while( *crv != NULL ) - { - if( (*crv)->grp_id == grp_id ) - return( 1 ); - crv++; - } - - return( 0 ); -} -#endif /* POLARSSL_ECDSA_C */ - -/* - * Try picking a certificate for this ciphersuite, - * return 0 on success and -1 on failure. - */ -static int ssl_pick_cert( ssl_context *ssl, - const ssl_ciphersuite_t * ciphersuite_info ) -{ - ssl_key_cert *cur, *list; - pk_type_t pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); - -#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) - if( ssl->handshake->sni_key_cert != NULL ) - list = ssl->handshake->sni_key_cert; - else -#endif - list = ssl->handshake->key_cert; - - if( pk_alg == POLARSSL_PK_NONE ) - return( 0 ); - - for( cur = list; cur != NULL; cur = cur->next ) - { - if( ! pk_can_do( cur->key, pk_alg ) ) - continue; - -#if defined(POLARSSL_ECDSA_C) - if( pk_alg == POLARSSL_PK_ECDSA ) - { - if( ssl_key_matches_curves( cur->key, ssl->handshake->curves ) ) - break; - } - else -#endif - break; - } - - if( cur == NULL ) - return( -1 ); - - ssl->handshake->key_cert = cur; - return( 0 ); -} -#endif /* POLARSSL_X509_CRT_PARSE_C */ - static int ssl_parse_client_hello( ssl_context *ssl ) { int ret; @@ -1014,15 +1138,20 @@ static int ssl_parse_client_hello( ssl_context *ssl ) buf[1], buf[2] ) ); /* - * SSLv3 Client Hello + * SSLv3/TLS Client Hello * * Record layer: * 0 . 0 message type * 1 . 2 protocol version * 3 . 4 message length */ + + /* According to RFC 5246 Appendix E.1, the version here is typically + * "{03,00}, the lowest version number supported by the client, [or] the + * value of ClientHello.client_version", so the only meaningful check here + * is the major version shouldn't be less than 3 */ if( buf[0] != SSL_MSG_HANDSHAKE || - buf[1] != SSL_MAJOR_VERSION_3 ) + buf[1] < SSL_MAJOR_VERSION_3 ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); @@ -1030,7 +1159,7 @@ static int ssl_parse_client_hello( ssl_context *ssl ) n = ( buf[3] << 8 ) | buf[4]; - if( n < 45 || n > 2048 ) + if( n < 45 || n > SSL_MAX_CONTENT_LEN ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); @@ -1061,8 +1190,9 @@ static int ssl_parse_client_hello( ssl_context *ssl ) * 38 . 38 session id length * 39 . 38+x session id * 39+x . 40+x ciphersuitelist length - * 41+x . .. ciphersuitelist - * .. . .. compression alg. + * 41+x . 40+y ciphersuitelist + * 41+y . 41+y compression alg length + * 42+y . 41+z compression algs * .. . .. extensions */ SSL_DEBUG_BUF( 4, "record contents", buf, n ); @@ -1077,21 +1207,24 @@ static int ssl_parse_client_hello( ssl_context *ssl ) /* * Check the handshake type and protocol version */ - if( buf[0] != SSL_HS_CLIENT_HELLO || - buf[4] != SSL_MAJOR_VERSION_3 ) + if( buf[0] != SSL_HS_CLIENT_HELLO ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } - ssl->major_ver = SSL_MAJOR_VERSION_3; - ssl->minor_ver = ( buf[5] <= ssl->max_minor_ver ) - ? buf[5] : ssl->max_minor_ver; + ssl->major_ver = buf[4]; + ssl->minor_ver = buf[5]; - if( ssl->minor_ver < ssl->min_minor_ver ) + ssl->handshake->max_major_ver = ssl->major_ver; + ssl->handshake->max_minor_ver = ssl->minor_ver; + + if( ssl->major_ver < ssl->min_major_ver || + ssl->minor_ver < ssl->min_minor_ver ) { SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" - " [%d:%d] < [%d:%d]", ssl->major_ver, ssl->minor_ver, + " [%d:%d] < [%d:%d]", + ssl->major_ver, ssl->minor_ver, ssl->min_major_ver, ssl->min_minor_ver ) ); ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL, @@ -1100,8 +1233,13 @@ static int ssl_parse_client_hello( ssl_context *ssl ) return( POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); } - ssl->handshake->max_major_ver = buf[4]; - ssl->handshake->max_minor_ver = buf[5]; + if( ssl->major_ver > ssl->max_major_ver ) + { + ssl->major_ver = ssl->max_major_ver; + ssl->minor_ver = ssl->max_minor_ver; + } + else if( ssl->minor_ver > ssl->max_minor_ver ) + ssl->minor_ver = ssl->max_minor_ver; memcpy( ssl->handshake->randbytes, buf + 6, 32 ); @@ -1119,7 +1257,7 @@ static int ssl_parse_client_hello( ssl_context *ssl ) */ sess_len = buf[38]; - if( sess_len > 32 ) + if( sess_len > 32 || sess_len > n - 42 ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); @@ -1137,7 +1275,7 @@ static int ssl_parse_client_hello( ssl_context *ssl ) ciph_len = ( buf[39 + sess_len] << 8 ) | ( buf[40 + sess_len] ); - if( ciph_len < 2 || ciph_len > 256 || ( ciph_len % 2 ) != 0 ) + if( ciph_len < 2 || ( ciph_len % 2 ) != 0 || ciph_len > n - 42 - sess_len ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); @@ -1148,7 +1286,8 @@ static int ssl_parse_client_hello( ssl_context *ssl ) */ comp_len = buf[41 + sess_len + ciph_len]; - if( comp_len < 1 || comp_len > 16 ) + if( comp_len < 1 || comp_len > 16 || + comp_len > n - 42 - sess_len - ciph_len ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); @@ -1312,6 +1451,16 @@ static int ssl_parse_client_hello( ssl_context *ssl ) break; #endif /* POLARSSL_SSL_SESSION_TICKETS */ +#if defined(POLARSSL_SSL_ALPN) + case TLS_EXT_ALPN: + SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); + + ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + default: SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", ext_id ) ); @@ -1372,58 +1521,27 @@ static int ssl_parse_client_hello( ssl_context *ssl ) * and certificate from the SNI callback triggered by the SNI extension.) */ ciphersuites = ssl->ciphersuite_list[ssl->minor_ver]; + ciphersuite_info = NULL; +#if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE) + for( j = 0, p = buf + 41 + sess_len; j < ciph_len; j += 2, p += 2 ) + { + for( i = 0; ciphersuites[i] != 0; i++ ) +#else for( i = 0; ciphersuites[i] != 0; i++ ) { - for( j = 0, p = buf + 41 + sess_len; j < ciph_len; - j += 2, p += 2 ) - { - if( p[0] == ( ( ciphersuites[i] >> 8 ) & 0xFF ) && - p[1] == ( ( ciphersuites[i] ) & 0xFF ) ) - { - ciphersuite_info = ssl_ciphersuite_from_id( ciphersuites[i] ); - - if( ciphersuite_info == NULL ) - { - SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", - ciphersuites[i] ) ); - return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); - } - - if( ciphersuite_info->min_minor_ver > ssl->minor_ver || - ciphersuite_info->max_minor_ver < ssl->minor_ver ) - continue; - -#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) - if( ssl_ciphersuite_uses_ec( ciphersuite_info ) && - ( ssl->handshake->curves == NULL || - ssl->handshake->curves[0] == NULL ) ) - continue; -#endif - -#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) - /* If the ciphersuite requires a pre-shared key and we don't - * have one, skip it now rather than failing later */ - if( ssl_ciphersuite_uses_psk( ciphersuite_info ) && - ssl->f_psk == NULL && - ( ssl->psk == NULL || ssl->psk_identity == NULL || - ssl->psk_identity_len == 0 || ssl->psk_len == 0 ) ) - continue; + for( j = 0, p = buf + 41 + sess_len; j < ciph_len; j += 2, p += 2 ) #endif + { + if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || + p[1] != ( ( ciphersuites[i] ) & 0xFF ) ) + continue; -#if defined(POLARSSL_X509_CRT_PARSE_C) - /* - * Final check: if ciphersuite requires us to have a - * certificate/key of a particular type: - * - select the appropriate certificate if we have one, or - * - try the next ciphersuite if we don't - * This must be done last since we modify the key_cert list. - */ - if( ssl_pick_cert( ssl, ciphersuite_info ) != 0 ) - continue; -#endif + if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], + &ciphersuite_info ) ) != 0 ) + return( ret ); + if( ciphersuite_info != NULL ) goto have_ciphersuite; - } } } @@ -1583,6 +1701,42 @@ static void ssl_write_supported_point_formats_ext( ssl_context *ssl, } #endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */ +#if defined(POLARSSL_SSL_ALPN ) +static void ssl_write_alpn_ext( ssl_context *ssl, + unsigned char *buf, size_t *olen ) +{ + if( ssl->alpn_chosen == NULL ) + { + *olen = 0; + return; + } + + SSL_DEBUG_MSG( 3, ( "server hello, adding alpn extension" ) ); + + /* + * 0 . 1 ext identifier + * 2 . 3 ext length + * 4 . 5 protocol list length + * 6 . 6 protocol name length + * 7 . 7+n protocol name + */ + buf[0] = (unsigned char)( ( TLS_EXT_ALPN >> 8 ) & 0xFF ); + buf[1] = (unsigned char)( ( TLS_EXT_ALPN ) & 0xFF ); + + *olen = 7 + strlen( ssl->alpn_chosen ); + + buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF ); + buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF ); + + buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF ); + buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF ); + + buf[6] = (unsigned char)( ( ( *olen - 7 ) ) & 0xFF ); + + memcpy( buf + 7, ssl->alpn_chosen, *olen - 7 ); +} +#endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */ + static int ssl_write_server_hello( ssl_context *ssl ) { #if defined(POLARSSL_HAVE_TIME) @@ -1594,6 +1748,12 @@ static int ssl_write_server_hello( ssl_context *ssl ) SSL_DEBUG_MSG( 2, ( "=> write server hello" ) ); + if( ssl->f_rng == NULL ) + { + SSL_DEBUG_MSG( 1, ( "no RNG provided") ); + return( POLARSSL_ERR_SSL_NO_RNG ); + } + /* * 0 . 0 handshake type * 1 . 3 handshake length @@ -1623,7 +1783,7 @@ static int ssl_write_server_hello( ssl_context *ssl ) return( ret ); p += 4; -#endif +#endif /* POLARSSL_HAVE_TIME */ if( ( ret = ssl->f_rng( ssl->p_rng, p, 28 ) ) != 0 ) return( ret ); @@ -1645,6 +1805,7 @@ static int ssl_write_server_hello( ssl_context *ssl ) ssl->f_get_cache != NULL && ssl->f_get_cache( ssl->p_get_cache, ssl->session_negotiate ) == 0 ) { + SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) ); ssl->handshake->resume = 1; } @@ -1742,11 +1903,19 @@ static int ssl_write_server_hello( ssl_context *ssl ) ext_len += olen; #endif +#if defined(POLARSSL_SSL_ALPN) + ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) ); - *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( ext_len ) & 0xFF ); - p += ext_len; + if( ext_len > 0 ) + { + *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ext_len ) & 0xFF ); + p += ext_len; + } ssl->out_msglen = p - buf; ssl->out_msgtype = SSL_MSG_HANDSHAKE; @@ -1765,12 +1934,12 @@ static int ssl_write_server_hello( ssl_context *ssl ) !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) static int ssl_write_certificate_request( ssl_context *ssl ) { - int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) { @@ -1779,8 +1948,8 @@ static int ssl_write_certificate_request( ssl_context *ssl ) return( 0 ); } - SSL_DEBUG_MSG( 1, ( "should not happen" ) ); - return( ret ); + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } #else static int ssl_write_certificate_request( ssl_context *ssl ) @@ -1797,6 +1966,7 @@ static int ssl_write_certificate_request( ssl_context *ssl ) ssl->state++; if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK || ssl->authmode == SSL_VERIFY_NONE ) @@ -1811,7 +1981,7 @@ static int ssl_write_certificate_request( ssl_context *ssl ) * 4 . 4 cert type count * 5 .. m-1 cert types * m .. m+1 sig alg length (TLS 1.2 only) - * m+1 .. n-1 SignatureAndHashAlgorithms (TLS 1.2 only) + * m+1 .. n-1 SignatureAndHashAlgorithms (TLS 1.2 only) * n .. n+1 length of all DNs * n+2 .. n+3 length of DN 1 * n+4 .. ... Distinguished Name #1 @@ -1894,7 +2064,7 @@ static int ssl_write_certificate_request( ssl_context *ssl ) crt = ssl->ca_chain; total_dn_size = 0; - while( crt != NULL ) + while( crt != NULL && crt->version != 0 ) { if( p - buf > 4096 ) break; @@ -1925,7 +2095,33 @@ static int ssl_write_certificate_request( ssl_context *ssl ) } #endif /* !POLARSSL_KEY_EXCHANGE_RSA_ENABLED && !POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED && - !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ + !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +static int ssl_get_ecdh_params_from_cert( ssl_context *ssl ) +{ + int ret; + + if( ! pk_can_do( ssl_own_key( ssl ), POLARSSL_PK_ECKEY ) ) + { + SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) ); + return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH ); + } + + if( ( ret = ecdh_get_params( &ssl->handshake->ecdh_ctx, + pk_ec( *ssl_own_key( ssl ) ), + POLARSSL_ECDH_OURS ) ) != 0 ) + { + SSL_DEBUG_RET( 1, ( "ecdh_get_params" ), ret ); + return( ret ); + } + + return( 0 ); +} +#endif /* POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || + POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ static int ssl_write_server_key_exchange( ssl_context *ssl ) { @@ -1948,6 +2144,9 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); +#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ) @@ -1956,6 +2155,20 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) ssl->state++; return( 0 ); } +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_ECDSA ) + { + ssl_get_ecdh_params_from_cert( ssl ); + + SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) ); + ssl->state++; + return( 0 ); + } +#endif #if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) @@ -1993,9 +2206,8 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) } if( ( ret = dhm_make_params( &ssl->handshake->dhm_ctx, - (int) mpi_size( &ssl->handshake->dhm_ctx.P ), - p, - &len, ssl->f_rng, ssl->p_rng ) ) != 0 ) + (int) mpi_size( &ssl->handshake->dhm_ctx.P ), + p, &len, ssl->f_rng, ssl->p_rng ) ) != 0 ) { SSL_DEBUG_RET( 1, "dhm_make_params", ret ); return( ret ); @@ -2015,10 +2227,7 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED || POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - +#if defined(POLARSSL_KEY_EXCHANGE__SOME__ECDHE_ENABLED) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) @@ -2031,16 +2240,36 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) * ECPoint public; * } ServerECDHParams; */ + const ecp_curve_info **curve = NULL; +#if defined(POLARSSL_SSL_SET_CURVES) + const ecp_group_id *gid; + + /* Match our preference list against the offered curves */ + for( gid = ssl->curve_list; *gid != POLARSSL_ECP_DP_NONE; gid++ ) + for( curve = ssl->handshake->curves; *curve != NULL; curve++ ) + if( (*curve)->grp_id == *gid ) + goto curve_matching_done; + +curve_matching_done: +#else + curve = ssl->handshake->curves; +#endif + + if( *curve == NULL ) + { + SSL_DEBUG_MSG( 1, ( "no matching curve for ECDHE" ) ); + return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN ); + } + + SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) ); + if( ( ret = ecp_use_known_dp( &ssl->handshake->ecdh_ctx.grp, - ssl->handshake->curves[0]->grp_id ) ) != 0 ) + (*curve)->grp_id ) ) != 0 ) { SSL_DEBUG_RET( 1, "ecp_use_known_dp", ret ); return( ret ); } - SSL_DEBUG_MSG( 2, ( "ECDH curve size: %d", - (int) ssl->handshake->ecdh_ctx.grp.nbits ) ); - if( ( ret = ecdh_make_params( &ssl->handshake->ecdh_ctx, &len, p, SSL_MAX_CONTENT_LEN - n, ssl->f_rng, ssl->p_rng ) ) != 0 ) @@ -2057,9 +2286,7 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) SSL_DEBUG_ECP( 3, "ECDH: Q ", &ssl->handshake->ecdh_ctx.Q ); } -#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ +#endif /* POLARSSL_KEY_EXCHANGE__SOME__ECDHE_ENABLED */ #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ @@ -2084,14 +2311,14 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) if( md_alg == POLARSSL_MD_NONE ) { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } } else -#endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ #if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ defined(POLARSSL_SSL_PROTO_TLS1_1) - if ( ciphersuite_info->key_exchange == + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA ) { md_alg = POLARSSL_MD_SHA1; @@ -2112,6 +2339,9 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) md5_context md5; sha1_context sha1; + md5_init( &md5 ); + sha1_init( &sha1 ); + /* * digitally-signed struct { * opaque md5_hash[16]; @@ -2136,6 +2366,9 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) sha1_finish( &sha1, hash + 16 ); hashlen = 36; + + md5_free( &md5 ); + sha1_free( &sha1 ); } else #endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 || \ @@ -2145,6 +2378,9 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) if( md_alg != POLARSSL_MD_NONE ) { md_context_t ctx; + const md_info_t *md_info = md_info_from_type( md_alg ); + + md_init( &ctx ); /* Info from md_alg will be used instead */ hashlen = 0; @@ -2156,7 +2392,7 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) * ServerDHParams params; * }; */ - if( ( ret = md_init_ctx( &ctx, md_info_from_type(md_alg) ) ) != 0 ) + if( ( ret = md_init_ctx( &ctx, md_info ) ) != 0 ) { SSL_DEBUG_RET( 1, "md_init_ctx", ret ); return( ret ); @@ -2166,20 +2402,14 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) md_update( &ctx, ssl->handshake->randbytes, 64 ); md_update( &ctx, dig_signed, dig_signed_len ); md_finish( &ctx, hash ); - - if( ( ret = md_free_ctx( &ctx ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "md_free_ctx", ret ); - return( ret ); - } - + md_free( &ctx ); } else #endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \ POLARSSL_SSL_PROTO_TLS1_2 */ { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen : @@ -2285,19 +2515,20 @@ static int ssl_parse_client_dh_public( ssl_context *ssl, unsigned char **p, n = ( (*p)[0] << 8 ) | (*p)[1]; *p += 2; - if( n < 1 || n > ssl->handshake->dhm_ctx.len || *p + n > end ) + if( *p + n > end ) { SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); } - if( ( ret = dhm_read_public( &ssl->handshake->dhm_ctx, - *p, n ) ) != 0 ) + if( ( ret = dhm_read_public( &ssl->handshake->dhm_ctx, *p, n ) ) != 0 ) { SSL_DEBUG_RET( 1, "dhm_read_public", ret ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); } + *p += n; + SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY ); return( ret ); @@ -2346,7 +2577,7 @@ static int ssl_parse_encrypted_pms( ssl_context *ssl, ret = pk_decrypt( ssl_own_key( ssl ), p, len, pms, &ssl->handshake->pmslen, - sizeof(ssl->handshake->premaster), + sizeof( ssl->handshake->premaster ) - pms_offset, ssl->f_rng, ssl->p_rng ); if( ret != 0 || ssl->handshake->pmslen != 48 || @@ -2408,11 +2639,10 @@ static int ssl_parse_client_psk_identity( ssl_context *ssl, unsigned char **p, if( ssl->f_psk != NULL ) { - if( ( ret != ssl->f_psk( ssl->p_psk, ssl, *p, n ) ) != 0 ) + if( ssl->f_psk( ssl->p_psk, ssl, *p, n ) != 0 ) ret = POLARSSL_ERR_SSL_UNKNOWN_IDENTITY; } - - if( ret == 0 ) + else { /* Identity is not a big secret since clients send it in the clear, * but treat it carefully anyway, just in case */ @@ -2437,9 +2667,8 @@ static int ssl_parse_client_psk_identity( ssl_context *ssl, unsigned char **p, } *p += n; - ret = 0; - return( ret ); + return( 0 ); } #endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */ @@ -2474,7 +2703,7 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA ) { unsigned char *p = ssl->in_msg + 4; - unsigned char *end = ssl->in_msg + ssl->in_msglen; + unsigned char *end = ssl->in_msg + ssl->in_hslen; if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 ) { @@ -2482,7 +2711,13 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) return( ret ); } - ssl->handshake->pmslen = ssl->handshake->dhm_ctx.len; + if( p != end ) + { + SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + ssl->handshake->pmslen = POLARSSL_PREMASTER_SIZE; if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx, ssl->handshake->premaster, @@ -2498,21 +2733,16 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) else #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED */ #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA || - ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA ) + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_ECDSA ) { - size_t n = ssl->in_msg[3]; - - if( n < 1 || n > mpi_size( &ssl->handshake->ecdh_ctx.grp.P ) * 2 + 2 || - n + 4 != ssl->in_hslen ) - { - SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - if( ( ret = ecdh_read_public( &ssl->handshake->ecdh_ctx, - ssl->in_msg + 4, n ) ) != 0 ) + ssl->in_msg + 4, ssl->in_hslen - 4 ) ) != 0 ) { SSL_DEBUG_RET( 1, "ecdh_read_public", ret ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); @@ -2534,12 +2764,14 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) } else #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ #if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ) { unsigned char *p = ssl->in_msg + 4; - unsigned char *end = ssl->in_msg + ssl->in_msglen; + unsigned char *end = ssl->in_msg + ssl->in_hslen; if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) { @@ -2547,6 +2779,12 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) return( ret ); } + if( p != end ) + { + SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + if( ( ret = ssl_psk_derive_premaster( ssl, ciphersuite_info->key_exchange ) ) != 0 ) { @@ -2560,7 +2798,7 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ) { unsigned char *p = ssl->in_msg + 4; - unsigned char *end = ssl->in_msg + ssl->in_msglen; + unsigned char *end = ssl->in_msg + ssl->in_hslen; if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) { @@ -2587,7 +2825,7 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ) { unsigned char *p = ssl->in_msg + 4; - unsigned char *end = ssl->in_msg + ssl->in_msglen; + unsigned char *end = ssl->in_msg + ssl->in_hslen; if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) { @@ -2600,6 +2838,12 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) return( ret ); } + if( p != end ) + { + SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + if( ( ret = ssl_psk_derive_premaster( ssl, ciphersuite_info->key_exchange ) ) != 0 ) { @@ -2613,7 +2857,7 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) { unsigned char *p = ssl->in_msg + 4; - unsigned char *end = ssl->in_msg + ssl->in_msglen; + unsigned char *end = ssl->in_msg + ssl->in_hslen; if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) { @@ -2644,10 +2888,10 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) { if( ( ret = ssl_parse_encrypted_pms( ssl, ssl->in_msg + 4, - ssl->in_msg + ssl->in_msglen, + ssl->in_msg + ssl->in_hslen, 0 ) ) != 0 ) { - SSL_DEBUG_RET( 1, ( "ssl_parse_parse_ecrypted_pms_secret" ), ret ); + SSL_DEBUG_RET( 1, ( "ssl_parse_parse_encrypted_pms_secret" ), ret ); return( ret ); } } @@ -2655,7 +2899,7 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) #endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED */ { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } if( ( ret = ssl_derive_keys( ssl ) ) != 0 ) @@ -2677,12 +2921,12 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) static int ssl_parse_certificate_verify( ssl_context *ssl ) { - int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ) { @@ -2691,8 +2935,8 @@ static int ssl_parse_certificate_verify( ssl_context *ssl ) return( 0 ); } - SSL_DEBUG_MSG( 1, ( "should not happen" ) ); - return( ret ); + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } #else static int ssl_parse_certificate_verify( ssl_context *ssl ) @@ -2711,6 +2955,7 @@ static int ssl_parse_certificate_verify( ssl_context *ssl ) SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ) { @@ -2775,7 +3020,8 @@ static int ssl_parse_certificate_verify( ssl_context *ssl ) } } else -#endif +#endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 || + POLARSSL_SSL_PROTO_TLS1_1 */ #if defined(POLARSSL_SSL_PROTO_TLS1_2) if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) { @@ -2820,7 +3066,7 @@ static int ssl_parse_certificate_verify( ssl_context *ssl ) #endif /* POLARSSL_SSL_PROTO_TLS1_2 */ { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } sig_len = ( ssl->in_msg[4 + sa_len] << 8 ) | ssl->in_msg[5 + sa_len]; @@ -2886,15 +3132,18 @@ static int ssl_write_new_session_ticket( ssl_context *ssl ) ssl->out_msglen = 10 + tlen; + /* + * Morally equivalent to updating ssl->state, but NewSessionTicket and + * ChangeCipherSpec share the same state. + */ + ssl->handshake->new_session_ticket = 0; + if( ( ret = ssl_write_record( ssl ) ) != 0 ) { SSL_DEBUG_RET( 1, "ssl_write_record", ret ); return( ret ); } - /* No need to remember writing a NewSessionTicket any more */ - ssl->handshake->new_session_ticket = 0; - SSL_DEBUG_MSG( 2, ( "<= write new session ticket" ) ); return( 0 ); @@ -3017,4 +3266,4 @@ int ssl_handshake_server_step( ssl_context *ssl ) return( ret ); } -#endif +#endif /* POLARSSL_SSL_SRV_C */ diff --git a/pdns/ext/polarssl/library/ssl_tls.c b/pdns/ext/polarssl/library/ssl_tls.c index bca55da97..8613b8d0e 100644 --- a/pdns/ext/polarssl/library/ssl_tls.c +++ b/pdns/ext/polarssl/library/ssl_tls.c @@ -1,7 +1,7 @@ /* * SSLv3/TLSv1 shared functions * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -31,15 +31,24 @@ * http://www.ietf.org/rfc/rfc4346.txt */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_SSL_TLS_C) #include "polarssl/debug.h" #include "polarssl/ssl.h" -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_X509_CRT_PARSE_C) && \ + defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) +#include "polarssl/oid.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else #define polarssl_malloc malloc #define polarssl_free free @@ -52,6 +61,11 @@ #define strcasecmp _stricmp #endif +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) /* * Convert max_fragment_length codes to length. @@ -87,8 +101,8 @@ static int ssl_session_copy( ssl_session *dst, const ssl_session *src ) x509_crt_init( dst->peer_cert ); - if( ( ret = x509_crt_parse( dst->peer_cert, src->peer_cert->raw.p, - src->peer_cert->raw.len ) != 0 ) ) + if( ( ret = x509_crt_parse_der( dst->peer_cert, src->peer_cert->raw.p, + src->peer_cert->raw.len ) ) != 0 ) { polarssl_free( dst->peer_cert ); dst->peer_cert = NULL; @@ -112,19 +126,19 @@ static int ssl_session_copy( ssl_session *dst, const ssl_session *src ) } #if defined(POLARSSL_SSL_HW_RECORD_ACCEL) -int (*ssl_hw_record_init)(ssl_context *ssl, - const unsigned char *key_enc, const unsigned char *key_dec, - size_t keylen, - const unsigned char *iv_enc, const unsigned char *iv_dec, - size_t ivlen, - const unsigned char *mac_enc, const unsigned char *mac_dec, - size_t maclen) = NULL; -int (*ssl_hw_record_activate)(ssl_context *ssl, int direction) = NULL; -int (*ssl_hw_record_reset)(ssl_context *ssl) = NULL; -int (*ssl_hw_record_write)(ssl_context *ssl) = NULL; -int (*ssl_hw_record_read)(ssl_context *ssl) = NULL; -int (*ssl_hw_record_finish)(ssl_context *ssl) = NULL; -#endif +int (*ssl_hw_record_init)( ssl_context *ssl, + const unsigned char *key_enc, const unsigned char *key_dec, + size_t keylen, + const unsigned char *iv_enc, const unsigned char *iv_dec, + size_t ivlen, + const unsigned char *mac_enc, const unsigned char *mac_dec, + size_t maclen ) = NULL; +int (*ssl_hw_record_activate)( ssl_context *ssl, int direction) = NULL; +int (*ssl_hw_record_reset)( ssl_context *ssl ) = NULL; +int (*ssl_hw_record_write)( ssl_context *ssl ) = NULL; +int (*ssl_hw_record_read)( ssl_context *ssl ) = NULL; +int (*ssl_hw_record_finish)( ssl_context *ssl ) = NULL; +#endif /* POLARSSL_SSL_HW_RECORD_ACCEL */ /* * Key material generation @@ -142,6 +156,9 @@ static int ssl3_prf( const unsigned char *secret, size_t slen, unsigned char sha1sum[20]; ((void)label); + md5_init( &md5 ); + sha1_init( &sha1 ); + /* * SSLv3: * block = @@ -166,11 +183,11 @@ static int ssl3_prf( const unsigned char *secret, size_t slen, md5_finish( &md5, dstbuf + i * 16 ); } - memset( &md5, 0, sizeof( md5 ) ); - memset( &sha1, 0, sizeof( sha1 ) ); + md5_free( &md5 ); + sha1_free( &sha1 ); - memset( padding, 0, sizeof( padding ) ); - memset( sha1sum, 0, sizeof( sha1sum ) ); + polarssl_zeroize( padding, sizeof( padding ) ); + polarssl_zeroize( sha1sum, sizeof( sha1sum ) ); return( 0 ); } @@ -232,8 +249,8 @@ static int tls1_prf( const unsigned char *secret, size_t slen, dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] ); } - memset( tmp, 0, sizeof( tmp ) ); - memset( h_i, 0, sizeof( h_i ) ); + polarssl_zeroize( tmp, sizeof( tmp ) ); + polarssl_zeroize( h_i, sizeof( h_i ) ); return( 0 ); } @@ -275,8 +292,8 @@ static int tls_prf_sha256( const unsigned char *secret, size_t slen, dstbuf[i + j] = h_i[j]; } - memset( tmp, 0, sizeof( tmp ) ); - memset( h_i, 0, sizeof( h_i ) ); + polarssl_zeroize( tmp, sizeof( tmp ) ); + polarssl_zeroize( h_i, sizeof( h_i ) ); return( 0 ); } @@ -317,44 +334,44 @@ static int tls_prf_sha384( const unsigned char *secret, size_t slen, dstbuf[i + j] = h_i[j]; } - memset( tmp, 0, sizeof( tmp ) ); - memset( h_i, 0, sizeof( h_i ) ); + polarssl_zeroize( tmp, sizeof( tmp ) ); + polarssl_zeroize( h_i, sizeof( h_i ) ); return( 0 ); } #endif /* POLARSSL_SHA512_C */ #endif /* POLARSSL_SSL_PROTO_TLS1_2 */ -static void ssl_update_checksum_start(ssl_context *, const unsigned char *, size_t); +static void ssl_update_checksum_start( ssl_context *, const unsigned char *, size_t ); #if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ defined(POLARSSL_SSL_PROTO_TLS1_1) -static void ssl_update_checksum_md5sha1(ssl_context *, const unsigned char *, size_t); +static void ssl_update_checksum_md5sha1( ssl_context *, const unsigned char *, size_t ); #endif #if defined(POLARSSL_SSL_PROTO_SSL3) -static void ssl_calc_verify_ssl(ssl_context *,unsigned char *); -static void ssl_calc_finished_ssl(ssl_context *,unsigned char *,int); +static void ssl_calc_verify_ssl( ssl_context *, unsigned char * ); +static void ssl_calc_finished_ssl( ssl_context *, unsigned char *, int ); #endif #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) -static void ssl_calc_verify_tls(ssl_context *,unsigned char *); -static void ssl_calc_finished_tls(ssl_context *,unsigned char *,int); +static void ssl_calc_verify_tls( ssl_context *, unsigned char * ); +static void ssl_calc_finished_tls( ssl_context *, unsigned char *, int ); #endif #if defined(POLARSSL_SSL_PROTO_TLS1_2) #if defined(POLARSSL_SHA256_C) -static void ssl_update_checksum_sha256(ssl_context *, const unsigned char *, size_t); -static void ssl_calc_verify_tls_sha256(ssl_context *,unsigned char *); -static void ssl_calc_finished_tls_sha256(ssl_context *,unsigned char *,int); +static void ssl_update_checksum_sha256( ssl_context *, const unsigned char *, size_t ); +static void ssl_calc_verify_tls_sha256( ssl_context *,unsigned char * ); +static void ssl_calc_finished_tls_sha256( ssl_context *,unsigned char *, int ); #endif #if defined(POLARSSL_SHA512_C) -static void ssl_update_checksum_sha384(ssl_context *, const unsigned char *, size_t); -static void ssl_calc_verify_tls_sha384(ssl_context *,unsigned char *); -static void ssl_calc_finished_tls_sha384(ssl_context *,unsigned char *,int); -#endif +static void ssl_update_checksum_sha384( ssl_context *, const unsigned char *, size_t ); +static void ssl_calc_verify_tls_sha384( ssl_context *, unsigned char * ); +static void ssl_calc_finished_tls_sha384( ssl_context *, unsigned char *, int ); #endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ int ssl_derive_keys( ssl_context *ssl ) { @@ -432,10 +449,10 @@ int ssl_derive_keys( ssl_context *ssl ) } else #endif -#endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } /* @@ -457,7 +474,7 @@ int ssl_derive_keys( ssl_context *ssl ) "master secret", handshake->randbytes, 64, session->master, 48 ); - memset( handshake->premaster, 0, sizeof( handshake->premaster ) ); + polarssl_zeroize( handshake->premaster, sizeof(handshake->premaster) ); } else SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) ); @@ -468,7 +485,7 @@ int ssl_derive_keys( ssl_context *ssl ) memcpy( tmp, handshake->randbytes, 64 ); memcpy( handshake->randbytes, tmp + 32, 32 ); memcpy( handshake->randbytes + 32, tmp, 32 ); - memset( tmp, 0, sizeof( tmp ) ); + polarssl_zeroize( tmp, sizeof( tmp ) ); /* * SSLv3: @@ -491,63 +508,87 @@ int ssl_derive_keys( ssl_context *ssl ) SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 ); SSL_DEBUG_BUF( 4, "key block", keyblk, 256 ); - memset( handshake->randbytes, 0, sizeof( handshake->randbytes ) ); + polarssl_zeroize( handshake->randbytes, sizeof( handshake->randbytes ) ); /* * Determine the appropriate key, IV and MAC length. */ - if( cipher_info->mode == POLARSSL_MODE_GCM ) + transform->keylen = cipher_info->key_length / 8; + + if( cipher_info->mode == POLARSSL_MODE_GCM || + cipher_info->mode == POLARSSL_MODE_CCM ) { - transform->keylen = cipher_info->key_length; - transform->keylen /= 8; - transform->minlen = 1; + transform->maclen = 0; + transform->ivlen = 12; transform->fixed_ivlen = 4; - transform->maclen = 0; + + /* Minimum length is expicit IV + tag */ + transform->minlen = transform->ivlen - transform->fixed_ivlen + + ( transform->ciphersuite_info->flags & + POLARSSL_CIPHERSUITE_SHORT_TAG ? 8 : 16 ); } else { - if( md_info->type != POLARSSL_MD_NONE ) - { - int ret; - - if( ( ret = md_init_ctx( &transform->md_ctx_enc, md_info ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "md_init_ctx", ret ); - return( ret ); - } + int ret; - if( ( ret = md_init_ctx( &transform->md_ctx_dec, md_info ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "md_init_ctx", ret ); - return( ret ); - } + /* Initialize HMAC contexts */ + if( ( ret = md_init_ctx( &transform->md_ctx_enc, md_info ) ) != 0 || + ( ret = md_init_ctx( &transform->md_ctx_dec, md_info ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "md_init_ctx", ret ); + return( ret ); + } - transform->maclen = md_get_size( md_info ); + /* Get MAC length */ + transform->maclen = md_get_size( md_info ); #if defined(POLARSSL_SSL_TRUNCATED_HMAC) - /* - * If HMAC is to be truncated, we shall keep the leftmost bytes, - * (rfc 6066 page 13 or rfc 2104 section 4), - * so we only need to adjust the length here. - */ - if( session->trunc_hmac == SSL_TRUNC_HMAC_ENABLED ) - transform->maclen = SSL_TRUNCATED_HMAC_LEN; + /* + * If HMAC is to be truncated, we shall keep the leftmost bytes, + * (rfc 6066 page 13 or rfc 2104 section 4), + * so we only need to adjust the length here. + */ + if( session->trunc_hmac == SSL_TRUNC_HMAC_ENABLED ) + transform->maclen = SSL_TRUNCATED_HMAC_LEN; #endif /* POLARSSL_SSL_TRUNCATED_HMAC */ - } - transform->keylen = cipher_info->key_length; - transform->keylen /= 8; + /* IV length */ transform->ivlen = cipher_info->iv_size; - transform->minlen = transform->keylen; - if( transform->minlen < transform->maclen ) + /* Minimum length */ + if( cipher_info->mode == POLARSSL_MODE_STREAM ) + transform->minlen = transform->maclen; + else { - if( cipher_info->mode == POLARSSL_MODE_STREAM ) - transform->minlen = transform->maclen; + /* + * GenericBlockCipher: + * first multiple of blocklen greater than maclen + * + IV except for SSL3 and TLS 1.0 + */ + transform->minlen = transform->maclen + + cipher_info->block_size + - transform->maclen % cipher_info->block_size; + +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) + if( ssl->minor_ver == SSL_MINOR_VERSION_0 || + ssl->minor_ver == SSL_MINOR_VERSION_1 ) + ; /* No need to adjust minlen */ else - transform->minlen += transform->keylen; +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1_1) || defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == SSL_MINOR_VERSION_2 || + ssl->minor_ver == SSL_MINOR_VERSION_3 ) + { + transform->minlen += transform->ivlen; + } + else +#endif + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } } } @@ -596,11 +637,17 @@ int ssl_derive_keys( ssl_context *ssl ) #if defined(POLARSSL_SSL_PROTO_SSL3) if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) { + if( transform->maclen > sizeof transform->mac_enc ) + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + memcpy( transform->mac_enc, mac_enc, transform->maclen ); memcpy( transform->mac_dec, mac_dec, transform->maclen ); } else -#endif +#endif /* POLARSSL_SSL_PROTO_SSL3 */ #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ defined(POLARSSL_SSL_PROTO_TLS1_2) if( ssl->minor_ver >= SSL_MINOR_VERSION_1 ) @@ -612,11 +659,11 @@ int ssl_derive_keys( ssl_context *ssl ) #endif { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } #if defined(POLARSSL_SSL_HW_RECORD_ACCEL) - if( ssl_hw_record_init != NULL) + if( ssl_hw_record_init != NULL ) { int ret = 0; @@ -629,10 +676,10 @@ int ssl_derive_keys( ssl_context *ssl ) transform->maclen ) ) != 0 ) { SSL_DEBUG_RET( 1, "ssl_hw_record_init", ret ); - return POLARSSL_ERR_SSL_HW_ACCEL_FAILED; + return( POLARSSL_ERR_SSL_HW_ACCEL_FAILED ); } } -#endif +#endif /* POLARSSL_SSL_HW_RECORD_ACCEL */ if( ( ret = cipher_init_ctx( &transform->cipher_ctx_enc, cipher_info ) ) != 0 ) @@ -683,7 +730,7 @@ int ssl_derive_keys( ssl_context *ssl ) } #endif /* POLARSSL_CIPHER_MODE_CBC */ - memset( keyblk, 0, sizeof( keyblk ) ); + polarssl_zeroize( keyblk, sizeof( keyblk ) ); #if defined(POLARSSL_ZLIB_SUPPORT) // Initialize compression @@ -707,7 +754,8 @@ int ssl_derive_keys( ssl_context *ssl ) memset( &transform->ctx_deflate, 0, sizeof( transform->ctx_deflate ) ); memset( &transform->ctx_inflate, 0, sizeof( transform->ctx_inflate ) ); - if( deflateInit( &transform->ctx_deflate, Z_DEFAULT_COMPRESSION ) != Z_OK || + if( deflateInit( &transform->ctx_deflate, + Z_DEFAULT_COMPRESSION ) != Z_OK || inflateInit( &transform->ctx_inflate ) != Z_OK ) { SSL_DEBUG_MSG( 1, ( "Failed to initialize compression" ) ); @@ -760,9 +808,12 @@ void ssl_calc_verify_ssl( ssl_context *ssl, unsigned char hash[36] ) SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); + md5_free( &md5 ); + sha1_free( &sha1 ); + return; } -#endif +#endif /* POLARSSL_SSL_PROTO_SSL3 */ #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) void ssl_calc_verify_tls( ssl_context *ssl, unsigned char hash[36] ) @@ -781,6 +832,9 @@ void ssl_calc_verify_tls( ssl_context *ssl, unsigned char hash[36] ) SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); + md5_free( &md5 ); + sha1_free( &sha1 ); + return; } #endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 */ @@ -799,6 +853,8 @@ void ssl_calc_verify_tls_sha256( ssl_context *ssl, unsigned char hash[32] ) SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 ); SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); + sha256_free( &sha256 ); + return; } #endif /* POLARSSL_SHA256_C */ @@ -816,6 +872,8 @@ void ssl_calc_verify_tls_sha384( ssl_context *ssl, unsigned char hash[48] ) SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 ); SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); + sha512_free( &sha512 ); + return; } #endif /* POLARSSL_SHA512_C */ @@ -863,19 +921,18 @@ int ssl_psk_derive_premaster( ssl_context *ssl, key_exchange_type_t key_ex ) if( key_ex == POLARSSL_KEY_EXCHANGE_DHE_PSK ) { int ret; - size_t len = ssl->handshake->dhm_ctx.len; - - if( end - p < 2 + (int) len ) - return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + size_t len = end - ( p + 2 ); - *(p++) = (unsigned char)( len >> 8 ); - *(p++) = (unsigned char)( len ); + /* Write length only when we know the actual value */ if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx, - p, &len, ssl->f_rng, ssl->p_rng ) ) != 0 ) + p + 2, &len, + ssl->f_rng, ssl->p_rng ) ) != 0 ) { SSL_DEBUG_RET( 1, "dhm_calc_secret", ret ); return( ret ); } + *(p++) = (unsigned char)( len >> 8 ); + *(p++) = (unsigned char)( len ); p += len; SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); @@ -889,7 +946,7 @@ int ssl_psk_derive_premaster( ssl_context *ssl, key_exchange_type_t key_ex ) size_t zlen; if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen, - p + 2, end - (p + 2), + p + 2, end - ( p + 2 ), ssl->f_rng, ssl->p_rng ) ) != 0 ) { SSL_DEBUG_RET( 1, "ecdh_calc_secret", ret ); @@ -906,10 +963,13 @@ int ssl_psk_derive_premaster( ssl_context *ssl, key_exchange_type_t key_ex ) #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } /* opaque psk<0..2^16-1>; */ + if( end - p < 2 + (int) ssl->psk_len ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + *(p++) = (unsigned char)( ssl->psk_len >> 8 ); *(p++) = (unsigned char)( ssl->psk_len ); memcpy( p, ssl->psk, ssl->psk_len ); @@ -941,6 +1001,8 @@ static void ssl_mac( md_context_t *md_ctx, unsigned char *secret, padlen = 40; else if( md_type == POLARSSL_MD_SHA256 ) padlen = 32; + else if( md_type == POLARSSL_MD_SHA384 ) + padlen = 16; memcpy( header, ctr, 8 ); header[ 8] = (unsigned char) type; @@ -970,17 +1032,19 @@ static void ssl_mac( md_context_t *md_ctx, unsigned char *secret, static int ssl_encrypt_buf( ssl_context *ssl ) { size_t i; + const cipher_mode_t mode = cipher_get_cipher_mode( + &ssl->transform_out->cipher_ctx_enc ); SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) ); /* - * Add MAC before encrypt, except for GCM + * Add MAC before encrypt, except for AEAD modes */ #if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) || \ ( defined(POLARSSL_CIPHER_MODE_CBC) && \ ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) ) ) - if( ssl->transform_out->cipher_ctx_enc.cipher_info->mode != - POLARSSL_MODE_GCM ) + if( mode != POLARSSL_MODE_GCM && + mode != POLARSSL_MODE_CCM ) { #if defined(POLARSSL_SSL_PROTO_SSL3) if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) @@ -1007,7 +1071,7 @@ static int ssl_encrypt_buf( ssl_context *ssl ) #endif { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } SSL_DEBUG_BUF( 4, "computed mac", @@ -1016,14 +1080,13 @@ static int ssl_encrypt_buf( ssl_context *ssl ) ssl->out_msglen += ssl->transform_out->maclen; } -#endif /* GCM not the only option */ +#endif /* AEAD not the only option */ /* * Encrypt */ #if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) - if( ssl->transform_out->cipher_ctx_enc.cipher_info->mode == - POLARSSL_MODE_STREAM ) + if( mode == POLARSSL_MODE_STREAM ) { int ret; size_t olen = 0; @@ -1035,61 +1098,34 @@ static int ssl_encrypt_buf( ssl_context *ssl ) SSL_DEBUG_BUF( 4, "before encrypt: output payload", ssl->out_msg, ssl->out_msglen ); - if( ( ret = cipher_reset( &ssl->transform_out->cipher_ctx_enc ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "cipher_reset", ret ); - return( ret ); - } - - if( ( ret = cipher_set_iv( &ssl->transform_out->cipher_ctx_enc, + if( ( ret = cipher_crypt( &ssl->transform_out->cipher_ctx_enc, ssl->transform_out->iv_enc, - ssl->transform_out->ivlen ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "cipher_set_iv", ret ); - return( ret ); - } - - if( ( ret = cipher_update( &ssl->transform_out->cipher_ctx_enc, - ssl->out_msg, ssl->out_msglen, ssl->out_msg, - &olen ) ) != 0 ) + ssl->transform_out->ivlen, + ssl->out_msg, ssl->out_msglen, + ssl->out_msg, &olen ) ) != 0 ) { - SSL_DEBUG_RET( 1, "cipher_update", ret ); + SSL_DEBUG_RET( 1, "cipher_crypt", ret ); return( ret ); } if( ssl->out_msglen != olen ) { - SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect %d %d", - ssl->out_msglen, olen ) ); - return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); - } - - if( ( ret = cipher_finish( &ssl->transform_out->cipher_ctx_enc, - ssl->out_msg + olen, &olen ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "cipher_finish", ret ); - return( ret ); - } - - if( 0 != olen ) - { - SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect %d %d", - 0, olen ) ); + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } } else #endif /* POLARSSL_ARC4_C || POLARSSL_CIPHER_NULL_CIPHER */ -#if defined(POLARSSL_GCM_C) - if( ssl->transform_out->cipher_ctx_enc.cipher_info->mode == - POLARSSL_MODE_GCM ) +#if defined(POLARSSL_GCM_C) || defined(POLARSSL_CCM_C) + if( mode == POLARSSL_MODE_GCM || + mode == POLARSSL_MODE_CCM ) { - size_t enc_msglen, olen, totlen; + int ret; + size_t enc_msglen, olen; unsigned char *enc_msg; unsigned char add_data[13]; - int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; - - enc_msglen = ssl->out_msglen; + unsigned char taglen = ssl->transform_out->ciphersuite_info->flags & + POLARSSL_CIPHERSUITE_SHORT_TAG ? 8 : 16; memcpy( add_data, ssl->out_ctr, 8 ); add_data[8] = ssl->out_msgtype; @@ -1105,8 +1141,8 @@ static int ssl_encrypt_buf( ssl_context *ssl ) * Generate IV */ ret = ssl->f_rng( ssl->p_rng, - ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen, - ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen ); + ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen, + ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen ); if( ret != 0 ) return( ret ); @@ -1115,7 +1151,7 @@ static int ssl_encrypt_buf( ssl_context *ssl ) ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen ); SSL_DEBUG_BUF( 4, "IV used", ssl->out_iv, - ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen ); + ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen ); /* * Fix pointer positions and message length with added IV @@ -1133,62 +1169,35 @@ static int ssl_encrypt_buf( ssl_context *ssl ) ssl->out_msg, ssl->out_msglen ); /* - * Encrypt + * Encrypt and authenticate */ - if( ( ret = cipher_set_iv( &ssl->transform_out->cipher_ctx_enc, - ssl->transform_out->iv_enc, - ssl->transform_out->ivlen ) ) != 0 || - ( ret = cipher_reset( &ssl->transform_out->cipher_ctx_enc ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = cipher_update_ad( &ssl->transform_out->cipher_ctx_enc, - add_data, 13 ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = cipher_update( &ssl->transform_out->cipher_ctx_enc, - enc_msg, enc_msglen, - enc_msg, &olen ) ) != 0 ) - { - return( ret ); - } - totlen = olen; - - if( ( ret = cipher_finish( &ssl->transform_out->cipher_ctx_enc, - enc_msg + olen, &olen ) ) != 0 ) + if( ( ret = cipher_auth_encrypt( &ssl->transform_out->cipher_ctx_enc, + ssl->transform_out->iv_enc, + ssl->transform_out->ivlen, + add_data, 13, + enc_msg, enc_msglen, + enc_msg, &olen, + enc_msg + enc_msglen, taglen ) ) != 0 ) { + SSL_DEBUG_RET( 1, "cipher_auth_encrypt", ret ); return( ret ); } - totlen += olen; - if( totlen != enc_msglen ) + if( olen != enc_msglen ) { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( -1 ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } - /* - * Authenticate - */ - ssl->out_msglen += 16; - - if( ( ret = cipher_write_tag( &ssl->transform_out->cipher_ctx_enc, - enc_msg + enc_msglen, 16 ) ) != 0 ) - { - return( ret ); - } + ssl->out_msglen += taglen; - SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen, 16 ); + SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen, taglen ); } else -#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_GCM_C || POLARSSL_CCM_C */ #if defined(POLARSSL_CIPHER_MODE_CBC) && \ ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) ) - if( ssl->transform_out->cipher_ctx_enc.cipher_info->mode == - POLARSSL_MODE_CBC ) + if( mode == POLARSSL_MODE_CBC ) { int ret; unsigned char *enc_msg; @@ -1236,46 +1245,25 @@ static int ssl_encrypt_buf( ssl_context *ssl ) SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " "including %d bytes of IV and %d bytes of padding", - ssl->out_msglen, ssl->transform_out->ivlen, padlen + 1 ) ); + ssl->out_msglen, ssl->transform_out->ivlen, + padlen + 1 ) ); SSL_DEBUG_BUF( 4, "before encrypt: output payload", ssl->out_iv, ssl->out_msglen ); - if( ( ret = cipher_reset( &ssl->transform_out->cipher_ctx_enc ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "cipher_reset", ret ); - return( ret ); - } - - if( ( ret = cipher_set_iv( &ssl->transform_out->cipher_ctx_enc, + if( ( ret = cipher_crypt( &ssl->transform_out->cipher_ctx_enc, ssl->transform_out->iv_enc, - ssl->transform_out->ivlen ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "cipher_set_iv", ret ); - return( ret ); - } - - if( ( ret = cipher_update( &ssl->transform_out->cipher_ctx_enc, - enc_msg, enc_msglen, enc_msg, - &olen ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "cipher_update", ret ); - return( ret ); - } - - enc_msglen -= olen; - - if( ( ret = cipher_finish( &ssl->transform_out->cipher_ctx_enc, - enc_msg + olen, &olen ) ) != 0 ) + ssl->transform_out->ivlen, + enc_msg, enc_msglen, + enc_msg, &olen ) ) != 0 ) { - SSL_DEBUG_RET( 1, "cipher_finish", ret ); + SSL_DEBUG_RET( 1, "cipher_crypt", ret ); return( ret ); } if( enc_msglen != olen ) { - SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect %d %d", - enc_msglen, olen ) ); + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } @@ -1296,13 +1284,20 @@ static int ssl_encrypt_buf( ssl_context *ssl ) ( POLARSSL_AES_C || POLARSSL_CAMELLIA_C ) */ { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } for( i = 8; i > 0; i-- ) if( ++ssl->out_ctr[i - 1] != 0 ) break; + /* The loops goes to its end iff the counter is wrapping */ + if( i == 0 ) + { + SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) ); + return( POLARSSL_ERR_SSL_COUNTER_WRAPPING ); + } + SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) ); return( 0 ); @@ -1312,8 +1307,14 @@ static int ssl_encrypt_buf( ssl_context *ssl ) static int ssl_decrypt_buf( ssl_context *ssl ) { - size_t i, padlen = 0, correct = 1; - unsigned char tmp[POLARSSL_SSL_MAX_MAC_SIZE]; + size_t i; + const cipher_mode_t mode = cipher_get_cipher_mode( + &ssl->transform_in->cipher_ctx_dec ); +#if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) || \ + ( defined(POLARSSL_CIPHER_MODE_CBC) && \ + ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) ) ) + size_t padlen = 0, correct = 1; +#endif SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) ); @@ -1325,72 +1326,54 @@ static int ssl_decrypt_buf( ssl_context *ssl ) } #if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) - if( ssl->transform_in->cipher_ctx_dec.cipher_info->mode == - POLARSSL_MODE_STREAM ) + if( mode == POLARSSL_MODE_STREAM ) { int ret; size_t olen = 0; padlen = 0; - if( ( ret = cipher_reset( &ssl->transform_in->cipher_ctx_dec ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "cipher_reset", ret ); - return( ret ); - } - - if( ( ret = cipher_set_iv( &ssl->transform_in->cipher_ctx_dec, + if( ( ret = cipher_crypt( &ssl->transform_in->cipher_ctx_dec, ssl->transform_in->iv_dec, - ssl->transform_in->ivlen ) ) != 0 ) + ssl->transform_in->ivlen, + ssl->in_msg, ssl->in_msglen, + ssl->in_msg, &olen ) ) != 0 ) { - SSL_DEBUG_RET( 1, "cipher_set_iv", ret ); - return( ret ); - } - - if( ( ret = cipher_update( &ssl->transform_in->cipher_ctx_dec, - ssl->in_msg, ssl->in_msglen, ssl->in_msg, - &olen ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "cipher_update", ret ); + SSL_DEBUG_RET( 1, "cipher_crypt", ret ); return( ret ); } if( ssl->in_msglen != olen ) { - SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect" ) ); - return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); - } - - if( ( ret = cipher_finish( &ssl->transform_in->cipher_ctx_dec, - ssl->in_msg + olen, &olen ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "cipher_finish", ret ); - return( ret ); - } - - if( 0 != olen ) - { - SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect" ) ); + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } } else #endif /* POLARSSL_ARC4_C || POLARSSL_CIPHER_NULL_CIPHER */ -#if defined(POLARSSL_GCM_C) - if( ssl->transform_in->cipher_ctx_dec.cipher_info->mode == - POLARSSL_MODE_GCM ) +#if defined(POLARSSL_GCM_C) || defined(POLARSSL_CCM_C) + if( mode == POLARSSL_MODE_GCM || + mode == POLARSSL_MODE_CCM ) { + int ret; + size_t dec_msglen, olen; unsigned char *dec_msg; unsigned char *dec_msg_result; - size_t dec_msglen, olen, totlen; unsigned char add_data[13]; - int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; + unsigned char taglen = ssl->transform_in->ciphersuite_info->flags & + POLARSSL_CIPHERSUITE_SHORT_TAG ? 8 : 16; + unsigned char explicit_iv_len = ssl->transform_in->ivlen - + ssl->transform_in->fixed_ivlen; - padlen = 0; + if( ssl->in_msglen < explicit_iv_len + taglen ) + { + SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) " + "+ taglen (%d)", ssl->in_msglen, + explicit_iv_len, taglen ) ); + return( POLARSSL_ERR_SSL_INVALID_MAC ); + } + dec_msglen = ssl->in_msglen - explicit_iv_len - taglen; - dec_msglen = ssl->in_msglen - ( ssl->transform_in->ivlen - - ssl->transform_in->fixed_ivlen ); - dec_msglen -= 16; dec_msg = ssl->in_msg; dec_msg_result = ssl->in_msg; ssl->in_msglen = dec_msglen; @@ -1411,63 +1394,38 @@ static int ssl_decrypt_buf( ssl_context *ssl ) SSL_DEBUG_BUF( 4, "IV used", ssl->transform_in->iv_dec, ssl->transform_in->ivlen ); - SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, 16 ); + SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, taglen ); /* - * Decrypt + * Decrypt and authenticate */ - if( ( ret = cipher_set_iv( &ssl->transform_in->cipher_ctx_dec, - ssl->transform_in->iv_dec, - ssl->transform_in->ivlen ) ) != 0 || - ( ret = cipher_reset( &ssl->transform_in->cipher_ctx_dec ) ) != 0 ) + if( ( ret = cipher_auth_decrypt( &ssl->transform_in->cipher_ctx_dec, + ssl->transform_in->iv_dec, + ssl->transform_in->ivlen, + add_data, 13, + dec_msg, dec_msglen, + dec_msg_result, &olen, + dec_msg + dec_msglen, taglen ) ) != 0 ) { - return( ret ); - } + SSL_DEBUG_RET( 1, "cipher_auth_decrypt", ret ); - if( ( ret = cipher_update_ad( &ssl->transform_in->cipher_ctx_dec, - add_data, 13 ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = cipher_update( &ssl->transform_in->cipher_ctx_dec, - dec_msg, dec_msglen, - dec_msg_result, &olen ) ) != 0 ) - { - return( ret ); - } - totlen = olen; + if( ret == POLARSSL_ERR_CIPHER_AUTH_FAILED ) + return( POLARSSL_ERR_SSL_INVALID_MAC ); - if( ( ret = cipher_finish( &ssl->transform_in->cipher_ctx_dec, - dec_msg_result + olen, &olen ) ) != 0 ) - { return( ret ); } - totlen += olen; - if( totlen != dec_msglen ) + if( olen != dec_msglen ) { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( -1 ); - } - - /* - * Authenticate - */ - if( ( ret = cipher_check_tag( &ssl->transform_in->cipher_ctx_dec, - dec_msg + dec_msglen, 16 ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "cipher_check_tag", ret ); - return( POLARSSL_ERR_SSL_INVALID_MAC ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } - } else -#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_GCM_C || POLARSSL_CCM_C */ #if defined(POLARSSL_CIPHER_MODE_CBC) && \ ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) ) - if( ssl->transform_in->cipher_ctx_dec.cipher_info->mode == - POLARSSL_MODE_CBC ) + if( mode == POLARSSL_MODE_CBC ) { /* * Decrypt and check the padding @@ -1497,8 +1455,10 @@ static int ssl_decrypt_buf( ssl_context *ssl ) if( ssl->in_msglen < minlen + ssl->transform_in->ivlen || ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 ) { - SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) + 1 ) ( + expl IV )", - ssl->in_msglen, ssl->transform_in->ivlen, ssl->transform_in->maclen ) ); + SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) " + "+ 1 ) ( + expl IV )", ssl->in_msglen, + ssl->transform_in->ivlen, + ssl->transform_in->maclen ) ); return( POLARSSL_ERR_SSL_INVALID_MAC ); } @@ -1520,39 +1480,19 @@ static int ssl_decrypt_buf( ssl_context *ssl ) } #endif /* POLARSSL_SSL_PROTO_TLS1_1 || POLARSSL_SSL_PROTO_TLS1_2 */ - if( ( ret = cipher_reset( &ssl->transform_in->cipher_ctx_dec ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "cipher_reset", ret ); - return( ret ); - } - - if( ( ret = cipher_set_iv( &ssl->transform_in->cipher_ctx_dec, + if( ( ret = cipher_crypt( &ssl->transform_in->cipher_ctx_dec, ssl->transform_in->iv_dec, - ssl->transform_in->ivlen ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "cipher_set_iv", ret ); - return( ret ); - } - - if( ( ret = cipher_update( &ssl->transform_in->cipher_ctx_dec, - dec_msg, dec_msglen, dec_msg_result, - &olen ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "cipher_update", ret ); - return( ret ); - } - - dec_msglen -= olen; - if( ( ret = cipher_finish( &ssl->transform_in->cipher_ctx_dec, - dec_msg_result + olen, &olen ) ) != 0 ) + ssl->transform_in->ivlen, + dec_msg, dec_msglen, + dec_msg_result, &olen ) ) != 0 ) { - SSL_DEBUG_RET( 1, "cipher_finish", ret ); + SSL_DEBUG_RET( 1, "cipher_crypt", ret ); return( ret ); } if( dec_msglen != olen ) { - SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect" ) ); + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } @@ -1594,7 +1534,7 @@ static int ssl_decrypt_buf( ssl_context *ssl ) } } else -#endif +#endif /* POLARSSL_SSL_PROTO_SSL3 */ #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ defined(POLARSSL_SSL_PROTO_TLS1_2) if( ssl->minor_ver > SSL_MINOR_VERSION_0 ) @@ -1606,6 +1546,22 @@ static int ssl_decrypt_buf( ssl_context *ssl ) size_t pad_count = 0, real_count = 1; size_t padding_idx = ssl->in_msglen - padlen - 1; + /* + * Padding is guaranteed to be incorrect if: + * 1. padlen >= ssl->in_msglen + * + * 2. padding_idx >= SSL_MAX_CONTENT_LEN + + * ssl->transform_in->maclen + * + * In both cases we reset padding_idx to a safe value (0) to + * prevent out-of-buffer reads. + */ + correct &= ( ssl->in_msglen >= padlen + 1 ); + correct &= ( padding_idx < SSL_MAX_CONTENT_LEN + + ssl->transform_in->maclen ); + + padding_idx *= correct; + for( i = 1; i <= 256; i++ ) { real_count &= ( i <= padlen ); @@ -1616,7 +1572,7 @@ static int ssl_decrypt_buf( ssl_context *ssl ) correct &= ( pad_count == padlen ); /* Only 1 on correct padding */ #if defined(POLARSSL_SSL_DEBUG_ALL) - if( padlen > 0 && correct == 0) + if( padlen > 0 && correct == 0 ) SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) ); #endif padlen &= correct * 0x1FF; @@ -1626,7 +1582,7 @@ static int ssl_decrypt_buf( ssl_context *ssl ) POLARSSL_SSL_PROTO_TLS1_2 */ { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } } else @@ -1634,21 +1590,23 @@ static int ssl_decrypt_buf( ssl_context *ssl ) ( POLARSSL_AES_C || POLARSSL_CAMELLIA_C ) */ { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } SSL_DEBUG_BUF( 4, "raw buffer after decryption", ssl->in_msg, ssl->in_msglen ); /* - * Always compute the MAC (RFC4346, CBCTIME), except for GCM of course + * Always compute the MAC (RFC4346, CBCTIME), except for AEAD of course */ #if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) || \ ( defined(POLARSSL_CIPHER_MODE_CBC) && \ ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) ) ) - if( ssl->transform_in->cipher_ctx_dec.cipher_info->mode != - POLARSSL_MODE_GCM ) + if( mode != POLARSSL_MODE_GCM && + mode != POLARSSL_MODE_CCM ) { + unsigned char tmp[POLARSSL_SSL_MAX_MAC_SIZE]; + ssl->in_msglen -= ( ssl->transform_in->maclen + padlen ); ssl->in_hdr[3] = (unsigned char)( ssl->in_msglen >> 8 ); @@ -1674,7 +1632,7 @@ static int ssl_decrypt_buf( ssl_context *ssl ) * Process MAC and always update for padlen afterwards to make * total time independent of padlen * - * extra_run compensates MAC check for padlen + * extra_run compensates MAC check for padlen * * Known timing attacks: * - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf) @@ -1704,7 +1662,7 @@ static int ssl_decrypt_buf( ssl_context *ssl ) POLARSSL_SSL_PROTO_TLS1_2 */ { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } SSL_DEBUG_BUF( 4, "message mac", tmp, ssl->transform_in->maclen ); @@ -1726,7 +1684,7 @@ static int ssl_decrypt_buf( ssl_context *ssl ) if( correct == 0 ) return( POLARSSL_ERR_SSL_INVALID_MAC ); } -#endif /* GCM not the only option */ +#endif /* AEAD not the only option */ if( ssl->in_msglen == 0 ) { @@ -1750,6 +1708,13 @@ static int ssl_decrypt_buf( ssl_context *ssl ) if( ++ssl->in_ctr[i - 1] != 0 ) break; + /* The loops goes to its end iff the counter is wrapping */ + if( i == 0 ) + { + SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) ); + return( POLARSSL_ERR_SSL_COUNTER_WRAPPING ); + } + SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) ); return( 0 ); @@ -1791,7 +1756,8 @@ static int ssl_compress_buf( ssl_context *ssl ) return( POLARSSL_ERR_SSL_COMPRESSION_FAILED ); } - ssl->out_msglen = SSL_BUFFER_LEN - ssl->transform_out->ctx_deflate.avail_out; + ssl->out_msglen = SSL_BUFFER_LEN - + ssl->transform_out->ctx_deflate.avail_out; SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ", ssl->out_msglen ) ); @@ -1836,7 +1802,8 @@ static int ssl_decompress_buf( ssl_context *ssl ) return( POLARSSL_ERR_SSL_COMPRESSION_FAILED ); } - ssl->in_msglen = SSL_MAX_CONTENT_LEN - ssl->transform_in->ctx_inflate.avail_out; + ssl->in_msglen = SSL_MAX_CONTENT_LEN - + ssl->transform_in->ctx_inflate.avail_out; SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ", ssl->in_msglen ) ); @@ -1860,6 +1827,12 @@ int ssl_fetch_input( ssl_context *ssl, size_t nb_want ) SSL_DEBUG_MSG( 2, ( "=> fetch input" ) ); + if( nb_want > SSL_BUFFER_LEN - 8 ) + { + SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) ); + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + while( ssl->in_left < nb_want ) { len = nb_want - ssl->in_left; @@ -1949,7 +1922,7 @@ int ssl_write_record( ssl_context *ssl ) #endif /*POLARSSL_ZLIB_SUPPORT */ #if defined(POLARSSL_SSL_HW_RECORD_ACCEL) - if( ssl_hw_record_write != NULL) + if( ssl_hw_record_write != NULL ) { SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_write()" ) ); @@ -1957,13 +1930,13 @@ int ssl_write_record( ssl_context *ssl ) if( ret != 0 && ret != POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH ) { SSL_DEBUG_RET( 1, "ssl_hw_record_write", ret ); - return POLARSSL_ERR_SSL_HW_ACCEL_FAILED; + return( POLARSSL_ERR_SSL_HW_ACCEL_FAILED ); } if( ret == 0 ) done = 1; } -#endif +#endif /* POLARSSL_SSL_HW_RECORD_ACCEL */ if( !done ) { ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; @@ -2013,9 +1986,6 @@ int ssl_read_record( ssl_context *ssl ) SSL_DEBUG_MSG( 2, ( "=> read record" ) ); - SSL_DEBUG_BUF( 4, "input record from network", - ssl->in_hdr, 5 + ssl->in_msglen ); - if( ssl->in_hslen != 0 && ssl->in_hslen < ssl->in_msglen ) { @@ -2046,7 +2016,8 @@ int ssl_read_record( ssl_context *ssl ) return( POLARSSL_ERR_SSL_INVALID_RECORD ); } - ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); + if( ssl->state != SSL_HANDSHAKE_OVER ) + ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); return( 0 ); } @@ -2082,13 +2053,20 @@ int ssl_read_record( ssl_context *ssl ) return( POLARSSL_ERR_SSL_INVALID_RECORD ); } + /* Sanity check (outer boundaries) */ + if( ssl->in_msglen < 1 || ssl->in_msglen > SSL_BUFFER_LEN - 13 ) + { + SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + return( POLARSSL_ERR_SSL_INVALID_RECORD ); + } + /* - * Make sure the message length is acceptable + * Make sure the message length is acceptable for the current transform + * and protocol version. */ if( ssl->transform_in == NULL ) { - if( ssl->in_msglen < 1 || - ssl->in_msglen > SSL_MAX_CONTENT_LEN ) + if( ssl->in_msglen > SSL_MAX_CONTENT_LEN ) { SSL_DEBUG_MSG( 1, ( "bad message length" ) ); return( POLARSSL_ERR_SSL_INVALID_RECORD ); @@ -2117,7 +2095,8 @@ int ssl_read_record( ssl_context *ssl ) * TLS encrypted messages can have up to 256 bytes of padding */ if( ssl->minor_ver >= SSL_MINOR_VERSION_1 && - ssl->in_msglen > ssl->transform_in->minlen + SSL_MAX_CONTENT_LEN + 256 ) + ssl->in_msglen > ssl->transform_in->minlen + + SSL_MAX_CONTENT_LEN + 256 ) { SSL_DEBUG_MSG( 1, ( "bad message length" ) ); return( POLARSSL_ERR_SSL_INVALID_RECORD ); @@ -2138,7 +2117,7 @@ int ssl_read_record( ssl_context *ssl ) ssl->in_hdr, 5 + ssl->in_msglen ); #if defined(POLARSSL_SSL_HW_RECORD_ACCEL) - if( ssl_hw_record_read != NULL) + if( ssl_hw_record_read != NULL ) { SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_read()" ) ); @@ -2146,13 +2125,13 @@ int ssl_read_record( ssl_context *ssl ) if( ret != 0 && ret != POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH ) { SSL_DEBUG_RET( 1, "ssl_hw_record_read", ret ); - return POLARSSL_ERR_SSL_HW_ACCEL_FAILED; + return( POLARSSL_ERR_SSL_HW_ACCEL_FAILED ); } if( ret == 0 ) done = 1; } -#endif +#endif /* POLARSSL_SSL_HW_RECORD_ACCEL */ if( !done && ssl->transform_in != NULL ) { if( ( ret = ssl_decrypt_buf( ssl ) ) != 0 ) @@ -2314,13 +2293,15 @@ int ssl_send_alert_message( ssl_context *ssl, /* * Handshake functions */ -#if !defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \ - !defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ - !defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ - !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +#if !defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) int ssl_write_certificate( ssl_context *ssl ) { - int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; SSL_DEBUG_MSG( 2, ( "=> write certificate" ) ); @@ -2334,13 +2315,12 @@ int ssl_write_certificate( ssl_context *ssl ) return( 0 ); } - SSL_DEBUG_MSG( 1, ( "should not happen" ) ); - return( ret ); + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } int ssl_parse_certificate( ssl_context *ssl ) { - int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) ); @@ -2354,8 +2334,8 @@ int ssl_parse_certificate( ssl_context *ssl ) return( 0 ); } - SSL_DEBUG_MSG( 1, ( "should not happen" ) ); - return( ret ); + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } #else int ssl_write_certificate( ssl_context *ssl ) @@ -2429,7 +2409,7 @@ int ssl_write_certificate( ssl_context *ssl ) while( crt != NULL ) { n = crt->raw.len; - if( i + 3 + n > SSL_MAX_CONTENT_LEN ) + if( n > SSL_MAX_CONTENT_LEN - 3 - i ) { SSL_DEBUG_MSG( 1, ( "certificate too large, %d > %d", i + 3 + n, SSL_MAX_CONTENT_LEN ) ); @@ -2487,7 +2467,8 @@ int ssl_parse_certificate( ssl_context *ssl ) } if( ssl->endpoint == SSL_IS_SERVER && - ssl->authmode == SSL_VERIFY_NONE ) + ( ssl->authmode == SSL_VERIFY_NONE || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ) ) { ssl->session_negotiate->verify_result = BADCERT_SKIP_VERIFY; SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); @@ -2621,6 +2602,30 @@ int ssl_parse_certificate( ssl_context *ssl ) SSL_DEBUG_CRT( 3, "peer certificate", ssl->session_negotiate->peer_cert ); + /* + * On client, make sure the server cert doesn't change during renego to + * avoid "triple handshake" attack: https://secure-resumption.com/ + */ + if( ssl->endpoint == SSL_IS_CLIENT && + ssl->renegotiation == SSL_RENEGOTIATION ) + { + if( ssl->session->peer_cert == NULL ) + { + SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE ); + } + + if( ssl->session->peer_cert->raw.len != + ssl->session_negotiate->peer_cert->raw.len || + memcmp( ssl->session->peer_cert->raw.p, + ssl->session_negotiate->peer_cert->raw.p, + ssl->session->peer_cert->raw.len ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE ); + } + } + if( ssl->authmode != SSL_VERIFY_NONE ) { if( ssl->ca_chain == NULL ) @@ -2629,13 +2634,46 @@ int ssl_parse_certificate( ssl_context *ssl ) return( POLARSSL_ERR_SSL_CA_CHAIN_REQUIRED ); } + /* + * Main check: verify certificate + */ ret = x509_crt_verify( ssl->session_negotiate->peer_cert, ssl->ca_chain, ssl->ca_crl, ssl->peer_cn, &ssl->session_negotiate->verify_result, ssl->f_vrfy, ssl->p_vrfy ); if( ret != 0 ) + { SSL_DEBUG_RET( 1, "x509_verify_cert", ret ); + } + + /* + * Secondary checks: always done, but change 'ret' only if it was 0 + */ + +#if defined(POLARSSL_SSL_SET_CURVES) + { + pk_context *pk = &ssl->session_negotiate->peer_cert->pk; + + /* If certificate uses an EC key, make sure the curve is OK */ + if( pk_can_do( pk, POLARSSL_PK_ECKEY ) && + ! ssl_curve_is_acceptable( ssl, pk_ec( *pk )->grp.id ) ) + { + SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) ); + if( ret == 0 ) + ret = POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE; + } + } +#endif /* POLARSSL_SSL_SET_CURVES */ + + if( ssl_check_cert_usage( ssl->session_negotiate->peer_cert, + ciphersuite_info, + ! ssl->endpoint ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) ); + if( ret == 0 ) + ret = POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE; + } if( ssl->authmode != SSL_VERIFY_REQUIRED ) ret = 0; @@ -2645,9 +2683,13 @@ int ssl_parse_certificate( ssl_context *ssl ) return( ret ); } -#endif /* !POLARSSL_KEY_EXCHANGE_RSA_ENABLED && - !POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED && - !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ +#endif /* !POLARSSL_KEY_EXCHANGE_RSA_ENABLED + !POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED + !POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED + !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED + !POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + !POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED + !POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ int ssl_write_change_cipher_spec( ssl_context *ssl ) { @@ -2726,8 +2768,10 @@ void ssl_optimize_checksum( ssl_context *ssl, else #endif #endif /* POLARSSL_SSL_PROTO_TLS1_2 */ - /* Should never happen */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return; + } } static void ssl_update_checksum_start( ssl_context *ssl, @@ -2847,12 +2891,12 @@ static void ssl_calc_finished_ssl( SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 ); - memset( &md5, 0, sizeof( md5_context ) ); - memset( &sha1, 0, sizeof( sha1_context ) ); + md5_free( &md5 ); + sha1_free( &sha1 ); - memset( padbuf, 0, sizeof( padbuf ) ); - memset( md5sum, 0, sizeof( md5sum ) ); - memset( sha1sum, 0, sizeof( sha1sum ) ); + polarssl_zeroize( padbuf, sizeof( padbuf ) ); + polarssl_zeroize( md5sum, sizeof( md5sum ) ); + polarssl_zeroize( sha1sum, sizeof( sha1sum ) ); SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); } @@ -2905,10 +2949,10 @@ static void ssl_calc_finished_tls( SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); - memset( &md5, 0, sizeof( md5_context ) ); - memset( &sha1, 0, sizeof( sha1_context ) ); + md5_free( &md5 ); + sha1_free( &sha1 ); - memset( padbuf, 0, sizeof( padbuf ) ); + polarssl_zeroize( padbuf, sizeof( padbuf ) ); SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); } @@ -2954,9 +2998,9 @@ static void ssl_calc_finished_tls_sha256( SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); - memset( &sha256, 0, sizeof( sha256_context ) ); + sha256_free( &sha256 ); - memset( padbuf, 0, sizeof( padbuf ) ); + polarssl_zeroize( padbuf, sizeof( padbuf ) ); SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); } @@ -3001,9 +3045,9 @@ static void ssl_calc_finished_tls_sha384( SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); - memset( &sha512, 0, sizeof( sha512_context ) ); + sha512_free( &sha512 ); - memset( padbuf, 0, sizeof( padbuf ) ); + polarssl_zeroize( padbuf, sizeof( padbuf ) ); SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); } @@ -3024,7 +3068,10 @@ void ssl_handshake_wrapup( ssl_context *ssl ) ssl->handshake = NULL; if( ssl->renegotiation == SSL_RENEGOTIATION ) + { ssl->renegotiation = SSL_RENEGOTIATION_DONE; + ssl->renego_records_seen = 0; + } /* * Switch in our now active transform context @@ -3105,7 +3152,8 @@ int ssl_write_finished( ssl_context *ssl ) ssl->state++; /* - * Switch to our negotiated transform and session parameters for outbound data. + * Switch to our negotiated transform and session parameters for outbound + * data. */ SSL_DEBUG_MSG( 3, ( "switching to new transform spec for outbound data" ) ); ssl->transform_out = ssl->transform_negotiate; @@ -3113,7 +3161,7 @@ int ssl_write_finished( ssl_context *ssl ) memset( ssl->out_ctr, 0, 8 ); #if defined(POLARSSL_SSL_HW_RECORD_ACCEL) - if( ssl_hw_record_activate != NULL) + if( ssl_hw_record_activate != NULL ) { if( ( ret = ssl_hw_record_activate( ssl, SSL_CHANNEL_OUTBOUND ) ) != 0 ) { @@ -3145,7 +3193,8 @@ int ssl_parse_finished( ssl_context *ssl ) ssl->handshake->calc_finished( ssl, buf, ssl->endpoint ^ 1 ); /* - * Switch to our negotiated transform and session parameters for inbound data. + * Switch to our negotiated transform and session parameters for inbound + * data. */ SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) ); ssl->transform_in = ssl->transform_negotiate; @@ -3164,7 +3213,7 @@ int ssl_parse_finished( ssl_context *ssl ) ssl->in_msg = ssl->in_iv; #if defined(POLARSSL_SSL_HW_RECORD_ACCEL) - if( ssl_hw_record_activate != NULL) + if( ssl_hw_record_activate != NULL ) { if( ( ret = ssl_hw_record_activate( ssl, SSL_CHANNEL_INBOUND ) ) != 0 ) { @@ -3221,64 +3270,109 @@ int ssl_parse_finished( ssl_context *ssl ) return( 0 ); } +static void ssl_handshake_params_init( ssl_handshake_params *handshake ) +{ + memset( handshake, 0, sizeof( ssl_handshake_params ) ); + +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) + md5_init( &handshake->fin_md5 ); + sha1_init( &handshake->fin_sha1 ); + md5_starts( &handshake->fin_md5 ); + sha1_starts( &handshake->fin_sha1 ); +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) + sha256_init( &handshake->fin_sha256 ); + sha256_starts( &handshake->fin_sha256, 0 ); +#endif +#if defined(POLARSSL_SHA512_C) + sha512_init( &handshake->fin_sha512 ); + sha512_starts( &handshake->fin_sha512, 1 ); +#endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + + handshake->update_checksum = ssl_update_checksum_start; + handshake->sig_alg = SSL_HASH_SHA1; + +#if defined(POLARSSL_DHM_C) + dhm_init( &handshake->dhm_ctx ); +#endif +#if defined(POLARSSL_ECDH_C) + ecdh_init( &handshake->ecdh_ctx ); +#endif +} + +static void ssl_transform_init( ssl_transform *transform ) +{ + memset( transform, 0, sizeof(ssl_transform) ); + + cipher_init( &transform->cipher_ctx_enc ); + cipher_init( &transform->cipher_ctx_dec ); + + md_init( &transform->md_ctx_enc ); + md_init( &transform->md_ctx_dec ); +} + +void ssl_session_init( ssl_session *session ) +{ + memset( session, 0, sizeof(ssl_session) ); +} + static int ssl_handshake_init( ssl_context *ssl ) { + /* Clear old handshake information if present */ if( ssl->transform_negotiate ) ssl_transform_free( ssl->transform_negotiate ); - else + if( ssl->session_negotiate ) + ssl_session_free( ssl->session_negotiate ); + if( ssl->handshake ) + ssl_handshake_free( ssl->handshake ); + + /* + * Either the pointers are now NULL or cleared properly and can be freed. + * Now allocate missing structures. + */ + if( ssl->transform_negotiate == NULL ) { ssl->transform_negotiate = (ssl_transform *) polarssl_malloc( sizeof(ssl_transform) ); } - if( ssl->session_negotiate ) - ssl_session_free( ssl->session_negotiate ); - else + if( ssl->session_negotiate == NULL ) { ssl->session_negotiate = (ssl_session *) polarssl_malloc( sizeof(ssl_session) ); } - if( ssl->handshake ) - ssl_handshake_free( ssl->handshake ); - else + if( ssl->handshake == NULL) { ssl->handshake = (ssl_handshake_params *) polarssl_malloc( sizeof(ssl_handshake_params) ); } + /* All pointers should exist and can be directly freed without issue */ if( ssl->handshake == NULL || ssl->transform_negotiate == NULL || ssl->session_negotiate == NULL ) { SSL_DEBUG_MSG( 1, ( "malloc() of ssl sub-contexts failed" ) ); - return( POLARSSL_ERR_SSL_MALLOC_FAILED ); - } - memset( ssl->handshake, 0, sizeof(ssl_handshake_params) ); - memset( ssl->transform_negotiate, 0, sizeof(ssl_transform) ); - memset( ssl->session_negotiate, 0, sizeof(ssl_session) ); + polarssl_free( ssl->handshake ); + polarssl_free( ssl->transform_negotiate ); + polarssl_free( ssl->session_negotiate ); -#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ - defined(POLARSSL_SSL_PROTO_TLS1_1) - md5_starts( &ssl->handshake->fin_md5 ); - sha1_starts( &ssl->handshake->fin_sha1 ); -#endif -#if defined(POLARSSL_SSL_PROTO_TLS1_2) -#if defined(POLARSSL_SHA256_C) - sha256_starts( &ssl->handshake->fin_sha256, 0 ); -#endif -#if defined(POLARSSL_SHA512_C) - sha512_starts( &ssl->handshake->fin_sha512, 1 ); -#endif -#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + ssl->handshake = NULL; + ssl->transform_negotiate = NULL; + ssl->session_negotiate = NULL; - ssl->handshake->update_checksum = ssl_update_checksum_start; - ssl->handshake->sig_alg = SSL_HASH_SHA1; + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + } -#if defined(POLARSSL_ECDH_C) - ecdh_init( &ssl->handshake->ecdh_ctx ); -#endif + /* Initialize structures */ + ssl_session_init( ssl->session_negotiate ); + ssl_transform_init( ssl->transform_negotiate ); + ssl_handshake_params_init( ssl->handshake ); #if defined(POLARSSL_X509_CRT_PARSE_C) ssl->handshake->key_cert = ssl->key_cert; @@ -3307,6 +3401,8 @@ int ssl_init( ssl_context *ssl ) ssl_set_ciphersuites( ssl, ssl_list_ciphersuites() ); + ssl->renego_max_records = SSL_RENEGO_MAX_RECORDS_DEFAULT; + #if defined(POLARSSL_DHM_C) if( ( ret = mpi_read_string( &ssl->dhm_P, 16, POLARSSL_DHM_RFC5114_MODP_1024_P) ) != 0 || @@ -3340,7 +3436,8 @@ int ssl_init( ssl_context *ssl ) if( ssl->out_ctr == NULL ) { SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed", len ) ); - polarssl_free( ssl-> in_ctr ); + polarssl_free( ssl->in_ctr ); + ssl->in_ctr = NULL; return( POLARSSL_ERR_SSL_MALLOC_FAILED ); } @@ -3351,6 +3448,10 @@ int ssl_init( ssl_context *ssl ) ssl->ticket_lifetime = SSL_DEFAULT_TICKET_LIFETIME; #endif +#if defined(POLARSSL_SSL_SET_CURVES) + ssl->curve_list = ecp_grp_id_list( ); +#endif + if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) return( ret ); @@ -3392,11 +3493,13 @@ int ssl_session_reset( ssl_context *ssl ) ssl->transform_in = NULL; ssl->transform_out = NULL; + ssl->renego_records_seen = 0; + memset( ssl->out_ctr, 0, SSL_BUFFER_LEN ); memset( ssl->in_ctr, 0, SSL_BUFFER_LEN ); #if defined(POLARSSL_SSL_HW_RECORD_ACCEL) - if( ssl_hw_record_reset != NULL) + if( ssl_hw_record_reset != NULL ) { SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_reset()" ) ); if( ( ret = ssl_hw_record_reset( ssl ) ) != 0 ) @@ -3421,6 +3524,10 @@ int ssl_session_reset( ssl_context *ssl ) ssl->session = NULL; } +#if defined(POLARSSL_SSL_ALPN) + ssl->alpn_chosen = NULL; +#endif + if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) return( ret ); @@ -3428,6 +3535,14 @@ int ssl_session_reset( ssl_context *ssl ) } #if defined(POLARSSL_SSL_SESSION_TICKETS) +static void ssl_ticket_keys_free( ssl_ticket_keys *tkeys ) +{ + aes_free( &tkeys->enc ); + aes_free( &tkeys->dec ); + + polarssl_zeroize( tkeys, sizeof(ssl_ticket_keys) ); +} + /* * Allocate and initialize ticket keys */ @@ -3444,18 +3559,31 @@ static int ssl_ticket_keys_init( ssl_context *ssl ) if( tkeys == NULL ) return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + aes_init( &tkeys->enc ); + aes_init( &tkeys->dec ); + if( ( ret = ssl->f_rng( ssl->p_rng, tkeys->key_name, 16 ) ) != 0 ) + { + ssl_ticket_keys_free( tkeys ); + polarssl_free( tkeys ); return( ret ); + } if( ( ret = ssl->f_rng( ssl->p_rng, buf, 16 ) ) != 0 || ( ret = aes_setkey_enc( &tkeys->enc, buf, 128 ) ) != 0 || ( ret = aes_setkey_dec( &tkeys->dec, buf, 128 ) ) != 0 ) { - return( ret ); + ssl_ticket_keys_free( tkeys ); + polarssl_free( tkeys ); + return( ret ); } if( ( ret = ssl->f_rng( ssl->p_rng, tkeys->mac_key, 16 ) ) != 0 ) + { + ssl_ticket_keys_free( tkeys ); + polarssl_free( tkeys ); return( ret ); + } ssl->ticket_keys = tkeys; @@ -3555,7 +3683,8 @@ void ssl_set_ciphersuites( ssl_context *ssl, const int *ciphersuites ) ssl->ciphersuite_list[SSL_MINOR_VERSION_3] = ciphersuites; } -void ssl_set_ciphersuites_for_version( ssl_context *ssl, const int *ciphersuites, +void ssl_set_ciphersuites_for_version( ssl_context *ssl, + const int *ciphersuites, int major, int minor ) { if( major != SSL_MAJOR_VERSION_3 ) @@ -3583,7 +3712,8 @@ static ssl_key_cert *ssl_add_key_cert( ssl_context *ssl ) if( ssl->key_cert == NULL ) { ssl->key_cert = key_cert; - ssl->handshake->key_cert = key_cert; + if( ssl->handshake != NULL ) + ssl->handshake->key_cert = key_cert; } else { @@ -3593,7 +3723,7 @@ static ssl_key_cert *ssl_add_key_cert( ssl_context *ssl ) last->next = key_cert; } - return key_cert; + return( key_cert ); } void ssl_set_ca_chain( ssl_context *ssl, x509_crt *ca_chain, @@ -3684,6 +3814,9 @@ int ssl_set_psk( ssl_context *ssl, const unsigned char *psk, size_t psk_len, if( psk == NULL || psk_identity == NULL ) return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + if( psk_len > POLARSSL_PSK_MAX_LEN ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + if( ssl->psk != NULL ) { polarssl_free( ssl->psk ); @@ -3694,7 +3827,8 @@ int ssl_set_psk( ssl_context *ssl, const unsigned char *psk, size_t psk_len, ssl->psk_identity_len = psk_identity_len; ssl->psk = (unsigned char *) polarssl_malloc( ssl->psk_len ); - ssl->psk_identity = (unsigned char *) polarssl_malloc( ssl->psk_identity_len ); + ssl->psk_identity = (unsigned char *) + polarssl_malloc( ssl->psk_identity_len ); if( ssl->psk == NULL || ssl->psk_identity == NULL ) return( POLARSSL_ERR_SSL_MALLOC_FAILED ); @@ -3739,13 +3873,13 @@ int ssl_set_dh_param_ctx( ssl_context *ssl, dhm_context *dhm_ctx ) { int ret; - if( ( ret = mpi_copy(&ssl->dhm_P, &dhm_ctx->P) ) != 0 ) + if( ( ret = mpi_copy( &ssl->dhm_P, &dhm_ctx->P ) ) != 0 ) { SSL_DEBUG_RET( 1, "mpi_copy", ret ); return( ret ); } - if( ( ret = mpi_copy(&ssl->dhm_G, &dhm_ctx->G) ) != 0 ) + if( ( ret = mpi_copy( &ssl->dhm_G, &dhm_ctx->G ) ) != 0 ) { SSL_DEBUG_RET( 1, "mpi_copy", ret ); return( ret ); @@ -3755,6 +3889,16 @@ int ssl_set_dh_param_ctx( ssl_context *ssl, dhm_context *dhm_ctx ) } #endif /* POLARSSL_DHM_C */ +#if defined(POLARSSL_SSL_SET_CURVES) +/* + * Set the allowed elliptic curves + */ +void ssl_set_curves( ssl_context *ssl, const ecp_group_id *curve_list ) +{ + ssl->curve_list = curve_list; +} +#endif + #if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) int ssl_set_hostname( ssl_context *ssl, const char *hostname ) { @@ -3789,6 +3933,37 @@ void ssl_set_sni( ssl_context *ssl, } #endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */ +#if defined(POLARSSL_SSL_ALPN) +int ssl_set_alpn_protocols( ssl_context *ssl, const char **protos ) +{ + size_t cur_len, tot_len; + const char **p; + + /* + * "Empty strings MUST NOT be included and byte strings MUST NOT be + * truncated". Check lengths now rather than later. + */ + tot_len = 0; + for( p = protos; *p != NULL; p++ ) + { + cur_len = strlen( *p ); + tot_len += cur_len; + + if( cur_len == 0 || cur_len > 255 || tot_len > 65535 ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + + ssl->alpn_list = protos; + + return( 0 ); +} + +const char *ssl_get_alpn_protocol( const ssl_context *ssl ) +{ + return( ssl->alpn_chosen ); +} +#endif /* POLARSSL_SSL_ALPN */ + void ssl_set_max_version( ssl_context *ssl, int major, int minor ) { if( major >= SSL_MIN_MAJOR_VERSION && major <= SSL_MAX_MAJOR_VERSION && @@ -3812,7 +3987,7 @@ void ssl_set_min_version( ssl_context *ssl, int major, int minor ) #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code ) { - if( mfl_code >= sizeof( mfl_code_to_length ) || + if( mfl_code >= SSL_MAX_FRAG_LEN_INVALID || mfl_code_to_length[mfl_code] > SSL_MAX_CONTENT_LEN ) { return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); @@ -3846,6 +4021,11 @@ void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy ) ssl->allow_legacy_renegotiation = allow_legacy; } +void ssl_set_renegotiation_enforced( ssl_context *ssl, int max_records ) +{ + ssl->renego_max_records = max_records; +} + #if defined(POLARSSL_SSL_SESSION_TICKETS) int ssl_set_session_tickets( ssl_context *ssl, int use_tickets ) { @@ -3882,7 +4062,7 @@ int ssl_get_verify_result( const ssl_context *ssl ) const char *ssl_get_ciphersuite( const ssl_context *ssl ) { if( ssl == NULL || ssl->session == NULL ) - return NULL; + return( NULL ); return ssl_get_ciphersuite_name( ssl->session->ciphersuite ); } @@ -3913,9 +4093,9 @@ const char *ssl_get_version( const ssl_context *ssl ) const x509_crt *ssl_get_peer_cert( const ssl_context *ssl ) { if( ssl == NULL || ssl->session == NULL ) - return NULL; + return( NULL ); - return ssl->session->peer_cert; + return( ssl->session->peer_cert ); } #endif /* POLARSSL_X509_CRT_PARSE_C */ @@ -4142,7 +4322,8 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len ) if( ssl->disable_renegotiation == SSL_RENEGOTIATION_DISABLED || ( ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION && - ssl->allow_legacy_renegotiation == SSL_LEGACY_NO_RENEGOTIATION ) ) + ssl->allow_legacy_renegotiation == + SSL_LEGACY_NO_RENEGOTIATION ) ) { SSL_DEBUG_MSG( 3, ( "ignoring renegotiation, sending alert" ) ); @@ -4156,7 +4337,7 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len ) return( ret ); } else -#endif +#endif /* POLARSSL_SSL_PROTO_SSL3 */ #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ defined(POLARSSL_SSL_PROTO_TLS1_2) if( ssl->minor_ver >= SSL_MINOR_VERSION_1 ) @@ -4169,10 +4350,11 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len ) } } else -#endif +#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || + POLARSSL_SSL_PROTO_TLS1_2 */ { SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); } } else @@ -4188,9 +4370,15 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len ) } else if( ssl->renegotiation == SSL_RENEGOTIATION_PENDING ) { - SSL_DEBUG_MSG( 1, ( "renegotiation requested, " - "but not honored by client" ) ); - return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); + ssl->renego_records_seen++; + + if( ssl->renego_max_records >= 0 && + ssl->renego_records_seen > ssl->renego_max_records ) + { + SSL_DEBUG_MSG( 1, ( "renegotiation requested, " + "but not honored by client" ) ); + return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); + } } else if( ssl->in_msgtype != SSL_MSG_APPLICATION_DATA ) { @@ -4315,18 +4503,21 @@ int ssl_close_notify( ssl_context *ssl ) void ssl_transform_free( ssl_transform *transform ) { + if( transform == NULL ) + return; + #if defined(POLARSSL_ZLIB_SUPPORT) deflateEnd( &transform->ctx_deflate ); inflateEnd( &transform->ctx_inflate ); #endif - cipher_free_ctx( &transform->cipher_ctx_enc ); - cipher_free_ctx( &transform->cipher_ctx_dec ); + cipher_free( &transform->cipher_ctx_enc ); + cipher_free( &transform->cipher_ctx_dec ); - md_free_ctx( &transform->md_ctx_enc ); - md_free_ctx( &transform->md_ctx_dec ); + md_free( &transform->md_ctx_enc ); + md_free( &transform->md_ctx_dec ); - memset( transform, 0, sizeof( ssl_transform ) ); + polarssl_zeroize( transform, sizeof( ssl_transform ) ); } #if defined(POLARSSL_X509_CRT_PARSE_C) @@ -4352,6 +4543,9 @@ static void ssl_key_cert_free( ssl_key_cert *key_cert ) void ssl_handshake_free( ssl_handshake_params *handshake ) { + if( handshake == NULL ) + return; + #if defined(POLARSSL_DHM_C) dhm_free( &handshake->dhm_ctx ); #endif @@ -4360,8 +4554,8 @@ void ssl_handshake_free( ssl_handshake_params *handshake ) #endif #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) - /* explicit void pointer cast for buggy MS compiler */ - polarssl_free( (void *) handshake->curves ); + /* explicit void pointer cast for buggy MS compiler */ + polarssl_free( (void *) handshake->curves ); #endif #if defined(POLARSSL_X509_CRT_PARSE_C) && \ @@ -4381,13 +4575,16 @@ void ssl_handshake_free( ssl_handshake_params *handshake ) cur = next; } } -#endif +#endif /* POLARSSL_X509_CRT_PARSE_C && POLARSSL_SSL_SERVER_NAME_INDICATION */ - memset( handshake, 0, sizeof( ssl_handshake_params ) ); + polarssl_zeroize( handshake, sizeof( ssl_handshake_params ) ); } void ssl_session_free( ssl_session *session ) { + if( session == NULL ) + return; + #if defined(POLARSSL_X509_CRT_PARSE_C) if( session->peer_cert != NULL ) { @@ -4400,7 +4597,7 @@ void ssl_session_free( ssl_session *session ) polarssl_free( session->ticket ); #endif - memset( session, 0, sizeof( ssl_session ) ); + polarssl_zeroize( session, sizeof( ssl_session ) ); } /* @@ -4408,24 +4605,27 @@ void ssl_session_free( ssl_session *session ) */ void ssl_free( ssl_context *ssl ) { + if( ssl == NULL ) + return; + SSL_DEBUG_MSG( 2, ( "=> free" ) ); if( ssl->out_ctr != NULL ) { - memset( ssl->out_ctr, 0, SSL_BUFFER_LEN ); + polarssl_zeroize( ssl->out_ctr, SSL_BUFFER_LEN ); polarssl_free( ssl->out_ctr ); } if( ssl->in_ctr != NULL ) { - memset( ssl->in_ctr, 0, SSL_BUFFER_LEN ); + polarssl_zeroize( ssl->in_ctr, SSL_BUFFER_LEN ); polarssl_free( ssl->in_ctr ); } #if defined(POLARSSL_ZLIB_SUPPORT) if( ssl->compress_buf != NULL ) { - memset( ssl->compress_buf, 0, SSL_BUFFER_LEN ); + polarssl_zeroize( ssl->compress_buf, SSL_BUFFER_LEN ); polarssl_free( ssl->compress_buf ); } #endif @@ -4459,13 +4659,17 @@ void ssl_free( ssl_context *ssl ) } #if defined(POLARSSL_SSL_SESSION_TICKETS) - polarssl_free( ssl->ticket_keys ); + if( ssl->ticket_keys ) + { + ssl_ticket_keys_free( ssl->ticket_keys ); + polarssl_free( ssl->ticket_keys ); + } #endif #if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) - if ( ssl->hostname != NULL ) + if( ssl->hostname != NULL ) { - memset( ssl->hostname, 0, ssl->hostname_len ); + polarssl_zeroize( ssl->hostname, ssl->hostname_len ); polarssl_free( ssl->hostname ); ssl->hostname_len = 0; } @@ -4474,8 +4678,8 @@ void ssl_free( ssl_context *ssl ) #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) if( ssl->psk != NULL ) { - memset( ssl->psk, 0, ssl->psk_len ); - memset( ssl->psk_identity, 0, ssl->psk_identity_len ); + polarssl_zeroize( ssl->psk, ssl->psk_len ); + polarssl_zeroize( ssl->psk_identity, ssl->psk_identity_len ); polarssl_free( ssl->psk ); polarssl_free( ssl->psk_identity ); ssl->psk_len = 0; @@ -4498,7 +4702,7 @@ void ssl_free( ssl_context *ssl ) SSL_DEBUG_MSG( 2, ( "<= free" ) ); /* Actually clear after last debug message */ - memset( ssl, 0, sizeof( ssl_context ) ); + polarssl_zeroize( ssl, sizeof( ssl_context ) ); } #if defined(POLARSSL_PK_C) @@ -4534,7 +4738,7 @@ pk_type_t ssl_pk_alg_from_sig( unsigned char sig ) return( POLARSSL_PK_NONE ); } } -#endif +#endif /* POLARSSL_PK_C */ /* * Convert between SSL_HASH_XXX and POLARSSL_MD_XXX @@ -4568,4 +4772,102 @@ md_type_t ssl_md_alg_from_hash( unsigned char hash ) } } +#if defined(POLARSSL_SSL_SET_CURVES) +/* + * Check is a curve proposed by the peer is in our list. + * Return 1 if we're willing to use it, 0 otherwise. + */ +int ssl_curve_is_acceptable( const ssl_context *ssl, ecp_group_id grp_id ) +{ + const ecp_group_id *gid; + + for( gid = ssl->curve_list; *gid != POLARSSL_ECP_DP_NONE; gid++ ) + if( *gid == grp_id ) + return( 1 ); + + return( 0 ); +} +#endif /* POLARSSL_SSL_SET_CURVES */ + +#if defined(POLARSSL_X509_CRT_PARSE_C) +int ssl_check_cert_usage( const x509_crt *cert, + const ssl_ciphersuite_t *ciphersuite, + int cert_endpoint ) +{ +#if defined(POLARSSL_X509_CHECK_KEY_USAGE) + int usage = 0; +#endif +#if defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) + const char *ext_oid; + size_t ext_len; +#endif + +#if !defined(POLARSSL_X509_CHECK_KEY_USAGE) && \ + !defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) + ((void) cert); + ((void) cert_endpoint); #endif + +#if defined(POLARSSL_X509_CHECK_KEY_USAGE) + if( cert_endpoint == SSL_IS_SERVER ) + { + /* Server part of the key exchange */ + switch( ciphersuite->key_exchange ) + { + case POLARSSL_KEY_EXCHANGE_RSA: + case POLARSSL_KEY_EXCHANGE_RSA_PSK: + usage = KU_KEY_ENCIPHERMENT; + break; + + case POLARSSL_KEY_EXCHANGE_DHE_RSA: + case POLARSSL_KEY_EXCHANGE_ECDHE_RSA: + case POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA: + usage = KU_DIGITAL_SIGNATURE; + break; + + case POLARSSL_KEY_EXCHANGE_ECDH_RSA: + case POLARSSL_KEY_EXCHANGE_ECDH_ECDSA: + usage = KU_KEY_AGREEMENT; + break; + + /* Don't use default: we want warnings when adding new values */ + case POLARSSL_KEY_EXCHANGE_NONE: + case POLARSSL_KEY_EXCHANGE_PSK: + case POLARSSL_KEY_EXCHANGE_DHE_PSK: + case POLARSSL_KEY_EXCHANGE_ECDHE_PSK: + usage = 0; + } + } + else + { + /* Client auth: we only implement rsa_sign and ecdsa_sign for now */ + usage = KU_DIGITAL_SIGNATURE; + } + + if( x509_crt_check_key_usage( cert, usage ) != 0 ) + return( -1 ); +#else + ((void) ciphersuite); +#endif /* POLARSSL_X509_CHECK_KEY_USAGE */ + +#if defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) + if( cert_endpoint == SSL_IS_SERVER ) + { + ext_oid = OID_SERVER_AUTH; + ext_len = OID_SIZE( OID_SERVER_AUTH ); + } + else + { + ext_oid = OID_CLIENT_AUTH; + ext_len = OID_SIZE( OID_CLIENT_AUTH ); + } + + if( x509_crt_check_extended_key_usage( cert, ext_oid, ext_len ) != 0 ) + return( -1 ); +#endif /* POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE */ + + return( 0 ); +} +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +#endif /* POLARSSL_SSL_TLS_C */ diff --git a/pdns/ext/polarssl/library/threading.c b/pdns/ext/polarssl/library/threading.c index 659aa7e4b..522c70fef 100644 --- a/pdns/ext/polarssl/library/threading.c +++ b/pdns/ext/polarssl/library/threading.c @@ -1,7 +1,7 @@ /* * Threading abstraction layer * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,43 +23,16 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_THREADING_C) #include "polarssl/threading.h" -#if defined(POLARSSL_THREADING_DUMMY) -static int threading_mutex_init_dummy( threading_mutex_t *mutex ) -{ - ((void) mutex ); - return( 0 ); -} - -static int threading_mutex_free_dummy( threading_mutex_t *mutex ) -{ - ((void) mutex ); - return( 0 ); -} - -static int threading_mutex_lock_dummy( threading_mutex_t *mutex ) -{ - ((void) mutex ); - return( 0 ); -} - -static int threading_mutex_unlock_dummy( threading_mutex_t *mutex ) -{ - ((void) mutex ); - return( 0 ); -} - -int (*polarssl_mutex_init)( threading_mutex_t * ) = threading_mutex_init_dummy; -int (*polarssl_mutex_free)( threading_mutex_t * ) = threading_mutex_free_dummy; -int (*polarssl_mutex_lock)( threading_mutex_t * ) = threading_mutex_lock_dummy; -int (*polarssl_mutex_unlock)( threading_mutex_t * ) = threading_mutex_unlock_dummy; -#endif /* POLARSSL_THREADING_DUMMY */ - #if defined(POLARSSL_THREADING_PTHREAD) static int threading_mutex_init_pthread( threading_mutex_t *mutex ) { @@ -112,10 +85,16 @@ int (*polarssl_mutex_unlock)( threading_mutex_t * ) = threading_mutex_unlock_pth #endif /* POLARSSL_THREADING_PTHREAD */ #if defined(POLARSSL_THREADING_ALT) -int (*polarssl_mutex_init)( threading_mutex_t * ) = NULL; -int (*polarssl_mutex_free)( threading_mutex_t * ) = NULL; -int (*polarssl_mutex_lock)( threading_mutex_t * ) = NULL; -int (*polarssl_mutex_unlock)( threading_mutex_t * ) = NULL; +static int threading_mutex_fail( threading_mutex_t *mutex ) +{ + ((void) mutex ); + return( POLARSSL_ERR_THREADING_BAD_INPUT_DATA ); +} + +int (*polarssl_mutex_init)( threading_mutex_t * ) = threading_mutex_fail; +int (*polarssl_mutex_free)( threading_mutex_t * ) = threading_mutex_fail; +int (*polarssl_mutex_lock)( threading_mutex_t * ) = threading_mutex_fail; +int (*polarssl_mutex_unlock)( threading_mutex_t * ) = threading_mutex_fail; int threading_set_alt( int (*mutex_init)( threading_mutex_t * ), int (*mutex_free)( threading_mutex_t * ), diff --git a/pdns/ext/polarssl/library/timing.c b/pdns/ext/polarssl/library/timing.c index 1b4311cbc..6c1dfa46b 100644 --- a/pdns/ext/polarssl/library/timing.c +++ b/pdns/ext/polarssl/library/timing.c @@ -1,7 +1,7 @@ /* * Portable interface to the CPU cycle counter * - * Copyright (C) 2006-2010, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,9 +23,20 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_printf printf +#endif -#if defined(POLARSSL_TIMING_C) +#if defined(POLARSSL_TIMING_C) && !defined(POLARSSL_TIMING_ALT) #include "polarssl/timing.h" @@ -52,10 +63,10 @@ struct _hr_time struct timeval start; }; -#endif +#endif /* _WIN32 && !EFIX64 && !EFI32 */ #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ - (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) + ( defined(_MSC_VER) && defined(_M_IX86) ) || defined(__WATCOMC__) #define POLARSSL_HAVE_HARDCLOCK @@ -66,7 +77,8 @@ unsigned long hardclock( void ) __asm mov [tsc], eax return( tsc ); } -#endif +#endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && + ( _MSC_VER && _M_IX86 ) || __WATCOMC__ */ #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ defined(__GNUC__) && defined(__i386__) @@ -76,26 +88,28 @@ unsigned long hardclock( void ) unsigned long hardclock( void ) { unsigned long lo, hi; - asm( "rdtsc" : "=a" (lo), "=d" (hi) ); + asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); return( lo ); } -#endif +#endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && + __GNUC__ && __i386__ */ #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ - defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__)) + defined(__GNUC__) && ( defined(__amd64__) || defined(__x86_64__) ) #define POLARSSL_HAVE_HARDCLOCK unsigned long hardclock( void ) { unsigned long lo, hi; - asm( "rdtsc" : "=a" (lo), "=d" (hi) ); - return( lo | (hi << 32) ); + asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); + return( lo | ( hi << 32 ) ); } -#endif +#endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && + __GNUC__ && ( __amd64__ || __x86_64__ ) */ #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ - defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) + defined(__GNUC__) && ( defined(__powerpc__) || defined(__ppc__) ) #define POLARSSL_HAVE_HARDCLOCK @@ -105,15 +119,16 @@ unsigned long hardclock( void ) do { - asm( "mftbu %0" : "=r" (tbu0) ); - asm( "mftb %0" : "=r" (tbl ) ); - asm( "mftbu %0" : "=r" (tbu1) ); + asm volatile( "mftbu %0" : "=r" (tbu0) ); + asm volatile( "mftb %0" : "=r" (tbl ) ); + asm volatile( "mftbu %0" : "=r" (tbu1) ); } while( tbu0 != tbu1 ); return( tbl ); } -#endif +#endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && + __GNUC__ && ( __powerpc__ || __ppc__ ) */ #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ defined(__GNUC__) && defined(__sparc64__) @@ -126,11 +141,12 @@ unsigned long hardclock( void ) unsigned long hardclock( void ) { unsigned long tick; - asm( "rdpr %%tick, %0;" : "=&r" (tick) ); + asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) ); return( tick ); } -#endif -#endif +#endif /* __OpenBSD__ */ +#endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && + __GNUC__ && __sparc64__ */ #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__) @@ -140,11 +156,12 @@ unsigned long hardclock( void ) unsigned long hardclock( void ) { unsigned long tick; - asm( ".byte 0x83, 0x41, 0x00, 0x00" ); - asm( "mov %%g1, %0" : "=r" (tick) ); + asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" ); + asm volatile( "mov %%g1, %0" : "=r" (tick) ); return( tick ); } -#endif +#endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && + __GNUC__ && __sparc__ && !__sparc64__ */ #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ defined(__GNUC__) && defined(__alpha__) @@ -154,10 +171,11 @@ unsigned long hardclock( void ) unsigned long hardclock( void ) { unsigned long cc; - asm( "rpcc %0" : "=r" (cc) ); + asm volatile( "rpcc %0" : "=r" (cc) ); return( cc & 0xFFFFFFFF ); } -#endif +#endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && + __GNUC__ && __alpha__ */ #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ defined(__GNUC__) && defined(__ia64__) @@ -167,10 +185,11 @@ unsigned long hardclock( void ) unsigned long hardclock( void ) { unsigned long itc; - asm( "mov %0 = ar.itc" : "=r" (itc) ); + asm volatile( "mov %0 = ar.itc" : "=r" (itc) ); return( itc ); } -#endif +#endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && + __GNUC__ && __ia64__ */ #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(_MSC_VER) && \ !defined(EFIX64) && !defined(EFI32) @@ -181,11 +200,11 @@ unsigned long hardclock( void ) { LARGE_INTEGER offset; - QueryPerformanceCounter( &offset ); + QueryPerformanceCounter( &offset ); - return (unsigned long)( offset.QuadPart ); + return( (unsigned long)( offset.QuadPart ) ); } -#endif +#endif /* !POLARSSL_HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */ #if !defined(POLARSSL_HAVE_HARDCLOCK) @@ -208,7 +227,7 @@ unsigned long hardclock( void ) return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000 + ( tv_cur.tv_usec - tv_init.tv_usec ) ); } -#endif +#endif /* !POLARSSL_HAVE_HARDCLOCK */ volatile int alarmed = 0; @@ -234,17 +253,17 @@ unsigned long get_timer( struct hr_time *val, int reset ) } DWORD WINAPI TimerProc( LPVOID uElapse ) -{ +{ Sleep( (DWORD) uElapse ); - alarmed = 1; + alarmed = 1; return( TRUE ); } void set_alarm( int seconds ) -{ +{ DWORD ThreadId; - alarmed = 0; + alarmed = 0; CloseHandle( CreateThread( NULL, 0, TimerProc, (LPVOID) ( seconds * 1000 ), 0, &ThreadId ) ); } @@ -254,7 +273,7 @@ void m_sleep( int milliseconds ) Sleep( milliseconds ); } -#else +#else /* _WIN32 && !EFIX64 && !EFI32 */ unsigned long get_timer( struct hr_time *val, int reset ) { @@ -282,10 +301,10 @@ void m_sleep( int milliseconds ) usleep( milliseconds * 1000 ); } -#else +#else /* INTEGRITY */ static void sighandler( int signum ) -{ +{ alarmed = 1; signal( signum, sighandler ); } @@ -302,12 +321,180 @@ void m_sleep( int milliseconds ) struct timeval tv; tv.tv_sec = milliseconds / 1000; - tv.tv_usec = milliseconds * 1000; + tv.tv_usec = ( milliseconds % 1000 ) * 1000; select( 0, NULL, NULL, NULL, &tv ); } #endif /* INTEGRITY */ -#endif +#endif /* _WIN32 && !EFIX64 && !EFI32 */ + +#if defined(POLARSSL_SELF_TEST) +/* To test net_usleep against our functions */ +#if defined(POLARSSL_NET_C) +#include "polarssl/net.h" #endif + +/* + * Busy-waits for the given number of milliseconds. + * Used for testing hardclock. + */ +static void busy_msleep( unsigned long msec ) +{ + struct hr_time hires; + unsigned long i = 0; /* for busy-waiting */ + volatile unsigned long j; /* to prevent optimisation */ + + (void) get_timer( &hires, 1 ); + + while( get_timer( &hires, 0 ) < msec ) + i++; + + j = i; + (void) j; +} + +/* + * Checkup routine + * + * Warning: this is work in progress, some tests may not be reliable enough + * yet! False positives may happen. + */ +int timing_self_test( int verbose ) +{ + unsigned long cycles, ratio; + unsigned long millisecs, secs; + int hardfail; + struct hr_time hires; + + if( verbose != 0 ) + polarssl_printf( " TIMING tests note: will take some time!\n" ); + + if( verbose != 0 ) + polarssl_printf( " TIMING test #1 (m_sleep / get_timer): " ); + + for( secs = 1; secs <= 3; secs++ ) + { + (void) get_timer( &hires, 1 ); + + m_sleep( 500 * secs ); + + millisecs = get_timer( &hires, 0 ); + + if( millisecs < 450 * secs || millisecs > 550 * secs ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( " TIMING test #2 (set_alarm / get_timer): " ); + + for( secs = 1; secs <= 3; secs++ ) + { + (void) get_timer( &hires, 1 ); + + set_alarm( secs ); + while( !alarmed ) + ; + + millisecs = get_timer( &hires, 0 ); + + if( millisecs < 900 * secs || millisecs > 1100 * secs ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( " TIMING test #3 (hardclock / get_timer): " ); + + /* + * Allow one failure for possible counter wrapping. + * On a 4Ghz 32-bit machine the cycle counter wraps about once per second; + * since the whole test is about 10ms, it shouldn't happen twice in a row. + */ + hardfail = 0; + +hard_test: + if( hardfail > 1 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + /* Get a reference ratio cycles/ms */ + millisecs = 1; + cycles = hardclock(); + busy_msleep( millisecs ); + cycles = hardclock() - cycles; + ratio = cycles / millisecs; + + /* Check that the ratio is mostly constant */ + for( millisecs = 2; millisecs <= 4; millisecs++ ) + { + cycles = hardclock(); + busy_msleep( millisecs ); + cycles = hardclock() - cycles; + + /* Allow variation up to 20% */ + if( cycles / millisecs < ratio - ratio / 5 || + cycles / millisecs > ratio + ratio / 5 ) + { + hardfail++; + goto hard_test; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + +#if defined(POLARSSL_NET_C) + if( verbose != 0 ) + polarssl_printf( " TIMING test #4 (net_usleep/ get_timer): " ); + + for( secs = 1; secs <= 3; secs++ ) + { + (void) get_timer( &hires, 1 ); + + net_usleep( 500000 * secs ); + + millisecs = get_timer( &hires, 0 ); + + if( millisecs < 450 * secs || millisecs > 550 * secs ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); +#endif /* POLARSSL_NET_C */ + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_TIMING_C && !POLARSSL_TIMING_ALT */ diff --git a/pdns/ext/polarssl/library/version.c b/pdns/ext/polarssl/library/version.c index c1080b781..c3c708a2d 100644 --- a/pdns/ext/polarssl/library/version.c +++ b/pdns/ext/polarssl/library/version.c @@ -1,7 +1,7 @@ /* * Version information * - * Copyright (C) 2006-2010, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,7 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_VERSION_C) @@ -34,17 +38,19 @@ const char version[] = POLARSSL_VERSION_STRING; unsigned int version_get_number() { - return POLARSSL_VERSION_NUMBER; + return( POLARSSL_VERSION_NUMBER ); } void version_get_string( char *string ) { - memcpy( string, POLARSSL_VERSION_STRING, sizeof( POLARSSL_VERSION_STRING ) ); + memcpy( string, POLARSSL_VERSION_STRING, + sizeof( POLARSSL_VERSION_STRING ) ); } void version_get_string_full( char *string ) { - memcpy( string, POLARSSL_VERSION_STRING_FULL, sizeof( POLARSSL_VERSION_STRING_FULL ) ); + memcpy( string, POLARSSL_VERSION_STRING_FULL, + sizeof( POLARSSL_VERSION_STRING_FULL ) ); } #endif /* POLARSSL_VERSION_C */ diff --git a/pdns/ext/polarssl/library/version_features.c b/pdns/ext/polarssl/library/version_features.c new file mode 100644 index 000000000..10231987f --- /dev/null +++ b/pdns/ext/polarssl/library/version_features.c @@ -0,0 +1,560 @@ +/* + * Version feature information + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_VERSION_C) + +#include "polarssl/version.h" + +#include + +#if defined(_MSC_VER) && !defined strcasecmp && !defined(EFIX64) && \ + !defined(EFI32) +#define strcasecmp _stricmp +#endif + +const char *features[] = { +#if defined(POLARSSL_VERSION_FEATURES) +#if defined(POLARSSL_HAVE_INT8) + "POLARSSL_HAVE_INT8", +#endif /* POLARSSL_HAVE_INT8 */ +#if defined(POLARSSL_HAVE_INT16) + "POLARSSL_HAVE_INT16", +#endif /* POLARSSL_HAVE_INT16 */ +#if defined(POLARSSL_HAVE_LONGLONG) + "POLARSSL_HAVE_LONGLONG", +#endif /* POLARSSL_HAVE_LONGLONG */ +#if defined(POLARSSL_HAVE_ASM) + "POLARSSL_HAVE_ASM", +#endif /* POLARSSL_HAVE_ASM */ +#if defined(POLARSSL_HAVE_SSE2) + "POLARSSL_HAVE_SSE2", +#endif /* POLARSSL_HAVE_SSE2 */ +#if defined(POLARSSL_HAVE_TIME) + "POLARSSL_HAVE_TIME", +#endif /* POLARSSL_HAVE_TIME */ +#if defined(POLARSSL_HAVE_IPV6) + "POLARSSL_HAVE_IPV6", +#endif /* POLARSSL_HAVE_IPV6 */ +#if defined(POLARSSL_PLATFORM_MEMORY) + "POLARSSL_PLATFORM_MEMORY", +#endif /* POLARSSL_PLATFORM_MEMORY */ +#if defined(POLARSSL_PLATFORM_NO_STD_FUNCTIONS) + "POLARSSL_PLATFORM_NO_STD_FUNCTIONS", +#endif /* POLARSSL_PLATFORM_NO_STD_FUNCTIONS */ +#if defined(POLARSSL_PLATFORM_PRINTF_ALT) + "POLARSSL_PLATFORM_PRINTF_ALT", +#endif /* POLARSSL_PLATFORM_PRINTF_ALT */ +#if defined(POLARSSL_PLATFORM_FPRINTF_ALT) + "POLARSSL_PLATFORM_FPRINTF_ALT", +#endif /* POLARSSL_PLATFORM_FPRINTF_ALT */ +#if defined(POLARSSL_TIMING_ALT) + "POLARSSL_TIMING_ALT", +#endif /* POLARSSL_TIMING_ALT */ +#if defined(POLARSSL_AES_ALT) + "POLARSSL_AES_ALT", +#endif /* POLARSSL_AES_ALT */ +#if defined(POLARSSL_ARC4_ALT) + "POLARSSL_ARC4_ALT", +#endif /* POLARSSL_ARC4_ALT */ +#if defined(POLARSSL_BLOWFISH_ALT) + "POLARSSL_BLOWFISH_ALT", +#endif /* POLARSSL_BLOWFISH_ALT */ +#if defined(POLARSSL_CAMELLIA_ALT) + "POLARSSL_CAMELLIA_ALT", +#endif /* POLARSSL_CAMELLIA_ALT */ +#if defined(POLARSSL_DES_ALT) + "POLARSSL_DES_ALT", +#endif /* POLARSSL_DES_ALT */ +#if defined(POLARSSL_XTEA_ALT) + "POLARSSL_XTEA_ALT", +#endif /* POLARSSL_XTEA_ALT */ +#if defined(POLARSSL_MD2_ALT) + "POLARSSL_MD2_ALT", +#endif /* POLARSSL_MD2_ALT */ +#if defined(POLARSSL_MD4_ALT) + "POLARSSL_MD4_ALT", +#endif /* POLARSSL_MD4_ALT */ +#if defined(POLARSSL_MD5_ALT) + "POLARSSL_MD5_ALT", +#endif /* POLARSSL_MD5_ALT */ +#if defined(POLARSSL_RIPEMD160_ALT) + "POLARSSL_RIPEMD160_ALT", +#endif /* POLARSSL_RIPEMD160_ALT */ +#if defined(POLARSSL_SHA1_ALT) + "POLARSSL_SHA1_ALT", +#endif /* POLARSSL_SHA1_ALT */ +#if defined(POLARSSL_SHA256_ALT) + "POLARSSL_SHA256_ALT", +#endif /* POLARSSL_SHA256_ALT */ +#if defined(POLARSSL_SHA512_ALT) + "POLARSSL_SHA512_ALT", +#endif /* POLARSSL_SHA512_ALT */ +#if defined(POLARSSL_AES_ROM_TABLES) + "POLARSSL_AES_ROM_TABLES", +#endif /* POLARSSL_AES_ROM_TABLES */ +#if defined(POLARSSL_CIPHER_MODE_CBC) + "POLARSSL_CIPHER_MODE_CBC", +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_CIPHER_MODE_CFB) + "POLARSSL_CIPHER_MODE_CFB", +#endif /* POLARSSL_CIPHER_MODE_CFB */ +#if defined(POLARSSL_CIPHER_MODE_CTR) + "POLARSSL_CIPHER_MODE_CTR", +#endif /* POLARSSL_CIPHER_MODE_CTR */ +#if defined(POLARSSL_CIPHER_NULL_CIPHER) + "POLARSSL_CIPHER_NULL_CIPHER", +#endif /* POLARSSL_CIPHER_NULL_CIPHER */ +#if defined(POLARSSL_CIPHER_PADDING_PKCS7) + "POLARSSL_CIPHER_PADDING_PKCS7", +#endif /* POLARSSL_CIPHER_PADDING_PKCS7 */ +#if defined(POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS) + "POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS", +#endif /* POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS */ +#if defined(POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN) + "POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN", +#endif /* POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN */ +#if defined(POLARSSL_CIPHER_PADDING_ZEROS) + "POLARSSL_CIPHER_PADDING_ZEROS", +#endif /* POLARSSL_CIPHER_PADDING_ZEROS */ +#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES) + "POLARSSL_ENABLE_WEAK_CIPHERSUITES", +#endif /* POLARSSL_ENABLE_WEAK_CIPHERSUITES */ +#if defined(POLARSSL_REMOVE_ARC4_CIPHERSUITES) + "POLARSSL_REMOVE_ARC4_CIPHERSUITES", +#endif /* POLARSSL_REMOVE_ARC4_CIPHERSUITES */ +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) + "POLARSSL_ECP_DP_SECP192R1_ENABLED", +#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) + "POLARSSL_ECP_DP_SECP224R1_ENABLED", +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) + "POLARSSL_ECP_DP_SECP256R1_ENABLED", +#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) + "POLARSSL_ECP_DP_SECP384R1_ENABLED", +#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) + "POLARSSL_ECP_DP_SECP521R1_ENABLED", +#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) + "POLARSSL_ECP_DP_SECP192K1_ENABLED", +#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED */ +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) + "POLARSSL_ECP_DP_SECP224K1_ENABLED", +#endif /* POLARSSL_ECP_DP_SECP224K1_ENABLED */ +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) + "POLARSSL_ECP_DP_SECP256K1_ENABLED", +#endif /* POLARSSL_ECP_DP_SECP256K1_ENABLED */ +#if defined(POLARSSL_ECP_DP_BP256R1_ENABLED) + "POLARSSL_ECP_DP_BP256R1_ENABLED", +#endif /* POLARSSL_ECP_DP_BP256R1_ENABLED */ +#if defined(POLARSSL_ECP_DP_BP384R1_ENABLED) + "POLARSSL_ECP_DP_BP384R1_ENABLED", +#endif /* POLARSSL_ECP_DP_BP384R1_ENABLED */ +#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) + "POLARSSL_ECP_DP_BP512R1_ENABLED", +#endif /* POLARSSL_ECP_DP_BP512R1_ENABLED */ +#if defined(POLARSSL_ECP_DP_M221_ENABLED) + "POLARSSL_ECP_DP_M221_ENABLED", +#endif /* POLARSSL_ECP_DP_M221_ENABLED */ +#if defined(POLARSSL_ECP_DP_M255_ENABLED) + "POLARSSL_ECP_DP_M255_ENABLED", +#endif /* POLARSSL_ECP_DP_M255_ENABLED */ +#if defined(POLARSSL_ECP_DP_M383_ENABLED) + "POLARSSL_ECP_DP_M383_ENABLED", +#endif /* POLARSSL_ECP_DP_M383_ENABLED */ +#if defined(POLARSSL_ECP_DP_M511_ENABLED) + "POLARSSL_ECP_DP_M511_ENABLED", +#endif /* POLARSSL_ECP_DP_M511_ENABLED */ +#if defined(POLARSSL_ECP_NIST_OPTIM) + "POLARSSL_ECP_NIST_OPTIM", +#endif /* POLARSSL_ECP_NIST_OPTIM */ +#if defined(POLARSSL_ECDSA_DETERMINISTIC) + "POLARSSL_ECDSA_DETERMINISTIC", +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ +#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) + "POLARSSL_KEY_EXCHANGE_PSK_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) + "POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) + "POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) + "POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) + "POLARSSL_KEY_EXCHANGE_RSA_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) + "POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) + "POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + "POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + "POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) + "POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED */ +#if defined(POLARSSL_PK_PARSE_EC_EXTENDED) + "POLARSSL_PK_PARSE_EC_EXTENDED", +#endif /* POLARSSL_PK_PARSE_EC_EXTENDED */ +#if defined(POLARSSL_ERROR_STRERROR_BC) + "POLARSSL_ERROR_STRERROR_BC", +#endif /* POLARSSL_ERROR_STRERROR_BC */ +#if defined(POLARSSL_ERROR_STRERROR_DUMMY) + "POLARSSL_ERROR_STRERROR_DUMMY", +#endif /* POLARSSL_ERROR_STRERROR_DUMMY */ +#if defined(POLARSSL_GENPRIME) + "POLARSSL_GENPRIME", +#endif /* POLARSSL_GENPRIME */ +#if defined(POLARSSL_FS_IO) + "POLARSSL_FS_IO", +#endif /* POLARSSL_FS_IO */ +#if defined(POLARSSL_NO_DEFAULT_ENTROPY_SOURCES) + "POLARSSL_NO_DEFAULT_ENTROPY_SOURCES", +#endif /* POLARSSL_NO_DEFAULT_ENTROPY_SOURCES */ +#if defined(POLARSSL_NO_PLATFORM_ENTROPY) + "POLARSSL_NO_PLATFORM_ENTROPY", +#endif /* POLARSSL_NO_PLATFORM_ENTROPY */ +#if defined(POLARSSL_ENTROPY_FORCE_SHA256) + "POLARSSL_ENTROPY_FORCE_SHA256", +#endif /* POLARSSL_ENTROPY_FORCE_SHA256 */ +#if defined(POLARSSL_MEMORY_DEBUG) + "POLARSSL_MEMORY_DEBUG", +#endif /* POLARSSL_MEMORY_DEBUG */ +#if defined(POLARSSL_MEMORY_BACKTRACE) + "POLARSSL_MEMORY_BACKTRACE", +#endif /* POLARSSL_MEMORY_BACKTRACE */ +#if defined(POLARSSL_PKCS1_V15) + "POLARSSL_PKCS1_V15", +#endif /* POLARSSL_PKCS1_V15 */ +#if defined(POLARSSL_PKCS1_V21) + "POLARSSL_PKCS1_V21", +#endif /* POLARSSL_PKCS1_V21 */ +#if defined(POLARSSL_RSA_NO_CRT) + "POLARSSL_RSA_NO_CRT", +#endif /* POLARSSL_RSA_NO_CRT */ +#if defined(POLARSSL_SELF_TEST) + "POLARSSL_SELF_TEST", +#endif /* POLARSSL_SELF_TEST */ +#if defined(POLARSSL_SSL_ALERT_MESSAGES) + "POLARSSL_SSL_ALERT_MESSAGES", +#endif /* POLARSSL_SSL_ALERT_MESSAGES */ +#if defined(POLARSSL_SSL_DEBUG_ALL) + "POLARSSL_SSL_DEBUG_ALL", +#endif /* POLARSSL_SSL_DEBUG_ALL */ +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) + "POLARSSL_SSL_HW_RECORD_ACCEL", +#endif /* POLARSSL_SSL_HW_RECORD_ACCEL */ +#if defined(POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) + "POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO", +#endif /* POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ +#if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE) + "POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE", +#endif /* POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE */ +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) + "POLARSSL_SSL_MAX_FRAGMENT_LENGTH", +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ +#if defined(POLARSSL_SSL_PROTO_SSL3) + "POLARSSL_SSL_PROTO_SSL3", +#endif /* POLARSSL_SSL_PROTO_SSL3 */ +#if defined(POLARSSL_SSL_PROTO_TLS1) + "POLARSSL_SSL_PROTO_TLS1", +#endif /* POLARSSL_SSL_PROTO_TLS1 */ +#if defined(POLARSSL_SSL_PROTO_TLS1_1) + "POLARSSL_SSL_PROTO_TLS1_1", +#endif /* POLARSSL_SSL_PROTO_TLS1_1 */ +#if defined(POLARSSL_SSL_PROTO_TLS1_2) + "POLARSSL_SSL_PROTO_TLS1_2", +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ +#if defined(POLARSSL_SSL_ALPN) + "POLARSSL_SSL_ALPN", +#endif /* POLARSSL_SSL_ALPN */ +#if defined(POLARSSL_SSL_SESSION_TICKETS) + "POLARSSL_SSL_SESSION_TICKETS", +#endif /* POLARSSL_SSL_SESSION_TICKETS */ +#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) + "POLARSSL_SSL_SERVER_NAME_INDICATION", +#endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */ +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) + "POLARSSL_SSL_TRUNCATED_HMAC", +#endif /* POLARSSL_SSL_TRUNCATED_HMAC */ +#if defined(POLARSSL_SSL_SET_CURVES) + "POLARSSL_SSL_SET_CURVES", +#endif /* POLARSSL_SSL_SET_CURVES */ +#if defined(POLARSSL_THREADING_ALT) + "POLARSSL_THREADING_ALT", +#endif /* POLARSSL_THREADING_ALT */ +#if defined(POLARSSL_THREADING_PTHREAD) + "POLARSSL_THREADING_PTHREAD", +#endif /* POLARSSL_THREADING_PTHREAD */ +#if defined(POLARSSL_VERSION_FEATURES) + "POLARSSL_VERSION_FEATURES", +#endif /* POLARSSL_VERSION_FEATURES */ +#if defined(POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3) + "POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3", +#endif /* POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 */ +#if defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) + "POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION", +#endif /* POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION */ +#if defined(POLARSSL_X509_CHECK_KEY_USAGE) + "POLARSSL_X509_CHECK_KEY_USAGE", +#endif /* POLARSSL_X509_CHECK_KEY_USAGE */ +#if defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) + "POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE", +#endif /* POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE */ +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) + "POLARSSL_X509_RSASSA_PSS_SUPPORT", +#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */ +#if defined(POLARSSL_ZLIB_SUPPORT) + "POLARSSL_ZLIB_SUPPORT", +#endif /* POLARSSL_ZLIB_SUPPORT */ +#if defined(POLARSSL_AESNI_C) + "POLARSSL_AESNI_C", +#endif /* POLARSSL_AESNI_C */ +#if defined(POLARSSL_AES_C) + "POLARSSL_AES_C", +#endif /* POLARSSL_AES_C */ +#if defined(POLARSSL_ARC4_C) + "POLARSSL_ARC4_C", +#endif /* POLARSSL_ARC4_C */ +#if defined(POLARSSL_ASN1_PARSE_C) + "POLARSSL_ASN1_PARSE_C", +#endif /* POLARSSL_ASN1_PARSE_C */ +#if defined(POLARSSL_ASN1_WRITE_C) + "POLARSSL_ASN1_WRITE_C", +#endif /* POLARSSL_ASN1_WRITE_C */ +#if defined(POLARSSL_BASE64_C) + "POLARSSL_BASE64_C", +#endif /* POLARSSL_BASE64_C */ +#if defined(POLARSSL_BIGNUM_C) + "POLARSSL_BIGNUM_C", +#endif /* POLARSSL_BIGNUM_C */ +#if defined(POLARSSL_BLOWFISH_C) + "POLARSSL_BLOWFISH_C", +#endif /* POLARSSL_BLOWFISH_C */ +#if defined(POLARSSL_CAMELLIA_C) + "POLARSSL_CAMELLIA_C", +#endif /* POLARSSL_CAMELLIA_C */ +#if defined(POLARSSL_CCM_C) + "POLARSSL_CCM_C", +#endif /* POLARSSL_CCM_C */ +#if defined(POLARSSL_CERTS_C) + "POLARSSL_CERTS_C", +#endif /* POLARSSL_CERTS_C */ +#if defined(POLARSSL_CIPHER_C) + "POLARSSL_CIPHER_C", +#endif /* POLARSSL_CIPHER_C */ +#if defined(POLARSSL_CTR_DRBG_C) + "POLARSSL_CTR_DRBG_C", +#endif /* POLARSSL_CTR_DRBG_C */ +#if defined(POLARSSL_DEBUG_C) + "POLARSSL_DEBUG_C", +#endif /* POLARSSL_DEBUG_C */ +#if defined(POLARSSL_DES_C) + "POLARSSL_DES_C", +#endif /* POLARSSL_DES_C */ +#if defined(POLARSSL_DHM_C) + "POLARSSL_DHM_C", +#endif /* POLARSSL_DHM_C */ +#if defined(POLARSSL_ECDH_C) + "POLARSSL_ECDH_C", +#endif /* POLARSSL_ECDH_C */ +#if defined(POLARSSL_ECDSA_C) + "POLARSSL_ECDSA_C", +#endif /* POLARSSL_ECDSA_C */ +#if defined(POLARSSL_ECP_C) + "POLARSSL_ECP_C", +#endif /* POLARSSL_ECP_C */ +#if defined(POLARSSL_ENTROPY_C) + "POLARSSL_ENTROPY_C", +#endif /* POLARSSL_ENTROPY_C */ +#if defined(POLARSSL_ERROR_C) + "POLARSSL_ERROR_C", +#endif /* POLARSSL_ERROR_C */ +#if defined(POLARSSL_GCM_C) + "POLARSSL_GCM_C", +#endif /* POLARSSL_GCM_C */ +#if defined(POLARSSL_HAVEGE_C) + "POLARSSL_HAVEGE_C", +#endif /* POLARSSL_HAVEGE_C */ +#if defined(POLARSSL_HMAC_DRBG_C) + "POLARSSL_HMAC_DRBG_C", +#endif /* POLARSSL_HMAC_DRBG_C */ +#if defined(POLARSSL_MD_C) + "POLARSSL_MD_C", +#endif /* POLARSSL_MD_C */ +#if defined(POLARSSL_MD2_C) + "POLARSSL_MD2_C", +#endif /* POLARSSL_MD2_C */ +#if defined(POLARSSL_MD4_C) + "POLARSSL_MD4_C", +#endif /* POLARSSL_MD4_C */ +#if defined(POLARSSL_MD5_C) + "POLARSSL_MD5_C", +#endif /* POLARSSL_MD5_C */ +#if defined(POLARSSL_MEMORY_C) + "POLARSSL_MEMORY_C", +#endif /* POLARSSL_MEMORY_C */ +#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) + "POLARSSL_MEMORY_BUFFER_ALLOC_C", +#endif /* POLARSSL_MEMORY_BUFFER_ALLOC_C */ +#if defined(POLARSSL_NET_C) + "POLARSSL_NET_C", +#endif /* POLARSSL_NET_C */ +#if defined(POLARSSL_OID_C) + "POLARSSL_OID_C", +#endif /* POLARSSL_OID_C */ +#if defined(POLARSSL_PADLOCK_C) + "POLARSSL_PADLOCK_C", +#endif /* POLARSSL_PADLOCK_C */ +#if defined(POLARSSL_PBKDF2_C) + "POLARSSL_PBKDF2_C", +#endif /* POLARSSL_PBKDF2_C */ +#if defined(POLARSSL_PEM_PARSE_C) + "POLARSSL_PEM_PARSE_C", +#endif /* POLARSSL_PEM_PARSE_C */ +#if defined(POLARSSL_PEM_WRITE_C) + "POLARSSL_PEM_WRITE_C", +#endif /* POLARSSL_PEM_WRITE_C */ +#if defined(POLARSSL_PK_C) + "POLARSSL_PK_C", +#endif /* POLARSSL_PK_C */ +#if defined(POLARSSL_PK_PARSE_C) + "POLARSSL_PK_PARSE_C", +#endif /* POLARSSL_PK_PARSE_C */ +#if defined(POLARSSL_PK_WRITE_C) + "POLARSSL_PK_WRITE_C", +#endif /* POLARSSL_PK_WRITE_C */ +#if defined(POLARSSL_PKCS5_C) + "POLARSSL_PKCS5_C", +#endif /* POLARSSL_PKCS5_C */ +#if defined(POLARSSL_PKCS11_C) + "POLARSSL_PKCS11_C", +#endif /* POLARSSL_PKCS11_C */ +#if defined(POLARSSL_PKCS12_C) + "POLARSSL_PKCS12_C", +#endif /* POLARSSL_PKCS12_C */ +#if defined(POLARSSL_PLATFORM_C) + "POLARSSL_PLATFORM_C", +#endif /* POLARSSL_PLATFORM_C */ +#if defined(POLARSSL_RIPEMD160_C) + "POLARSSL_RIPEMD160_C", +#endif /* POLARSSL_RIPEMD160_C */ +#if defined(POLARSSL_RSA_C) + "POLARSSL_RSA_C", +#endif /* POLARSSL_RSA_C */ +#if defined(POLARSSL_SHA1_C) + "POLARSSL_SHA1_C", +#endif /* POLARSSL_SHA1_C */ +#if defined(POLARSSL_SHA256_C) + "POLARSSL_SHA256_C", +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) + "POLARSSL_SHA512_C", +#endif /* POLARSSL_SHA512_C */ +#if defined(POLARSSL_SSL_CACHE_C) + "POLARSSL_SSL_CACHE_C", +#endif /* POLARSSL_SSL_CACHE_C */ +#if defined(POLARSSL_SSL_CLI_C) + "POLARSSL_SSL_CLI_C", +#endif /* POLARSSL_SSL_CLI_C */ +#if defined(POLARSSL_SSL_SRV_C) + "POLARSSL_SSL_SRV_C", +#endif /* POLARSSL_SSL_SRV_C */ +#if defined(POLARSSL_SSL_TLS_C) + "POLARSSL_SSL_TLS_C", +#endif /* POLARSSL_SSL_TLS_C */ +#if defined(POLARSSL_THREADING_C) + "POLARSSL_THREADING_C", +#endif /* POLARSSL_THREADING_C */ +#if defined(POLARSSL_TIMING_C) + "POLARSSL_TIMING_C", +#endif /* POLARSSL_TIMING_C */ +#if defined(POLARSSL_VERSION_C) + "POLARSSL_VERSION_C", +#endif /* POLARSSL_VERSION_C */ +#if defined(POLARSSL_X509_USE_C) + "POLARSSL_X509_USE_C", +#endif /* POLARSSL_X509_USE_C */ +#if defined(POLARSSL_X509_CRT_PARSE_C) + "POLARSSL_X509_CRT_PARSE_C", +#endif /* POLARSSL_X509_CRT_PARSE_C */ +#if defined(POLARSSL_X509_CRL_PARSE_C) + "POLARSSL_X509_CRL_PARSE_C", +#endif /* POLARSSL_X509_CRL_PARSE_C */ +#if defined(POLARSSL_X509_CSR_PARSE_C) + "POLARSSL_X509_CSR_PARSE_C", +#endif /* POLARSSL_X509_CSR_PARSE_C */ +#if defined(POLARSSL_X509_CREATE_C) + "POLARSSL_X509_CREATE_C", +#endif /* POLARSSL_X509_CREATE_C */ +#if defined(POLARSSL_X509_CRT_WRITE_C) + "POLARSSL_X509_CRT_WRITE_C", +#endif /* POLARSSL_X509_CRT_WRITE_C */ +#if defined(POLARSSL_X509_CSR_WRITE_C) + "POLARSSL_X509_CSR_WRITE_C", +#endif /* POLARSSL_X509_CSR_WRITE_C */ +#if defined(POLARSSL_XTEA_C) + "POLARSSL_XTEA_C", +#endif /* POLARSSL_XTEA_C */ +#endif /* POLARSSL_VERSION_FEATURES */ + NULL +}; + +int version_check_feature( const char *feature ) +{ + const char **idx = features; + + if( *idx == NULL ) + return( -2 ); + + if( feature == NULL ) + return( -1 ); + + while( *idx != NULL ) + { + if( !strcasecmp( *idx, feature ) ) + return( 0 ); + idx++; + } + return( -1 ); +} + +#endif /* POLARSSL_VERSION_C */ diff --git a/pdns/ext/polarssl/library/x509.c b/pdns/ext/polarssl/library/x509.c index 2ba1e8618..17c7a7db0 100644 --- a/pdns/ext/polarssl/library/x509.c +++ b/pdns/ext/polarssl/library/x509.c @@ -1,7 +1,7 @@ /* - * X.509 certificate and private key decoding + * X.509 common functions for parsing and verification * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -25,16 +25,19 @@ /* * The ITU-T X.509 standard defines a certificate format for PKI. * - * http://www.ietf.org/rfc/rfc3279.txt - * http://www.ietf.org/rfc/rfc3280.txt - * - * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc + * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) + * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) + * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) * * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_X509_USE_C) @@ -45,9 +48,10 @@ #include "polarssl/pem.h" #endif -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else +#define polarssl_printf printf #define polarssl_malloc malloc #define polarssl_free free #endif @@ -118,6 +122,223 @@ int x509_get_alg_null( unsigned char **p, const unsigned char *end, return( 0 ); } +/* + * Parse an algorithm identifier with (optional) paramaters + */ +int x509_get_alg( unsigned char **p, const unsigned char *end, + x509_buf *alg, x509_buf *params ) +{ + int ret; + + if( ( ret = asn1_get_alg( p, end, alg, params ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + return( 0 ); +} + +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) +/* + * HashAlgorithm ::= AlgorithmIdentifier + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL } + * + * For HashAlgorithm, parameters MUST be NULL or absent. + */ +static int x509_get_hash_alg( const x509_buf *alg, md_type_t *md_alg ) +{ + int ret; + unsigned char *p; + const unsigned char *end; + x509_buf md_oid; + size_t len; + + /* Make sure we got a SEQUENCE and setup bounds */ + if( alg->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); + + p = (unsigned char *) alg->p; + end = p + alg->len; + + if( p >= end ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + /* Parse md_oid */ + md_oid.tag = *p; + + if( ( ret = asn1_get_tag( &p, end, &md_oid.len, ASN1_OID ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + md_oid.p = p; + p += md_oid.len; + + /* Get md_alg from md_oid */ + if( ( ret = oid_get_md_alg( &md_oid, md_alg ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + /* Make sure params is absent of NULL */ + if( p == end ) + return( 0 ); + + if( ( ret = asn1_get_tag( &p, end, &len, ASN1_NULL ) ) != 0 || len != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p != end ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +/* + * RSASSA-PSS-params ::= SEQUENCE { + * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier, + * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier, + * saltLength [2] INTEGER DEFAULT 20, + * trailerField [3] INTEGER DEFAULT 1 } + * -- Note that the tags in this Sequence are explicit. + * + * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value + * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other + * option. Enfore this at parsing time. + */ +int x509_get_rsassa_pss_params( const x509_buf *params, + md_type_t *md_alg, md_type_t *mgf_md, + int *salt_len ) +{ + int ret; + unsigned char *p; + const unsigned char *end, *end2; + size_t len; + x509_buf alg_id, alg_params; + + /* First set everything to defaults */ + *md_alg = POLARSSL_MD_SHA1; + *mgf_md = POLARSSL_MD_SHA1; + *salt_len = 20; + + /* Make sure params is a SEQUENCE and setup bounds */ + if( params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); + + p = (unsigned char *) params->p; + end = p + params->len; + + if( p == end ) + return( 0 ); + + /* + * HashAlgorithm + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 ) + { + end2 = p + len; + + /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */ + if( ( ret = x509_get_alg_null( &p, end2, &alg_id ) ) != 0 ) + return( ret ); + + if( ( ret = oid_get_md_alg( &alg_id, md_alg ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p != end2 ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + } + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p == end ) + return( 0 ); + + /* + * MaskGenAlgorithm + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 ) + { + end2 = p + len; + + /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */ + if( ( ret = x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 ) + return( ret ); + + /* Only MFG1 is recognised for now */ + if( ! OID_CMP( OID_MGF1, &alg_id ) ) + return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE + + POLARSSL_ERR_OID_NOT_FOUND ); + + /* Parse HashAlgorithm */ + if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 ) + return( ret ); + + if( p != end2 ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + } + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p == end ) + return( 0 ); + + /* + * salt_len + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 2 ) ) == 0 ) + { + end2 = p + len; + + if( ( ret = asn1_get_int( &p, end2, salt_len ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p != end2 ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + } + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p == end ) + return( 0 ); + + /* + * trailer_field (if present, must be 1) + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) == 0 ) + { + int trailer_field; + + end2 = p + len; + + if( ( ret = asn1_get_int( &p, end2, &trailer_field ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p != end2 ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + if( trailer_field != 1 ) + return( POLARSSL_ERR_X509_INVALID_ALG ); + } + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p != end ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} +#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */ + /* * AttributeTypeAndValue ::= SEQUENCE { * type AttributeType, @@ -261,7 +482,7 @@ int x509_get_time( unsigned char **p, const unsigned char *end, tag = **p; - if ( tag == ASN1_UTC_TIME ) + if( tag == ASN1_UTC_TIME ) { (*p)++; ret = asn1_get_len( p, end, &len ); @@ -273,7 +494,7 @@ int x509_get_time( unsigned char **p, const unsigned char *end, memcpy( date, *p, ( len < sizeof( date ) - 1 ) ? len : sizeof( date ) - 1 ); - if( sscanf( date, "%2d%2d%2d%2d%2d%2d", + if( sscanf( date, "%2d%2d%2d%2d%2d%2dZ", &time->year, &time->mon, &time->day, &time->hour, &time->min, &time->sec ) < 5 ) return( POLARSSL_ERR_X509_INVALID_DATE ); @@ -285,7 +506,7 @@ int x509_get_time( unsigned char **p, const unsigned char *end, return( 0 ); } - else if ( tag == ASN1_GENERALIZED_TIME ) + else if( tag == ASN1_GENERALIZED_TIME ) { (*p)++; ret = asn1_get_len( p, end, &len ); @@ -297,7 +518,7 @@ int x509_get_time( unsigned char **p, const unsigned char *end, memcpy( date, *p, ( len < sizeof( date ) - 1 ) ? len : sizeof( date ) - 1 ); - if( sscanf( date, "%4d%2d%2d%2d%2d%2d", + if( sscanf( date, "%4d%2d%2d%2d%2d%2dZ", &time->year, &time->mon, &time->day, &time->hour, &time->min, &time->sec ) < 5 ) return( POLARSSL_ERR_X509_INVALID_DATE ); @@ -333,14 +554,51 @@ int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig ) return( 0 ); } -int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg, - pk_type_t *pk_alg ) +/* + * Get signature algorithm from alg OID and optional parameters + */ +int x509_get_sig_alg( const x509_buf *sig_oid, const x509_buf *sig_params, + md_type_t *md_alg, pk_type_t *pk_alg, + void **sig_opts ) { - int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg ); + int ret; - if( ret != 0 ) + if( *sig_opts != NULL ) + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); + + if( ( ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 ) return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG + ret ); +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) + if( *pk_alg == POLARSSL_PK_RSASSA_PSS ) + { + pk_rsassa_pss_options *pss_opts; + + pss_opts = polarssl_malloc( sizeof( pk_rsassa_pss_options ) ); + if( pss_opts == NULL ) + return( POLARSSL_ERR_X509_MALLOC_FAILED ); + + ret = x509_get_rsassa_pss_params( sig_params, + md_alg, + &pss_opts->mgf1_hash_id, + &pss_opts->expected_salt_len ); + if( ret != 0 ) + { + polarssl_free( pss_opts ); + return( ret ); + } + + *sig_opts = (void *) pss_opts; + } + else +#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */ + { + /* Make sure parameters are absent or NULL */ + if( ( sig_params->tag != ASN1_NULL && sig_params->tag != 0 ) || + sig_params->len != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG ); + } + return( 0 ); } @@ -444,7 +702,7 @@ int x509_load_file( const char *path, unsigned char **buf, size_t *n ) * This fuction tries to 'fix' this by at least suggesting enlarging the * size by 20. */ -static int compat_snprintf(char *str, size_t size, const char *format, ...) +static int compat_snprintf( char *str, size_t size, const char *format, ... ) { va_list ap; int res = -1; @@ -456,29 +714,29 @@ static int compat_snprintf(char *str, size_t size, const char *format, ...) va_end( ap ); // No quick fix possible - if ( res < 0 ) + if( res < 0 ) return( (int) size + 20 ); - return res; + return( res ); } #define snprintf compat_snprintf -#endif +#endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */ #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2 -#define SAFE_SNPRINTF() \ -{ \ - if( ret == -1 ) \ - return( -1 ); \ - \ - if ( (unsigned int) ret > n ) { \ - p[n - 1] = '\0'; \ - return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\ - } \ - \ - n -= (unsigned int) ret; \ - p += (unsigned int) ret; \ +#define SAFE_SNPRINTF() \ +{ \ + if( ret == -1 ) \ + return( -1 ); \ + \ + if( (unsigned int) ret > n ) { \ + p[n - 1] = '\0'; \ + return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \ + } \ + \ + n -= (unsigned int) ret; \ + p += (unsigned int) ret; \ } /* @@ -576,6 +834,51 @@ int x509_serial_gets( char *buf, size_t size, const x509_buf *serial ) return( (int) ( size - n ) ); } +/* + * Helper for writing signature algorithms + */ +int x509_sig_alg_gets( char *buf, size_t size, const x509_buf *sig_oid, + pk_type_t pk_alg, md_type_t md_alg, + const void *sig_opts ) +{ + int ret; + char *p = buf; + size_t n = size; + const char *desc = NULL; + + ret = oid_get_sig_alg_desc( sig_oid, &desc ); + if( ret != 0 ) + ret = snprintf( p, n, "???" ); + else + ret = snprintf( p, n, "%s", desc ); + SAFE_SNPRINTF(); + +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) + if( pk_alg == POLARSSL_PK_RSASSA_PSS ) + { + const pk_rsassa_pss_options *pss_opts; + const md_info_t *md_info, *mgf_md_info; + + pss_opts = (const pk_rsassa_pss_options *) sig_opts; + + md_info = md_info_from_type( md_alg ); + mgf_md_info = md_info_from_type( pss_opts->mgf1_hash_id ); + + ret = snprintf( p, n, " (%s, MGF1-%s, 0x%02X)", + md_info ? md_info->name : "???", + mgf_md_info ? mgf_md_info->name : "???", + pss_opts->expected_salt_len ); + SAFE_SNPRINTF(); + } +#else + ((void) pk_alg); + ((void) md_alg); + ((void) sig_opts); +#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */ + + return( (int) size - n ); +} + /* * Helper for writing "RSA key size", "EC key size", etc */ @@ -586,7 +889,7 @@ int x509_key_size_helper( char *buf, size_t size, const char *name ) int ret; if( strlen( name ) + sizeof( " key size" ) > size ) - return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL; + return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); ret = snprintf( p, n, "%s key size", name ); SAFE_SNPRINTF(); @@ -620,78 +923,108 @@ int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid ) * Return 0 if the x509_time is still valid, or 1 otherwise. */ #if defined(POLARSSL_HAVE_TIME) -int x509_time_expired( const x509_time *to ) -{ - int year, mon, day; - int hour, min, sec; +static void x509_get_current_time( x509_time *now ) +{ #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) SYSTEMTIME st; - GetLocalTime(&st); + GetSystemTime( &st ); - year = st.wYear; - mon = st.wMonth; - day = st.wDay; - hour = st.wHour; - min = st.wMinute; - sec = st.wSecond; + now->year = st.wYear; + now->mon = st.wMonth; + now->day = st.wDay; + now->hour = st.wHour; + now->min = st.wMinute; + now->sec = st.wSecond; #else - struct tm *lt; + struct tm lt; time_t tt; tt = time( NULL ); - lt = localtime( &tt ); - - year = lt->tm_year + 1900; - mon = lt->tm_mon + 1; - day = lt->tm_mday; - hour = lt->tm_hour; - min = lt->tm_min; - sec = lt->tm_sec; -#endif + gmtime_r( &tt, < ); + + now->year = lt.tm_year + 1900; + now->mon = lt.tm_mon + 1; + now->day = lt.tm_mday; + now->hour = lt.tm_hour; + now->min = lt.tm_min; + now->sec = lt.tm_sec; +#endif /* _WIN32 && !EFIX64 && !EFI32 */ +} - if( year > to->year ) +/* + * Return 0 if before <= after, 1 otherwise + */ +static int x509_check_time( const x509_time *before, const x509_time *after ) +{ + if( before->year > after->year ) return( 1 ); - if( year == to->year && - mon > to->mon ) + if( before->year == after->year && + before->mon > after->mon ) return( 1 ); - if( year == to->year && - mon == to->mon && - day > to->day ) + if( before->year == after->year && + before->mon == after->mon && + before->day > after->day ) return( 1 ); - if( year == to->year && - mon == to->mon && - day == to->day && - hour > to->hour ) + if( before->year == after->year && + before->mon == after->mon && + before->day == after->day && + before->hour > after->hour ) return( 1 ); - if( year == to->year && - mon == to->mon && - day == to->day && - hour == to->hour && - min > to->min ) + if( before->year == after->year && + before->mon == after->mon && + before->day == after->day && + before->hour == after->hour && + before->min > after->min ) return( 1 ); - if( year == to->year && - mon == to->mon && - day == to->day && - hour == to->hour && - min == to->min && - sec > to->sec ) + if( before->year == after->year && + before->mon == after->mon && + before->day == after->day && + before->hour == after->hour && + before->min == after->min && + before->sec > after->sec ) return( 1 ); return( 0 ); } + +int x509_time_expired( const x509_time *to ) +{ + x509_time now; + + x509_get_current_time( &now ); + + return( x509_check_time( &now, to ) ); +} + +int x509_time_future( const x509_time *from ) +{ + x509_time now; + + x509_get_current_time( &now ); + + return( x509_check_time( from, &now ) ); +} + #else /* POLARSSL_HAVE_TIME */ + int x509_time_expired( const x509_time *to ) { ((void) to); return( 0 ); } + +int x509_time_future( const x509_time *from ) +{ + ((void) from); + return( 0 ); +} #endif /* POLARSSL_HAVE_TIME */ #if defined(POLARSSL_SELF_TEST) @@ -704,14 +1037,14 @@ int x509_time_expired( const x509_time *to ) */ int x509_self_test( int verbose ) { -#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C) +#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_SHA1_C) int ret; int flags; x509_crt cacert; x509_crt clicert; if( verbose != 0 ) - printf( " X.509 certificate load: " ); + polarssl_printf( " X.509 certificate load: " ); x509_crt_init( &clicert ); @@ -720,7 +1053,7 @@ int x509_self_test( int verbose ) if( ret != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( ret ); } @@ -732,27 +1065,27 @@ int x509_self_test( int verbose ) if( ret != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); return( ret ); } if( verbose != 0 ) - printf( "passed\n X.509 signature verify: "); + polarssl_printf( "passed\n X.509 signature verify: "); ret = x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL ); if( ret != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - printf("ret = %d, &flags = %04x\n", ret, flags); + polarssl_printf( "ret = %d, &flags = %04x\n", ret, flags ); return( ret ); } if( verbose != 0 ) - printf( "passed\n\n"); + polarssl_printf( "passed\n\n"); x509_crt_free( &cacert ); x509_crt_free( &clicert ); @@ -761,9 +1094,9 @@ int x509_self_test( int verbose ) #else ((void) verbose); return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); -#endif +#endif /* POLARSSL_CERTS_C && POLARSSL_SHA1_C */ } -#endif +#endif /* POLARSSL_SELF_TEST */ #endif /* POLARSSL_X509_USE_C */ diff --git a/pdns/ext/polarssl/library/x509_create.c b/pdns/ext/polarssl/library/x509_create.c index fdf2a7246..101931332 100644 --- a/pdns/ext/polarssl/library/x509_create.c +++ b/pdns/ext/polarssl/library/x509_create.c @@ -1,7 +1,7 @@ /* * X.509 base functions for creating certificates / CSRs * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,7 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_X509_CREATE_C) @@ -36,6 +40,59 @@ #define strncasecmp _strnicmp #endif +typedef struct { + const char *name; + size_t name_len; + const char*oid; +} x509_attr_descriptor_t; + +#define ADD_STRLEN( s ) s, sizeof( s ) - 1 + +static const x509_attr_descriptor_t x509_attrs[] = +{ + { ADD_STRLEN( "CN" ), OID_AT_CN }, + { ADD_STRLEN( "commonName" ), OID_AT_CN }, + { ADD_STRLEN( "C" ), OID_AT_COUNTRY }, + { ADD_STRLEN( "countryName" ), OID_AT_COUNTRY }, + { ADD_STRLEN( "O" ), OID_AT_ORGANIZATION }, + { ADD_STRLEN( "organizationName" ), OID_AT_ORGANIZATION }, + { ADD_STRLEN( "L" ), OID_AT_LOCALITY }, + { ADD_STRLEN( "locality" ), OID_AT_LOCALITY }, + { ADD_STRLEN( "R" ), OID_PKCS9_EMAIL }, + { ADD_STRLEN( "OU" ), OID_AT_ORG_UNIT }, + { ADD_STRLEN( "organizationalUnitName" ), OID_AT_ORG_UNIT }, + { ADD_STRLEN( "ST" ), OID_AT_STATE }, + { ADD_STRLEN( "stateOrProvinceName" ), OID_AT_STATE }, + { ADD_STRLEN( "emailAddress" ), OID_PKCS9_EMAIL }, + { ADD_STRLEN( "serialNumber" ), OID_AT_SERIAL_NUMBER }, + { ADD_STRLEN( "postalAddress" ), OID_AT_POSTAL_ADDRESS }, + { ADD_STRLEN( "postalCode" ), OID_AT_POSTAL_CODE }, + { ADD_STRLEN( "dnQualifier" ), OID_AT_DN_QUALIFIER }, + { ADD_STRLEN( "title" ), OID_AT_TITLE }, + { ADD_STRLEN( "surName" ), OID_AT_SUR_NAME }, + { ADD_STRLEN( "SN" ), OID_AT_SUR_NAME }, + { ADD_STRLEN( "givenName" ), OID_AT_GIVEN_NAME }, + { ADD_STRLEN( "GN" ), OID_AT_GIVEN_NAME }, + { ADD_STRLEN( "initials" ), OID_AT_INITIALS }, + { ADD_STRLEN( "pseudonym" ), OID_AT_PSEUDONYM }, + { ADD_STRLEN( "generationQualifier" ), OID_AT_GENERATION_QUALIFIER }, + { ADD_STRLEN( "domainComponent" ), OID_DOMAIN_COMPONENT }, + { ADD_STRLEN( "DC" ), OID_DOMAIN_COMPONENT }, + { NULL, 0, NULL } +}; + +static const char *x509_at_oid_from_name( const char *name, size_t name_len ) +{ + const x509_attr_descriptor_t *cur; + + for( cur = x509_attrs; cur->name != NULL; cur++ ) + if( cur->name_len == name_len && + strncasecmp( cur->name, name, name_len ) == 0 ) + break; + + return( cur->oid ); +} + int x509_string_to_names( asn1_named_data **head, const char *name ) { int ret = 0; @@ -43,7 +100,6 @@ int x509_string_to_names( asn1_named_data **head, const char *name ) const char *end = s + strlen( s ); const char *oid = NULL; int in_tag = 1; - asn1_named_data *cur; /* Clear existing chain if present */ asn1_free_named_data_list( head ); @@ -52,27 +108,7 @@ int x509_string_to_names( asn1_named_data **head, const char *name ) { if( in_tag && *c == '=' ) { - if( c - s == 2 && strncasecmp( s, "CN", 2 ) == 0 ) - oid = OID_AT_CN; - else if( c - s == 1 && strncasecmp( s, "C", 1 ) == 0 ) - oid = OID_AT_COUNTRY; - else if( c - s == 1 && strncasecmp( s, "O", 1 ) == 0 ) - oid = OID_AT_ORGANIZATION; - else if( c - s == 1 && strncasecmp( s, "L", 1 ) == 0 ) - oid = OID_AT_LOCALITY; - else if( c - s == 1 && strncasecmp( s, "R", 1 ) == 0 ) - oid = OID_PKCS9_EMAIL; - else if( c - s == 2 && strncasecmp( s, "OU", 2 ) == 0 ) - oid = OID_AT_ORG_UNIT; - else if( c - s == 2 && strncasecmp( s, "ST", 2 ) == 0 ) - oid = OID_AT_STATE; - else if( c - s == 12 && strncasecmp( s, "serialNumber", 12 ) == 0 ) - oid = OID_AT_SERIAL_NUMBER; - else if( c - s == 13 && strncasecmp( s, "postalAddress", 13 ) == 0 ) - oid = OID_AT_POSTAL_ADDRESS; - else if( c - s == 10 && strncasecmp( s, "postalCode", 10 ) == 0 ) - oid = OID_AT_POSTAL_CODE; - else + if( ( oid = x509_at_oid_from_name( s, c - s ) ) == NULL ) { ret = POLARSSL_ERR_X509_UNKNOWN_OID; goto exit; @@ -84,9 +120,9 @@ int x509_string_to_names( asn1_named_data **head, const char *name ) if( !in_tag && ( *c == ',' || c == end ) ) { - if( ( cur = asn1_store_named_data( head, oid, strlen( oid ), - (unsigned char *) s, - c - s ) ) == NULL ) + if( asn1_store_named_data( head, oid, strlen( oid ), + (unsigned char *) s, + c - s ) == NULL ) { return( POLARSSL_ERR_X509_MALLOC_FAILED ); } @@ -165,10 +201,12 @@ static int x509_write_name( unsigned char **p, unsigned char *start, ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) ); ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SET ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | + ASN1_SET ) ); return( (int) len ); } @@ -189,7 +227,8 @@ int x509_write_names( unsigned char **p, unsigned char *start, } ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); return( (int) len ); } @@ -244,7 +283,8 @@ static int x509_write_extension( unsigned char **p, unsigned char *start, ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OID ) ); ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); return( (int) len ); } diff --git a/pdns/ext/polarssl/library/x509_crl.c b/pdns/ext/polarssl/library/x509_crl.c index 60a54f2e7..7dd53c2f6 100644 --- a/pdns/ext/polarssl/library/x509_crl.c +++ b/pdns/ext/polarssl/library/x509_crl.c @@ -1,7 +1,7 @@ /* - * X.509 certificate and private key decoding + * X.509 Certidicate Revocation List (CRL) parsing * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -25,16 +25,19 @@ /* * The ITU-T X.509 standard defines a certificate format for PKI. * - * http://www.ietf.org/rfc/rfc3279.txt - * http://www.ietf.org/rfc/rfc3280.txt - * - * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc + * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) + * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) + * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) * * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_X509_CRL_PARSE_C) @@ -44,8 +47,8 @@ #include "polarssl/pem.h" #endif -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else #define polarssl_malloc malloc #define polarssl_free free @@ -64,6 +67,11 @@ #include #endif +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + /* * Version ::= INTEGER { v1(0), v2(1) } */ @@ -133,7 +141,7 @@ static int x509_get_crl_entry_ext( unsigned char **p, size_t len = 0; /* OPTIONAL */ - if (end <= *p) + if( end <= *p ) return( 0 ); ext->tag = **p; @@ -154,7 +162,7 @@ static int x509_get_crl_entry_ext( unsigned char **p, return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); } - end = *p + ext->len; + end = *p + ext->len; if( end != *p + ext->len ) return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + @@ -220,13 +228,15 @@ static int x509_get_entries( unsigned char **p, if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 ) return( ret ); - if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 ) + if( ( ret = x509_get_time( p, end2, + &cur_entry->revocation_date ) ) != 0 ) return( ret ); - if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 ) + if( ( ret = x509_get_crl_entry_ext( p, end2, + &cur_entry->entry_ext ) ) != 0 ) return( ret ); - if ( *p < end ) + if( *p < end ) { cur_entry->next = polarssl_malloc( sizeof( x509_crl_entry ) ); @@ -250,11 +260,16 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen ) size_t len; unsigned char *p, *end; x509_crl *crl; + x509_buf sig_params1, sig_params2; + #if defined(POLARSSL_PEM_PARSE_C) size_t use_len; pem_context pem; #endif + memset( &sig_params1, 0, sizeof( x509_buf ) ); + memset( &sig_params2, 0, sizeof( x509_buf ) ); + crl = chain; /* @@ -269,7 +284,7 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen ) /* * Add new CRL on the end of the chain if needed. */ - if ( crl->version != 0 && crl->next == NULL) + if( crl->version != 0 && crl->next == NULL ) { crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) ); @@ -312,7 +327,7 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen ) return( ret ); } else -#endif +#endif /* POLARSSL_PEM_PARSE_C */ { /* * nope, copy the raw DER data @@ -373,7 +388,7 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen ) * signature AlgorithmIdentifier */ if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 || - ( ret = x509_get_alg_null( &p, end, &crl->sig_oid1 ) ) != 0 ) + ( ret = x509_get_alg( &p, end, &crl->sig_oid1, &sig_params1 ) ) != 0 ) { x509_crl_free( crl ); return( ret ); @@ -387,8 +402,9 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen ) return( POLARSSL_ERR_X509_UNKNOWN_VERSION ); } - if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md, - &crl->sig_pk ) ) != 0 ) + if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &sig_params1, + &crl->sig_md, &crl->sig_pk, + &crl->sig_opts ) ) != 0 ) { x509_crl_free( crl ); return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG ); @@ -426,9 +442,9 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen ) if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 ) { - if ( ret != ( POLARSSL_ERR_X509_INVALID_DATE + + if( ret != ( POLARSSL_ERR_X509_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) && - ret != ( POLARSSL_ERR_X509_INVALID_DATE + + ret != ( POLARSSL_ERR_X509_INVALID_DATE + POLARSSL_ERR_ASN1_OUT_OF_DATA ) ) { x509_crl_free( crl ); @@ -478,14 +494,16 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen ) * signatureAlgorithm AlgorithmIdentifier, * signatureValue BIT STRING */ - if( ( ret = x509_get_alg_null( &p, end, &crl->sig_oid2 ) ) != 0 ) + if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2, &sig_params2 ) ) != 0 ) { x509_crl_free( crl ); return( ret ); } if( crl->sig_oid1.len != crl->sig_oid2.len || - memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 ) + memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 || + sig_params1.len != sig_params2.len || + memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) { x509_crl_free( crl ); return( POLARSSL_ERR_X509_SIG_MISMATCH ); @@ -533,12 +551,12 @@ int x509_crl_parse_file( x509_crl *chain, const char *path ) size_t n; unsigned char *buf; - if ( ( ret = x509_load_file( path, &buf, &n ) ) != 0 ) + if( ( ret = x509_load_file( path, &buf, &n ) ) != 0 ) return( ret ); ret = x509_crl_parse( chain, buf, n ); - memset( buf, 0, n + 1 ); + polarssl_zeroize( buf, n + 1 ); polarssl_free( buf ); return( ret ); @@ -560,7 +578,7 @@ int x509_crl_parse_file( x509_crl *chain, const char *path ) * This fuction tries to 'fix' this by at least suggesting enlarging the * size by 20. */ -static int compat_snprintf(char *str, size_t size, const char *format, ...) +static int compat_snprintf( char *str, size_t size, const char *format, ... ) { va_list ap; int res = -1; @@ -572,29 +590,29 @@ static int compat_snprintf(char *str, size_t size, const char *format, ...) va_end( ap ); // No quick fix possible - if ( res < 0 ) + if( res < 0 ) return( (int) size + 20 ); - return res; + return( res ); } #define snprintf compat_snprintf -#endif +#endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */ #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2 -#define SAFE_SNPRINTF() \ -{ \ - if( ret == -1 ) \ - return( -1 ); \ - \ - if ( (unsigned int) ret > n ) { \ - p[n - 1] = '\0'; \ - return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\ - } \ - \ - n -= (unsigned int) ret; \ - p += (unsigned int) ret; \ +#define SAFE_SNPRINTF() \ +{ \ + if( ret == -1 ) \ + return( -1 ); \ + \ + if( (unsigned int) ret > n ) { \ + p[n - 1] = '\0'; \ + return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \ + } \ + \ + n -= (unsigned int) ret; \ + p += (unsigned int) ret; \ } /* @@ -611,7 +629,6 @@ int x509_crl_info( char *buf, size_t size, const char *prefix, int ret; size_t n; char *p; - const char *desc; const x509_crl_entry *entry; p = buf; @@ -652,7 +669,7 @@ int x509_crl_info( char *buf, size_t size, const char *prefix, prefix ); SAFE_SNPRINTF(); - ret = x509_serial_gets( p, n, &entry->serial); + ret = x509_serial_gets( p, n, &entry->serial ); SAFE_SNPRINTF(); ret = snprintf( p, n, " revocation date: " \ @@ -668,11 +685,8 @@ int x509_crl_info( char *buf, size_t size, const char *prefix, ret = snprintf( p, n, "\n%ssigned using : ", prefix ); SAFE_SNPRINTF(); - ret = oid_get_sig_alg_desc( &crl->sig_oid1, &desc ); - if( ret != 0 ) - ret = snprintf( p, n, "???" ); - else - ret = snprintf( p, n, "%s", desc ); + ret = x509_sig_alg_gets( p, n, &crl->sig_oid1, crl->sig_pk, crl->sig_md, + crl->sig_opts ); SAFE_SNPRINTF(); ret = snprintf( p, n, "\n" ); @@ -706,12 +720,16 @@ void x509_crl_free( x509_crl *crl ) do { +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) + polarssl_free( crl_cur->sig_opts ); +#endif + name_cur = crl_cur->issuer.next; while( name_cur != NULL ) { name_prv = name_cur; name_cur = name_cur->next; - memset( name_prv, 0, sizeof( x509_name ) ); + polarssl_zeroize( name_prv, sizeof( x509_name ) ); polarssl_free( name_prv ); } @@ -720,13 +738,13 @@ void x509_crl_free( x509_crl *crl ) { entry_prv = entry_cur; entry_cur = entry_cur->next; - memset( entry_prv, 0, sizeof( x509_crl_entry ) ); + polarssl_zeroize( entry_prv, sizeof( x509_crl_entry ) ); polarssl_free( entry_prv ); } if( crl_cur->raw.p != NULL ) { - memset( crl_cur->raw.p, 0, crl_cur->raw.len ); + polarssl_zeroize( crl_cur->raw.p, crl_cur->raw.len ); polarssl_free( crl_cur->raw.p ); } @@ -740,11 +758,11 @@ void x509_crl_free( x509_crl *crl ) crl_prv = crl_cur; crl_cur = crl_cur->next; - memset( crl_prv, 0, sizeof( x509_crl ) ); + polarssl_zeroize( crl_prv, sizeof( x509_crl ) ); if( crl_prv != crl ) polarssl_free( crl_prv ); } while( crl_cur != NULL ); } -#endif +#endif /* POLARSSL_X509_CRL_PARSE_C */ diff --git a/pdns/ext/polarssl/library/x509_crt.c b/pdns/ext/polarssl/library/x509_crt.c index 6a127b267..03cdda807 100644 --- a/pdns/ext/polarssl/library/x509_crt.c +++ b/pdns/ext/polarssl/library/x509_crt.c @@ -1,7 +1,7 @@ /* - * X.509 certificate and private key decoding + * X.509 certificate parsing and verification * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -25,16 +25,19 @@ /* * The ITU-T X.509 standard defines a certificate format for PKI. * - * http://www.ietf.org/rfc/rfc3279.txt - * http://www.ietf.org/rfc/rfc3280.txt - * - * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc + * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) + * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) + * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) * * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_X509_CRT_PARSE_C) @@ -44,13 +47,17 @@ #include "polarssl/pem.h" #endif -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else #define polarssl_malloc malloc #define polarssl_free free #endif +#if defined(POLARSSL_THREADING_C) +#include "polarssl/threading.h" +#endif + #include #include #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) @@ -65,13 +72,18 @@ #if defined(POLARSSL_FS_IO) #include -#if !defined(_WIN32) +#if !defined(_WIN32) || defined(EFIX64) || defined(EFI32) #include #include #include #endif #endif +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + /* * Version ::= INTEGER { v1(0), v2(1), v3(2) } */ @@ -188,7 +200,7 @@ static int x509_get_basic_constraints( unsigned char **p, return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); if( *p == end ) - return 0; + return( 0 ); if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 ) { @@ -203,7 +215,7 @@ static int x509_get_basic_constraints( unsigned char **p, } if( *p == end ) - return 0; + return( 0 ); if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 ) return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); @@ -214,7 +226,7 @@ static int x509_get_basic_constraints( unsigned char **p, (*max_pathlen)++; - return 0; + return( 0 ); } static int x509_get_ns_cert_type( unsigned char **p, @@ -233,7 +245,7 @@ static int x509_get_ns_cert_type( unsigned char **p, /* Get actual bitstring */ *ns_cert_type = *bs.p; - return 0; + return( 0 ); } static int x509_get_key_usage( unsigned char **p, @@ -252,7 +264,7 @@ static int x509_get_key_usage( unsigned char **p, /* Get actual bitstring */ *key_usage = *bs.p; - return 0; + return( 0 ); } /* @@ -274,7 +286,7 @@ static int x509_get_ext_key_usage( unsigned char **p, return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + POLARSSL_ERR_ASN1_INVALID_LENGTH ); - return 0; + return( 0 ); } /* @@ -337,20 +349,15 @@ static int x509_get_subject_alt_name( unsigned char **p, return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); + /* Skip everything but DNS name */ if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) ) { *p += tag_len; continue; } - buf = &(cur->buf); - buf->tag = tag; - buf->p = *p; - buf->len = tag_len; - *p += buf->len; - /* Allocate and assign next pointer */ - if (*p < end) + if( cur->buf.p != NULL ) { cur->next = (asn1_sequence *) polarssl_malloc( sizeof( asn1_sequence ) ); @@ -362,6 +369,12 @@ static int x509_get_subject_alt_name( unsigned char **p, memset( cur->next, 0, sizeof( asn1_sequence ) ); cur = cur->next; } + + buf = &(cur->buf); + buf->tag = tag; + buf->p = *p; + buf->len = tag_len; + *p += buf->len; } /* Set final sequence entry's next pointer to NULL */ @@ -458,7 +471,7 @@ static int x509_get_crt_ext( unsigned char **p, if( is_critical ) { /* Data is marked as critical: fail */ - return ( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); } #endif @@ -473,35 +486,35 @@ static int x509_get_crt_ext( unsigned char **p, /* Parse basic constraints */ if( ( ret = x509_get_basic_constraints( p, end_ext_octet, &crt->ca_istrue, &crt->max_pathlen ) ) != 0 ) - return ( ret ); + return( ret ); break; case EXT_KEY_USAGE: /* Parse key usage */ if( ( ret = x509_get_key_usage( p, end_ext_octet, &crt->key_usage ) ) != 0 ) - return ( ret ); + return( ret ); break; case EXT_EXTENDED_KEY_USAGE: /* Parse extended key usage */ if( ( ret = x509_get_ext_key_usage( p, end_ext_octet, &crt->ext_key_usage ) ) != 0 ) - return ( ret ); + return( ret ); break; case EXT_SUBJECT_ALT_NAME: /* Parse subject alt name */ if( ( ret = x509_get_subject_alt_name( p, end_ext_octet, &crt->subject_alt_names ) ) != 0 ) - return ( ret ); + return( ret ); break; case EXT_NS_CERT_TYPE: /* Parse netscape certificate type */ if( ( ret = x509_get_ns_cert_type( p, end_ext_octet, &crt->ns_cert_type ) ) != 0 ) - return ( ret ); + return( ret ); break; default: @@ -525,6 +538,10 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf, int ret; size_t len; unsigned char *p, *end, *crt_end; + x509_buf sig_params1, sig_params2; + + memset( &sig_params1, 0, sizeof( x509_buf ) ); + memset( &sig_params2, 0, sizeof( x509_buf ) ); /* * Check for valid input @@ -539,8 +556,6 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf, memcpy( p, buf, buflen ); - buflen = 0; - crt->raw.p = p; crt->raw.len = len; end = p + len; @@ -590,7 +605,8 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf, */ if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 || ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 || - ( ret = x509_get_alg_null( &p, end, &crt->sig_oid1 ) ) != 0 ) + ( ret = x509_get_alg( &p, end, &crt->sig_oid1, + &sig_params1 ) ) != 0 ) { x509_crt_free( crt ); return( ret ); @@ -604,8 +620,9 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf, return( POLARSSL_ERR_X509_UNKNOWN_VERSION ); } - if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_md, - &crt->sig_pk ) ) != 0 ) + if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &sig_params1, + &crt->sig_md, &crt->sig_pk, + &crt->sig_opts ) ) != 0 ) { x509_crt_free( crt ); return( ret ); @@ -705,7 +722,7 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf, if( crt->version == 3 ) { #endif - ret = x509_get_crt_ext( &p, end, crt); + ret = x509_get_crt_ext( &p, end, crt ); if( ret != 0 ) { x509_crt_free( crt ); @@ -731,14 +748,16 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf, * signatureAlgorithm AlgorithmIdentifier, * signatureValue BIT STRING */ - if( ( ret = x509_get_alg_null( &p, end, &crt->sig_oid2 ) ) != 0 ) + if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2, &sig_params2 ) ) != 0 ) { x509_crt_free( crt ); return( ret ); } if( crt->sig_oid1.len != crt->sig_oid2.len || - memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 ) + memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 || + sig_params1.len != sig_params2.len || + memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) { x509_crt_free( crt ); return( POLARSSL_ERR_X509_SIG_MISMATCH ); @@ -785,7 +804,7 @@ int x509_crt_parse_der( x509_crt *chain, const unsigned char *buf, /* * Add new certificate on the end of the chain if needed. */ - if ( crt->version != 0 && crt->next == NULL) + if( crt->version != 0 && crt->next == NULL ) { crt->next = (x509_crt *) polarssl_malloc( sizeof( x509_crt ) ); @@ -812,7 +831,8 @@ int x509_crt_parse_der( x509_crt *chain, const unsigned char *buf, } /* - * Parse one or more PEM certificates from a buffer and add them to the chained list + * Parse one or more PEM certificates from a buffer and add them to the chained + * list */ int x509_crt_parse( x509_crt *chain, const unsigned char *buf, size_t buflen ) { @@ -905,7 +925,7 @@ int x509_crt_parse( x509_crt *chain, const unsigned char *buf, size_t buflen ) success = 1; } } -#endif +#endif /* POLARSSL_PEM_PARSE_C */ if( success ) return( total_failed ); @@ -925,17 +945,21 @@ int x509_crt_parse_file( x509_crt *chain, const char *path ) size_t n; unsigned char *buf; - if ( ( ret = x509_load_file( path, &buf, &n ) ) != 0 ) + if( ( ret = x509_load_file( path, &buf, &n ) ) != 0 ) return( ret ); ret = x509_crt_parse( chain, buf, n ); - memset( buf, 0, n + 1 ); + polarssl_zeroize( buf, n + 1 ); polarssl_free( buf ); return( ret ); } +#if defined(POLARSSL_THREADING_PTHREAD) +static threading_mutex_t readdir_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + int x509_crt_parse_path( x509_crt *chain, const char *path ) { int ret = 0; @@ -943,40 +967,41 @@ int x509_crt_parse_path( x509_crt *chain, const char *path ) int w_ret; WCHAR szDir[MAX_PATH]; char filename[MAX_PATH]; - char *p; + char *p; int len = (int) strlen( path ); - WIN32_FIND_DATAW file_data; + WIN32_FIND_DATAW file_data; HANDLE hFind; if( len > MAX_PATH - 3 ) return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); - memset( szDir, 0, sizeof(szDir) ); - memset( filename, 0, MAX_PATH ); - memcpy( filename, path, len ); - filename[len++] = '\\'; - p = filename + len; + memset( szDir, 0, sizeof(szDir) ); + memset( filename, 0, MAX_PATH ); + memcpy( filename, path, len ); + filename[len++] = '\\'; + p = filename + len; filename[len++] = '*'; - w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 ); + w_ret = MultiByteToWideChar( CP_ACP, 0, filename, len, szDir, + MAX_PATH - 3 ); hFind = FindFirstFileW( szDir, &file_data ); - if (hFind == INVALID_HANDLE_VALUE) + if( hFind == INVALID_HANDLE_VALUE ) return( POLARSSL_ERR_X509_FILE_IO_ERROR ); len = MAX_PATH - len; do { - memset( p, 0, len ); + memset( p, 0, len ); if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) continue; - w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName, - lstrlenW(file_data.cFileName), - p, len - 1, - NULL, NULL ); + w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName, + lstrlenW( file_data.cFileName ), + p, len - 1, + NULL, NULL ); w_ret = x509_crt_parse_file( chain, filename ); if( w_ret < 0 ) @@ -986,34 +1011,34 @@ int x509_crt_parse_path( x509_crt *chain, const char *path ) } while( FindNextFileW( hFind, &file_data ) != 0 ); - if (GetLastError() != ERROR_NO_MORE_FILES) + if( GetLastError() != ERROR_NO_MORE_FILES ) ret = POLARSSL_ERR_X509_FILE_IO_ERROR; FindClose( hFind ); #else /* _WIN32 */ -#if defined(POLARSSL_HAVE_READDIR_R) - int t_ret, i; + int t_ret; struct stat sb; - struct dirent entry, *result = NULL; + struct dirent *entry; char entry_name[255]; DIR *dir = opendir( path ); - if( dir == NULL) + if( dir == NULL ) return( POLARSSL_ERR_X509_FILE_IO_ERROR ); - while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 ) - { - if( result == NULL ) - break; - - snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name ); +#if defined(POLARSSL_THREADING_PTHREAD) + if( ( ret = polarssl_mutex_lock( &readdir_mutex ) ) != 0 ) + return( ret ); +#endif - i = stat( entry_name, &sb ); + while( ( entry = readdir( dir ) ) != NULL ) + { + snprintf( entry_name, sizeof entry_name, "%s/%s", path, entry->d_name ); - if( i == -1 ) + if( stat( entry_name, &sb ) == -1 ) { closedir( dir ); - return( POLARSSL_ERR_X509_FILE_IO_ERROR ); + ret = POLARSSL_ERR_X509_FILE_IO_ERROR; + goto cleanup; } if( !S_ISREG( sb.st_mode ) ) @@ -1028,11 +1053,13 @@ int x509_crt_parse_path( x509_crt *chain, const char *path ) ret += t_ret; } closedir( dir ); -#else /* POLARSSL_HAVE_READDIR_R */ - ((void) chain); - ((void) path); - ret = POLARSSL_ERR_X509_FEATURE_UNAVAILABLE; -#endif /* POLARSSL_HAVE_READDIR_R */ + +cleanup: +#if defined(POLARSSL_THREADING_PTHREAD) + if( polarssl_mutex_unlock( &readdir_mutex ) != 0 ) + ret = POLARSSL_ERR_THREADING_MUTEX_ERROR; +#endif + #endif /* _WIN32 */ return( ret ); @@ -1054,7 +1081,7 @@ int x509_crt_parse_path( x509_crt *chain, const char *path ) * This fuction tries to 'fix' this by at least suggesting enlarging the * size by 20. */ -static int compat_snprintf(char *str, size_t size, const char *format, ...) +static int compat_snprintf( char *str, size_t size, const char *format, ... ) { va_list ap; int res = -1; @@ -1066,105 +1093,330 @@ static int compat_snprintf(char *str, size_t size, const char *format, ...) va_end( ap ); // No quick fix possible - if ( res < 0 ) + if( res < 0 ) return( (int) size + 20 ); - return res; + return( res ); } #define snprintf compat_snprintf -#endif +#endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */ #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2 -#define SAFE_SNPRINTF() \ -{ \ - if( ret == -1 ) \ - return( -1 ); \ - \ - if ( (unsigned int) ret > n ) { \ - p[n - 1] = '\0'; \ - return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\ - } \ - \ - n -= (unsigned int) ret; \ - p += (unsigned int) ret; \ +#define SAFE_SNPRINTF() \ +{ \ + if( ret == -1 ) \ + return( -1 ); \ + \ + if( (unsigned int) ret > n ) { \ + p[n - 1] = '\0'; \ + return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \ + } \ + \ + n -= (unsigned int) ret; \ + p += (unsigned int) ret; \ +} + +static int x509_info_subject_alt_name( char **buf, size_t *size, + const x509_sequence *subject_alt_name ) +{ + size_t i; + size_t n = *size; + char *p = *buf; + const x509_sequence *cur = subject_alt_name; + const char *sep = ""; + size_t sep_len = 0; + + while( cur != NULL ) + { + if( cur->buf.len + sep_len >= n ) + { + *p = '\0'; + return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); + } + + n -= cur->buf.len + sep_len; + for( i = 0; i < sep_len; i++ ) + *p++ = sep[i]; + for( i = 0; i < cur->buf.len; i++ ) + *p++ = cur->buf.p[i]; + + sep = ", "; + sep_len = 2; + + cur = cur->next; + } + + *p = '\0'; + + *size = n; + *buf = p; + + return( 0 ); +} + +#define PRINT_ITEM(i) \ + { \ + ret = snprintf( p, n, "%s" i, sep ); \ + SAFE_SNPRINTF(); \ + sep = ", "; \ + } + +#define CERT_TYPE(type,name) \ + if( ns_cert_type & type ) \ + PRINT_ITEM( name ); + +static int x509_info_cert_type( char **buf, size_t *size, + unsigned char ns_cert_type ) +{ + int ret; + size_t n = *size; + char *p = *buf; + const char *sep = ""; + + CERT_TYPE( NS_CERT_TYPE_SSL_CLIENT, "SSL Client" ); + CERT_TYPE( NS_CERT_TYPE_SSL_SERVER, "SSL Server" ); + CERT_TYPE( NS_CERT_TYPE_EMAIL, "Email" ); + CERT_TYPE( NS_CERT_TYPE_OBJECT_SIGNING, "Object Signing" ); + CERT_TYPE( NS_CERT_TYPE_RESERVED, "Reserved" ); + CERT_TYPE( NS_CERT_TYPE_SSL_CA, "SSL CA" ); + CERT_TYPE( NS_CERT_TYPE_EMAIL_CA, "Email CA" ); + CERT_TYPE( NS_CERT_TYPE_OBJECT_SIGNING_CA, "Object Signing CA" ); + + *size = n; + *buf = p; + + return( 0 ); +} + +#define KEY_USAGE(code,name) \ + if( key_usage & code ) \ + PRINT_ITEM( name ); + +static int x509_info_key_usage( char **buf, size_t *size, + unsigned char key_usage ) +{ + int ret; + size_t n = *size; + char *p = *buf; + const char *sep = ""; + + KEY_USAGE( KU_DIGITAL_SIGNATURE, "Digital Signature" ); + KEY_USAGE( KU_NON_REPUDIATION, "Non Repudiation" ); + KEY_USAGE( KU_KEY_ENCIPHERMENT, "Key Encipherment" ); + KEY_USAGE( KU_DATA_ENCIPHERMENT, "Data Encipherment" ); + KEY_USAGE( KU_KEY_AGREEMENT, "Key Agreement" ); + KEY_USAGE( KU_KEY_CERT_SIGN, "Key Cert Sign" ); + KEY_USAGE( KU_CRL_SIGN, "CRL Sign" ); + + *size = n; + *buf = p; + + return( 0 ); +} + +static int x509_info_ext_key_usage( char **buf, size_t *size, + const x509_sequence *extended_key_usage ) +{ + int ret; + const char *desc; + size_t n = *size; + char *p = *buf; + const x509_sequence *cur = extended_key_usage; + const char *sep = ""; + + while( cur != NULL ) + { + if( oid_get_extended_key_usage( &cur->buf, &desc ) != 0 ) + desc = "???"; + + ret = snprintf( p, n, "%s%s", sep, desc ); + SAFE_SNPRINTF(); + + sep = ", "; + + cur = cur->next; + } + + *size = n; + *buf = p; + + return( 0 ); } /* * Return an informational string about the certificate. */ -#define BEFORE_COLON 14 -#define BC "14" +#define BEFORE_COLON 18 +#define BC "18" int x509_crt_info( char *buf, size_t size, const char *prefix, const x509_crt *crt ) { int ret; size_t n; char *p; - const char *desc = NULL; char key_size_str[BEFORE_COLON]; p = buf; n = size; - ret = snprintf( p, n, "%scert. version : %d\n", + ret = snprintf( p, n, "%scert. version : %d\n", prefix, crt->version ); SAFE_SNPRINTF(); - ret = snprintf( p, n, "%sserial number : ", + ret = snprintf( p, n, "%sserial number : ", prefix ); SAFE_SNPRINTF(); - ret = x509_serial_gets( p, n, &crt->serial); + ret = x509_serial_gets( p, n, &crt->serial ); SAFE_SNPRINTF(); - ret = snprintf( p, n, "\n%sissuer name : ", prefix ); + ret = snprintf( p, n, "\n%sissuer name : ", prefix ); SAFE_SNPRINTF(); ret = x509_dn_gets( p, n, &crt->issuer ); SAFE_SNPRINTF(); - ret = snprintf( p, n, "\n%ssubject name : ", prefix ); + ret = snprintf( p, n, "\n%ssubject name : ", prefix ); SAFE_SNPRINTF(); ret = x509_dn_gets( p, n, &crt->subject ); SAFE_SNPRINTF(); - ret = snprintf( p, n, "\n%sissued on : " \ + ret = snprintf( p, n, "\n%sissued on : " \ "%04d-%02d-%02d %02d:%02d:%02d", prefix, crt->valid_from.year, crt->valid_from.mon, crt->valid_from.day, crt->valid_from.hour, crt->valid_from.min, crt->valid_from.sec ); SAFE_SNPRINTF(); - ret = snprintf( p, n, "\n%sexpires on : " \ + ret = snprintf( p, n, "\n%sexpires on : " \ "%04d-%02d-%02d %02d:%02d:%02d", prefix, crt->valid_to.year, crt->valid_to.mon, crt->valid_to.day, crt->valid_to.hour, crt->valid_to.min, crt->valid_to.sec ); SAFE_SNPRINTF(); - ret = snprintf( p, n, "\n%ssigned using : ", prefix ); + ret = snprintf( p, n, "\n%ssigned using : ", prefix ); SAFE_SNPRINTF(); - ret = oid_get_sig_alg_desc( &crt->sig_oid1, &desc ); - if( ret != 0 ) - ret = snprintf( p, n, "???" ); - else - ret = snprintf( p, n, "%s", desc ); + ret = x509_sig_alg_gets( p, n, &crt->sig_oid1, crt->sig_pk, + crt->sig_md, crt->sig_opts ); SAFE_SNPRINTF(); + /* Key size */ if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON, pk_get_name( &crt->pk ) ) ) != 0 ) { return( ret ); } - ret = snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str, + ret = snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str, (int) pk_get_size( &crt->pk ) ); SAFE_SNPRINTF(); + /* + * Optional extensions + */ + + if( crt->ext_types & EXT_BASIC_CONSTRAINTS ) + { + ret = snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix, + crt->ca_istrue ? "true" : "false" ); + SAFE_SNPRINTF(); + + if( crt->max_pathlen > 0 ) + { + ret = snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 ); + SAFE_SNPRINTF(); + } + } + + if( crt->ext_types & EXT_SUBJECT_ALT_NAME ) + { + ret = snprintf( p, n, "\n%ssubject alt name : ", prefix ); + SAFE_SNPRINTF(); + + if( ( ret = x509_info_subject_alt_name( &p, &n, + &crt->subject_alt_names ) ) != 0 ) + return( ret ); + } + + if( crt->ext_types & EXT_NS_CERT_TYPE ) + { + ret = snprintf( p, n, "\n%scert. type : ", prefix ); + SAFE_SNPRINTF(); + + if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 ) + return( ret ); + } + + if( crt->ext_types & EXT_KEY_USAGE ) + { + ret = snprintf( p, n, "\n%skey usage : ", prefix ); + SAFE_SNPRINTF(); + + if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 ) + return( ret ); + } + + if( crt->ext_types & EXT_EXTENDED_KEY_USAGE ) + { + ret = snprintf( p, n, "\n%sext key usage : ", prefix ); + SAFE_SNPRINTF(); + + if( ( ret = x509_info_ext_key_usage( &p, &n, + &crt->ext_key_usage ) ) != 0 ) + return( ret ); + } + + ret = snprintf( p, n, "\n" ); + SAFE_SNPRINTF(); + return( (int) ( size - n ) ); } +#if defined(POLARSSL_X509_CHECK_KEY_USAGE) +int x509_crt_check_key_usage( const x509_crt *crt, int usage ) +{ + if( ( crt->ext_types & EXT_KEY_USAGE ) != 0 && + ( crt->key_usage & usage ) != usage ) + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); + + return( 0 ); +} +#endif + +#if defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) +int x509_crt_check_extended_key_usage( const x509_crt *crt, + const char *usage_oid, + size_t usage_len ) +{ + const x509_sequence *cur; + + /* Extension is not mandatory, absent means no restriction */ + if( ( crt->ext_types & EXT_EXTENDED_KEY_USAGE ) == 0 ) + return( 0 ); + + /* + * Look for the requested usage (or wildcard ANY) in our list + */ + for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next ) + { + const x509_buf *cur_oid = &cur->buf; + + if( cur_oid->len == usage_len && + memcmp( cur_oid->p, usage_oid, usage_len ) == 0 ) + { + return( 0 ); + } + + if( OID_CMP( OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) ) + return( 0 ); + } + + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); +} +#endif /* POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE */ + #if defined(POLARSSL_X509_CRL_PARSE_C) /* * Return 1 if the certificate is revoked, or 0 otherwise. @@ -1218,6 +1470,17 @@ static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca, continue; } + /* + * Check if the CA is configured to sign CRLs + */ +#if defined(POLARSSL_X509_CHECK_KEY_USAGE) + if( x509_crt_check_key_usage( ca, KU_CRL_SIGN ) != 0 ) + { + flags |= BADCRL_NOT_TRUSTED; + break; + } +#endif + /* * Check if CRL is correctly signed by the trusted CA */ @@ -1233,9 +1496,9 @@ static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca, md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ); - if( pk_can_do( &ca->pk, crl_list->sig_pk ) == 0 || - pk_verify( &ca->pk, crl_list->sig_md, hash, md_info->size, - crl_list->sig.p, crl_list->sig.len ) != 0 ) + if( pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk, + crl_list->sig_md, hash, md_info->size, + crl_list->sig.p, crl_list->sig.len ) != 0 ) { flags |= BADCRL_NOT_TRUSTED; break; @@ -1247,10 +1510,13 @@ static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca, if( x509_time_expired( &crl_list->next_update ) ) flags |= BADCRL_EXPIRED; + if( x509_time_future( &crl_list->this_update ) ) + flags |= BADCRL_FUTURE; + /* * Check if certificate is revoked */ - if( x509_crt_revoked(crt, crl_list) ) + if( x509_crt_revoked( crt, crl_list ) ) { flags |= BADCERT_REVOKED; break; @@ -1258,7 +1524,7 @@ static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca, crl_list = crl_list->next; } - return flags; + return( flags ); } #endif /* POLARSSL_X509_CRL_PARSE_C */ @@ -1273,11 +1539,15 @@ static int x509_name_cmp( const void *s1, const void *s2, size_t len ) { diff = n1[i] ^ n2[i]; - if( ( n1[i] >= 'a' || n1[i] <= 'z' ) && ( diff == 0 || diff == 32 ) ) + if( diff == 0 ) continue; - if( ( n1[i] >= 'A' || n1[i] <= 'Z' ) && ( diff == 0 || diff == 32 ) ) + if( diff == 32 && + ( ( n1[i] >= 'a' && n1[i] <= 'z' ) || + ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) ) + { continue; + } return( 1 ); } @@ -1288,12 +1558,12 @@ static int x509_name_cmp( const void *s1, const void *s2, size_t len ) static int x509_wildcard_verify( const char *cn, x509_buf *name ) { size_t i; - size_t cn_idx = 0; + size_t cn_idx = 0, cn_len = strlen( cn ); if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' ) return( 0 ); - for( i = 0; i < strlen( cn ); ++i ) + for( i = 0; i < cn_len; ++i ) { if( cn[i] == '.' ) { @@ -1305,7 +1575,7 @@ static int x509_wildcard_verify( const char *cn, x509_buf *name ) if( cn_idx == 0 ) return( 0 ); - if( strlen( cn ) - cn_idx == name->len - 1 && + if( cn_len - cn_idx == name->len - 1 && x509_name_cmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 ) { return( 1 ); @@ -1314,6 +1584,56 @@ static int x509_wildcard_verify( const char *cn, x509_buf *name ) return( 0 ); } +/* + * Check if 'parent' is a suitable parent (signing CA) for 'child'. + * Return 0 if yes, -1 if not. + * + * top means parent is a locally-trusted certificate + * bottom means child is the end entity cert + */ +static int x509_crt_check_parent( const x509_crt *child, + const x509_crt *parent, + int top, int bottom ) +{ + int need_ca_bit; + + /* Parent must be the issuer */ + if( child->issuer_raw.len != parent->subject_raw.len || + memcmp( child->issuer_raw.p, parent->subject_raw.p, + child->issuer_raw.len ) != 0 ) + { + return( -1 ); + } + + /* Parent must have the basicConstraints CA bit set as a general rule */ + need_ca_bit = 1; + + /* Exception: v1/v2 certificates that are locally trusted. */ + if( top && parent->version < 3 ) + need_ca_bit = 0; + + /* Exception: self-signed end-entity certs that are locally trusted. */ + if( top && bottom && + child->raw.len == parent->raw.len && + memcmp( child->raw.p, parent->raw.p, child->raw.len ) == 0 ) + { + need_ca_bit = 0; + } + + if( need_ca_bit && ! parent->ca_istrue ) + return( -1 ); + +#if defined(POLARSSL_X509_CHECK_KEY_USAGE) + if( need_ca_bit && + x509_crt_check_key_usage( parent, KU_KEY_CERT_SIGN ) != 0 ) + { + return( -1 ); + } +#endif + + return( 0 ); +} + static int x509_crt_verify_top( x509_crt *child, x509_crt *trust_ca, x509_crl *ca_crl, int path_cnt, int *flags, @@ -1328,6 +1648,9 @@ static int x509_crt_verify_top( if( x509_time_expired( &child->valid_to ) ) *flags |= BADCERT_EXPIRED; + if( x509_time_future( &child->valid_from ) ) + *flags |= BADCERT_FUTURE; + /* * Child is the top of the chain. Check against the trust_ca list. */ @@ -1344,16 +1667,10 @@ static int x509_crt_verify_top( else md( md_info, child->tbs.p, child->tbs.len, hash ); - while( trust_ca != NULL ) + for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next ) { - if( trust_ca->version == 0 || - child->issuer_raw.len != trust_ca->subject_raw.len || - memcmp( child->issuer_raw.p, trust_ca->subject_raw.p, - child->issuer_raw.len ) != 0 ) - { - trust_ca = trust_ca->next; + if( x509_crt_check_parent( child, trust_ca, 1, path_cnt == 0 ) != 0 ) continue; - } /* * Reduce path_len to check against if top of the chain is @@ -1369,15 +1686,13 @@ static int x509_crt_verify_top( if( trust_ca->max_pathlen > 0 && trust_ca->max_pathlen < check_path_cnt ) { - trust_ca = trust_ca->next; continue; } - if( pk_can_do( &trust_ca->pk, child->sig_pk ) == 0 || - pk_verify( &trust_ca->pk, child->sig_md, hash, md_info->size, - child->sig.p, child->sig.len ) != 0 ) + if( pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk, + child->sig_md, hash, md_info->size, + child->sig.p, child->sig.len ) != 0 ) { - trust_ca = trust_ca->next; continue; } @@ -1408,17 +1723,23 @@ static int x509_crt_verify_top( if( x509_time_expired( &trust_ca->valid_to ) ) ca_flags |= BADCERT_EXPIRED; + if( x509_time_future( &trust_ca->valid_from ) ) + ca_flags |= BADCERT_FUTURE; + if( NULL != f_vrfy ) { - if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 ) + if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, + &ca_flags ) ) != 0 ) + { return( ret ); + } } } /* Call callback on top cert */ if( NULL != f_vrfy ) { - if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 ) + if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 ) return( ret ); } @@ -1442,6 +1763,9 @@ static int x509_crt_verify_child( if( x509_time_expired( &child->valid_to ) ) *flags |= BADCERT_EXPIRED; + if( x509_time_future( &child->valid_from ) ) + *flags |= BADCERT_FUTURE; + md_info = md_info_from_type( child->sig_md ); if( md_info == NULL ) { @@ -1454,9 +1778,9 @@ static int x509_crt_verify_child( { md( md_info, child->tbs.p, child->tbs.len, hash ); - if( pk_can_do( &parent->pk, child->sig_pk ) == 0 || - pk_verify( &parent->pk, child->sig_md, hash, md_info->size, - child->sig.p, child->sig.len ) != 0 ) + if( pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk, + child->sig_md, hash, md_info->size, + child->sig.p, child->sig.len ) != 0 ) { *flags |= BADCERT_NOT_TRUSTED; } @@ -1467,34 +1791,28 @@ static int x509_crt_verify_child( *flags |= x509_crt_verifycrl(child, parent, ca_crl); #endif - grandparent = parent->next; - - while( grandparent != NULL ) + /* Look for a grandparent upwards the chain */ + for( grandparent = parent->next; + grandparent != NULL; + grandparent = grandparent->next ) { - if( grandparent->version == 0 || - grandparent->ca_istrue == 0 || - parent->issuer_raw.len != grandparent->subject_raw.len || - memcmp( parent->issuer_raw.p, grandparent->subject_raw.p, - parent->issuer_raw.len ) != 0 ) - { - grandparent = grandparent->next; - continue; - } - break; + if( x509_crt_check_parent( parent, grandparent, + 0, path_cnt == 0 ) == 0 ) + break; } + /* Is our parent part of the chain or at the top? */ if( grandparent != NULL ) { - /* - * Part of the chain - */ - ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy ); + ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl, + path_cnt + 1, &parent_flags, f_vrfy, p_vrfy ); if( ret != 0 ) return( ret ); } else { - ret = x509_crt_verify_top( parent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy ); + ret = x509_crt_verify_top( parent, trust_ca, ca_crl, + path_cnt + 1, &parent_flags, f_vrfy, p_vrfy ); if( ret != 0 ) return( ret ); } @@ -1578,37 +1896,25 @@ int x509_crt_verify( x509_crt *crt, } } - /* - * Iterate upwards in the given cert chain, to find our crt parent. - * Ignore any upper cert with CA != TRUE. - */ - parent = crt->next; - - while( parent != NULL && parent->version != 0 ) + /* Look for a parent upwards the chain */ + for( parent = crt->next; parent != NULL; parent = parent->next ) { - if( parent->ca_istrue == 0 || - crt->issuer_raw.len != parent->subject_raw.len || - memcmp( crt->issuer_raw.p, parent->subject_raw.p, - crt->issuer_raw.len ) != 0 ) - { - parent = parent->next; - continue; - } - break; + if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 ) + break; } + /* Are we part of the chain or at the top? */ if( parent != NULL ) { - /* - * Part of the chain - */ - ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy ); + ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, + pathlen, flags, f_vrfy, p_vrfy ); if( ret != 0 ) return( ret ); } else { - ret = x509_crt_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy ); + ret = x509_crt_verify_top( crt, trust_ca, ca_crl, + pathlen, flags, f_vrfy, p_vrfy ); if( ret != 0 ) return( ret ); } @@ -1646,12 +1952,16 @@ void x509_crt_free( x509_crt *crt ) { pk_free( &cert_cur->pk ); +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) + polarssl_free( cert_cur->sig_opts ); +#endif + name_cur = cert_cur->issuer.next; while( name_cur != NULL ) { name_prv = name_cur; name_cur = name_cur->next; - memset( name_prv, 0, sizeof( x509_name ) ); + polarssl_zeroize( name_prv, sizeof( x509_name ) ); polarssl_free( name_prv ); } @@ -1660,7 +1970,7 @@ void x509_crt_free( x509_crt *crt ) { name_prv = name_cur; name_cur = name_cur->next; - memset( name_prv, 0, sizeof( x509_name ) ); + polarssl_zeroize( name_prv, sizeof( x509_name ) ); polarssl_free( name_prv ); } @@ -1669,7 +1979,7 @@ void x509_crt_free( x509_crt *crt ) { seq_prv = seq_cur; seq_cur = seq_cur->next; - memset( seq_prv, 0, sizeof( x509_sequence ) ); + polarssl_zeroize( seq_prv, sizeof( x509_sequence ) ); polarssl_free( seq_prv ); } @@ -1678,13 +1988,13 @@ void x509_crt_free( x509_crt *crt ) { seq_prv = seq_cur; seq_cur = seq_cur->next; - memset( seq_prv, 0, sizeof( x509_sequence ) ); + polarssl_zeroize( seq_prv, sizeof( x509_sequence ) ); polarssl_free( seq_prv ); } if( cert_cur->raw.p != NULL ) { - memset( cert_cur->raw.p, 0, cert_cur->raw.len ); + polarssl_zeroize( cert_cur->raw.p, cert_cur->raw.len ); polarssl_free( cert_cur->raw.p ); } @@ -1698,11 +2008,11 @@ void x509_crt_free( x509_crt *crt ) cert_prv = cert_cur; cert_cur = cert_cur->next; - memset( cert_prv, 0, sizeof( x509_crt ) ); + polarssl_zeroize( cert_prv, sizeof( x509_crt ) ); if( cert_prv != crt ) polarssl_free( cert_prv ); } while( cert_cur != NULL ); } -#endif +#endif /* POLARSSL_X509_CRT_PARSE_C */ diff --git a/pdns/ext/polarssl/library/x509_csr.c b/pdns/ext/polarssl/library/x509_csr.c index c0c7679c0..0b4f771f9 100644 --- a/pdns/ext/polarssl/library/x509_csr.c +++ b/pdns/ext/polarssl/library/x509_csr.c @@ -1,7 +1,7 @@ /* * X.509 Certificate Signing Request (CSR) parsing * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -25,16 +25,19 @@ /* * The ITU-T X.509 standard defines a certificate format for PKI. * - * http://www.ietf.org/rfc/rfc3279.txt - * http://www.ietf.org/rfc/rfc3280.txt - * - * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc + * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) + * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) + * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) * * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_X509_CSR_PARSE_C) @@ -44,8 +47,8 @@ #include "polarssl/pem.h" #endif -#if defined(POLARSSL_MEMORY_C) -#include "polarssl/memory.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" #else #define polarssl_malloc malloc #define polarssl_free free @@ -58,6 +61,11 @@ #include #endif +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + /* * Version ::= INTEGER { v1(0) } */ @@ -82,17 +90,17 @@ static int x509_csr_get_version( unsigned char **p, } /* - * Parse a CSR + * Parse a CSR in DER format */ -int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen ) +int x509_csr_parse_der( x509_csr *csr, + const unsigned char *buf, size_t buflen ) { int ret; size_t len; unsigned char *p, *end; -#if defined(POLARSSL_PEM_PARSE_C) - size_t use_len; - pem_context pem; -#endif + x509_buf sig_params; + + memset( &sig_params, 0, sizeof( x509_buf ) ); /* * Check for valid input @@ -102,49 +110,15 @@ int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen ) x509_csr_init( csr ); -#if defined(POLARSSL_PEM_PARSE_C) - pem_init( &pem ); - ret = pem_read_buffer( &pem, - "-----BEGIN CERTIFICATE REQUEST-----", - "-----END CERTIFICATE REQUEST-----", - buf, NULL, 0, &use_len ); - - if( ret == 0 ) - { - /* - * Was PEM encoded - */ - buflen -= use_len; - buf += use_len; - - /* - * Steal PEM buffer - */ - p = pem.buf; - pem.buf = NULL; - len = pem.buflen; - pem_free( &pem ); - } - else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - { - pem_free( &pem ); - return( ret ); - } - else -#endif - { - /* - * nope, copy the raw DER data - */ - p = (unsigned char *) polarssl_malloc( len = buflen ); + /* + * first copy the raw DER data + */ + p = (unsigned char *) polarssl_malloc( len = buflen ); - if( p == NULL ) - return( POLARSSL_ERR_X509_MALLOC_FAILED ); + if( p == NULL ) + return( POLARSSL_ERR_X509_MALLOC_FAILED ); - memcpy( p, buf, buflen ); - - buflen = 0; - } + memcpy( p, buf, buflen ); csr->raw.p = p; csr->raw.len = len; @@ -251,14 +225,15 @@ int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen ) * signatureAlgorithm AlgorithmIdentifier, * signature BIT STRING */ - if( ( ret = x509_get_alg_null( &p, end, &csr->sig_oid ) ) != 0 ) + if( ( ret = x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 ) { x509_csr_free( csr ); return( ret ); } - if( ( ret = x509_get_sig_alg( &csr->sig_oid, &csr->sig_md, - &csr->sig_pk ) ) != 0 ) + if( ( ret = x509_get_sig_alg( &csr->sig_oid, &sig_params, + &csr->sig_md, &csr->sig_pk, + &csr->sig_opts ) ) != 0 ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG ); @@ -280,6 +255,51 @@ int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen ) return( 0 ); } +/* + * Parse a CSR, allowing for PEM or raw DER encoding + */ +int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen ) +{ + int ret; +#if defined(POLARSSL_PEM_PARSE_C) + size_t use_len; + pem_context pem; +#endif + + /* + * Check for valid input + */ + if( csr == NULL || buf == NULL ) + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); + +#if defined(POLARSSL_PEM_PARSE_C) + pem_init( &pem ); + ret = pem_read_buffer( &pem, + "-----BEGIN CERTIFICATE REQUEST-----", + "-----END CERTIFICATE REQUEST-----", + buf, NULL, 0, &use_len ); + + if( ret == 0 ) + { + /* + * Was PEM encoded, parse the result + */ + if( ( ret = x509_csr_parse_der( csr, pem.buf, pem.buflen ) ) != 0 ) + return( ret ); + + pem_free( &pem ); + return( 0 ); + } + else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + { + pem_free( &pem ); + return( ret ); + } + else +#endif /* POLARSSL_PEM_PARSE_C */ + return( x509_csr_parse_der( csr, buf, buflen ) ); +} + #if defined(POLARSSL_FS_IO) /* * Load a CSR into the structure @@ -290,12 +310,12 @@ int x509_csr_parse_file( x509_csr *csr, const char *path ) size_t n; unsigned char *buf; - if ( ( ret = x509_load_file( path, &buf, &n ) ) != 0 ) + if( ( ret = x509_load_file( path, &buf, &n ) ) != 0 ) return( ret ); ret = x509_csr_parse( csr, buf, n ); - memset( buf, 0, n + 1 ); + polarssl_zeroize( buf, n + 1 ); polarssl_free( buf ); return( ret ); @@ -317,7 +337,7 @@ int x509_csr_parse_file( x509_csr *csr, const char *path ) * This fuction tries to 'fix' this by at least suggesting enlarging the * size by 20. */ -static int compat_snprintf(char *str, size_t size, const char *format, ...) +static int compat_snprintf( char *str, size_t size, const char *format, ... ) { va_list ap; int res = -1; @@ -329,29 +349,29 @@ static int compat_snprintf(char *str, size_t size, const char *format, ...) va_end( ap ); // No quick fix possible - if ( res < 0 ) + if( res < 0 ) return( (int) size + 20 ); - return res; + return( res ); } #define snprintf compat_snprintf -#endif +#endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */ #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2 -#define SAFE_SNPRINTF() \ -{ \ - if( ret == -1 ) \ - return( -1 ); \ - \ - if ( (unsigned int) ret > n ) { \ - p[n - 1] = '\0'; \ - return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\ - } \ - \ - n -= (unsigned int) ret; \ - p += (unsigned int) ret; \ +#define SAFE_SNPRINTF() \ +{ \ + if( ret == -1 ) \ + return( -1 ); \ + \ + if( (unsigned int) ret > n ) { \ + p[n - 1] = '\0'; \ + return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \ + } \ + \ + n -= (unsigned int) ret; \ + p += (unsigned int) ret; \ } #define BEFORE_COLON 14 @@ -365,7 +385,6 @@ int x509_csr_info( char *buf, size_t size, const char *prefix, int ret; size_t n; char *p; - const char *desc; char key_size_str[BEFORE_COLON]; p = buf; @@ -383,11 +402,8 @@ int x509_csr_info( char *buf, size_t size, const char *prefix, ret = snprintf( p, n, "\n%ssigned using : ", prefix ); SAFE_SNPRINTF(); - ret = oid_get_sig_alg_desc( &csr->sig_oid, &desc ); - if( ret != 0 ) - ret = snprintf( p, n, "???" ); - else - ret = snprintf( p, n, "%s", desc ); + ret = x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md, + csr->sig_opts ); SAFE_SNPRINTF(); if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON, @@ -424,22 +440,26 @@ void x509_csr_free( x509_csr *csr ) pk_free( &csr->pk ); +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) + polarssl_free( csr->sig_opts ); +#endif + name_cur = csr->subject.next; while( name_cur != NULL ) { name_prv = name_cur; name_cur = name_cur->next; - memset( name_prv, 0, sizeof( x509_name ) ); + polarssl_zeroize( name_prv, sizeof( x509_name ) ); polarssl_free( name_prv ); } if( csr->raw.p != NULL ) { - memset( csr->raw.p, 0, csr->raw.len ); + polarssl_zeroize( csr->raw.p, csr->raw.len ); polarssl_free( csr->raw.p ); } - memset( csr, 0, sizeof( x509_csr ) ); + polarssl_zeroize( csr, sizeof( x509_csr ) ); } #endif /* POLARSSL_X509_CSR_PARSE_C */ diff --git a/pdns/ext/polarssl/library/x509write_crt.c b/pdns/ext/polarssl/library/x509write_crt.c index 15a1194ed..e298c24ec 100644 --- a/pdns/ext/polarssl/library/x509write_crt.c +++ b/pdns/ext/polarssl/library/x509write_crt.c @@ -1,7 +1,7 @@ /* * X.509 certificate writing * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -29,7 +29,11 @@ * - attributes: PKCS#9 v2.0 aka RFC 2985 */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_X509_CRT_WRITE_C) @@ -42,6 +46,11 @@ #include "polarssl/pem.h" #endif /* POLARSSL_PEM_WRITE_C */ +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + void x509write_crt_init( x509write_cert *ctx ) { memset( ctx, 0, sizeof(x509write_cert) ); @@ -58,7 +67,7 @@ void x509write_crt_free( x509write_cert *ctx ) asn1_free_named_data_list( &ctx->issuer ); asn1_free_named_data_list( &ctx->extensions ); - memset( ctx, 0, sizeof(x509write_cert) ); + polarssl_zeroize( ctx, sizeof(x509write_cert) ); } void x509write_crt_set_version( x509write_cert *ctx, int version ) @@ -106,8 +115,8 @@ int x509write_crt_set_serial( x509write_cert *ctx, const mpi *serial ) int x509write_crt_set_validity( x509write_cert *ctx, const char *not_before, const char *not_after ) { - if( strlen(not_before) != X509_RFC5280_UTC_TIME_LEN - 1 || - strlen(not_after) != X509_RFC5280_UTC_TIME_LEN - 1 ) + if( strlen( not_before ) != X509_RFC5280_UTC_TIME_LEN - 1 || + strlen( not_after ) != X509_RFC5280_UTC_TIME_LEN - 1 ) { return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); } @@ -151,7 +160,8 @@ int x509write_crt_set_basic_constraints( x509write_cert *ctx, } ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); return x509write_crt_set_extension( ctx, OID_BASIC_CONSTRAINTS, OID_SIZE( OID_BASIC_CONSTRAINTS ), @@ -166,7 +176,7 @@ int x509write_crt_set_subject_key_identifier( x509write_cert *ctx ) unsigned char *c = buf + sizeof(buf); size_t len = 0; - memset( buf, 0, sizeof(buf)); + memset( buf, 0, sizeof(buf) ); ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, ctx->subject_key ) ); sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 ); @@ -188,7 +198,7 @@ int x509write_crt_set_authority_key_identifier( x509write_cert *ctx ) unsigned char *c = buf + sizeof(buf); size_t len = 0; - memset( buf, 0, sizeof(buf)); + memset( buf, 0, sizeof(buf) ); ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, ctx->issuer_key ) ); sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 ); @@ -199,7 +209,8 @@ int x509write_crt_set_authority_key_identifier( x509write_cert *ctx ) ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONTEXT_SPECIFIC | 0 ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); return x509write_crt_set_extension( ctx, OID_AUTHORITY_KEY_IDENTIFIER, OID_SIZE( OID_AUTHORITY_KEY_IDENTIFIER ), @@ -313,9 +324,11 @@ int x509write_crt_der( x509write_cert *ctx, unsigned char *buf, size_t size, */ ASN1_CHK_ADD( len, x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONTEXT_SPECIFIC | + ASN1_CONSTRUCTED | 3 ) ); /* * SubjectPublicKeyInfo @@ -345,7 +358,8 @@ int x509write_crt_der( x509write_cert *ctx, unsigned char *buf, size_t size, len += sub_len; ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); /* * Issuer ::= Name @@ -370,10 +384,12 @@ int x509write_crt_der( x509write_cert *ctx, unsigned char *buf, size_t size, ASN1_CHK_ADD( sub_len, asn1_write_int( &c, tmp_buf, ctx->version ) ); len += sub_len; ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONTEXT_SPECIFIC | + ASN1_CONSTRUCTED | 0 ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); /* * Make signature @@ -398,7 +414,8 @@ int x509write_crt_der( x509write_cert *ctx, unsigned char *buf, size_t size, len += sig_and_oid_len; ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); return( (int) len ); } diff --git a/pdns/ext/polarssl/library/x509write_csr.c b/pdns/ext/polarssl/library/x509write_csr.c index 3a49aee94..53ae9c63b 100644 --- a/pdns/ext/polarssl/library/x509write_csr.c +++ b/pdns/ext/polarssl/library/x509write_csr.c @@ -1,7 +1,7 @@ /* * X.509 Certificate Signing Request writing * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -28,7 +28,11 @@ * - attributes: PKCS#9 v2.0 aka RFC 2985 */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_X509_CSR_WRITE_C) @@ -43,6 +47,11 @@ #include #include +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + void x509write_csr_init( x509write_csr *ctx ) { memset( ctx, 0, sizeof(x509write_csr) ); @@ -53,7 +62,7 @@ void x509write_csr_free( x509write_csr *ctx ) asn1_free_named_data_list( &ctx->subject ); asn1_free_named_data_list( &ctx->extensions ); - memset( ctx, 0, sizeof(x509write_csr) ); + polarssl_zeroize( ctx, sizeof(x509write_csr) ); } void x509write_csr_set_md_alg( x509write_csr *ctx, md_type_t md_alg ) @@ -146,20 +155,24 @@ int x509write_csr_der( x509write_csr *ctx, unsigned char *buf, size_t size, if( len ) { ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SET ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | + ASN1_SET ) ); ASN1_CHK_ADD( len, asn1_write_oid( &c, tmp_buf, OID_PKCS9_CSR_EXT_REQ, OID_SIZE( OID_PKCS9_CSR_EXT_REQ ) ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); } ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | + ASN1_CONTEXT_SPECIFIC ) ); ASN1_CHK_ADD( pub_len, pk_write_pubkey_der( ctx->key, tmp_buf, c - tmp_buf ) ); @@ -177,7 +190,8 @@ int x509write_csr_der( x509write_csr *ctx, unsigned char *buf, size_t size, ASN1_CHK_ADD( len, asn1_write_int( &c, tmp_buf, 0 ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); /* * Prepare signature @@ -208,7 +222,8 @@ int x509write_csr_der( x509write_csr *ctx, unsigned char *buf, size_t size, len += sig_and_oid_len; ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) ); - ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); return( (int) len ); } diff --git a/pdns/ext/polarssl/library/xtea.c b/pdns/ext/polarssl/library/xtea.c index 2cb2f30d1..75215c50a 100644 --- a/pdns/ext/polarssl/library/xtea.c +++ b/pdns/ext/polarssl/library/xtea.c @@ -1,7 +1,7 @@ /* * An 32-bit implementation of the XTEA algorithm * - * Copyright (C) 2006-2013, Brainspark B.V. + * Copyright (C) 2006-2014, Brainspark B.V. * * This file is part of PolarSSL (http://www.polarssl.org) * Lead Maintainer: Paul Bakker @@ -23,14 +23,29 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if !defined(POLARSSL_CONFIG_FILE) #include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif #if defined(POLARSSL_XTEA_C) #include "polarssl/xtea.h" +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + #if !defined(POLARSSL_XTEA_ALT) +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + /* * 32-bit integer manipulation macros (big endian) */ @@ -54,6 +69,19 @@ } #endif +void xtea_init( xtea_context *ctx ) +{ + memset( ctx, 0, sizeof( xtea_context ) ); +} + +void xtea_free( xtea_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( xtea_context ) ); +} + /* * XTEA key schedule */ @@ -61,7 +89,7 @@ void xtea_setup( xtea_context *ctx, const unsigned char key[16] ) { int i; - memset(ctx, 0, sizeof(xtea_context)); + memset( ctx, 0, sizeof(xtea_context) ); for( i = 0; i < 4; i++ ) { @@ -132,7 +160,7 @@ int xtea_crypt_cbc( xtea_context *ctx, int mode, size_t length, memcpy( temp, input, 8 ); xtea_crypt_ecb( ctx, mode, input, output ); - for(i = 0; i < 8; i++) + for( i = 0; i < 8; i++ ) output[i] = (unsigned char)( output[i] ^ iv[i] ); memcpy( iv, temp, 8 ); @@ -213,14 +241,15 @@ static const unsigned char xtea_test_ct[6][8] = */ int xtea_self_test( int verbose ) { - int i; + int i, ret = 0; unsigned char buf[8]; xtea_context ctx; + xtea_init( &ctx ); for( i = 0; i < 6; i++ ) { if( verbose != 0 ) - printf( " XTEA test #%d: ", i + 1 ); + polarssl_printf( " XTEA test #%d: ", i + 1 ); memcpy( buf, xtea_test_pt[i], 8 ); @@ -230,21 +259,25 @@ int xtea_self_test( int verbose ) if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 ) { if( verbose != 0 ) - printf( "failed\n" ); + polarssl_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto exit; } if( verbose != 0 ) - printf( "passed\n" ); + polarssl_printf( "passed\n" ); } if( verbose != 0 ) - printf( "\n" ); + polarssl_printf( "\n" ); - return( 0 ); +exit: + xtea_free( &ctx ); + + return( ret ); } -#endif +#endif /* POLARSSL_SELF_TEST */ -#endif +#endif /* POLARSSL_XTEA_C */