diff nss/lib/freebl/tlsprfalg.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nss/lib/freebl/tlsprfalg.c	Mon Jul 28 10:47:06 2014 +0200
@@ -0,0 +1,136 @@
+/* tlsprfalg.c - TLS Pseudo Random Function (PRF) implementation
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifdef FREEBL_NO_DEPEND
+#include "stubs.h"
+#endif
+
+#include "blapi.h"
+#include "hasht.h"
+#include "alghmac.h"
+
+
+#define PHASH_STATE_MAX_LEN HASH_LENGTH_MAX
+
+/* TLS P_hash function */
+SECStatus
+TLS_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 = HASH_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, sizeof(state));
+    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, sizeof(outbuf));
+	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, sizeof(state));
+	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, PR_TRUE);
+    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 = TLS_P_hash(HASH_AlgMD5, &S1, label, seed, result, isFIPS);
+    if (status != SECSuccess)
+	goto loser;
+
+    status = TLS_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;
+}
+
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)