Closed
Bug 336509
Opened 19 years ago
Closed 19 years ago
Continuous RNG test failure does not immediately put the FIPS module in the error state
Categories
(NSS :: Libraries, defect, P1)
Tracking
(Not tracked)
RESOLVED
FIXED
3.11.3
People
(Reporter: wtc, Unassigned)
Details
Attachments
(4 files, 2 obsolete files)
8.64 KB,
patch
|
Details | Diff | Splinter Review | |
583 bytes,
patch
|
neil.williams
:
review+
|
Details | Diff | Splinter Review |
20.50 KB,
patch
|
Details | Diff | Splinter Review | |
988 bytes,
patch
|
Details | Diff | Splinter Review |
FIPS 140-2 Sec. 4.9 "Self-Tests" on p. 33 says:
If a cryptographic module fails a self-test, the module shall
enter an error state [...]. The cryptographic module shall not
perform any cryptographic operations while in an error state.
[...]
One of the self-tests is the continuous random number generation
(RNG) test. If our RNG fails this test, we put the RNG itself in
the invalid state (see the statement "rng->isValid = PR_FALSE;" in
prng_fips1861.c:alg_fips186_2_cn_1), and the RNG can't be used
while it is in the invalid state (see the test for rng->isValid at
the beginning of the alg_fips186_2_cn_1 function). But we do not
put the FIPS module in the error state. We made an effort to do
that in fipstokn.c:FC_GenerateRandom, however, the C_GenerateRandom
function is not the only PKCS #11 function that uses the RNG.
Many other PKCS #11 functions, such the key generation functions,
also use the RNG, but we do not check for continuous RNG test failure
in those functions. So, if the continuous RNG test fails during
key generation, the FIPS module can still be used to perform many
cryptographic operations until its C_GenerateRandom function is
invoked.
Although this is not a strict conformance to the FIPS 140-2
requirement, I think we meet the spirit of the requirement because
we do put the RNG in the error (invalid) state.
Reporter | ||
Comment 1•19 years ago
|
||
One way to fix this is to add a callback function to freebl
that is called when the continuous RNG test fails. Then
softoken registers a callback with freebl that puts the
softoken in the error state and logs an audit message.
Note that this patch contains some audit-related changes
to lib/softoken/fipstokn.c that should be ignored. This
patch should not be applied as is. This patch is intended
to illustrate how this solution works. This patch unfortunately
introduces a circular dependency between freebl and softoken
(the callback), but it requires fewer changes to the softoken
and is more robust with respect to future changes to the softoken.
Another solution is to check for continuous RNG test failure
after every call to RNG_RandomUpdate or
RNG_GenerateGlobalRandomBytes in lib/softoken.
Reporter | ||
Comment 2•19 years ago
|
||
This patch implements the solution I outlined at the end of comment 1,
except that it doesn't check for continuous RNG test failure after calls
to RNG_RandomUpdate. The rationale is:
There are 106 RNG_RandomUpdate calls in lib/freebl and we don't check
any of their return values. Although RNG_RandomUpdate does perform
the continuous RNG test, it doesn't generate any output, and a
continuous RNG test failure during RNG_RandomUpdate will be detected
the next time we call RNG_GenerateGlobalRandomBytes. So it is safe
to not check for continuous RNG test failure after calls to
RNG_RandomUpdate (including calls to RNG_RNGInit and
RNG_SystemInfoForRNG, which call RNG_RandomUpdate).
I check for continuous RNG test failure after calls to the following
functions:
- RNG_GenerateGlobalRandomBytes
- DSA_GenerateGlobalRandomBytes (very similar to the above function)
and calls to freebl functions that call the above two functions:
- RSA_NewKey
- RSA_PrivateKeyOp (RNG used for RSA bliding)
- RSA_PrivateKeyOpDoubleChecked (RNG used for RSA bliding)
- DSA_NewKey
- DSA_SignDigest
- DH_GenParam
- DH_NewKey
- EC_NewKey
- ECDSA_SignDigest
- PQG_ParamGen
- PQG_ParamGenSeedLen
This list was generated using LXR. Code reviewers don't need to verify
this list is correct.
When the continuous RNG test fails, the error code is SEC_ERROR_LIBRARY_FAILURE.
To make it easier to put the FIPS token in the Error state from any source
file in lib/softoken, I made the variable 'fatalError' extern and renamed it
nsf_fatalError.
Attachment #230789 -
Flags: superreview?(nelson)
Attachment #230789 -
Flags: review?(rrelyea)
Reporter | ||
Comment 3•19 years ago
|
||
Comment on attachment 230789 [details] [diff] [review]
Solution 2: check for continuous RNG test failure after every call to RNG_GenerateGlobalRandomBytes call
I just realized that RNG_GenerateGlobalRandomBytes may
also fail with the error codes SEC_ERROR_INVALID_ARGS and
SEC_ERROR_NEED_RANDOM. I'm not checking the error code on
RNG_GenerateGlobalRandomBytes failure because existing code
in NSC_GenerateRandom isn't checking the error code. If
you think we should check for the error code SEC_ERROR_LIBRARY_FAILURE
on RNG_GenerateGlobalRandomBytes failure, please note it in
your code review comments.
Note that not checking for the error code still meets the
FIPS requirement. It just means we're putting the FIPS
token in the Error state under more conditions than required
by FIPS.
Reporter | ||
Updated•19 years ago
|
Severity: trivial → normal
Status: NEW → ASSIGNED
Priority: -- → P1
Target Milestone: --- → 3.11.5
Reporter | ||
Comment 4•19 years ago
|
||
Using LXR, you can verify that prng_GenerateGlobalRandomBytes is
only used inside the file lib/freebl/prng_fips1861.c. Therefore
it should be made static. This patch is intended for the NSS
trunk only.
Attachment #230792 -
Flags: review?(neil.williams)
Reporter | ||
Comment 5•19 years ago
|
||
I attached the wrong patch. Sorry. This is the correct patch.
Attachment #230792 -
Attachment is obsolete: true
Attachment #230794 -
Flags: review?(neil.williams)
Attachment #230792 -
Flags: review?(neil.williams)
Comment 6•19 years ago
|
||
Comment on attachment 230789 [details] [diff] [review]
Solution 2: check for continuous RNG test failure after every call to RNG_GenerateGlobalRandomBytes call
r+
I'd also like to see, however, RNG_GenerateGlobalRandomBytes return a new error code for failure of the random number generator and use that error code to determin when to set nsf_fatalerror.
bob
Attachment #230789 -
Flags: review?(rrelyea) → review+
Comment 7•19 years ago
|
||
Comment on attachment 230789 [details] [diff] [review]
Solution 2: check for continuous RNG test failure after every call to RNG_GenerateGlobalRandomBytes call
Questions and observation about this patch (not the final review):
1. what does nsf mean? National Science Foundation is the only expansion
of that abbreviation that I know.
2. IINM, By NSS convention, external names of the form
"prefix underscore suffix"
are reserved for function names. In particular, the underscore after the
prefix signifies being a function, so I'd rather not see this global variable
named with an underscore.
3. This is a global variable. Now, imagine that we have multiple virtual
softoken tokens, running concurrently in separate virtual slots, perhaps
some in FIPS mode and some not. An error in any one of them would disable
them all, all slots, FIPS or not. yes?
Do we need an array of these variables, one per slot?
Reporter | ||
Comment 8•19 years ago
|
||
The "f" in "nsf" means "FIPS". I believe "ns" means "Netscape".
The "nsf" prefix comes from the existing extern variable "nsf_init".
Note that I modeled the variable name "nsf_fatalError" after "nsf_init".
(There is a static variable named "nsc_init" for the non-FIPS token.)
I'll be happy to rename nsf_fatalError. Could you suggest a name?
fipsFatalError?
The FIPS token uses two global variables, fatalError and isLoggedIn,
that I agree should be per-slot. In fact, the SFTKSlot structure also
has an isLoggedIn field. I guess these are global variables
so that the FC_xxx functions can test them on entry to the functions.
If they are per-slot, the FC_xxx functions would need to decode the
slot ID or get the SFTKSlot structure from the session handle, which
would be redundant with what the NSC_xxx functions do. Here is an
example that illustrates this point:
CK_RV FC_EncryptInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
SFTK_FIPSCHECK();
return NSC_EncryptInit(hSession,pMechanism,hKey);
}
Ideally, SFTK_FIPSCHECK() should not need to decode hSession.
In the current design, we put all the FIPS tokens in the Error
state. Worse, the isLoggedIn variable applies to all the FIPS
token. I hope that we don't need to support more than one FIPS
token in NSS 3.11.x.
Comment 9•19 years ago
|
||
Comment on attachment 230794 [details] [diff] [review]
Correction: Make prng_GenerateGlobalRandomBytes static (for the NSS trunk only)
Review for this patch only. I read, but did not study, the previous patch.
Attachment #230794 -
Flags: review?(neil.williams) → review+
Reporter | ||
Comment 10•19 years ago
|
||
Comment on attachment 230794 [details] [diff] [review]
Correction: Make prng_GenerateGlobalRandomBytes static (for the NSS trunk only)
I checked in the patch to make prng_GenerateGlobalRandomBytes
static on the NSS trunk (NSS 3.12).
Checking in prng_fips1861.c;
/cvsroot/mozilla/security/nss/lib/freebl/prng_fips1861.c,v <-- prng_fips1861.c
new revision: 1.24; previous revision: 1.23
done
Comment 11•19 years ago
|
||
Comment on attachment 230789 [details] [diff] [review]
Solution 2: check for continuous RNG test failure after every call to RNG_GenerateGlobalRandomBytes call
Regarding comment 3:
I think we don't care why the PRNG failed. If the PRNG failed,
then the FIPS token is dead, regardless of the reason.
I think we should use as few prefixes as possible in each module of
NSS (where softoken is a module). So, rather than inventing YA new
one for two global variables, let's use sftk (with no underscore).
So, nsf_init -> sftkInit and
nsf_fataError-> sftkFatalError and
isLoggedIn -> sftkIsLoggedIn.
I think we can live with the idea that a PRNG failure will disable
all our slots.
IIRC, presently, when we are in "FIPS mode" we only have one slot,
not two (not a DB slot and a "generic crypto" slot).
AS LONG AS THAT REMAINS TRUE, I don't have a problem with a single
global variable sftkIsLoggedIn, PROVIDED that it is only used in FIPS
mode. But if we're using a single global variable that confuses the
logged in state of multiple slots, when we are operating with multiple
slots, THAT needs to be fixed ASAP, IMO.
So, r+, conditional upon the name changes shown above.
Attachment #230789 -
Flags: superreview?(nelson) → superreview+
Reporter | ||
Comment 12•19 years ago
|
||
In this patch I use the variable name sftk_fatalError and declare
it in a different header file, softoken.h. I didn't find any variable
name in lib/softoken of the form sftkFooBar. The command
"grep sftk * | grep -v _" showed that sftkFooBar is used for type names.
I checked in this patch on the NSS trunk (3.12) and NSS_3_11_BRANCH (3.11.3).
Attachment #230789 -
Attachment is obsolete: true
Reporter | ||
Updated•19 years ago
|
Status: ASSIGNED → RESOLVED
Closed: 19 years ago
Resolution: --- → FIXED
Target Milestone: 3.11.5 → 3.11.3
Reporter | ||
Comment 13•19 years ago
|
||
This patch makes a minor adjustment to the patch I just checked in.
In lib/softoken/pkcs11.c, we should set sftk_fatalError to PR_TRUE
only if RNG_GenerateGlobalRandomBytes fails.
Reporter | ||
Comment 14•19 years ago
|
||
Comment on attachment 231444 [details] [diff] [review]
Minor change
I forgot to say that I've checked in this patch on the NSS trunk (3.12)
and NSS_3_11_BRANCH (3.11.3).
You need to log in
before you can comment on or make changes to this bug.
Description
•