I was looking at the FIPS certified version of OpenSSL and noticed that they need to execute an integrity check of the library every time it loads. As a result, the library needs to be loaded at a fixed base address to execute the validation. My question is, is there any other way to do so?
It can very well be the case that the base address that the library wants to be loaded at is already in use by some other program.
- 3,191
- 1
- 16
- 35
-
1On a modern OS each process gets its own memory map. The only problem would be if another process were using a shared library (say, library A) in that address and the process with openssl loaded (and verified) now wanted to share from that library (library A). But that's rare and can be re-remapped. – grochmal Sep 30 '16 at 19:15
-
Ohkay, so my problem with address loading aside, is doing a checksum of my memory a good way to test the integrity of the library? Or should I do something else? – Limit Sep 30 '16 at 20:58
1 Answers
Since you mention OpenSSL, I am only considering libraries that are compiled into machine code. Some of it may be relevant to higher level libraries (also called modules), e.g. python or java bytecode, but not all.
How to validate the integrity of a library at run time?
FIPS 140 states several POST (Power-On Self-Test) tests that needs to be performed, and that is a pretty decent way of validating a library at runtime. Note that such a library assumes that you are loading a FIPS validated library in the first place, therefore you are confident that what you have on disk (before loading) is the correct (validated) library. Let's go through a couple of attack vectors:
- You may download a different library than you intended. i.e. an attacker did tamper with your connection and gave you his library instead of the FIPS validated one (or instead of a library validated/trustful in another way). This can be prevented by signing the library and verifying the signature with a key obtained by another channel. This is also a valid mitigation technique to obtain sources code for a library.
- Someone may tamper with the library on disk. To protect against that you first have operating system permissions, and second you can maintain a checksum of the library in a different location (not on the same machine since an attacker could tamper with the checksum as well).
- An attacker may tamper with the library that is already in memory of the process. POSTs protect against this to certain extent. POSTs that are executed only once will protect only against tamper during the memory loading, but you can run POSTs from time to time to ensure that no tamper is happening.
As a result, the library needs to be loaded at a fixed base address to execute the validation.
It can very well be the case that the base address that the library wants to be loaded at is already in use by some other program.
Not at all, POSTs are normally part of the library code. They're just like tests but they're part of the code of the library itself. On a modern OS a shared library will use PIC (Position Independent Code) which will ensure that all jumps are in relative positions.
Moreover, all modern OSes perform memory mapping for each process therefore the same memory location in two processes rarely correspond to the same place in the virtual memory (which in turn rarely correspond to physical memory, yes there is a minimum of two mappings in a typical OS).
Making a checksum of a memory location inside another process is kind of silly. The location may be in memory pages that are not continuous and you will need to find the order of them and replicate it. Something that the kernel is already doing for you (the kernel has the map of that process memory into the memory pages). Therefore the best place to perform the checksum is inside the process that is loading the library, and since you may want to make that checksum from several processes that load that library the best place to put that code is inside the library! Ooops, that turns out to be a Power-On Self-Test (a POST).
You mention OpenSSL, OpenSSL has its own set of POSTs already built-in, see below:
OpenSSL FIPS
The OpenSSL FIPS module (the OpenSSL that has been FIPS validated) has several POSTs. Yet OpenSSL is a very peculiar FIPS verified library, it probably is the only FIPS verified library that comes in source code form.
The user manual for the FIPS OpenSSL (see the references below) has an entire chapter (chapter 4) about obtaining and building OpenSSL so that it can be considered FIPS verified. Interestingly, it covers some of the attack vectors noted at the beginning of the answer. Assuming you got a FIPS verified OpenSSL you now need to call:
FIPS_mode_set()
Once the library loads. This performs several POSTs, and only after you run this you can consider the FIPS OpenSSL to be a FIPS verified library. These are several POSTs that verify the OpenSSL during runtime, the POSTs are described in section 6.3 of the user manual. Moreover, since OpenSSL comes in source form, you can be also look at the POSTs in the code.
References: