Skip to content

Commit c4b3183

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` 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` Fix: nodejs/node-v0.x-archive#25463
1 parent 43a82f8 commit c4b3183

File tree

4 files changed

+115
-1
lines changed

4 files changed

+115
-1
lines changed

configure

+25-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,14 @@ 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+
o['make_global_settings'] = [
731+
['LINK', '<(openssl_fips)/bin/fipsld'],
732+
]
733+
else:
734+
o['variables']['openssl_fips'] = ''
735+
723736

724737
if options.without_ssl:
725738
return
@@ -1025,10 +1038,21 @@ configure_fullystatic(output)
10251038
# move everything else to target_defaults
10261039
variables = output['variables']
10271040
del output['variables']
1041+
1042+
# make_global_settings should be a root level element too
1043+
if 'make_global_settings' in output:
1044+
make_global_settings = output['make_global_settings']
1045+
del output['make_global_settings']
1046+
else:
1047+
make_global_settings = False
1048+
10281049
output = {
10291050
'variables': variables,
1030-
'target_defaults': output
1051+
'target_defaults': output,
10311052
}
1053+
if make_global_settings != False:
1054+
output['make_global_settings'] = make_global_settings
1055+
10321056
pprint.pprint(output, indent=2)
10331057

10341058
write('config.gypi', do_not_edit +

deps/openssl/fips/fipsld.diff

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
diff --git a/out/bin/fipsld.bak b/out/bin/fipsld
2+
index 62565fd..3e7ce4f 100755
3+
--- a/out/bin/fipsld.bak
4+
+++ b/out/bin/fipsld
5+
@@ -12,6 +12,7 @@
6+
7+
#set -x
8+
9+
+CC=${CXX}
10+
CC=${FIPSLD_CC:-${CC}}
11+
[ -n "${CC}" ] || { echo '$CC is not defined'; exit 1; }
12+
13+
@@ -36,9 +37,9 @@ TARGET=`(while [ "x$1" != "x" -a "x$1" != "x-o" ]; do shift; done; echo $2)`
14+
# procedures are already embedded into and executed in shared library
15+
# context.
16+
case `basename "${TARGET}"` in
17+
-libcrypto*|libfips*|*.dll) ;;
18+
+libopenssl*|libcrypto*|libfips*|*.dll) ;;
19+
*) case "$*" in
20+
- *libcrypto.a*|*-lcrypto*|*fipscanister.o*) ;;
21+
+ *libopenssl.a*|*libcrypto.a*|*-lcrypto*|*fipscanister.o*) ;;
22+
*) exec ${CC} "$@" ;;
23+
esac
24+
esac
25+
@@ -124,7 +125,7 @@ lib*|*.dll) # must be linking a shared lib...
26+
27+
/bin/rm -f "${TARGET}"
28+
${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \
29+
- "${PREMAIN_C}" \
30+
+ -x c "${PREMAIN_C}" -x none \
31+
${_WL_PREMAIN} "$@"
32+
33+
if [ "x${FIPS_SIG}" != "x" ]; then
34+
@@ -143,7 +144,7 @@ lib*|*.dll) # must be linking a shared lib...
35+
36+
# recompile with signature...
37+
${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \
38+
- -DHMAC_SHA1_SIG=\"${SIG}\" "${PREMAIN_C}" \
39+
+ -DHMAC_SHA1_SIG=\"${SIG}\" -x c "${PREMAIN_C}" -x none \
40+
${_WL_PREMAIN} "$@"
41+
;;
42+
43+
@@ -172,7 +173,7 @@ lib*|*.dll) # must be linking a shared lib...
44+
45+
/bin/rm -f "${TARGET}"
46+
${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \
47+
- "${PREMAIN_C}" \
48+
+ -x c "${PREMAIN_C}" -x none \
49+
${_WL_PREMAIN} "$@"
50+
51+
if [ "x${FIPS_SIG}" != "x" ]; then
52+
@@ -191,7 +192,7 @@ lib*|*.dll) # must be linking a shared lib...
53+
54+
# recompile with signature...
55+
${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \
56+
- -DHMAC_SHA1_SIG=\"${SIG}\" "${PREMAIN_C}" \
57+
+ -DHMAC_SHA1_SIG=\"${SIG}\" -x c "${PREMAIN_C}" -x none \
58+
${_WL_PREMAIN} "$@"
59+
;;
60+
esac

deps/openssl/openssl.gyp

+20
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,25 @@
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+
'direct_dependent_settings': {
35+
'defines': [
36+
'OPENSSL_FIPS',
37+
],
38+
'include_dirs': [
39+
'<(openssl_fips)/include',
40+
],
41+
},
42+
}],
43+
2444
['openssl_no_asm!=0', {
2545
# Disable asm
2646
'defines': [

src/node_crypto.cc

+10
Original file line numberDiff line numberDiff line change
@@ -5071,6 +5071,16 @@ void InitCryptoOnce() {
50715071
CRYPTO_set_locking_callback(crypto_lock_cb);
50725072
CRYPTO_THREADID_set_callback(crypto_threadid_cb);
50735073

5074+
#ifdef OPENSSL_FIPS
5075+
if (!FIPS_mode_set(1)) {
5076+
int r;
5077+
r = ERR_get_error();
5078+
fprintf(stderr, "openssl fips failed: %s\n", ERR_error_string(r, NULL));
5079+
UNREACHABLE();
5080+
}
5081+
#endif /* BUD_FIPS_ENABLED */
5082+
5083+
50745084
// Turn off compression. Saves memory and protects against CRIME attacks.
50755085
#if !defined(OPENSSL_NO_COMP)
50765086
#if OPENSSL_VERSION_NUMBER < 0x00908000L

0 commit comments

Comments
 (0)