Skip to content

Commit 0f68377

Browse files
committed
crypto: support FIPS mode of OpenSSL
Support building and running with FIPS-compliant OpenSSL. The process is following: 1. Download and verify `openssl-fips-x.x.x.tar.gz` from https://www.openssl.org/source/ 2. Extract source to `openssl-fips` folder 3. ``cd openssl-fips && ./config fipscanisterbuild --prefix=`pwd`/out`` (NOTE: On OS X, you may want to run ``./Configure darwin64-x86_64-cc --prefix=`pwd`/out`` if you are going to build x64-mode io.js) 4. `make -j && make install` 5. Get into io.js checkout folder 6. `./configure --openssl-fips=/path/to/openssl-fips/out` 7. Build io.js with `make -j` 8. Verify with `node -p "process.versions.openssl"` (`1.0.2a-fips`) Fix: nodejs/node-v0.x-archive#25463 PR-URL: #1890 Reviewed-By: Rod Vagg <[email protected]> Reviewed-By: Shigeki Ohtsu <[email protected]>
1 parent 53a4eb3 commit 0f68377

File tree

8 files changed

+112
-3
lines changed

8 files changed

+112
-3
lines changed

README.md

+23
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
io.js
23
=====
34

@@ -249,6 +250,28 @@ as `deps/icu` (You'll have: `deps/icu/source/...`)
249250
> vcbuild full-icu
250251
```
251252

253+
# Building io.js with FIPS-compliant OpenSSL
254+
255+
NOTE: Windows is not yet supported
256+
257+
It is possible to build io.js with
258+
[OpenSSL FIPS module](https://www.openssl.org/docs/fips/fipsnotes.html).
259+
260+
Instructions:
261+
262+
1. Download and verify `openssl-fips-x.x.x.tar.gz` from
263+
https://www.openssl.org/source/
264+
2. Extract source to `openssl-fips` folder
265+
3. ``cd openssl-fips && ./config fipscanisterbuild --prefix=`pwd`/out``
266+
(NOTE: On OS X, you may want to run
267+
``./Configure darwin64-x86_64-cc --prefix=`pwd`/out`` if you are going to
268+
build x64-mode io.js)
269+
4. `make -j && make install`
270+
5. Get into io.js checkout folder
271+
6. `./configure --openssl-fips=/path/to/openssl-fips/out`
272+
7. Build io.js with `make -j`
273+
8. Verify with `node -p "process.versions.openssl"` (`1.0.2a-fips`)
274+
252275
## Resources for Newcomers
253276

254277
* [CONTRIBUTING.md](./CONTRIBUTING.md)

common.gypi

+5
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@
3838
'OBJ_DIR': '<(PRODUCT_DIR)/obj.target',
3939
'V8_BASE': '<(PRODUCT_DIR)/obj.target/deps/v8/tools/gyp/libv8_base.a',
4040
}],
41+
['openssl_fips != ""', {
42+
'OPENSSL_PRODUCT': 'libcrypto.a',
43+
}, {
44+
'OPENSSL_PRODUCT': 'libopenssl.a',
45+
}],
4146
['OS=="mac"', {
4247
'clang%': 1,
4348
}, {

configure

+27-1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ parser.add_option("--openssl-no-asm",
8888
dest="openssl_no_asm",
8989
help="Do not build optimized assembly for OpenSSL")
9090

91+
parser.add_option('--openssl-fips',
92+
action='store',
93+
dest='openssl_fips',
94+
help='Build OpenSSL using FIPS canister .o file in supplied folder')
95+
9196
shared_optgroup.add_option('--shared-http-parser',
9297
action='store_true',
9398
dest='shared_http_parser',
@@ -720,6 +725,16 @@ def configure_openssl(o):
720725
o['variables']['node_use_openssl'] = b(not options.without_ssl)
721726
o['variables']['node_shared_openssl'] = b(options.shared_openssl)
722727
o['variables']['openssl_no_asm'] = 1 if options.openssl_no_asm else 0
728+
if options.openssl_fips:
729+
o['variables']['openssl_fips'] = options.openssl_fips
730+
fips_dir = os.path.join(root_dir, 'deps', 'openssl', 'fips')
731+
fips_ld = os.path.abspath(os.path.join(fips_dir, 'fipsld'))
732+
o['make_global_settings'] = [
733+
['LINK', fips_ld + ' <(openssl_fips)/bin/fipsld'],
734+
]
735+
else:
736+
o['variables']['openssl_fips'] = ''
737+
723738

724739
if options.without_ssl:
725740
return
@@ -1025,10 +1040,21 @@ configure_fullystatic(output)
10251040
# move everything else to target_defaults
10261041
variables = output['variables']
10271042
del output['variables']
1043+
1044+
# make_global_settings should be a root level element too
1045+
if 'make_global_settings' in output:
1046+
make_global_settings = output['make_global_settings']
1047+
del output['make_global_settings']
1048+
else:
1049+
make_global_settings = False
1050+
10281051
output = {
10291052
'variables': variables,
1030-
'target_defaults': output
1053+
'target_defaults': output,
10311054
}
1055+
if make_global_settings:
1056+
output['make_global_settings'] = make_global_settings
1057+
10321058
pprint.pprint(output, indent=2)
10331059

10341060
write('config.gypi', do_not_edit +

deps/openssl/fips/fipscc

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/sh
2+
ARGS=
3+
CXX=${CXX:-g++}
4+
5+
while [ "x$1" != "x" ]; do
6+
ARG=$1
7+
shift
8+
case $ARG in
9+
*fips_premain.c) ARGS="$ARGS -x c $ARG -x none";;
10+
*) ARGS="$ARGS $ARG";;
11+
esac
12+
done
13+
14+
echo $CXX $ARGS
15+
${CXX} $ARGS

deps/openssl/fips/fipsld

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/sh
2+
3+
# NOTE: Just a wrapper around normal fipsld
4+
FIPSLD=$1
5+
shift
6+
7+
DIR=`dirname $0`
8+
FIPSLD_CC=$DIR/fipscc $FIPSLD $@

deps/openssl/openssl.gyp

+23
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
'openssl_no_asm%': 0,
1010
'llvm_version%': 0,
1111
'gas_version%': 0,
12+
'openssl_fips%': 'false',
1213
},
1314
'targets': [
1415
{
@@ -21,6 +22,28 @@
2122
['exclude', 'store/.*$']
2223
],
2324
'conditions': [
25+
# FIPS
26+
['openssl_fips != ""', {
27+
'defines': [
28+
'OPENSSL_FIPS',
29+
],
30+
'include_dirs': [
31+
'<(openssl_fips)/include',
32+
],
33+
34+
# Trick fipsld, it expects to see libcrypto.a
35+
'product_name': 'crypto',
36+
37+
'direct_dependent_settings': {
38+
'defines': [
39+
'OPENSSL_FIPS',
40+
],
41+
'include_dirs': [
42+
'<(openssl_fips)/include',
43+
],
44+
},
45+
}],
46+
2447
['openssl_no_asm!=0', {
2548
# Disable asm
2649
'defines': [

node.gyp

+2-2
Original file line numberDiff line numberDiff line change
@@ -234,13 +234,13 @@
234234
[ 'node_target_type!="static_library"', {
235235
'xcode_settings': {
236236
'OTHER_LDFLAGS': [
237-
'-Wl,-force_load,<(PRODUCT_DIR)/libopenssl.a',
237+
'-Wl,-force_load,<(PRODUCT_DIR)/<(OPENSSL_PRODUCT)',
238238
],
239239
},
240240
'conditions': [
241241
['OS in "linux freebsd"', {
242242
'ldflags': [
243-
'-Wl,--whole-archive <(PRODUCT_DIR)/libopenssl.a',
243+
'-Wl,--whole-archive <(PRODUCT_DIR)/<(OPENSSL_PRODUCT)',
244244
'-Wl,--no-whole-archive',
245245
],
246246
}],

src/node_crypto.cc

+9
Original file line numberDiff line numberDiff line change
@@ -5097,6 +5097,15 @@ void InitCryptoOnce() {
50975097
CRYPTO_set_locking_callback(crypto_lock_cb);
50985098
CRYPTO_THREADID_set_callback(crypto_threadid_cb);
50995099

5100+
#ifdef OPENSSL_FIPS
5101+
if (!FIPS_mode_set(1)) {
5102+
int err = ERR_get_error();
5103+
fprintf(stderr, "openssl fips failed: %s\n", ERR_error_string(err, NULL));
5104+
UNREACHABLE();
5105+
}
5106+
#endif // OPENSSL_FIPS
5107+
5108+
51005109
// Turn off compression. Saves memory and protects against CRIME attacks.
51015110
#if !defined(OPENSSL_NO_COMP)
51025111
#if OPENSSL_VERSION_NUMBER < 0x00908000L

0 commit comments

Comments
 (0)