Mercurial > trustbridge > nss-cmake-static
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
1 /* tlsprfalg.c - TLS Pseudo Random Function (PRF) implementation | |
2 * | |
3 * This Source Code Form is subject to the terms of the Mozilla Public | |
4 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
6 | |
7 #ifdef FREEBL_NO_DEPEND | |
8 #include "stubs.h" | |
9 #endif | |
10 | |
11 #include "blapi.h" | |
12 #include "hasht.h" | |
13 #include "alghmac.h" | |
14 | |
15 | |
16 #define PHASH_STATE_MAX_LEN HASH_LENGTH_MAX | |
17 | |
18 /* TLS P_hash function */ | |
19 SECStatus | |
20 TLS_P_hash(HASH_HashType hashType, const SECItem *secret, const char *label, | |
21 SECItem *seed, SECItem *result, PRBool isFIPS) | |
22 { | |
23 unsigned char state[PHASH_STATE_MAX_LEN]; | |
24 unsigned char outbuf[PHASH_STATE_MAX_LEN]; | |
25 unsigned int state_len = 0, label_len = 0, outbuf_len = 0, chunk_size; | |
26 unsigned int remaining; | |
27 unsigned char *res; | |
28 SECStatus status; | |
29 HMACContext *cx; | |
30 SECStatus rv = SECFailure; | |
31 const SECHashObject *hashObj = HASH_GetRawHashObject(hashType); | |
32 | |
33 PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len)); | |
34 PORT_Assert((seed != NULL) && (seed->data != NULL)); | |
35 PORT_Assert((result != NULL) && (result->data != NULL)); | |
36 | |
37 remaining = result->len; | |
38 res = result->data; | |
39 | |
40 if (label != NULL) | |
41 label_len = PORT_Strlen(label); | |
42 | |
43 cx = HMAC_Create(hashObj, secret->data, secret->len, isFIPS); | |
44 if (cx == NULL) | |
45 goto loser; | |
46 | |
47 /* initialize the state = A(1) = HMAC_hash(secret, seed) */ | |
48 HMAC_Begin(cx); | |
49 HMAC_Update(cx, (unsigned char *)label, label_len); | |
50 HMAC_Update(cx, seed->data, seed->len); | |
51 status = HMAC_Finish(cx, state, &state_len, sizeof(state)); | |
52 if (status != SECSuccess) | |
53 goto loser; | |
54 | |
55 /* generate a block at a time until we're done */ | |
56 while (remaining > 0) { | |
57 | |
58 HMAC_Begin(cx); | |
59 HMAC_Update(cx, state, state_len); | |
60 if (label_len) | |
61 HMAC_Update(cx, (unsigned char *)label, label_len); | |
62 HMAC_Update(cx, seed->data, seed->len); | |
63 status = HMAC_Finish(cx, outbuf, &outbuf_len, sizeof(outbuf)); | |
64 if (status != SECSuccess) | |
65 goto loser; | |
66 | |
67 /* Update the state = A(i) = HMAC_hash(secret, A(i-1)) */ | |
68 HMAC_Begin(cx); | |
69 HMAC_Update(cx, state, state_len); | |
70 status = HMAC_Finish(cx, state, &state_len, sizeof(state)); | |
71 if (status != SECSuccess) | |
72 goto loser; | |
73 | |
74 chunk_size = PR_MIN(outbuf_len, remaining); | |
75 PORT_Memcpy(res, &outbuf, chunk_size); | |
76 res += chunk_size; | |
77 remaining -= chunk_size; | |
78 } | |
79 | |
80 rv = SECSuccess; | |
81 | |
82 loser: | |
83 /* clear out state so it's not left on the stack */ | |
84 if (cx) | |
85 HMAC_Destroy(cx, PR_TRUE); | |
86 PORT_Memset(state, 0, sizeof(state)); | |
87 PORT_Memset(outbuf, 0, sizeof(outbuf)); | |
88 return rv; | |
89 } | |
90 | |
91 SECStatus | |
92 TLS_PRF(const SECItem *secret, const char *label, SECItem *seed, | |
93 SECItem *result, PRBool isFIPS) | |
94 { | |
95 SECStatus rv = SECFailure, status; | |
96 unsigned int i; | |
97 SECItem tmp = { siBuffer, NULL, 0}; | |
98 SECItem S1; | |
99 SECItem S2; | |
100 | |
101 PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len)); | |
102 PORT_Assert((seed != NULL) && (seed->data != NULL)); | |
103 PORT_Assert((result != NULL) && (result->data != NULL)); | |
104 | |
105 S1.type = siBuffer; | |
106 S1.len = (secret->len / 2) + (secret->len & 1); | |
107 S1.data = secret->data; | |
108 | |
109 S2.type = siBuffer; | |
110 S2.len = S1.len; | |
111 S2.data = secret->data + (secret->len - S2.len); | |
112 | |
113 tmp.data = (unsigned char*)PORT_Alloc(result->len); | |
114 if (tmp.data == NULL) | |
115 goto loser; | |
116 tmp.len = result->len; | |
117 | |
118 status = TLS_P_hash(HASH_AlgMD5, &S1, label, seed, result, isFIPS); | |
119 if (status != SECSuccess) | |
120 goto loser; | |
121 | |
122 status = TLS_P_hash(HASH_AlgSHA1, &S2, label, seed, &tmp, isFIPS); | |
123 if (status != SECSuccess) | |
124 goto loser; | |
125 | |
126 for (i = 0; i < result->len; i++) | |
127 result->data[i] ^= tmp.data[i]; | |
128 | |
129 rv = SECSuccess; | |
130 | |
131 loser: | |
132 if (tmp.data != NULL) | |
133 PORT_ZFree(tmp.data, tmp.len); | |
134 return rv; | |
135 } | |
136 |