Kyle Hamilton wrote:
On Dec 2, 2007 4:31 PM, Steve Marquess <[EMAIL PROTECTED]> wrote:

...<big snip>...

c) I would like to know where to find the formal specification
documents for what must be met in a module boundary, ...

The module boundary is *the* key concept for FIPS 140-2. It is also a very elusive concept in the context of software libraries -- like pornography ("I know it when I see it") or the blind men meeting an elephant, everyone seems to have some notion of what is is but can't clearly articulate it. I thought I understood it five years ago, now it's more of a puzzle to me than ever. Here's my own personal perspective on some of the pieces to that puzzle. Since the term "module" means something different here than for software engineering I capitalize it in the following:

1) The "Module boundary" concept dates from the time when cryptography was done entirely in hardware. The Module boundary for hardware is the metal enclosure for the hardware device (or the circuit board for a backplane device). The buttons and switches on the case and the wires leading into it are the interface. Easy enough to grasp so far. When you start talking about software running on a modern multi-tasking, virtual memory computer it gets confusing.

2) There is the "Module boundary" (the most commonly heard term). But, you will also hear "algorithm boundary", "physical boundary", and "logical boundary". None of those terms are entirely synonymous. My best understanding is that the algorithm boundaries are entirely subsumed within the generic Module boundary, the logical boundary is kinda sorta the same as the Module boundary for a running process, the physical boundary is roughly equivalent to an idealized computer representative of the one used for the validation testing. But, I've seen all these terms used in contexts that leave me wondering.

3) For software Modules the integrity test (a digest check) is performed over the contents of the Module. Well, sort of. There are two acceptable techniques that I know of. One is to create the software as a runtime binary file (typically a shared library file for a crypto library, or a standalone application program) and call the file itself as it resides on disk the crypto Module. In this case the Module is one contiguous string of bits, note that string of bits includes "glue" data for the run-time loader. The reference digest value itself can't be included in that file, of course, so it is placed in a separate file. The second technique is to perform the digest over the text (machine code) and read-only data segments of the program as mapped into memory by the run-time loader. In this case the Module is two (or more) separate contiguous strings of bits in memory (or memory mapped disk sectors). Those reference digest values can be embedded in the runtime binary file, outside of the Module boundary.

4) The Module boundary is *not* every location the program counter visits during the execution of the code between the call to and return from a function in the Module. That program counter will traverse code in the text segment(s) -- definitely in the boundary. It will also traverse code in system (kernel) calls -- definitely *outside* the boundary. It will traverse code in userspace shared libraries, and here it gets really fuzzy. Calls from the Module to "standard system library functions" are ok, those libraries are not considered internal to the boundary. So libc, for example, is not in the boundary. The malloc functions are not, most interesting (because they export the CSPs -- secrets -- that are supposed to remain in the boundary). What exactly is a "standard system library"? Good question. Is /usr/lib/libc.so? Certainly! Is /usr/lib/libssl.so, which is provided by many vendors as part of the base operating system distribution, such a libary? Certainly not! Is /usr/lib/libncurses.so? /usr/lib/libm.so? /usr/lib/libstdc++.so? Who knows? The term "cryptographically significant" will arise in these discussions. I won't even pretend to understand that term, that's one for scripture interpretation.

5) Physical consanguinity within the Module boundary is significant. By this I mean that the sequence of machine instructions and read-only data that comprise the code of the Module must always occur in a fixed relationship with respect to ascending memory addresses. When a build-time linker (ld) creates an executable binary from an archive library containing the object modules, A, B, C, it doesn't much care what order (in terms of ascending memory addresses) they appear in the output file; A-B-C, B-C-A, etc. Even though the resulting executables are functionally identical that is not acceptable for a FIPS 140-2 Module, the runtime code must be guaranteed to be in the same sequence (this requirement inspired the fipscanister.o "monolithic" object module).

6) The digest does more than merely verify that the Module code has not been corrupted. It also existentially defines the Module. We encountered a specific requirement that the digest *cannot* cover any code not properly part of the Module. Specifically, if you want your Module to be a single runtime executable containing the three crypto related object modules A,B,C and the unrealted modules X,Y,Z, the resulting linked program containing the object modules A,B,C,X,Y,Z cannot be defined as the Module. The digest over all six object modules will of course verify that A,B,C have not been corrupted, but including X,Y,Z in that digest is not allowed. Instead the digest must cover A,B,C only. The fipscanister.o monolithic object modules addresses this requirement as well.

If you're confused now, welcome to the club.

-Steve M.

--
Steve Marquess
Open Source Software Institute
[EMAIL PROTECTED]

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [email protected]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to