| 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 | } |