rv = ssl3_GenerateSessionKeys(ss, pms); if (rv != SECSuccess) { goto bail_out;
if (pms || (!pwSpec->msItem.len && !pwSpec->master_secret)) { rv = ssl3_DeriveMasterSecret(ss, pms); if (rv != SECSuccess) { goto done;   } } if (pwSpec->msItem.len && pwSpec->msItem.data) {  const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; PRBool             isTLS   = (PRBool)(kea_def->tls_keygen || (pwSpec->version > SSL_LIBRARY_VERSION_3_0)); pwSpec->bypassCiphers = PR_TRUE; rv = ssl3_KeyAndMacDeriveBypass( pwSpec, (const unsigned char *)&ss->ssl3.hs.client_random, (const unsigned char *)&ss->ssl3.hs.server_random, isTLS, (PRBool)(kea_def->is_limited)); if (rv == SECSuccess) { rv = ssl3_InitPendingContextsBypass(ss); } } else if (pwSpec->master_secret) { rv = ssl3_DeriveConnectionKeysPKCS11(ss); if (rv == SECSuccess) { rv = ssl3_InitPendingContextsPKCS11(ss); } } else { PORT_Assert(pwSpec->master_secret); PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); rv = SECFailure;
ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms){      ssl3CipherSpec  *  pwSpec;const ssl3BulkCipherDef *cipher_def;      PK11Context *      serverContext = NULL;      PK11Context *      clientContext = NULL;      SECItem *          param;      CK_ULONG           macLength;      SSLCipherAlgorithm calg;      SECStatus          rv;      CK_MECHANISM_TYPE  mechanism;      CK_MECHANISM_TYPE  mac_mech;      SECItem            iv;      SECItem            mac_param;    PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));    ssl_GetSpecWriteLock(ss);	/**************************************/    PORT_Assert(ss->ssl3->prSpec == ss->ssl3->pwSpec);    pwSpec        = ss->ssl3->pwSpec;    cipher_def    = pwSpec->cipher_def;    macLength     = pwSpec->mac_size;    /* generate session keys from pms (if pms is not NULL) or ms */    rv = ssl3_GenerateSessionKeys(ss, pms);    if (rv != SECSuccess) {    	goto bail_out;	/* err code set by ssl3_GenerateSessionKeys */    }    pwSpec->client.write_mac_context = NULL;    pwSpec->server.write_mac_context = NULL;    mac_param.data = (unsigned char *)&macLength;    mac_param.len  = sizeof(macLength);    mac_param.type = 0;    mac_mech       = pwSpec->mac_def->mmech;    if (cipher_def->calg == calg_null) {	pwSpec->encode  = Null_Cipher;	pwSpec->decode  = Null_Cipher;        pwSpec->destroy = NULL;	pwSpec->client.write_mac_context = PK11_CreateContextBySymKey(		mac_mech, CKA_SIGN, pwSpec->client.write_mac_key, &mac_param);	if (pwSpec->client.write_mac_context == NULL)  {	    ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);	    goto fail;	}	pwSpec->server.write_mac_context = PK11_CreateContextBySymKey(		mac_mech, CKA_SIGN, pwSpec->server.write_mac_key, &mac_param);	if (pwSpec->server.write_mac_context == NULL) {	    ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);	    goto fail;	}	goto success;    }    calg = cipher_def->calg;    PORT_Assert(alg2Mech[calg].calg == calg);    mechanism = alg2Mech[calg].cmech;    /*     * build the server context     */    iv.data = pwSpec->server.write_iv;    iv.len  = cipher_def->iv_size;    param = PK11_ParamFromIV(mechanism, &iv);    if (param == NULL) {	ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE);    	goto fail;    }    serverContext = PK11_CreateContextBySymKey(mechanism,				(ss->sec.isServer ? CKA_ENCRYPT : CKA_DECRYPT),				pwSpec->server.write_key, param);    iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len);    if (iv.data)    	PORT_Memcpy(pwSpec->server.write_iv, iv.data, iv.len);    SECITEM_FreeItem(param, PR_TRUE);    if (serverContext == NULL) {	ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);    	goto fail;    }    /*     * build the client context     */    iv.data = pwSpec->client.write_iv;    iv.len  = cipher_def->iv_size;    param = PK11_ParamFromIV(mechanism, &iv);    if (param == NULL) {	ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE);    	goto fail;    }    clientContext = PK11_CreateContextBySymKey(mechanism,				(ss->sec.isServer ? CKA_DECRYPT : CKA_ENCRYPT),				pwSpec->client.write_key, param);    iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len);    if (iv.data)    	PORT_Memcpy(pwSpec->client.write_iv, iv.data, iv.len);    SECITEM_FreeItem(param,PR_TRUE);    if (clientContext == NULL) {	ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);    	goto fail;    }    pwSpec->encodeContext = (ss->sec.isServer) ? serverContext : clientContext;    pwSpec->decodeContext = (ss->sec.isServer) ? clientContext : serverContext;    pwSpec->encode  = (SSLCipher) PK11_CipherOp;    pwSpec->decode  = (SSLCipher) PK11_CipherOp;    pwSpec->destroy = (SSLDestroy) PK11_DestroyContext;    serverContext = NULL;    clientContext = NULL;    pwSpec->client.write_mac_context = PK11_CreateContextBySymKey(		mac_mech,CKA_SIGN, pwSpec->client.write_mac_key,&mac_param);    if (pwSpec->client.write_mac_context == NULL)  {	ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);    	goto fail;    }    pwSpec->server.write_mac_context = PK11_CreateContextBySymKey(		mac_mech, CKA_SIGN, pwSpec->server.write_mac_key,&mac_param);    if (pwSpec->server.write_mac_context == NULL) {	ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);    	goto fail;    }success:    ssl_ReleaseSpecWriteLock(ss);	/******************************/    return SECSuccess;fail:    if (serverContext != NULL) PK11_DestroyContext(serverContext, PR_TRUE);    if (clientContext != NULL) PK11_DestroyContext(clientContext, PR_TRUE);    if (pwSpec->client.write_mac_context != NULL) {    	PK11_DestroyContext(pwSpec->client.write_mac_context,PR_TRUE);	pwSpec->client.write_mac_context = NULL;    }    if (pwSpec->server.write_mac_context != NULL) {    	PK11_DestroyContext(pwSpec->server.write_mac_context,PR_TRUE);	pwSpec->server.write_mac_context = NULL;    }bail_out:    ssl_ReleaseSpecWriteLock(ss);    return SECFailure;}