Mercurial > trustbridge > nss-cmake-static
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 |