File: | s/lib/ssl/sslprimitive.c |
Warning: | line 70, column 5 Null pointer passed to 2nd parameter expecting 'nonnull' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | |||
2 | /* | |||
3 | * SSL Primitives: Public HKDF and AEAD Functions | |||
4 | * | |||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | |||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | |||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |||
8 | ||||
9 | #include "blapit.h" | |||
10 | #include "keyhi.h" | |||
11 | #include "pk11pub.h" | |||
12 | #include "sechash.h" | |||
13 | #include "ssl.h" | |||
14 | #include "sslexp.h" | |||
15 | #include "sslerr.h" | |||
16 | #include "sslproto.h" | |||
17 | ||||
18 | #include "sslimpl.h" | |||
19 | #include "tls13con.h" | |||
20 | #include "tls13hkdf.h" | |||
21 | ||||
22 | struct SSLAeadContextStr { | |||
23 | /* sigh, the API creates a single context, but then uses either encrypt | |||
24 | * and decrypt on that context. We should take an encrypt/decrypt | |||
25 | * variable here, but for now create two contexts. */ | |||
26 | PK11Context *encryptContext; | |||
27 | PK11Context *decryptContext; | |||
28 | int tagLen; | |||
29 | int ivLen; | |||
30 | unsigned char iv[MAX_IV_LENGTH24]; | |||
31 | }; | |||
32 | ||||
33 | SECStatus | |||
34 | SSLExp_MakeVariantAead(PRUint16 version, PRUint16 cipherSuite, SSLProtocolVariant variant, | |||
35 | PK11SymKey *secret, const char *labelPrefix, | |||
36 | unsigned int labelPrefixLen, SSLAeadContext **ctx) | |||
37 | { | |||
38 | SSLAeadContext *out = NULL((void*)0); | |||
39 | char label[255]; // Maximum length label. | |||
40 | static const char *const keySuffix = "key"; | |||
41 | static const char *const ivSuffix = "iv"; | |||
42 | CK_MECHANISM_TYPE mech; | |||
43 | SECItem nullParams = { siBuffer, NULL((void*)0), 0 }; | |||
44 | PK11SymKey *key = NULL((void*)0); | |||
45 | ||||
46 | PORT_Assert(strlen(keySuffix) >= strlen(ivSuffix))((strlen(keySuffix) >= strlen(ivSuffix))?((void)0):PR_Assert ("strlen(keySuffix) >= strlen(ivSuffix)","sslprimitive.c", 46)); | |||
47 | if (secret == NULL((void*)0) || ctx == NULL((void*)0) || | |||
48 | (labelPrefix == NULL((void*)0) && labelPrefixLen > 0) || | |||
49 | labelPrefixLen + strlen(keySuffix) > sizeof(label)) { | |||
50 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); | |||
51 | goto loser; | |||
52 | } | |||
53 | ||||
54 | SSLHashType hash; | |||
55 | const ssl3BulkCipherDef *cipher; | |||
56 | SECStatus rv = tls13_GetHashAndCipher(version, cipherSuite, | |||
57 | &hash, &cipher); | |||
58 | if (rv != SECSuccess) { | |||
59 | goto loser; /* Code already set. */ | |||
60 | } | |||
61 | ||||
62 | out = PORT_ZNew(SSLAeadContext)(SSLAeadContext *)PORT_ZAlloc_Util(sizeof(SSLAeadContext)); | |||
63 | if (out == NULL((void*)0)) { | |||
64 | goto loser; | |||
65 | } | |||
66 | mech = ssl3_Alg2Mech(cipher->calg); | |||
67 | out->ivLen = cipher->iv_size + cipher->explicit_nonce_size; | |||
68 | out->tagLen = cipher->tag_size; | |||
69 | ||||
70 | memcpy(label, labelPrefix, labelPrefixLen); | |||
| ||||
71 | memcpy(label + labelPrefixLen, ivSuffix, strlen(ivSuffix)); | |||
72 | unsigned int labelLen = labelPrefixLen + strlen(ivSuffix); | |||
73 | unsigned int ivLen = cipher->iv_size + cipher->explicit_nonce_size; | |||
74 | rv = tls13_HkdfExpandLabelRaw(secret, hash, | |||
75 | NULL((void*)0), 0, // Handshake hash. | |||
76 | label, labelLen, variant, | |||
77 | out->iv, ivLen); | |||
78 | if (rv != SECSuccess) { | |||
79 | goto loser; | |||
80 | } | |||
81 | ||||
82 | memcpy(label + labelPrefixLen, keySuffix, strlen(keySuffix)); | |||
83 | labelLen = labelPrefixLen + strlen(keySuffix); | |||
84 | rv = tls13_HkdfExpandLabel(secret, hash, | |||
85 | NULL((void*)0), 0, // Handshake hash. | |||
86 | label, labelLen, mech, cipher->key_size, | |||
87 | variant, &key); | |||
88 | if (rv != SECSuccess) { | |||
89 | goto loser; | |||
90 | } | |||
91 | ||||
92 | /* We really need to change the API to Create a context for each | |||
93 | * encrypt and decrypt rather than a single call that does both. it's | |||
94 | * almost certain that the underlying application tries to use the same | |||
95 | * context for both. */ | |||
96 | out->encryptContext = PK11_CreateContextBySymKey(mech, | |||
97 | CKA_NSS_MESSAGE0x82000000L | CKA_ENCRYPT0x00000104UL, | |||
98 | key, &nullParams); | |||
99 | if (out->encryptContext == NULL((void*)0)) { | |||
100 | goto loser; | |||
101 | } | |||
102 | ||||
103 | out->decryptContext = PK11_CreateContextBySymKey(mech, | |||
104 | CKA_NSS_MESSAGE0x82000000L | CKA_DECRYPT0x00000105UL, | |||
105 | key, &nullParams); | |||
106 | if (out->decryptContext == NULL((void*)0)) { | |||
107 | goto loser; | |||
108 | } | |||
109 | ||||
110 | PK11_FreeSymKey(key); | |||
111 | *ctx = out; | |||
112 | return SECSuccess; | |||
113 | ||||
114 | loser: | |||
115 | PK11_FreeSymKey(key); | |||
116 | SSLExp_DestroyAead(out); | |||
117 | return SECFailure; | |||
118 | } | |||
119 | ||||
120 | SECStatus | |||
121 | SSLExp_MakeAead(PRUint16 version, PRUint16 cipherSuite, PK11SymKey *secret, | |||
122 | const char *labelPrefix, unsigned int labelPrefixLen, SSLAeadContext **ctx) | |||
123 | { | |||
124 | return SSLExp_MakeVariantAead(version, cipherSuite, ssl_variant_stream, secret, | |||
125 | labelPrefix, labelPrefixLen, ctx); | |||
| ||||
126 | } | |||
127 | ||||
128 | SECStatus | |||
129 | SSLExp_DestroyAead(SSLAeadContext *ctx) | |||
130 | { | |||
131 | if (!ctx) { | |||
132 | return SECSuccess; | |||
133 | } | |||
134 | if (ctx->encryptContext) { | |||
135 | PK11_DestroyContext(ctx->encryptContext, PR_TRUE1); | |||
136 | } | |||
137 | if (ctx->decryptContext) { | |||
138 | PK11_DestroyContext(ctx->decryptContext, PR_TRUE1); | |||
139 | } | |||
140 | ||||
141 | PORT_ZFreePORT_ZFree_Util(ctx, sizeof(*ctx)); | |||
142 | return SECSuccess; | |||
143 | } | |||
144 | ||||
145 | /* Bug 1529440 exists to refactor this and the other AEAD uses. */ | |||
146 | static SECStatus | |||
147 | ssl_AeadInner(const SSLAeadContext *ctx, PK11Context *context, | |||
148 | PRBool decrypt, PRUint64 counter, | |||
149 | const PRUint8 *aad, unsigned int aadLen, | |||
150 | const PRUint8 *in, unsigned int inLen, | |||
151 | PRUint8 *out, unsigned int *outLen, unsigned int maxOut) | |||
152 | { | |||
153 | if (ctx == NULL((void*)0) || (aad == NULL((void*)0) && aadLen > 0) || in == NULL((void*)0) || | |||
154 | out == NULL((void*)0) || outLen == NULL((void*)0)) { | |||
155 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); | |||
156 | return SECFailure; | |||
157 | } | |||
158 | ||||
159 | // Setup the nonce. | |||
160 | PRUint8 nonce[sizeof(counter)] = { 0 }; | |||
161 | sslBuffer nonceBuf = SSL_BUFFER_FIXED(nonce, sizeof(counter)){ nonce, 0, sizeof(counter), 1 }; | |||
162 | SECStatus rv = sslBuffer_AppendNumber(&nonceBuf, counter, sizeof(counter)); | |||
163 | if (rv != SECSuccess) { | |||
164 | PORT_Assert(0)((0)?((void)0):PR_Assert("0","sslprimitive.c",164)); | |||
165 | return SECFailure; | |||
166 | } | |||
167 | /* at least on encrypt, we should not be using CKG_NO_GENERATE, but | |||
168 | * the current experimental API has the application tracking the counter | |||
169 | * rather than token. We should look at the QUIC code and see if the | |||
170 | * counter can be moved internally where it belongs. That would | |||
171 | * also get rid of the formatting code above and have the API | |||
172 | * call tls13_AEAD directly in SSLExp_Aead* */ | |||
173 | return tls13_AEAD(context, decrypt, CKG_NO_GENERATE0x00000000UL, 0, ctx->iv, NULL((void*)0), | |||
174 | ctx->ivLen, nonce, sizeof(counter), aad, aadLen, | |||
175 | out, outLen, maxOut, ctx->tagLen, in, inLen); | |||
176 | } | |||
177 | ||||
178 | SECStatus | |||
179 | SSLExp_AeadEncrypt(const SSLAeadContext *ctx, PRUint64 counter, | |||
180 | const PRUint8 *aad, unsigned int aadLen, | |||
181 | const PRUint8 *plaintext, unsigned int plaintextLen, | |||
182 | PRUint8 *out, unsigned int *outLen, unsigned int maxOut) | |||
183 | { | |||
184 | // false == encrypt | |||
185 | return ssl_AeadInner(ctx, ctx->encryptContext, PR_FALSE0, counter, | |||
186 | aad, aadLen, plaintext, plaintextLen, | |||
187 | out, outLen, maxOut); | |||
188 | } | |||
189 | ||||
190 | SECStatus | |||
191 | SSLExp_AeadDecrypt(const SSLAeadContext *ctx, PRUint64 counter, | |||
192 | const PRUint8 *aad, unsigned int aadLen, | |||
193 | const PRUint8 *ciphertext, unsigned int ciphertextLen, | |||
194 | PRUint8 *out, unsigned int *outLen, unsigned int maxOut) | |||
195 | { | |||
196 | // true == decrypt | |||
197 | return ssl_AeadInner(ctx, ctx->decryptContext, PR_TRUE1, counter, | |||
198 | aad, aadLen, ciphertext, ciphertextLen, | |||
199 | out, outLen, maxOut); | |||
200 | } | |||
201 | ||||
202 | SECStatus | |||
203 | SSLExp_HkdfExtract(PRUint16 version, PRUint16 cipherSuite, | |||
204 | PK11SymKey *salt, PK11SymKey *ikm, PK11SymKey **keyp) | |||
205 | { | |||
206 | if (keyp == NULL((void*)0)) { | |||
207 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); | |||
208 | return SECFailure; | |||
209 | } | |||
210 | ||||
211 | SSLHashType hash; | |||
212 | SECStatus rv = tls13_GetHashAndCipher(version, cipherSuite, | |||
213 | &hash, NULL((void*)0)); | |||
214 | if (rv != SECSuccess) { | |||
215 | return SECFailure; /* Code already set. */ | |||
216 | } | |||
217 | return tls13_HkdfExtract(salt, ikm, hash, keyp); | |||
218 | } | |||
219 | ||||
220 | SECStatus | |||
221 | SSLExp_HkdfExpandLabel(PRUint16 version, PRUint16 cipherSuite, PK11SymKey *prk, | |||
222 | const PRUint8 *hsHash, unsigned int hsHashLen, | |||
223 | const char *label, unsigned int labelLen, PK11SymKey **keyp) | |||
224 | { | |||
225 | return SSLExp_HkdfVariantExpandLabel(version, cipherSuite, prk, hsHash, hsHashLen, | |||
226 | label, labelLen, ssl_variant_stream, keyp); | |||
227 | } | |||
228 | ||||
229 | SECStatus | |||
230 | SSLExp_HkdfVariantExpandLabel(PRUint16 version, PRUint16 cipherSuite, PK11SymKey *prk, | |||
231 | const PRUint8 *hsHash, unsigned int hsHashLen, | |||
232 | const char *label, unsigned int labelLen, | |||
233 | SSLProtocolVariant variant, PK11SymKey **keyp) | |||
234 | { | |||
235 | if (prk == NULL((void*)0) || keyp == NULL((void*)0) || | |||
236 | label == NULL((void*)0) || labelLen == 0) { | |||
237 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); | |||
238 | return SECFailure; | |||
239 | } | |||
240 | ||||
241 | SSLHashType hash; | |||
242 | SECStatus rv = tls13_GetHashAndCipher(version, cipherSuite, | |||
243 | &hash, NULL((void*)0)); | |||
244 | if (rv != SECSuccess) { | |||
245 | return SECFailure; /* Code already set. */ | |||
246 | } | |||
247 | return tls13_HkdfExpandLabel(prk, hash, hsHash, hsHashLen, label, labelLen, | |||
248 | CKM_HKDF_DERIVE0x0000402aUL, | |||
249 | tls13_GetHashSizeForHash(hash), variant, keyp); | |||
250 | } | |||
251 | ||||
252 | SECStatus | |||
253 | SSLExp_HkdfExpandLabelWithMech(PRUint16 version, PRUint16 cipherSuite, PK11SymKey *prk, | |||
254 | const PRUint8 *hsHash, unsigned int hsHashLen, | |||
255 | const char *label, unsigned int labelLen, | |||
256 | CK_MECHANISM_TYPE mech, unsigned int keySize, | |||
257 | PK11SymKey **keyp) | |||
258 | { | |||
259 | return SSLExp_HkdfVariantExpandLabelWithMech(version, cipherSuite, prk, hsHash, hsHashLen, | |||
260 | label, labelLen, mech, keySize, | |||
261 | ssl_variant_stream, keyp); | |||
262 | } | |||
263 | ||||
264 | SECStatus | |||
265 | SSLExp_HkdfVariantExpandLabelWithMech(PRUint16 version, PRUint16 cipherSuite, PK11SymKey *prk, | |||
266 | const PRUint8 *hsHash, unsigned int hsHashLen, | |||
267 | const char *label, unsigned int labelLen, | |||
268 | CK_MECHANISM_TYPE mech, unsigned int keySize, | |||
269 | SSLProtocolVariant variant, PK11SymKey **keyp) | |||
270 | { | |||
271 | if (prk == NULL((void*)0) || keyp == NULL((void*)0) || | |||
272 | label == NULL((void*)0) || labelLen == 0 || | |||
273 | mech == CKM_INVALID_MECHANISM0xffffffffUL || keySize == 0) { | |||
274 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); | |||
275 | return SECFailure; | |||
276 | } | |||
277 | ||||
278 | SSLHashType hash; | |||
279 | SECStatus rv = tls13_GetHashAndCipher(version, cipherSuite, | |||
280 | &hash, NULL((void*)0)); | |||
281 | if (rv != SECSuccess) { | |||
282 | return SECFailure; /* Code already set. */ | |||
283 | } | |||
284 | return tls13_HkdfExpandLabel(prk, hash, hsHash, hsHashLen, label, labelLen, | |||
285 | mech, keySize, variant, keyp); | |||
286 | } | |||
287 | ||||
288 | SECStatus | |||
289 | ssl_CreateMaskingContextInner(PRUint16 version, PRUint16 cipherSuite, | |||
290 | SSLProtocolVariant variant, | |||
291 | PK11SymKey *secret, | |||
292 | const char *label, | |||
293 | unsigned int labelLen, | |||
294 | SSLMaskingContext **ctx) | |||
295 | { | |||
296 | if (!secret || !ctx || (!label && labelLen)) { | |||
297 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); | |||
298 | return SECFailure; | |||
299 | } | |||
300 | ||||
301 | SSLMaskingContext *out = PORT_ZNew(SSLMaskingContext)(SSLMaskingContext *)PORT_ZAlloc_Util(sizeof(SSLMaskingContext )); | |||
302 | if (out == NULL((void*)0)) { | |||
303 | goto loser; | |||
304 | } | |||
305 | ||||
306 | SSLHashType hash; | |||
307 | const ssl3BulkCipherDef *cipher; | |||
308 | SECStatus rv = tls13_GetHashAndCipher(version, cipherSuite, | |||
309 | &hash, &cipher); | |||
310 | if (rv != SECSuccess) { | |||
311 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); | |||
312 | goto loser; /* Code already set. */ | |||
313 | } | |||
314 | ||||
315 | out->mech = tls13_SequenceNumberEncryptionMechanism(cipher->calg); | |||
316 | if (out->mech == CKM_INVALID_MECHANISM0xffffffffUL) { | |||
317 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); | |||
318 | goto loser; | |||
319 | } | |||
320 | ||||
321 | // Derive the masking key | |||
322 | rv = tls13_HkdfExpandLabel(secret, hash, | |||
323 | NULL((void*)0), 0, // Handshake hash. | |||
324 | label, labelLen, | |||
325 | out->mech, | |||
326 | cipher->key_size, variant, | |||
327 | &out->secret); | |||
328 | if (rv != SECSuccess) { | |||
329 | goto loser; | |||
330 | } | |||
331 | ||||
332 | out->version = version; | |||
333 | out->cipherSuite = cipherSuite; | |||
334 | ||||
335 | *ctx = out; | |||
336 | return SECSuccess; | |||
337 | loser: | |||
338 | SSLExp_DestroyMaskingContext(out); | |||
339 | return SECFailure; | |||
340 | } | |||
341 | ||||
342 | SECStatus | |||
343 | ssl_CreateMaskInner(SSLMaskingContext *ctx, const PRUint8 *sample, | |||
344 | unsigned int sampleLen, PRUint8 *outMask, | |||
345 | unsigned int maskLen) | |||
346 | { | |||
347 | if (!ctx || !sample || !sampleLen || !outMask || !maskLen) { | |||
348 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); | |||
349 | return SECFailure; | |||
350 | } | |||
351 | ||||
352 | if (ctx->secret == NULL((void*)0)) { | |||
353 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_NO_KEY); | |||
354 | return SECFailure; | |||
355 | } | |||
356 | ||||
357 | SECStatus rv = SECFailure; | |||
358 | unsigned int outMaskLen = 0; | |||
359 | int paramLen = 0; | |||
360 | ||||
361 | /* Internal output len/buf, for use if the caller allocated and requested | |||
362 | * less than one block of output. |oneBlock| should have size equal to the | |||
363 | * largest block size supported below. */ | |||
364 | PRUint8 oneBlock[AES_BLOCK_SIZE16]; | |||
365 | PRUint8 *outMask_ = outMask; | |||
366 | unsigned int maskLen_ = maskLen; | |||
367 | ||||
368 | switch (ctx->mech) { | |||
369 | case CKM_AES_ECB0x00001081UL: | |||
370 | if (sampleLen < AES_BLOCK_SIZE16) { | |||
371 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); | |||
372 | return SECFailure; | |||
373 | } | |||
374 | if (maskLen_ < AES_BLOCK_SIZE16) { | |||
375 | outMask_ = oneBlock; | |||
376 | maskLen_ = sizeof(oneBlock); | |||
377 | } | |||
378 | rv = PK11_Encrypt(ctx->secret, | |||
379 | ctx->mech, | |||
380 | NULL((void*)0), | |||
381 | outMask_, &outMaskLen, maskLen_, | |||
382 | sample, AES_BLOCK_SIZE16); | |||
383 | if (rv == SECSuccess && | |||
384 | maskLen < AES_BLOCK_SIZE16) { | |||
385 | memcpy(outMask, outMask_, maskLen); | |||
386 | } | |||
387 | break; | |||
388 | case CKM_NSS_CHACHA20_CTR((0x80000000UL | 0x4E534350) + 33): | |||
389 | paramLen = 16; | |||
390 | /* fall through */ | |||
391 | case CKM_CHACHA200x00001226UL: | |||
392 | paramLen = (paramLen) ? paramLen : sizeof(CK_CHACHA20_PARAMS); | |||
393 | if (sampleLen < paramLen) { | |||
394 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); | |||
395 | return SECFailure; | |||
396 | } | |||
397 | ||||
398 | SECItem param; | |||
399 | param.type = siBuffer; | |||
400 | param.len = paramLen; | |||
401 | param.data = (PRUint8 *)sample; // const-cast :( | |||
402 | unsigned char zeros[128] = { 0 }; | |||
403 | ||||
404 | if (maskLen > sizeof(zeros)) { | |||
405 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_OUTPUT_LEN); | |||
406 | return SECFailure; | |||
407 | } | |||
408 | ||||
409 | rv = PK11_Encrypt(ctx->secret, | |||
410 | ctx->mech, | |||
411 | ¶m, | |||
412 | outMask, &outMaskLen, | |||
413 | maskLen, | |||
414 | zeros, maskLen); | |||
415 | break; | |||
416 | default: | |||
417 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); | |||
418 | return SECFailure; | |||
419 | } | |||
420 | ||||
421 | if (rv != SECSuccess) { | |||
422 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_PKCS11_FUNCTION_FAILED); | |||
423 | return SECFailure; | |||
424 | } | |||
425 | ||||
426 | // Ensure we produced at least as much material as requested. | |||
427 | if (outMaskLen < maskLen) { | |||
428 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_OUTPUT_LEN); | |||
429 | return SECFailure; | |||
430 | } | |||
431 | ||||
432 | return SECSuccess; | |||
433 | } | |||
434 | ||||
435 | SECStatus | |||
436 | ssl_DestroyMaskingContextInner(SSLMaskingContext *ctx) | |||
437 | { | |||
438 | if (!ctx) { | |||
439 | return SECSuccess; | |||
440 | } | |||
441 | ||||
442 | PK11_FreeSymKey(ctx->secret); | |||
443 | PORT_ZFreePORT_ZFree_Util(ctx, sizeof(*ctx)); | |||
444 | return SECSuccess; | |||
445 | } | |||
446 | ||||
447 | SECStatus | |||
448 | SSLExp_CreateMask(SSLMaskingContext *ctx, const PRUint8 *sample, | |||
449 | unsigned int sampleLen, PRUint8 *outMask, | |||
450 | unsigned int maskLen) | |||
451 | { | |||
452 | return ssl_CreateMaskInner(ctx, sample, sampleLen, outMask, maskLen); | |||
453 | } | |||
454 | ||||
455 | SECStatus | |||
456 | SSLExp_CreateMaskingContext(PRUint16 version, PRUint16 cipherSuite, | |||
457 | PK11SymKey *secret, | |||
458 | const char *label, | |||
459 | unsigned int labelLen, | |||
460 | SSLMaskingContext **ctx) | |||
461 | { | |||
462 | return ssl_CreateMaskingContextInner(version, cipherSuite, ssl_variant_stream, secret, | |||
463 | label, labelLen, ctx); | |||
464 | } | |||
465 | ||||
466 | SECStatus | |||
467 | SSLExp_CreateVariantMaskingContext(PRUint16 version, PRUint16 cipherSuite, | |||
468 | SSLProtocolVariant variant, | |||
469 | PK11SymKey *secret, | |||
470 | const char *label, | |||
471 | unsigned int labelLen, | |||
472 | SSLMaskingContext **ctx) | |||
473 | { | |||
474 | return ssl_CreateMaskingContextInner(version, cipherSuite, variant, secret, | |||
475 | label, labelLen, ctx); | |||
476 | } | |||
477 | ||||
478 | SECStatus | |||
479 | SSLExp_DestroyMaskingContext(SSLMaskingContext *ctx) | |||
480 | { | |||
481 | return ssl_DestroyMaskingContextInner(ctx); | |||
482 | } |