Reputation: 11
I am building a FIPS-capable version of OpenSSL for use as a shared library, using the following versions:
FIPS Module: 2.0.16
OpenSSL: 1.0.2n
And when I build it for x86 natively, I have no issues and the module can enter FIPS mode (through FIPS_mode_set(1)) successfully.
However, when I cross-compile for arm (linux_armv4) and use the provided incore script to generate the library fingerprint, the "FIPS_mode_set(1)" call was failing with an invalid fingerprint.
I tracked this down to the incore script itself where the script was getting the offset of "FIPS_text_start" and "FIPS_text_end". When pritned out, these addresses appear to be 1 off of the value of the actual locations for the symbols in the library. To confirm, I subtracted 1 from each and re-ran the signature generation (before and after given below):
Note: This snippet starts at line 407 of the incore script
Before:
sub FIPS_incore_fingerprint {
my $p1 = $FIPS_text_start->{st_offset};
my $p2 = $FIPS_text_end->{st_offset};
After:
sub FIPS_incore_fingerprint {
my $p1 = $FIPS_text_start->{st_offset}-1;
my $p2 = $FIPS_text_end->{st_offset}-1;
Which, when loaded on to the arm system, passed the fingerprint and returned from "FIPS_mode_set" successfully.
However, that change likely invalidates the FIPS certification of the library, from guidance in the OpenSSL FIPS user guide. I am not very familiar with perl, and do not know what could be causing this off-by-one, besides some kind of compiler nuance that I'm not familiar with, and am looking for any advice that people may have.
Summary:
Upvotes: 0
Views: 263
Reputation: 1
I just faced the same problem on my linux/ARM platform. Is it possible that you are building THUMB code instead of ARM?
Unfortunately, it seems like the FIPS incore script only supports the traditional ARM instruction set and does not account for THUMB mode.
An easy way to know if you are building with THUMB code is to look for the "-mthumb" flag on your gcc command line. In my case, I removed the "-mthumb" flag and everything suddenly aligned correctly without having to change the incore script.
The ARM architecture supports 2 families of instruction sets: the traditional 32-bit ARM instructions, and the 16-bit THUMB instructions.
All addresses must be divisible by 4 in ARM mode (4-bytes aligned), and divisible by 2 in THUMB mode (2-bytes aligned), leaving all the odd addresses unused. They decided to use the least significant bit of the addresses (that was always zero) to determine whether the code being branched should be run with ARM (LSB = 0) or THUMB (LSB = 1) instructions. In other words, when we see an odd address number, it means the code located at [odd_address - 1] needs to be interpreted as THUMB instructions. Reference: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0100a/armasm_cegbgefe.htm
The FIPS incore script uses the ELF symbol table directly to find the address of the FIPS_text_start and FIPS_text_end objects, without looking if they are odd/even numbers. If the module to be signed was built in THUMB mode, the LSB of the addresses will be set to 1, explaining the "-1" offset required in the script. Of course, if the module is built with the traditional ARM instruction set, the LSB of the addresses is set to 0 and everything is aligned.
Upvotes: 0