comparison nss/lib/softoken/tlsprf.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 /* tlsprf.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 #include "pkcs11i.h"
8 #include "blapi.h"
9
10 #define SFTK_OFFSETOF(str, memb) ((PRPtrdiff)(&(((str *)0)->memb)))
11
12 static void sftk_TLSPRFNull(void *data, PRBool freeit)
13 {
14 return;
15 }
16
17 typedef struct {
18 PRUint32 cxSize; /* size of allocated block, in bytes. */
19 PRUint32 cxBufSize; /* sizeof buffer at cxBufPtr. */
20 unsigned char *cxBufPtr; /* points to real buffer, may be cxBuf. */
21 PRUint32 cxKeyLen; /* bytes of cxBufPtr containing key. */
22 PRUint32 cxDataLen; /* bytes of cxBufPtr containing data. */
23 SECStatus cxRv; /* records failure of void functions. */
24 PRBool cxIsFIPS; /* true if conforming to FIPS 198. */
25 HASH_HashType cxHashAlg; /* hash algorithm to use for TLS 1.2+ */
26 unsigned char cxBuf[512]; /* actual size may be larger than 512. */
27 } TLSPRFContext;
28
29 static void
30 sftk_TLSPRFHashUpdate(TLSPRFContext *cx, const unsigned char *data,
31 unsigned int data_len)
32 {
33 PRUint32 bytesUsed = cx->cxKeyLen + cx->cxDataLen;
34
35 if (cx->cxRv != SECSuccess) /* function has previously failed. */
36 return;
37 if (bytesUsed + data_len > cx->cxBufSize) {
38 /* We don't use realloc here because
39 ** (a) realloc doesn't zero out the old block, and
40 ** (b) if realloc fails, we lose the old block.
41 */
42 PRUint32 newBufSize = bytesUsed + data_len + 512;
43 unsigned char * newBuf = (unsigned char *)PORT_Alloc(newBufSize);
44 if (!newBuf) {
45 cx->cxRv = SECFailure;
46 return;
47 }
48 PORT_Memcpy(newBuf, cx->cxBufPtr, bytesUsed);
49 if (cx->cxBufPtr != cx->cxBuf) {
50 PORT_ZFree(cx->cxBufPtr, bytesUsed);
51 }
52 cx->cxBufPtr = newBuf;
53 cx->cxBufSize = newBufSize;
54 }
55 PORT_Memcpy(cx->cxBufPtr + bytesUsed, data, data_len);
56 cx->cxDataLen += data_len;
57 }
58
59 static void
60 sftk_TLSPRFEnd(TLSPRFContext *ctx, unsigned char *hashout,
61 unsigned int *pDigestLen, unsigned int maxDigestLen)
62 {
63 *pDigestLen = 0; /* tells Verify that no data has been input yet. */
64 }
65
66 /* Compute the PRF values from the data previously input. */
67 static SECStatus
68 sftk_TLSPRFUpdate(TLSPRFContext *cx,
69 unsigned char *sig, /* output goes here. */
70 unsigned int * sigLen, /* how much output. */
71 unsigned int maxLen, /* output buffer size */
72 unsigned char *hash, /* unused. */
73 unsigned int hashLen) /* unused. */
74 {
75 SECStatus rv;
76 SECItem sigItem;
77 SECItem seedItem;
78 SECItem secretItem;
79
80 if (cx->cxRv != SECSuccess)
81 return cx->cxRv;
82
83 secretItem.data = cx->cxBufPtr;
84 secretItem.len = cx->cxKeyLen;
85
86 seedItem.data = cx->cxBufPtr + cx->cxKeyLen;
87 seedItem.len = cx->cxDataLen;
88
89 sigItem.data = sig;
90 sigItem.len = maxLen;
91
92 if (cx->cxHashAlg != HASH_AlgNULL) {
93 rv = TLS_P_hash(cx->cxHashAlg, &secretItem, NULL, &seedItem, &sigItem,
94 cx->cxIsFIPS);
95 } else {
96 rv = TLS_PRF(&secretItem, NULL, &seedItem, &sigItem, cx->cxIsFIPS);
97 }
98 if (rv == SECSuccess && sigLen != NULL)
99 *sigLen = sigItem.len;
100 return rv;
101
102 }
103
104 static SECStatus
105 sftk_TLSPRFVerify(TLSPRFContext *cx,
106 unsigned char *sig, /* input, for comparison. */
107 unsigned int sigLen, /* length of sig. */
108 unsigned char *hash, /* data to be verified. */
109 unsigned int hashLen) /* size of hash data. */
110 {
111 unsigned char * tmp = (unsigned char *)PORT_Alloc(sigLen);
112 unsigned int tmpLen = sigLen;
113 SECStatus rv;
114
115 if (!tmp)
116 return SECFailure;
117 if (hashLen) {
118 /* hashLen is non-zero when the user does a one-step verify.
119 ** In this case, none of the data has been input yet.
120 */
121 sftk_TLSPRFHashUpdate(cx, hash, hashLen);
122 }
123 rv = sftk_TLSPRFUpdate(cx, tmp, &tmpLen, sigLen, NULL, 0);
124 if (rv == SECSuccess) {
125 rv = (SECStatus)(1 - !PORT_Memcmp(tmp, sig, sigLen));
126 }
127 PORT_ZFree(tmp, sigLen);
128 return rv;
129 }
130
131 static void
132 sftk_TLSPRFHashDestroy(TLSPRFContext *cx, PRBool freeit)
133 {
134 if (freeit) {
135 if (cx->cxBufPtr != cx->cxBuf)
136 PORT_ZFree(cx->cxBufPtr, cx->cxBufSize);
137 PORT_ZFree(cx, cx->cxSize);
138 }
139 }
140
141 CK_RV
142 sftk_TLSPRFInit(SFTKSessionContext *context,
143 SFTKObject * key,
144 CK_KEY_TYPE key_type,
145 HASH_HashType hash_alg)
146 {
147 SFTKAttribute * keyVal;
148 TLSPRFContext * prf_cx;
149 CK_RV crv = CKR_HOST_MEMORY;
150 PRUint32 keySize;
151 PRUint32 blockSize;
152
153 if (key_type != CKK_GENERIC_SECRET)
154 return CKR_KEY_TYPE_INCONSISTENT; /* CKR_KEY_FUNCTION_NOT_PERMITTED */
155
156 context->multi = PR_TRUE;
157
158 keyVal = sftk_FindAttribute(key, CKA_VALUE);
159 keySize = (!keyVal) ? 0 : keyVal->attrib.ulValueLen;
160 blockSize = keySize + sizeof(TLSPRFContext);
161 prf_cx = (TLSPRFContext *)PORT_Alloc(blockSize);
162 if (!prf_cx)
163 goto done;
164 prf_cx->cxSize = blockSize;
165 prf_cx->cxKeyLen = keySize;
166 prf_cx->cxDataLen = 0;
167 prf_cx->cxBufSize = blockSize - SFTK_OFFSETOF(TLSPRFContext, cxBuf);
168 prf_cx->cxRv = SECSuccess;
169 prf_cx->cxIsFIPS = (key->slot->slotID == FIPS_SLOT_ID);
170 prf_cx->cxBufPtr = prf_cx->cxBuf;
171 prf_cx->cxHashAlg = hash_alg;
172 if (keySize)
173 PORT_Memcpy(prf_cx->cxBufPtr, keyVal->attrib.pValue, keySize);
174
175 context->hashInfo = (void *) prf_cx;
176 context->cipherInfo = (void *) prf_cx;
177 context->hashUpdate = (SFTKHash) sftk_TLSPRFHashUpdate;
178 context->end = (SFTKEnd) sftk_TLSPRFEnd;
179 context->update = (SFTKCipher) sftk_TLSPRFUpdate;
180 context->verify = (SFTKVerify) sftk_TLSPRFVerify;
181 context->destroy = (SFTKDestroy) sftk_TLSPRFNull;
182 context->hashdestroy = (SFTKDestroy) sftk_TLSPRFHashDestroy;
183 crv = CKR_OK;
184
185 done:
186 if (keyVal)
187 sftk_FreeAttribute(keyVal);
188 return crv;
189 }
190
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)