diff options
Diffstat (limited to 'security/nss/lib/softoken/tlsprf.c')
-rw-r--r-- | security/nss/lib/softoken/tlsprf.c | 334 |
1 files changed, 0 insertions, 334 deletions
diff --git a/security/nss/lib/softoken/tlsprf.c b/security/nss/lib/softoken/tlsprf.c deleted file mode 100644 index 9d1a6e677..000000000 --- a/security/nss/lib/softoken/tlsprf.c +++ /dev/null @@ -1,334 +0,0 @@ -/* tlsprf.c - TLS Pseudo Random Function (PRF) implementation - * - * 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 Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - * - * $Id$ - */ - -#include "pkcs11i.h" -#include "sechash.h" -#include "alghmac.h" - -#define PK11_OFFSETOF(str, memb) ((PRPtrdiff)(&(((str *)0)->memb))) - -#define PHASH_STATE_MAX_LEN 20 - -/* TLS P_hash function */ -static SECStatus -pk11_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 -pk11_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 = 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, 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 pk11_TLSPRFNull(void *data, PRBool freeit) -{ - return; -} - -typedef struct { - PRUint32 cxSize; /* size of allocated block, in bytes. */ - PRUint32 cxBufSize; /* sizeof buffer at cxBufPtr. */ - unsigned char *cxBufPtr; /* points to real buffer, may be cxBuf. */ - PRUint32 cxKeyLen; /* bytes of cxBufPtr containing key. */ - PRUint32 cxDataLen; /* bytes of cxBufPtr 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; - -static void -pk11_TLSPRFHashUpdate(TLSPRFContext *cx, const unsigned char *data, - unsigned int data_len) -{ - PRUint32 bytesUsed = cx->cxKeyLen + cx->cxDataLen; - - if (cx->cxRv != SECSuccess) /* function has previously failed. */ - return; - if (bytesUsed + data_len > cx->cxBufSize) { - /* We don't use realloc here because - ** (a) realloc doesn't zero out the old block, and - ** (b) if realloc fails, we lose the old block. - */ - PRUint32 newBufSize = bytesUsed + data_len + 512; - unsigned char * newBuf = (unsigned char *)PORT_Alloc(newBufSize); - if (!newBuf) { - cx->cxRv = SECFailure; - return; - } - PORT_Memcpy(newBuf, cx->cxBufPtr, bytesUsed); - if (cx->cxBufPtr != cx->cxBuf) { - PORT_ZFree(cx->cxBufPtr, bytesUsed); - } - cx->cxBufPtr = newBuf; - cx->cxBufSize = newBufSize; - } - PORT_Memcpy(cx->cxBufPtr + bytesUsed, data, data_len); - cx->cxDataLen += data_len; -} - -static void -pk11_TLSPRFEnd(TLSPRFContext *ctx, unsigned char *hashout, - unsigned int *pDigestLen, unsigned int maxDigestLen) -{ - *pDigestLen = 0; /* tells Verify that no data has been input yet. */ -} - -/* Compute the PRF values from the data previously input. */ -static SECStatus -pk11_TLSPRFUpdate(TLSPRFContext *cx, - unsigned char *sig, /* output goes here. */ - unsigned int * sigLen, /* how much output. */ - unsigned int maxLen, /* output buffer size */ - unsigned char *hash, /* unused. */ - unsigned int hashLen) /* unused. */ -{ - SECStatus rv; - SECItem sigItem; - SECItem seedItem; - SECItem secretItem; - - if (cx->cxRv != SECSuccess) - return cx->cxRv; - - secretItem.data = cx->cxBufPtr; - secretItem.len = cx->cxKeyLen; - - seedItem.data = cx->cxBufPtr + cx->cxKeyLen; - seedItem.len = cx->cxDataLen; - - sigItem.data = sig; - sigItem.len = maxLen; - - rv = pk11_PRF(&secretItem, NULL, &seedItem, &sigItem, cx->cxIsFIPS); - if (rv == SECSuccess && sigLen != NULL) - *sigLen = sigItem.len; - return rv; - -} - -static SECStatus -pk11_TLSPRFVerify(TLSPRFContext *cx, - unsigned char *sig, /* input, for comparison. */ - unsigned int sigLen, /* length of sig. */ - unsigned char *hash, /* data to be verified. */ - unsigned int hashLen) /* size of hash data. */ -{ - unsigned char * tmp = (unsigned char *)PORT_Alloc(sigLen); - unsigned int tmpLen = sigLen; - SECStatus rv; - - if (!tmp) - return SECFailure; - if (hashLen) { - /* hashLen is non-zero when the user does a one-step verify. - ** In this case, none of the data has been input yet. - */ - pk11_TLSPRFHashUpdate(cx, hash, hashLen); - } - rv = pk11_TLSPRFUpdate(cx, tmp, &tmpLen, sigLen, NULL, 0); - if (rv == SECSuccess) { - rv = (SECStatus)(1 - !PORT_Memcmp(tmp, sig, sigLen)); - } - PORT_ZFree(tmp, sigLen); - return rv; -} - -static void -pk11_TLSPRFHashDestroy(TLSPRFContext *cx, PRBool freeit) -{ - if (freeit) { - if (cx->cxBufPtr != cx->cxBuf) - PORT_ZFree(cx->cxBufPtr, cx->cxBufSize); - PORT_ZFree(cx, cx->cxSize); - } -} - -CK_RV -pk11_TLSPRFInit(PK11SessionContext *context, - PK11Object * key, - CK_KEY_TYPE key_type) -{ - PK11Attribute * keyVal; - TLSPRFContext * prf_cx; - CK_RV crv = CKR_HOST_MEMORY; - PRUint32 keySize; - PRUint32 blockSize; - - if (key_type != CKK_GENERIC_SECRET) - return CKR_KEY_TYPE_INCONSISTENT; /* CKR_KEY_FUNCTION_NOT_PERMITTED */ - - context->multi = PR_TRUE; - - keyVal = pk11_FindAttribute(key, CKA_VALUE); - keySize = (!keyVal) ? 0 : keyVal->attrib.ulValueLen; - blockSize = keySize + sizeof(TLSPRFContext); - prf_cx = (TLSPRFContext *)PORT_Alloc(blockSize); - if (!prf_cx) - goto done; - prf_cx->cxSize = blockSize; - prf_cx->cxKeyLen = keySize; - prf_cx->cxDataLen = 0; - prf_cx->cxBufSize = blockSize - PK11_OFFSETOF(TLSPRFContext, cxBuf); - prf_cx->cxRv = SECSuccess; - prf_cx->cxIsFIPS = (key->slot->slotID == FIPS_SLOT_ID); - prf_cx->cxBufPtr = prf_cx->cxBuf; - if (keySize) - PORT_Memcpy(prf_cx->cxBufPtr, keyVal->attrib.pValue, keySize); - - context->hashInfo = (void *) prf_cx; - context->cipherInfo = (void *) prf_cx; - context->hashUpdate = (PK11Hash) pk11_TLSPRFHashUpdate; - context->end = (PK11End) pk11_TLSPRFEnd; - context->update = (PK11Cipher) pk11_TLSPRFUpdate; - context->verify = (PK11Verify) pk11_TLSPRFVerify; - context->destroy = (PK11Destroy) pk11_TLSPRFNull; - context->hashdestroy = (PK11Destroy) pk11_TLSPRFHashDestroy; - crv = CKR_OK; - -done: - if (keyVal) - pk11_FreeAttribute(keyVal); - return crv; -} - |