From 08af7dba2aa7ea49858d0f05c68fd21cdadf4c15 Mon Sep 17 00:00:00 2001 From: Shigeki Ohtsu Date: Wed, 7 Mar 2018 22:31:05 +0900 Subject: [PATCH] build: add OpenSSL-1.1.0 support - For Windows, nasm is new build requirements and openssl_no_asm is set to 1 with warning if it is not installed. - For use of openssl assemble codes, either gas_version >= 2.23, xcode_version >= 5.0 ,llvm_version >= 3.3 or nasm_version >= 2.10 is needed. Otherwise, openssl_no_asm is set to 1 with warning. - FIPS is not supported in OpenSSL-1.1.0 so that it leads an error when openssl_fips options is enabled in configure. Fixes: https://github.com/nodejs/node/issues/4270 PR-URL: https://github.com/nodejs/node/pull/19794 Reviewed-By: James M Snell Reviewed-By: Rod Vagg Reviewed-By: Michael Dawson --- BUILDING.md | 56 +++++++++++++-------------------------- configure | 67 +++++++++++++++++++++++++++++++++-------------- node.gyp | 4 +-- tools/mkssldef.py | 2 +- 4 files changed, 68 insertions(+), 61 deletions(-) diff --git a/BUILDING.md b/BUILDING.md index e3bd7a7e9db..19b227af403 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -88,6 +88,23 @@ Depending on host platform, the selection of toolchains may vary. * Visual Studio 2017 or the Build Tools thereof +#### OpenSSL asm support + +OpenSSL-1.1.0 requires the following asssembler version for use of asm +support. + +* gas (GNU assembler) version 2.23 or higher +* xcode version 5.0 or higher +* llvm version 3.3 or higher +* nasm version 2.10 or higher in Windows + +Otherwise, `--openssl-no-asm` is added with warning in configure. + +*Note:* The forthcoming OpenSSL-1.1.1 will require higher + version. Please refer + https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_ia32cap.html for + details. + ## Building Node.js on supported platforms *Note:* All prerequisites can be easily installed by following @@ -377,44 +394,7 @@ as `deps/icu` (You'll have: `deps/icu/source/...`) ## Building Node.js with FIPS-compliant OpenSSL -It is possible to build Node.js with the -[OpenSSL FIPS module](https://www.openssl.org/docs/fipsnotes.html) on POSIX -systems. Windows is not supported. - -Building in this way does not mean the runtime is FIPS 140-2 validated, but -rather that the runtime uses a validated module. In addition, the validation for -the underlying module is only valid if it is deployed in accordance with its -[security policy](http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp1747.pdf). -If you need FIPS validated cryptography it is recommended that you read both -the [security policy](http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp1747.pdf) -and [user guide](https://openssl.org/docs/fips/UserGuide-2.0.pdf). - -### Instructions - -1. Obtain a copy of openssl-fips-x.x.x.tar.gz. - To comply with the security policy you must ensure the path - through which you get the file complies with the requirements - for a "secure installation" as described in section 6.6 in - the [user guide](https://openssl.org/docs/fips/UserGuide-2.0.pdf). - For evaluation/experimentation, you can simply download and verify - `openssl-fips-x.x.x.tar.gz` from https://www.openssl.org/source/ -2. Extract source to `openssl-fips` folder and `cd openssl-fips` -3. `./config` -4. `make` -5. `make install` - (NOTE: to comply with the security policy you must use the exact - commands in steps 3-5 without any additional options as per - Appendix A in the [security policy](http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp1747.pdf). - The only exception is that `./config no-asm` can be - used in place of `./config`, and the FIPSDIR environment variable - may be used to specify a non-standard install folder for the - validated module, as per User Guide sections 4.2.1, 4.2.2, and 4.2.3. -6. Get into Node.js checkout folder -7. `./configure --openssl-fips=/path/to/openssl-fips/installdir` - For example on ubuntu 12 the installation directory was - `/usr/local/ssl/fips-2.0` -8. Build Node.js with `make -j` -9. Verify with `node -p "process.versions.openssl"` (for example `1.0.2a-fips`) +This version of Node.js does not support FIPS. ## Building Node.js with external core modules diff --git a/configure b/configure index 84273f93950..e1843240adb 100755 --- a/configure +++ b/configure @@ -639,6 +639,25 @@ def get_version_helper(cc, regexp): else: return 0 +def get_nasm_version(asm): + try: + proc = subprocess.Popen(shlex.split(asm) + ['-v'], + stdin=subprocess.PIPE, stderr=subprocess.PIPE, + stdout=subprocess.PIPE) + except OSError: + warn('''No acceptable ASM compiler found! + Please make sure you have installed nasm from http://www.nasm.us + and refer BUILDING.md.''') + return 0 + + match = re.match(r"NASM version ([2-9]\.[0-9][0-9]+)", + proc.communicate()[0]) + + if match: + return match.group(1) + else: + return 0 + def get_llvm_version(cc): return get_version_helper( cc, r"(^(?:FreeBSD )?clang version|based on LLVM) ([3-9]\.[0-9]+)") @@ -677,6 +696,11 @@ def get_gas_version(cc): # quite prepared to go that far yet. def check_compiler(o): if sys.platform == 'win32': + if not options.openssl_no_asm: + nasm_version = get_nasm_version('nasm') + o['variables']['nasm_version'] = nasm_version + if nasm_version == 0: + o['variables']['openssl_no_asm'] = 1 return ok, is_clang, clang_version, gcc_version = try_check_compiler(CXX, 'c++') @@ -1039,32 +1063,35 @@ def configure_v8(o): def configure_openssl(o): - o['variables']['node_use_openssl'] = b(not options.without_ssl) - o['variables']['node_shared_openssl'] = b(options.shared_openssl) - o['variables']['openssl_no_asm'] = 1 if options.openssl_no_asm else 0 + variables = o['variables'] + variables['node_use_openssl'] = b(not options.without_ssl) + variables['node_shared_openssl'] = b(options.shared_openssl) + variables['openssl_no_asm'] = 1 if options.openssl_no_asm else 0 if options.use_openssl_ca_store: o['defines'] += ['NODE_OPENSSL_CERT_STORE'] if options.openssl_system_ca_path: - o['variables']['openssl_system_ca_path'] = options.openssl_system_ca_path - o['variables']['node_without_node_options'] = b(options.without_node_options) + variables['openssl_system_ca_path'] = options.openssl_system_ca_path + variables['node_without_node_options'] = b(options.without_node_options) if options.without_node_options: o['defines'] += ['NODE_WITHOUT_NODE_OPTIONS'] + + # supported asm compiler for AVX2. See https://github.com/openssl/openssl/ + # blob/OpenSSL_1_1_0-stable/crypto/modes/asm/aesni-gcm-x86_64.pl#L52-L69 + openssl110_asm_supported = \ + ('gas_version' in variables and variables['gas_version'] >= '2.23') or \ + ('xcode_version' in variables and variables['xcode_version'] >= '5.0') or \ + ('llvm_version' in variables and variables['llvm_version'] >= '3.3') or \ + ('nasm_version' in variables and variables['nasm_version'] >= '2.10') + + if not openssl110_asm_supported and variables['openssl_no_asm'] == 0: + warn('''openssl_no_asm is enabled due to missed or old assembler. + Please refer BUILDING.md''') + variables['openssl_no_asm'] = 1 + if options.openssl_fips: - o['variables']['openssl_fips'] = options.openssl_fips - fips_dir = os.path.join('deps', 'openssl', 'fips') - fips_ld = os.path.abspath(os.path.join(fips_dir, 'fipsld')) - # LINK is for Makefiles, LD/LDXX is for ninja - o['make_fips_settings'] = [ - ['LINK', fips_ld + ' <(openssl_fips)/bin/fipsld'], - ['LD', fips_ld + ' <(openssl_fips)/bin/fipsld'], - ['LDXX', fips_ld + ' <(openssl_fips)/bin/fipsld'], - ] - else: - o['variables']['openssl_fips'] = '' - try: - os.remove('config_fips.gypi') - except OSError: - pass + print('Error: FIPS is not supported yet in this version') + exit(1) + variables['openssl_fips'] = '' if options.without_ssl: def without_ssl_error(option): diff --git a/node.gyp b/node.gyp index 4709e5ec1e2..0f6c1609690 100644 --- a/node.gyp +++ b/node.gyp @@ -609,8 +609,8 @@ { 'action_name': 'mkssldef', 'inputs': [ - 'deps/openssl/openssl/util/libeay.num', - 'deps/openssl/openssl/util/ssleay.num', + 'deps/openssl/openssl/util/libcrypto.num', + 'deps/openssl/openssl/util/libssl.num', ], 'outputs': ['<(SHARED_INTERMEDIATE_DIR)/openssl.def'], 'action': [ diff --git a/tools/mkssldef.py b/tools/mkssldef.py index 8354e5712ef..3ff53531667 100755 --- a/tools/mkssldef.py +++ b/tools/mkssldef.py @@ -26,7 +26,7 @@ if __name__ == '__main__': for filename in filenames: for line in open(filename).readlines(): - name, _, meta, _ = re.split('\s+', line) + name, _, _, meta, _ = re.split('\s+', line) if any(map(lambda p: p.match(name), excludes)): continue meta = meta.split(':') assert meta[0] in ('EXIST', 'NOEXIST')