Skip to content

Commit

Permalink
Bug 148220: implements FIPS 198 conformance. r=relyea.
Browse files Browse the repository at this point in the history
Modified Files: alghmac.c alghmac.h lowpbe.c pkcs11c.c
  • Loading branch information
wtc%netscape.com committed Aug 7, 2002
2 parents 0e05279 + f2fa0ca commit ab0b985
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 18 deletions.
9 changes: 8 additions & 1 deletion security/nss/lib/softoken/alghmac.c
Expand Up @@ -43,6 +43,7 @@ struct HMACContextStr {
const SECHashObject *hashobj;
unsigned char ipad[HMAC_PAD_SIZE];
unsigned char opad[HMAC_PAD_SIZE];
PRBool isFIPS;
};

void
Expand All @@ -58,12 +59,17 @@ HMAC_Destroy(HMACContext *cx)

HMACContext *
HMAC_Create(const SECHashObject *hash_obj, const unsigned char *secret,
unsigned int secret_len)
unsigned int secret_len, PRBool isFIPS)
{
HMACContext *cx;
int i;
unsigned char hashed_secret[SHA1_LENGTH];

/* required by FIPS 198 Section 3 */
if (isFIPS && secret_len < hash_obj->length/2) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
cx = (HMACContext*)PORT_ZAlloc(sizeof(HMACContext));
if (cx == NULL)
return NULL;
Expand Down Expand Up @@ -93,6 +99,7 @@ HMAC_Create(const SECHashObject *hash_obj, const unsigned char *secret,
cx->opad[i] ^= secret[i];
}
PORT_Memset(hashed_secret, 0, sizeof hashed_secret);
cx->isFIPS = isFIPS;
return cx;

loser:
Expand Down
3 changes: 2 additions & 1 deletion security/nss/lib/softoken/alghmac.h
Expand Up @@ -47,12 +47,13 @@ HMAC_Destroy(HMACContext *cx);
* should be, SEC_OID_MD5, SEC_OID_SHA1, or SEC_OID_MD2.
* secret the secret with which the HMAC is performed.
* secret_len the length of the secret.
* isFIPS true if conforming to FIPS 198.
*
* NULL is returned if an error occurs.
*/
extern HMACContext *
HMAC_Create(const SECHashObject *hashObj, const unsigned char *secret,
unsigned int secret_len);
unsigned int secret_len, PRBool isFIPS);

/* reset HMAC for a fresh round */
extern void
Expand Down
4 changes: 2 additions & 2 deletions security/nss/lib/softoken/lowpbe.c
Expand Up @@ -216,7 +216,7 @@ nsspkcs5_PFXPBE(const SECHashObject *hashObj, NSSPKCS5PBEParameter *pbe_param,
PORT_Memcpy(state, pbe_param->salt.data, pbe_param->salt.len);
}

cx = HMAC_Create(hashObj, init_hash->data, init_hash->len);
cx = HMAC_Create(hashObj, init_hash->data, init_hash->len, PR_TRUE);
if (cx == NULL) {
rv = SECFailure;
goto loser;
Expand Down Expand Up @@ -329,7 +329,7 @@ nsspkcs5_PBKFD2_F(const SECHashObject *hashobj, SECItem *pwitem, SECItem *salt,
unsigned char *last = NULL;
int lastLength = salt->len + 4;

cx=HMAC_Create(hashobj,pwitem->data,pwitem->len);
cx=HMAC_Create(hashobj,pwitem->data,pwitem->len,PR_TRUE);
if (cx == NULL) {
goto loser;
}
Expand Down
45 changes: 31 additions & 14 deletions security/nss/lib/softoken/pkcs11c.c
Expand Up @@ -64,7 +64,7 @@
#include "alghmac.h"
#include "softoken.h"
#include "secasn1.h"
/*#include "secmodi.h" */
#include "secerr.h"

#include "pcert.h"
#include "ssl3prot.h" /* for SSL3_RANDOM_LENGTH */
Expand All @@ -88,7 +88,7 @@

/* forward static declaration. */
static SECStatus pk11_PRF(const SECItem *secret, const char *label,
SECItem *seed, SECItem *result);
SECItem *seed, SECItem *result, PRBool isFIPS);

#define PK11_OFFSETOF(str, memb) ((PRPtrdiff)(&(((str *)0)->memb)))

Expand Down Expand Up @@ -1283,17 +1283,26 @@ pk11_doHMACInit(PK11SessionContext *context,HASH_HashType hash,
HMACContext *HMACcontext;
CK_ULONG *intpointer;
const SECHashObject *hashObj = &SECRawHashObjects[hash];
PRBool isFIPS = (key->slot->slotID == FIPS_SLOT_ID);

/* required by FIPS 198 Section 4 */
if (isFIPS && (mac_size < 4 || mac_size < hashObj->length/2)) {
return CKR_BUFFER_TOO_SMALL;
}

keyval = pk11_FindAttribute(key,CKA_VALUE);
if (keyval == NULL) return CKR_KEY_SIZE_RANGE;

HMACcontext = HMAC_Create(hashObj,
(const unsigned char*)keyval->attrib.pValue,
keyval->attrib.ulValueLen);
keyval->attrib.ulValueLen, isFIPS);
context->hashInfo = HMACcontext;
context->multi = PR_TRUE;
pk11_FreeAttribute(keyval);
if (context->hashInfo == NULL) {
if (PORT_GetError() == SEC_ERROR_INVALID_ARGS) {
return CKR_KEY_SIZE_RANGE;
}
return CKR_HOST_MEMORY;
}
context->hashUpdate = (PK11Hash) HMAC_Update;
Expand Down Expand Up @@ -1439,6 +1448,7 @@ typedef struct {
PRUint32 cxKeyLen; /* number of bytes of cxBuf containing key. */
PRUint32 cxDataLen; /* number of bytes of cxBuf containing data. */
SECStatus cxRv; /* records failure of void functions. */
PRBool cxIsFIPS; /* true if conforming to FIPS 198. */
unsigned char cxBuf[512]; /* actual size may be larger than 512. */
} TLSPRFContext;

Expand Down Expand Up @@ -1505,7 +1515,7 @@ pk11_TLSPRFUpdate(TLSPRFContext *cx,
sigItem.data = sig;
sigItem.len = maxLen;

rv = pk11_PRF(&secretItem, NULL, &seedItem, &sigItem);
rv = pk11_PRF(&secretItem, NULL, &seedItem, &sigItem, cx->cxIsFIPS);
if (rv == SECSuccess && sigLen != NULL)
*sigLen = sigItem.len;
return rv;
Expand Down Expand Up @@ -1572,6 +1582,7 @@ pk11_TLSPRFInit(PK11SessionContext *context,
prf_cx->cxKeyLen = keySize;
prf_cx->cxDataLen = 0;
prf_cx->cxRv = SECSuccess;
prf_cx->cxIsFIPS = (key->slot->slotID == FIPS_SLOT_ID);
if (keySize)
PORT_Memcpy(prf_cx->cxBuf, keyVal->attrib.pValue, keySize);

Expand Down Expand Up @@ -4124,7 +4135,7 @@ pk11_MapKeySize(CK_KEY_TYPE keyType) {
/* TLS P_hash function */
static SECStatus
pk11_P_hash(HASH_HashType hashType, const SECItem *secret, const char *label,
SECItem *seed, SECItem *result)
SECItem *seed, SECItem *result, PRBool isFIPS)
{
unsigned char state[PHASH_STATE_MAX_LEN];
unsigned char outbuf[PHASH_STATE_MAX_LEN];
Expand All @@ -4146,7 +4157,7 @@ pk11_P_hash(HASH_HashType hashType, const SECItem *secret, const char *label,
if (label != NULL)
label_len = PORT_Strlen(label);

cx = HMAC_Create(hashObj, secret->data, secret->len);
cx = HMAC_Create(hashObj, secret->data, secret->len, isFIPS);
if (cx == NULL)
goto loser;

Expand Down Expand Up @@ -4196,7 +4207,7 @@ pk11_P_hash(HASH_HashType hashType, const SECItem *secret, const char *label,

static SECStatus
pk11_PRF(const SECItem *secret, const char *label, SECItem *seed,
SECItem *result)
SECItem *result, PRBool isFIPS)
{
SECStatus rv = SECFailure, status;
unsigned int i;
Expand All @@ -4221,11 +4232,11 @@ pk11_PRF(const SECItem *secret, const char *label, SECItem *seed,
goto loser;
tmp.len = result->len;

status = pk11_P_hash(HASH_AlgMD5, &S1, label, seed, result);
status = pk11_P_hash(HASH_AlgMD5, &S1, label, seed, result, isFIPS);
if (status != SECSuccess)
goto loser;

status = pk11_P_hash(HASH_AlgSHA1, &S2, label, seed, &tmp);
status = pk11_P_hash(HASH_AlgSHA1, &S2, label, seed, &tmp, isFIPS);
if (status != SECSuccess)
goto loser;

Expand Down Expand Up @@ -4291,6 +4302,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
unsigned char sha_out[SHA1_LENGTH];
unsigned char key_block[NUM_MIXERS * MD5_LENGTH];
unsigned char key_block2[MD5_LENGTH];
PRBool isFIPS;

/*
* now lets create an object to hang the attributes off of
Expand All @@ -4301,6 +4313,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
if (key == NULL) {
return CKR_HOST_MEMORY;
}
isFIPS = (slot->slotID == FIPS_SLOT_ID);

/*
* load the template values into the object
Expand Down Expand Up @@ -4443,7 +4456,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH,
ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);

status = pk11_PRF(&pms, "master secret", &crsr, &master);
status = pk11_PRF(&pms, "master secret", &crsr, &master, isFIPS);
if (status != SECSuccess) {
crv = CKR_FUNCTION_FAILED;
break;
Expand Down Expand Up @@ -4574,7 +4587,8 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
ssl3_keys->RandomInfo.pClientRandom,
SSL3_RANDOM_LENGTH);

status = pk11_PRF(&master, "key expansion", &srcr, &keyblk);
status = pk11_PRF(&master, "key expansion", &srcr, &keyblk,
isFIPS);
if (status != SECSuccess) {
goto key_and_mac_derive_fail;
}
Expand Down Expand Up @@ -4774,7 +4788,8 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
i += effKeySize;
keyblk.data = key_block2;
keyblk.len = sizeof key_block2;
status = pk11_PRF(&secret, "client write key", &crsr, &keyblk);
status = pk11_PRF(&secret, "client write key", &crsr, &keyblk,
isFIPS);
if (status != SECSuccess) {
goto key_and_mac_derive_fail;
}
Expand All @@ -4795,7 +4810,8 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
i += effKeySize;
keyblk.data = key_block2;
keyblk.len = sizeof key_block2;
status = pk11_PRF(&secret, "server write key", &crsr, &keyblk);
status = pk11_PRF(&secret, "server write key", &crsr, &keyblk,
isFIPS);
if (status != SECSuccess) {
goto key_and_mac_derive_fail;
}
Expand All @@ -4816,7 +4832,8 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
secret.len = 0;
keyblk.data = &key_block[i];
keyblk.len = 2 * IVSize;
status = pk11_PRF(&secret, "IV block", &crsr, &keyblk);
status = pk11_PRF(&secret, "IV block", &crsr, &keyblk,
isFIPS);
if (status != SECSuccess) {
goto key_and_mac_derive_fail;
}
Expand Down

0 comments on commit ab0b985

Please sign in to comment.