aboutsummaryrefslogtreecommitdiffstats
path: root/README.build
blob: b675686609c15a120f59494282b100bc7e1b3745 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
===============
Introduce
===============
The OpenSSL Project is a collaborative effort to develop a robust,
commercial-grade, full-featured, and Open Source toolkit implementing the
Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1)
protocols as well as a full-strength general purpose cryptography library
managed by a worldwide community of volunteers that use the Internet to
communicate, plan, and develop the OpenSSL toolkit and its related documentation.

The Federal Information Processing Standard (FIPS) Publication 140-2
is a U.S. government computer security standard used to accredit
cryptographic modules.

OpenSSL itself is not validated, and never will be. Instead a special
carefully defined software component called the OpenSSL FIPS Object Module
has been created. This Module was designed for compatibility with OpenSSL
so that products using the OpenSSL API can be converted to use validated
cryptography with minimal effort.

References Documents:
https://www.openssl.org/docs/fips.html
https://www.openssl.org/docs/fips/UserGuide-2.0.pdf
https://www.openssl.org/docs/fips/SecurityPolicy-2.0.16.pdf
https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp2398.pdf


===============
Building
===============
The following software must be built according to the instructions within
the UserGuide-2.0.pdf (referenced above).  Precompiled versions in this
directory were built using the method listed below.

In order to build a precompiled version of the binary, you must first
construct a target system that includes a target development environment
and meta-openssl102-fips layer without feature/openssl-fips

The easiest way to do this with Yocto is include this layer [1]
and meta-openssl102 [2], and install packagegroup-core-buildessential
to image [3]

[1] git://git.yoctoproject.org/meta-openssl102-fips
[2] git://git.yoctoproject.org/meta-openssl102
    Manually set 1.0.2% to openssl preferred version
    echo "PREFERRED_VERSION_openssl = '1.0.2%'" >> conf/local.conf
[3] echo "IMAGE_INSTALL:append = ' packagegroup-core-buildessential'" >> conf/local.conf

The easiest way to do this with Wind River Linux is include:

    --templates features/target-toolchain --templates feature/openssl102 --layers meta-openssl102-fips

    Note: do not include template feature/openssl-fips

Additionally you will need a way to get the openssl-fips module source to
the target for the build.  Adding ssh/scp is recommended, to add these
add the following to your local.conf file:

    IMAGE_INSTALL:append = " openssh-ssh openssh-scp"

If you are building with configurations that have security software enabled,
such as SE Linux, you may be required to boot in a non-enforcing mode to
follow the steps below.  The configuration options necessary to boot into
non-enforcing mode may vary depending on the security software and 
configuration.

Building Steps (based on section 4 of the UsersGuide-2.0.pdf):

1. Acquire the OpenSSL FIPS Object Module v2.0.  See section 4.1 of
   the UsersGuide-2.0.pdf for information required to meet CMVP "trusted
   path" requirements.

   At the time this document was written:

      openssl-fips-2.0.16.tar.gz

2. Transfer the verified file to the target system configured with a
   target compiler.  Note: keep in mind the requirements of section
   4 and the discussion from section 6.6 of the UsersGuide-2.0.pdf

3. Building the FIPS Object Module
    (On the target system)

      gunzip -c openssl-fips-2.0.16.tar.gz | tar xf -
      cd openssl-fips-2.0.16

    # Follow the steps U1 or U2 in Appendx A of the Security Policy
    # For U1:

      ./config no-asm
      make
      make install

    # For U2:

      ./config
      make
      make install

    Selection of U1 vs U2 approach needs to be considered under the
    configurations in the UserGuide.  In some cases, only U1 or U2
    will build and test properly for a given system configuration.  If
    one approach does not work, it's advised to try the other approach.

    Note that as a condition of the FIPS 140-2 validation no other
    user specified configuration options may be specified.
    This restriction means that an optional install prefix cannot
    be specified!  However, there is no restriction on subsequent
    manual relocation of the generated files to the desired final location.

    In order to support cross compilation with the FIPS Object Module, the
    'incore' script needs to also be available.

      cp util/incore /usr/local/ssl/fips-2.0/bin/.

    We also advise you to run the test suite as well using:

      make build_tests
      ./test/fips_test_suite fullpost

4. Tar up the results and transfer back to your build system
    (On the target system)
    In the following <target_arch> refers to one of the defined target
    architectures such as: x86, x86_64, powerpc, or armv7l

      tar c /usr/local/ssl | bzip2 > openssl-fips-<openssl_version>-<target_arch>-install.tar.bz2

    Move the tar archive back to your host project into a directory accessable
    by the build system.

5.  Configure the build system to enable openssl-fips and locate your custom
    prebuilt tar archive.

    For Yocto, in your build directory, edit conf/local.conf, add:
      IMAGE_INSTALL:append = " openssl-fips-dev"
      OPENSSL_FIPS_ENABLED = "1"
      OPENSSL_FIPS_PREBUILT = "<path>"

    For Wind River Linux, in your build directory, edit conf/local.conf, add:
      WRTEMPLATE += "feature/openssl-fips"
      OPENSSL_FIPS_PREBUILT = "<path>"

    Where path is the location on the host with the prebuilt openssl-fips.

    Note: If you add or update the archive after trying to build openssl-fips,
    the system may cache the failure message.  You may have to manually clear
    the cache by running: rm -rf tmp-glibc/cache

=======================
Test Examples In Target
=======================
1. OpenSSL FIPS Power-On-Self-Test(POST)
    $ <openssl-fips>/test/fips_test_suite post
or: $ <openssl-fips>/fips_test_suite fullpost
        FIPS-mode test application
        FIPS 2.0.1 validated test module 12 Jun 2012

		DRBG AES-256-CTR DF test started
		DRBG AES-256-CTR DF test OK
    1. Non-Approved cryptographic operation test...
	a. Included algorithm (D-H)......successful
	POST started
		Integrity  test started
		Integrity  test OK
		DRBG AES-256-CTR DF test started
		DRBG AES-256-CTR DF test OK

        ...

	POST Success
    Testing operation failure with DRBG entropy failure
		Pairwise Consistency DSA test started
		Pairwise Consistency DSA test OK
	DSA key generated OK as expected.
		DRBG SHA512 test started
		DRBG SHA512 test OK
	DRBG entropy fail failed as expected
	DSA signing failed as expected
	ECDSA key generation failed as expected.
    Induced failure test completed with 0 errors
	successful as expected

    All tests completed with 0 errors

2. OpenSSL MD5 in FIPS mode
    $ env OPENSSL_FIPS=1 /usr/bin/openssl md5 /usr/bin/openssl
    Error setting digest md5
    3073021576:error:060A80A3:digital envelope routines:FIPS_DIGESTINIT:disabled for fips:fips_md.c:180:

    # If no FIPS module linked, openssl will say something else when OPENSSL_FIPS=1
    # Try the following command in local host PC.
    $ env OPENSSL_FIPS=1 /usr/bin/openssl md5 /usr/bin/openssl
    FIPS mode not supported.

3. OpenSSL MD5 in non-FIPS mode
    $ /usr/bin/openssl md5 /usr/bin/openssl
    MD5(/usr/bin/openssl)= 0b6ea5fd013fd1d9d00a95a44acc61c9

4. OpenSSL SHA1 in FIPS mode
    $ env OPENSSL_FIPS=1 /usr/bin/openssl sha1 /usr/bin/openssl
    SHA1(/usr/bin/openssl)= 39c978de7152036e73ad2e62f677878f37d3f980

5. OpenSSL SHA1 in non-FIPS mode
    $ /usr/bin/openssl sha1 /usr/bin/openssl
    SHA1(/usr/bin/openssl)= 39c978de7152036e73ad2e62f677878f37d3f980

===========================
Example OpenSSL Based Application
(Appendix C in UsersGuide-2.0.pdf)
===========================
In this application all cryptography is provided through the FIPS Object
Module and the FIPS mode initialization is performed via the FIPS_mode_set()
call. The command generates a HMAC-SHA-1 digest of an input stream or a
file, using the same arbitrary key as the OpenSSL FIPS Module file integrity
check

1. Linking with the Shared Object (cross compiling)
Linking with the shared object is easiest. That's because the FIPS Capable library
build process takes care of a number of items for you, including running fipsld on
the shared object libcrypto.so. Then you could dynamicly link the library (-lcrypto)
in your recipe as normal.
More details at recipe openssl-fips-example do_compile task

2. Linking with the Static Archive (on the target)
Linking against the static library is more challenging. That's because you have to
set two variables -- CC and FIPSLD_CC and compile with the modified CC. They must be
exported because fipsld uses them in child shells. Behind the scenes, fipsld will
compile and link fips_premain.c, modify the libcrypto archive, assemble the final
program, and embed the fingerprint.

On host:
edit local.conf to add openssl-fips-example to image
$ echo 'IMAGE_INSTALL:append = " openssl-fips-example"' >> conf/local.conf
$ bitbake <image>

On target:
$ cd /usr/lib64/ssl/fips-2.0/test
$ make
gcc -c fips_hmac.c
FIPSLD_CC=gcc /usr/lib64/ssl/fips-2.0//bin/fipsld -o fips_hmac fips_hmac.o /usr/lib64/libcrypto.a -ldl

3. Run applications with fips enabled on target
All of them will generate the same HMAC-SHA-1 digest
$ cd /usr/lib64/ssl/fips-2.0/test
$ ./fips_hmac -v ./fips_hmac.c
FIPS mode enabled
ae25ad68d9a8cc04075100563a437fa37829afcc

# ./fips_hmac.cross -v ./fips_hmac.c
FIPS mode enabled
ae25ad68d9a8cc04075100563a437fa37829afcc

Note this sample command is functionally equivalent to:
$ env OPENSSL_FIPS=1 openssl sha1 -hmac etaonrishdlcupfm fips_hmac.c
HMAC-SHA1(fips_hmac.c)= ae25ad68d9a8cc04075100563a437fa37829afcc

=======================
Known Issues
=======================
If the CPU on target machine which building FIPS object module is newer than
Nehalem (e.g. Sandy Brigde) or is an Intel Atom processor. Then you may
encounter an error when building openssl with the FIPS object module:
qemu: uncaught target signal 4 (Illegal instruction).

The current processor emulated in qemu is set to Nehalem. But the GCC will use
-march=native to enable all instruction subsets supported by the target machine
when building FIPS object module. The illegal instruction error will occur if
some instruction subsets (e.g AVX/AVX2) are not supported by Nehalem.

To check if the CPU is Intel Atom:
$ cat /proc/cpuinfo | grep "Atom"

To check if the CPU supports AVX/AVX2:
$ cat /proc/cpuinfo | grep "avx"
Or:
$ gcc -dM -E - < /dev/null | grep "AVX"

As a workaround, we can specify -march=nehalem in GCC before build the FIPS
object module:
$ export CC="gcc -march=nehalem"
$ ./config [no-asm]
$ make
$ make install