mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Move the TLS Pseudo Random Function (PRF) and the HMAC algorithm from
softoken to freebl. Bug 303316. r=wtchang (with suggested changes) Modified Files: freebl/blapi.h freebl/ldvector.c freebl/loader.c freebl/loader.h freebl/manifest.mn softoken/lowpbe.c softoken/manifest.mn softoken/pkcs11c.c softoken/pkcs11i.h softoken/tlsprf.c Added Files: freebl/alghmac.c freebl/alghmac.h freebl/rawhash.c freebl/tlsprfalg.c Removed Files: softoken/alghmac.c softoken/alghmac.h softoken/rawhash.c
This commit is contained in:
parent
9a8510d59b
commit
1f607bc371
@ -37,13 +37,14 @@
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: blapi.h,v 1.19 2005/08/06 07:24:21 nelsonb%netscape.com Exp $ */
|
||||
/* $Id: blapi.h,v 1.20 2005/08/06 09:27:28 nelsonb%netscape.com Exp $ */
|
||||
|
||||
#ifndef _BLAPI_H_
|
||||
#define _BLAPI_H_
|
||||
|
||||
#include "blapit.h"
|
||||
|
||||
#include "hasht.h"
|
||||
#include "alghmac.h"
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
@ -939,6 +940,14 @@ extern SECStatus SHA384_Flatten(SHA384Context *cx,unsigned char *space);
|
||||
extern SHA384Context * SHA384_Resurrect(unsigned char *space, void *arg);
|
||||
extern void SHA384_Clone(SHA384Context *dest, SHA384Context *src);
|
||||
|
||||
/****************************************
|
||||
* implement TLS Pseudo Random Function (PRF)
|
||||
*/
|
||||
|
||||
extern SECStatus
|
||||
TLS_PRF(const SECItem *secret, const char *label, SECItem *seed,
|
||||
SECItem *result, PRBool isFIPS);
|
||||
|
||||
/******************************************/
|
||||
/*
|
||||
** Pseudo Random Number Generation. FIPS compliance desirable.
|
||||
@ -1044,6 +1053,9 @@ PRBool BLAPI_SHVerify(const char *name, PRFuncPtr addr);
|
||||
**************************************************************************/
|
||||
PRBool BLAPI_VerifySelf(const char *name);
|
||||
|
||||
/*********************************************************************/
|
||||
extern const SECHashObject * SEC_GetRawHashObject(HASH_HashType hashType);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* _BLAPI_H_ */
|
||||
|
@ -37,9 +37,10 @@
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: ldvector.c,v 1.9 2005/08/06 07:24:21 nelsonb%netscape.com Exp $ */
|
||||
/* $Id: ldvector.c,v 1.10 2005/08/06 09:27:28 nelsonb%netscape.com Exp $ */
|
||||
|
||||
#include "loader.h"
|
||||
#include "alghmac.h"
|
||||
|
||||
static const struct FREEBLVectorStr vector =
|
||||
{
|
||||
@ -207,6 +208,17 @@ static const struct FREEBLVectorStr vector =
|
||||
SHA384_Clone,
|
||||
SHA512_Clone,
|
||||
|
||||
TLS_PRF,
|
||||
SEC_GetRawHashObject,
|
||||
|
||||
HMAC_Destroy,
|
||||
HMAC_Create,
|
||||
HMAC_Init,
|
||||
HMAC_Begin,
|
||||
HMAC_Update,
|
||||
HMAC_Finish,
|
||||
HMAC_Clone,
|
||||
|
||||
/* End of Version 3.008. */
|
||||
};
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: loader.c,v 1.19 2005/08/06 07:24:21 nelsonb%netscape.com Exp $ */
|
||||
/* $Id: loader.c,v 1.20 2005/08/06 09:27:28 nelsonb%netscape.com Exp $ */
|
||||
|
||||
#include "loader.h"
|
||||
#include "prmem.h"
|
||||
@ -1489,3 +1489,81 @@ SHA512_Clone(SHA512Context *dest, SHA512Context *src)
|
||||
return;
|
||||
(vector->p_SHA512_Clone)(dest, src);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
TLS_PRF(const SECItem *secret, const char *label,
|
||||
SECItem *seed, SECItem *result, PRBool isFIPS)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
return (vector->p_TLS_PRF)(secret, label, seed, result, isFIPS);
|
||||
}
|
||||
|
||||
const SECHashObject *
|
||||
SEC_GetRawHashObject(HASH_HashType hashType)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return NULL;
|
||||
return (vector->p_SEC_GetRawHashObject)(hashType);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HMAC_Destroy(HMACContext *cx)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return;
|
||||
(vector->p_HMAC_Destroy)(cx);
|
||||
}
|
||||
|
||||
HMACContext *
|
||||
HMAC_Create(const SECHashObject *hashObj, const unsigned char *secret,
|
||||
unsigned int secret_len, PRBool isFIPS)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return NULL;
|
||||
return (vector->p_HMAC_Create)(hashObj, secret, secret_len, isFIPS);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
HMAC_Init(HMACContext *cx, const SECHashObject *hashObj,
|
||||
const unsigned char *secret, unsigned int secret_len, PRBool isFIPS)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return NULL;
|
||||
return (vector->p_HMAC_Init)(cx, hashObj, secret, secret_len, isFIPS);
|
||||
}
|
||||
|
||||
void
|
||||
HMAC_Begin(HMACContext *cx)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return;
|
||||
(vector->p_HMAC_Begin)(cx);
|
||||
}
|
||||
|
||||
void
|
||||
HMAC_Update(HMACContext *cx, const unsigned char *data, unsigned int data_len)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return;
|
||||
(vector->p_HMAC_Update)(cx, data, data_len);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
HMAC_Finish(HMACContext *cx, unsigned char *result, unsigned int *result_len,
|
||||
unsigned int max_result_len)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
return (vector->p_HMAC_Finish)(cx, result, result_len, max_result_len);
|
||||
}
|
||||
|
||||
HMACContext *
|
||||
HMAC_Clone(HMACContext *cx)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return NULL;
|
||||
return (vector->p_HMAC_Clone)(cx);
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: loader.h,v 1.13 2005/08/06 07:24:21 nelsonb%netscape.com Exp $ */
|
||||
/* $Id: loader.h,v 1.14 2005/08/06 09:27:28 nelsonb%netscape.com Exp $ */
|
||||
|
||||
#ifndef _LOADER_H_
|
||||
#define _LOADER_H_ 1
|
||||
@ -426,6 +426,26 @@ struct FREEBLVectorStr {
|
||||
void (* p_SHA384_Clone)(SHA384Context *dest, SHA384Context *src);
|
||||
void (* p_SHA512_Clone)(SHA512Context *dest, SHA512Context *src);
|
||||
|
||||
SECStatus (* p_TLS_PRF)(const SECItem *secret, const char *label,
|
||||
SECItem *seed, SECItem *result, PRBool isFIPS);
|
||||
|
||||
const SECHashObject *(* p_SEC_GetRawHashObject)(HASH_HashType hashType);
|
||||
|
||||
void (* p_HMAC_Destroy)(HMACContext *cx);
|
||||
HMACContext * (* p_HMAC_Create)(const SECHashObject *hashObj,
|
||||
const unsigned char *secret,
|
||||
unsigned int secret_len, PRBool isFIPS);
|
||||
SECStatus (* p_HMAC_Init)(HMACContext *cx, const SECHashObject *hash_obj,
|
||||
const unsigned char *secret,
|
||||
unsigned int secret_len, PRBool isFIPS);
|
||||
void (* p_HMAC_Begin)(HMACContext *cx);
|
||||
void (* p_HMAC_Update)(HMACContext *cx, const unsigned char *data,
|
||||
unsigned int data_len);
|
||||
SECStatus (* p_HMAC_Finish)(HMACContext *cx, unsigned char *result,
|
||||
unsigned int *result_len,
|
||||
unsigned int max_result_len);
|
||||
HMACContext * (* p_HMAC_Clone)(HMACContext *cx);
|
||||
|
||||
/* Version 3.008 came to here */
|
||||
};
|
||||
|
||||
|
@ -21,8 +21,7 @@
|
||||
#
|
||||
# Contributor(s):
|
||||
# Dr Vipul Gupta <vipul.gupta@sun.com> and
|
||||
# Douglas Stebila <douglas@stebila.ca>, Sun Microsystems
|
||||
# Laboratories
|
||||
# Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -66,6 +65,7 @@ EXPORTS = \
|
||||
$(NULL)
|
||||
|
||||
PRIVATE_EXPORTS = \
|
||||
alghmac.h \
|
||||
blapi.h \
|
||||
secmpi.h \
|
||||
secrng.h \
|
||||
@ -96,6 +96,8 @@ CSRCS = \
|
||||
md2.c \
|
||||
md5.c \
|
||||
sha512.c \
|
||||
alghmac.c \
|
||||
rawhash.c \
|
||||
alg2268.c \
|
||||
arcfour.c \
|
||||
arcfive.c \
|
||||
@ -109,6 +111,7 @@ CSRCS = \
|
||||
dsa.c \
|
||||
rsa.c \
|
||||
shvfy.c \
|
||||
tlsprfalg.c \
|
||||
$(MPI_SRCS) \
|
||||
$(ECL_SRCS) \
|
||||
$(NULL)
|
||||
@ -116,6 +119,7 @@ CSRCS = \
|
||||
ALL_CSRCS := $(CSRCS)
|
||||
|
||||
ALL_HDRS = \
|
||||
alghmac.h \
|
||||
blapi.h \
|
||||
blapit.h \
|
||||
des.h \
|
||||
|
163
security/nss/lib/freebl/tlsprfalg.c
Normal file
163
security/nss/lib/freebl/tlsprfalg.c
Normal file
@ -0,0 +1,163 @@
|
||||
/* tlsprfalg.c - TLS Pseudo Random Function (PRF) implementation
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: tlsprfalg.c,v 1.2 2005/08/06 09:27:28 nelsonb%netscape.com Exp $ */
|
||||
|
||||
#include "sechash.h"
|
||||
#include "alghmac.h"
|
||||
#include "blapi.h"
|
||||
|
||||
#define PHASH_STATE_MAX_LEN 20
|
||||
|
||||
/* TLS P_hash function */
|
||||
static SECStatus
|
||||
sftk_P_hash(HASH_HashType hashType, const SECItem *secret, const char *label,
|
||||
SECItem *seed, SECItem *result, PRBool isFIPS)
|
||||
{
|
||||
unsigned char state[PHASH_STATE_MAX_LEN];
|
||||
unsigned char outbuf[PHASH_STATE_MAX_LEN];
|
||||
unsigned int state_len = 0, label_len = 0, outbuf_len = 0, chunk_size;
|
||||
unsigned int remaining;
|
||||
unsigned char *res;
|
||||
SECStatus status;
|
||||
HMACContext *cx;
|
||||
SECStatus rv = SECFailure;
|
||||
const SECHashObject *hashObj = SEC_GetRawHashObject(hashType);
|
||||
|
||||
PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
|
||||
PORT_Assert((seed != NULL) && (seed->data != NULL));
|
||||
PORT_Assert((result != NULL) && (result->data != NULL));
|
||||
|
||||
remaining = result->len;
|
||||
res = result->data;
|
||||
|
||||
if (label != NULL)
|
||||
label_len = PORT_Strlen(label);
|
||||
|
||||
cx = HMAC_Create(hashObj, secret->data, secret->len, isFIPS);
|
||||
if (cx == NULL)
|
||||
goto loser;
|
||||
|
||||
/* initialize the state = A(1) = HMAC_hash(secret, seed) */
|
||||
HMAC_Begin(cx);
|
||||
HMAC_Update(cx, (unsigned char *)label, label_len);
|
||||
HMAC_Update(cx, seed->data, seed->len);
|
||||
status = HMAC_Finish(cx, state, &state_len, PHASH_STATE_MAX_LEN);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
/* generate a block at a time until we're done */
|
||||
while (remaining > 0) {
|
||||
|
||||
HMAC_Begin(cx);
|
||||
HMAC_Update(cx, state, state_len);
|
||||
if (label_len)
|
||||
HMAC_Update(cx, (unsigned char *)label, label_len);
|
||||
HMAC_Update(cx, seed->data, seed->len);
|
||||
status = HMAC_Finish(cx, outbuf, &outbuf_len, PHASH_STATE_MAX_LEN);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
/* Update the state = A(i) = HMAC_hash(secret, A(i-1)) */
|
||||
HMAC_Begin(cx);
|
||||
HMAC_Update(cx, state, state_len);
|
||||
status = HMAC_Finish(cx, state, &state_len, PHASH_STATE_MAX_LEN);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
chunk_size = PR_MIN(outbuf_len, remaining);
|
||||
PORT_Memcpy(res, &outbuf, chunk_size);
|
||||
res += chunk_size;
|
||||
remaining -= chunk_size;
|
||||
}
|
||||
|
||||
rv = SECSuccess;
|
||||
|
||||
loser:
|
||||
/* clear out state so it's not left on the stack */
|
||||
if (cx) HMAC_Destroy(cx);
|
||||
PORT_Memset(state, 0, sizeof(state));
|
||||
PORT_Memset(outbuf, 0, sizeof(outbuf));
|
||||
return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
TLS_PRF(const SECItem *secret, const char *label, SECItem *seed,
|
||||
SECItem *result, PRBool isFIPS)
|
||||
{
|
||||
SECStatus rv = SECFailure, status;
|
||||
unsigned int i;
|
||||
SECItem tmp = { siBuffer, NULL, 0};
|
||||
SECItem S1;
|
||||
SECItem S2;
|
||||
|
||||
PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
|
||||
PORT_Assert((seed != NULL) && (seed->data != NULL));
|
||||
PORT_Assert((result != NULL) && (result->data != NULL));
|
||||
|
||||
S1.type = siBuffer;
|
||||
S1.len = (secret->len / 2) + (secret->len & 1);
|
||||
S1.data = secret->data;
|
||||
|
||||
S2.type = siBuffer;
|
||||
S2.len = S1.len;
|
||||
S2.data = secret->data + (secret->len - S2.len);
|
||||
|
||||
tmp.data = (unsigned char*)PORT_Alloc(result->len);
|
||||
if (tmp.data == NULL)
|
||||
goto loser;
|
||||
tmp.len = result->len;
|
||||
|
||||
status = sftk_P_hash(HASH_AlgMD5, &S1, label, seed, result, isFIPS);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
status = sftk_P_hash(HASH_AlgSHA1, &S2, label, seed, &tmp, isFIPS);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
for (i = 0; i < result->len; i++)
|
||||
result->data[i] ^= tmp.data[i];
|
||||
|
||||
rv = SECSuccess;
|
||||
|
||||
loser:
|
||||
if (tmp.data != NULL)
|
||||
PORT_ZFree(tmp.data, tmp.len);
|
||||
return rv;
|
||||
}
|
||||
|
@ -587,7 +587,7 @@ nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
|
||||
iv->len = pbe_param->ivLen;
|
||||
}
|
||||
|
||||
hashObj = &SECRawHashObjects[pbe_param->hashType];
|
||||
hashObj = SEC_GetRawHashObject(pbe_param->hashType);
|
||||
switch (pbe_param->pbeType) {
|
||||
case NSSPKCS5_PBKDF1:
|
||||
hash = nsspkcs5_PBKDF1Extended(hashObj,pbe_param,pwitem,faulty3DES);
|
||||
|
@ -61,7 +61,6 @@ PRIVATE_EXPORTS = \
|
||||
$(NULL)
|
||||
|
||||
CSRCS = \
|
||||
alghmac.c \
|
||||
dbinit.c \
|
||||
dbmshim.c \
|
||||
ecdecode.c \
|
||||
@ -77,7 +76,6 @@ CSRCS = \
|
||||
pkcs11.c \
|
||||
pkcs11c.c \
|
||||
pkcs11u.c \
|
||||
rawhash.c \
|
||||
rsawrapr.c \
|
||||
softkver.c \
|
||||
tlsprf.c \
|
||||
|
@ -1266,7 +1266,7 @@ sftk_doHMACInit(SFTKSessionContext *context,HASH_HashType hash,
|
||||
SFTKAttribute *keyval;
|
||||
HMACContext *HMACcontext;
|
||||
CK_ULONG *intpointer;
|
||||
const SECHashObject *hashObj = &SECRawHashObjects[hash];
|
||||
const SECHashObject *hashObj = SEC_GetRawHashObject(hash);
|
||||
PRBool isFIPS = (key->slot->slotID == FIPS_SLOT_ID);
|
||||
|
||||
/* required by FIPS 198 Section 4 */
|
||||
@ -4705,7 +4705,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
|
||||
PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH,
|
||||
ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);
|
||||
|
||||
status = sftk_PRF(&pms, "master secret", &crsr, &master, isFIPS);
|
||||
status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS);
|
||||
if (status != SECSuccess) {
|
||||
crv = CKR_FUNCTION_FAILED;
|
||||
break;
|
||||
@ -4836,7 +4836,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
|
||||
ssl3_keys->RandomInfo.pClientRandom,
|
||||
SSL3_RANDOM_LENGTH);
|
||||
|
||||
status = sftk_PRF(&master, "key expansion", &srcr, &keyblk,
|
||||
status = TLS_PRF(&master, "key expansion", &srcr, &keyblk,
|
||||
isFIPS);
|
||||
if (status != SECSuccess) {
|
||||
goto key_and_mac_derive_fail;
|
||||
@ -5043,7 +5043,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
|
||||
i += effKeySize;
|
||||
keyblk.data = key_block2;
|
||||
keyblk.len = sizeof key_block2;
|
||||
status = sftk_PRF(&secret, "client write key", &crsr, &keyblk,
|
||||
status = TLS_PRF(&secret, "client write key", &crsr, &keyblk,
|
||||
isFIPS);
|
||||
if (status != SECSuccess) {
|
||||
goto key_and_mac_derive_fail;
|
||||
@ -5065,7 +5065,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
|
||||
i += effKeySize;
|
||||
keyblk.data = key_block2;
|
||||
keyblk.len = sizeof key_block2;
|
||||
status = sftk_PRF(&secret, "server write key", &crsr, &keyblk,
|
||||
status = TLS_PRF(&secret, "server write key", &crsr, &keyblk,
|
||||
isFIPS);
|
||||
if (status != SECSuccess) {
|
||||
goto key_and_mac_derive_fail;
|
||||
@ -5087,7 +5087,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
|
||||
secret.len = 0;
|
||||
keyblk.data = &key_block[i];
|
||||
keyblk.len = 2 * IVSize;
|
||||
status = sftk_PRF(&secret, "IV block", &crsr, &keyblk,
|
||||
status = TLS_PRF(&secret, "IV block", &crsr, &keyblk,
|
||||
isFIPS);
|
||||
if (status != SECSuccess) {
|
||||
goto key_and_mac_derive_fail;
|
||||
|
@ -683,10 +683,6 @@ SFTKTokenObject *sftk_convertSessionToToken(SFTKObject *so);
|
||||
* implement TLS Pseudo Random Function (PRF)
|
||||
*/
|
||||
|
||||
extern SECStatus
|
||||
sftk_PRF(const SECItem *secret, const char *label, SECItem *seed,
|
||||
SECItem *result, PRBool isFIPS);
|
||||
|
||||
extern CK_RV
|
||||
sftk_TLSPRFInit(SFTKSessionContext *context,
|
||||
SFTKObject * key,
|
||||
|
@ -35,135 +35,13 @@
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: tlsprf.c,v 1.5 2005/03/29 18:21:18 nelsonb%netscape.com Exp $ */
|
||||
/* $Id: tlsprf.c,v 1.6 2005/08/06 09:27:28 nelsonb%netscape.com Exp $ */
|
||||
|
||||
#include "pkcs11i.h"
|
||||
#include "sechash.h"
|
||||
#include "alghmac.h"
|
||||
#include "blapi.h"
|
||||
|
||||
#define SFTK_OFFSETOF(str, memb) ((PRPtrdiff)(&(((str *)0)->memb)))
|
||||
|
||||
#define PHASH_STATE_MAX_LEN 20
|
||||
|
||||
/* TLS P_hash function */
|
||||
static SECStatus
|
||||
sftk_P_hash(HASH_HashType hashType, const SECItem *secret, const char *label,
|
||||
SECItem *seed, SECItem *result, PRBool isFIPS)
|
||||
{
|
||||
unsigned char state[PHASH_STATE_MAX_LEN];
|
||||
unsigned char outbuf[PHASH_STATE_MAX_LEN];
|
||||
unsigned int state_len = 0, label_len = 0, outbuf_len = 0, chunk_size;
|
||||
unsigned int remaining;
|
||||
unsigned char *res;
|
||||
SECStatus status;
|
||||
HMACContext *cx;
|
||||
SECStatus rv = SECFailure;
|
||||
const SECHashObject *hashObj = &SECRawHashObjects[hashType];
|
||||
|
||||
PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
|
||||
PORT_Assert((seed != NULL) && (seed->data != NULL));
|
||||
PORT_Assert((result != NULL) && (result->data != NULL));
|
||||
|
||||
remaining = result->len;
|
||||
res = result->data;
|
||||
|
||||
if (label != NULL)
|
||||
label_len = PORT_Strlen(label);
|
||||
|
||||
cx = HMAC_Create(hashObj, secret->data, secret->len, isFIPS);
|
||||
if (cx == NULL)
|
||||
goto loser;
|
||||
|
||||
/* initialize the state = A(1) = HMAC_hash(secret, seed) */
|
||||
HMAC_Begin(cx);
|
||||
HMAC_Update(cx, (unsigned char *)label, label_len);
|
||||
HMAC_Update(cx, seed->data, seed->len);
|
||||
status = HMAC_Finish(cx, state, &state_len, PHASH_STATE_MAX_LEN);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
/* generate a block at a time until we're done */
|
||||
while (remaining > 0) {
|
||||
|
||||
HMAC_Begin(cx);
|
||||
HMAC_Update(cx, state, state_len);
|
||||
if (label_len)
|
||||
HMAC_Update(cx, (unsigned char *)label, label_len);
|
||||
HMAC_Update(cx, seed->data, seed->len);
|
||||
status = HMAC_Finish(cx, outbuf, &outbuf_len, PHASH_STATE_MAX_LEN);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
/* Update the state = A(i) = HMAC_hash(secret, A(i-1)) */
|
||||
HMAC_Begin(cx);
|
||||
HMAC_Update(cx, state, state_len);
|
||||
status = HMAC_Finish(cx, state, &state_len, PHASH_STATE_MAX_LEN);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
chunk_size = PR_MIN(outbuf_len, remaining);
|
||||
PORT_Memcpy(res, &outbuf, chunk_size);
|
||||
res += chunk_size;
|
||||
remaining -= chunk_size;
|
||||
}
|
||||
|
||||
rv = SECSuccess;
|
||||
|
||||
loser:
|
||||
/* if (cx) HMAC_Destroy(cx); */
|
||||
/* clear out state so it's not left on the stack */
|
||||
if (cx) HMAC_Destroy(cx);
|
||||
PORT_Memset(state, 0, sizeof(state));
|
||||
PORT_Memset(outbuf, 0, sizeof(outbuf));
|
||||
return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
sftk_PRF(const SECItem *secret, const char *label, SECItem *seed,
|
||||
SECItem *result, PRBool isFIPS)
|
||||
{
|
||||
SECStatus rv = SECFailure, status;
|
||||
unsigned int i;
|
||||
SECItem tmp = { siBuffer, NULL, 0};
|
||||
SECItem S1;
|
||||
SECItem S2;
|
||||
|
||||
PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
|
||||
PORT_Assert((seed != NULL) && (seed->data != NULL));
|
||||
PORT_Assert((result != NULL) && (result->data != NULL));
|
||||
|
||||
S1.type = siBuffer;
|
||||
S1.len = (secret->len / 2) + (secret->len & 1);
|
||||
S1.data = secret->data;
|
||||
|
||||
S2.type = siBuffer;
|
||||
S2.len = S1.len;
|
||||
S2.data = secret->data + (secret->len - S2.len);
|
||||
|
||||
tmp.data = (unsigned char*)PORT_Alloc(result->len);
|
||||
if (tmp.data == NULL)
|
||||
goto loser;
|
||||
tmp.len = result->len;
|
||||
|
||||
status = sftk_P_hash(HASH_AlgMD5, &S1, label, seed, result, isFIPS);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
status = sftk_P_hash(HASH_AlgSHA1, &S2, label, seed, &tmp, isFIPS);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
for (i = 0; i < result->len; i++)
|
||||
result->data[i] ^= tmp.data[i];
|
||||
|
||||
rv = SECSuccess;
|
||||
|
||||
loser:
|
||||
if (tmp.data != NULL)
|
||||
PORT_ZFree(tmp.data, tmp.len);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void sftk_TLSPRFNull(void *data, PRBool freeit)
|
||||
{
|
||||
return;
|
||||
@ -243,7 +121,7 @@ sftk_TLSPRFUpdate(TLSPRFContext *cx,
|
||||
sigItem.data = sig;
|
||||
sigItem.len = maxLen;
|
||||
|
||||
rv = sftk_PRF(&secretItem, NULL, &seedItem, &sigItem, cx->cxIsFIPS);
|
||||
rv = TLS_PRF(&secretItem, NULL, &seedItem, &sigItem, cx->cxIsFIPS);
|
||||
if (rv == SECSuccess && sigLen != NULL)
|
||||
*sigLen = sigItem.len;
|
||||
return rv;
|
||||
|
Loading…
Reference in New Issue
Block a user