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]