/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "plarena.h"

#include "blapit.h"
#include "seccomon.h"
#include "secitem.h"
#include "secport.h"
#include "hasht.h"
#include "pkcs11t.h"
#include "sechash.h"
#include "secasn1.h"
#include "secder.h"
#include "secoid.h"
#include "secerr.h"
#include "secmod.h"
#include "pk11func.h"
#include "secpkcs5.h"
#include "secmodi.h"
#include "secmodti.h"
#include "pkcs11.h"
#include "pk11func.h"
#include "secitem.h"
#include "keyhi.h"

typedef struct SEC_PKCS5PBEParameterStr SEC_PKCS5PBEParameter;
struct SEC_PKCS5PBEParameterStr {
    PLArenaPool *poolp;
    SECItem salt;              /* octet string */
    SECItem iteration;         /* integer */
    SECItem keyLength;         /* PKCS5v2 only */
    SECAlgorithmID *pPrfAlgId; /* PKCS5v2 only */
    SECAlgorithmID prfAlgId;   /* PKCS5v2 only */
};

/* PKCS5 V2 has an algorithm ID for the encryption and for
 * the key generation. This is valid for SEC_OID_PKCS5_PBES2
 * and SEC_OID_PKCS5_PBMAC1
 */
struct sec_pkcs5V2ParameterStr {
    PLArenaPool *poolp;
    SECAlgorithmID pbeAlgId;    /* real pbe algorithms */
    SECAlgorithmID cipherAlgId; /* encryption/mac */
};

typedef struct sec_pkcs5V2ParameterStr sec_pkcs5V2Parameter;

/* template for PKCS 5 PBE Parameter.  This template has been expanded
 * based upon the additions in PKCS 12.  This should eventually be moved
 * if RSA updates PKCS 5.
 */
const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate[] =
    {
      { SEC_ASN1_SEQUENCE,
        0, NULL, sizeof(SEC_PKCS5PBEParameter) },
      { SEC_ASN1_OCTET_STRING,
        offsetof(SEC_PKCS5PBEParameter, salt) },
      { SEC_ASN1_INTEGER,
        offsetof(SEC_PKCS5PBEParameter, iteration) },
      { 0 }
    };

const SEC_ASN1Template SEC_V2PKCS12PBEParameterTemplate[] =
    {
      { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
      { SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) },
      { SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) },
      { 0 }
    };

SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)

/* SECOID_PKCS5_PBKDF2 */
const SEC_ASN1Template SEC_PKCS5V2PBEParameterTemplate[] =
    {
      { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
      /* This is really a choice, but since we only understand this
     * choice, just inline it */
      { SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) },
      { SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) },
      { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL,
        offsetof(SEC_PKCS5PBEParameter, keyLength) },
      { SEC_ASN1_POINTER | SEC_ASN1_XTRN | SEC_ASN1_OPTIONAL,
        offsetof(SEC_PKCS5PBEParameter, pPrfAlgId),
        SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
      { 0 }
    };

/* SEC_OID_PKCS5_PBES2, SEC_OID_PKCS5_PBMAC1 */
const SEC_ASN1Template SEC_PKCS5V2ParameterTemplate[] =
    {
      { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
      { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(sec_pkcs5V2Parameter, pbeAlgId),
        SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
      { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
        offsetof(sec_pkcs5V2Parameter, cipherAlgId),
        SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
      { 0 }
    };

/*
 * maps a PBE algorithm to a crypto algorithm. for PKCS12 and PKCS5v1
 * for PKCS5v2 it returns SEC_OID_PKCS5_PBKDF2.
 */
SECOidTag
sec_pkcs5GetCryptoFromAlgTag(SECOidTag algorithm)
{
    switch (algorithm) {
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
        case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
            return SEC_OID_DES_EDE3_CBC;
        case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
        case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
        case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
            return SEC_OID_DES_CBC;
        case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
        case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
            return SEC_OID_RC2_CBC;
        case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
        case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
            return SEC_OID_RC4;
        case SEC_OID_PKCS5_PBKDF2:
        case SEC_OID_PKCS5_PBES2:
        case SEC_OID_PKCS5_PBMAC1:
            return SEC_OID_PKCS5_PBKDF2;
        default:
            break;
    }

    return SEC_OID_UNKNOWN;
}

/*
 * get a new PKCS5 V2 Parameter from the algorithm id.
 *  if arena is passed in, use it, otherwise create a new arena.
 */
sec_pkcs5V2Parameter *
sec_pkcs5_v2_get_v2_param(PLArenaPool *arena, SECAlgorithmID *algid)
{
    PLArenaPool *localArena = NULL;
    sec_pkcs5V2Parameter *pbeV2_param;
    SECStatus rv;

    if (arena == NULL) {
        localArena = arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
        if (arena == NULL) {
            return NULL;
        }
    }
    pbeV2_param = PORT_ArenaZNew(arena, sec_pkcs5V2Parameter);
    if (pbeV2_param == NULL) {
        goto loser;
    }

    rv = SEC_ASN1DecodeItem(arena, pbeV2_param,
                            SEC_PKCS5V2ParameterTemplate, &algid->parameters);
    if (rv == SECFailure) {
        goto loser;
    }

    pbeV2_param->poolp = arena;
    return pbeV2_param;
loser:
    if (localArena) {
        PORT_FreeArena(arena, PR_FALSE);
    }
    return NULL;
}

void
sec_pkcs5_v2_destroy_v2_param(sec_pkcs5V2Parameter *param)
{
    if (param && param->poolp) {
        PORT_FreeArena(param->poolp, PR_TRUE);
    }
}

/* maps crypto algorithm from PBE algorithm.
 */
SECOidTag
SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid)
{

    SECOidTag pbeAlg;
    SECOidTag cipherAlg;

    if (algid == NULL)
        return SEC_OID_UNKNOWN;

    pbeAlg = SECOID_GetAlgorithmTag(algid);
    cipherAlg = sec_pkcs5GetCryptoFromAlgTag(pbeAlg);
    if ((cipherAlg == SEC_OID_PKCS5_PBKDF2) &&
        (pbeAlg != SEC_OID_PKCS5_PBKDF2)) {
        sec_pkcs5V2Parameter *pbeV2_param;
        cipherAlg = SEC_OID_UNKNOWN;

        pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid);
        if (pbeV2_param != NULL) {
            cipherAlg = SECOID_GetAlgorithmTag(&pbeV2_param->cipherAlgId);
            sec_pkcs5_v2_destroy_v2_param(pbeV2_param);
        }
    }

    return cipherAlg;
}

/* check to see if an oid is a pbe algorithm
 */
PRBool
SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid)
{
    return (PRBool)(SEC_PKCS5GetCryptoAlgorithm(algid) != SEC_OID_UNKNOWN);
}

PRBool
SEC_PKCS5IsAlgorithmPBEAlgTag(SECOidTag algtag)
{
    return (PRBool)(sec_pkcs5GetCryptoFromAlgTag(algtag) != SEC_OID_UNKNOWN);
}

/*
 * find the most appropriate PKCS5v2 overall oid tag from a regular
 * cipher/hash algorithm tag.
 */
static SECOidTag
sec_pkcs5v2_get_pbe(SECOidTag algTag)
{
    /* if it's a valid hash oid... */
    if (HASH_GetHashOidTagByHMACOidTag(algTag) != SEC_OID_UNKNOWN) {
        /* use the MAC tag */
        return SEC_OID_PKCS5_PBMAC1;
    }
    if (HASH_GetHashTypeByOidTag(algTag) != HASH_AlgNULL) {
        /* eliminate Hash algorithms */
        return SEC_OID_UNKNOWN;
    }
    if (PK11_AlgtagToMechanism(algTag) != CKM_INVALID_MECHANISM) {
        /* it's not a hash, if it has a PKCS #11 mechanism associated
         * with it, assume it's a cipher. (NOTE this will generate
         * some false positives). */
        return SEC_OID_PKCS5_PBES2;
    }
    return SEC_OID_UNKNOWN;
}

/*
 * maps PBE algorithm from crypto algorithm, assumes SHA1 hashing.
 *  input keyLen in bits.
 */
SECOidTag
SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen)
{
    switch (algTag) {
        case SEC_OID_DES_EDE3_CBC:
            switch (keyLen) {
                case 168:
                case 192:
                case 0:
                    return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC;
                case 128:
                case 92:
                    return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC;
                default:
                    break;
            }
            break;
        case SEC_OID_DES_CBC:
            return SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC;
        case SEC_OID_RC2_CBC:
            switch (keyLen) {
                case 40:
                    return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
                case 128:
                case 0:
                    return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC;
                default:
                    break;
            }
            break;
        case SEC_OID_RC4:
            switch (keyLen) {
                case 40:
                    return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4;
                case 128:
                case 0:
                    return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4;
                default:
                    break;
            }
            break;
        default:
            return sec_pkcs5v2_get_pbe(algTag);
    }

    return SEC_OID_UNKNOWN;
}

static PRBool
sec_pkcs5_is_algorithm_v2_aes_algorithm(SECOidTag algorithm)
{
    switch (algorithm) {
        case SEC_OID_AES_128_CBC:
        case SEC_OID_AES_192_CBC:
        case SEC_OID_AES_256_CBC:
            return PR_TRUE;
        default:
            return PR_FALSE;
    }
}

static int
sec_pkcs5v2_aes_key_length(SECOidTag algorithm)
{
    switch (algorithm) {
        /* The key length for the AES-CBC-Pad algorithms are
         * determined from the undelying cipher algorithm.  */
        case SEC_OID_AES_128_CBC:
            return AES_128_KEY_LENGTH;
        case SEC_OID_AES_192_CBC:
            return AES_192_KEY_LENGTH;
        case SEC_OID_AES_256_CBC:
            return AES_256_KEY_LENGTH;
        default:
            break;
    }
    return 0;
}

/*
 * get the key length in bytes from a PKCS5 PBE
 */
static int
sec_pkcs5v2_key_length(SECAlgorithmID *algid, SECAlgorithmID *cipherAlgId)
{
    SECOidTag algorithm;
    PLArenaPool *arena = NULL;
    SEC_PKCS5PBEParameter p5_param;
    SECStatus rv;
    int length = -1;
    SECOidTag cipherAlg = SEC_OID_UNKNOWN;

    algorithm = SECOID_GetAlgorithmTag(algid);
    /* sanity check, they should all be PBKDF2 here */
    if (algorithm != SEC_OID_PKCS5_PBKDF2) {
        return -1;
    }

    arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
    if (arena == NULL) {
        goto loser;
    }
    PORT_Memset(&p5_param, 0, sizeof(p5_param));
    rv = SEC_ASN1DecodeItem(arena, &p5_param,
                            SEC_PKCS5V2PBEParameterTemplate, &algid->parameters);
    if (rv != SECSuccess) {
        goto loser;
    }

    if (cipherAlgId)
        cipherAlg = SECOID_GetAlgorithmTag(cipherAlgId);

    if (sec_pkcs5_is_algorithm_v2_aes_algorithm(cipherAlg)) {
        /* Previously, the PKCS#12 files created with the old NSS
         * releases encoded the maximum key size of AES (that is 32)
         * in the keyLength field of PBKDF2-params. That resulted in
         * always performing AES-256 even if AES-128-CBC or
         * AES-192-CBC is specified in the encryptionScheme field of
         * PBES2-params. This is wrong, but for compatibility reasons,
         * check the keyLength field and use the value if it is 32.
         */
        if (p5_param.keyLength.data != NULL) {
            length = DER_GetInteger(&p5_param.keyLength);
        }
        /* If the keyLength field is present and contains a value
         * other than 32, that means the file is created outside of
         * NSS, which we don't care about. Note that the following
         * also handles the case when the field is absent. */
        if (length != 32) {
            length = sec_pkcs5v2_aes_key_length(cipherAlg);
        }
    } else if (p5_param.keyLength.data != NULL) {
        length = DER_GetInteger(&p5_param.keyLength);
    } else {
        CK_MECHANISM_TYPE cipherMech;
        cipherMech = PK11_AlgtagToMechanism(cipherAlg);
        if (cipherMech == CKM_INVALID_MECHANISM) {
            goto loser;
        }
        length = PK11_GetMaxKeyLength(cipherMech);
    }

loser:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }
    return length;
}

/*
 *  get the key length in bytes needed for the PBE algorithm
 */
int
SEC_PKCS5GetKeyLength(SECAlgorithmID *algid)
{

    SECOidTag algorithm;

    if (algid == NULL)
        return SEC_OID_UNKNOWN;

    algorithm = SECOID_GetAlgorithmTag(algid);

    switch (algorithm) {
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
        case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
            return 24;
        case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
        case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
        case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
            return 8;
        case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
        case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
            return 5;
        case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
        case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
            return 16;
        case SEC_OID_PKCS5_PBKDF2:
            return sec_pkcs5v2_key_length(algid, NULL);
        case SEC_OID_PKCS5_PBES2:
        case SEC_OID_PKCS5_PBMAC1: {
            sec_pkcs5V2Parameter *pbeV2_param;
            int length = -1;
            pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid);
            if (pbeV2_param != NULL) {
                length = sec_pkcs5v2_key_length(&pbeV2_param->pbeAlgId,
                                                &pbeV2_param->cipherAlgId);
                sec_pkcs5_v2_destroy_v2_param(pbeV2_param);
            }
            return length;
        }

        default:
            break;
    }
    return -1;
}

/* the PKCS12 V2 algorithms only encode the salt, there is no iteration
 * count so we need a check for V2 algorithm parameters.
 */
static PRBool
sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(SECOidTag algorithm)
{
    switch (algorithm) {
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
        case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
            return PR_TRUE;
        default:
            break;
    }

    return PR_FALSE;
}

static PRBool
sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(SECOidTag algorithm)
{
    switch (algorithm) {
        case SEC_OID_PKCS5_PBES2:
        case SEC_OID_PKCS5_PBMAC1:
        case SEC_OID_PKCS5_PBKDF2:
            return PR_TRUE;
        default:
            break;
    }

    return PR_FALSE;
}

/* destroy a pbe parameter.  it assumes that the parameter was
 * generated using the appropriate create function and therefor
 * contains an arena pool.
 */
static void
sec_pkcs5_destroy_pbe_param(SEC_PKCS5PBEParameter *pbe_param)
{
    if (pbe_param != NULL)
        PORT_FreeArena(pbe_param->poolp, PR_TRUE);
}

/* creates a PBE parameter based on the PBE algorithm.  the only required
 * parameters are algorithm and interation.  the return is a PBE parameter
 * which conforms to PKCS 5 parameter unless an extended parameter is needed.
 * this is primarily if keyLength and a variable key length algorithm are
 * specified.
 *   salt -  if null, a salt will be generated from random bytes.
 *   iteration - number of iterations to perform hashing.
 *   keyLength - only used in variable key length algorithms. if specified,
 *            should be in bytes.
 * once a parameter is allocated, it should be destroyed calling
 * sec_pkcs5_destroy_pbe_parameter or SEC_PKCS5DestroyPBEParameter.
 */
#define DEFAULT_SALT_LENGTH 16
static SEC_PKCS5PBEParameter *
sec_pkcs5_create_pbe_parameter(SECOidTag algorithm,
                               SECItem *salt,
                               int iteration,
                               int keyLength,
                               SECOidTag prfAlg)
{
    PLArenaPool *poolp = NULL;
    SEC_PKCS5PBEParameter *pbe_param = NULL;
    SECStatus rv = SECSuccess;
    void *dummy = NULL;

    if (iteration < 0) {
        return NULL;
    }

    poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
    if (poolp == NULL)
        return NULL;

    pbe_param = (SEC_PKCS5PBEParameter *)PORT_ArenaZAlloc(poolp,
                                                          sizeof(SEC_PKCS5PBEParameter));
    if (!pbe_param) {
        PORT_FreeArena(poolp, PR_TRUE);
        return NULL;
    }

    pbe_param->poolp = poolp;

    rv = SECFailure;
    if (salt && salt->data) {
        rv = SECITEM_CopyItem(poolp, &pbe_param->salt, salt);
    } else {
        /* sigh, the old interface generated salt on the fly, so we have to
         * preserve the semantics */
        pbe_param->salt.len = DEFAULT_SALT_LENGTH;
        pbe_param->salt.data = PORT_ArenaZAlloc(poolp, DEFAULT_SALT_LENGTH);
        if (pbe_param->salt.data) {
            rv = PK11_GenerateRandom(pbe_param->salt.data, DEFAULT_SALT_LENGTH);
        }
    }

    if (rv != SECSuccess) {
        PORT_FreeArena(poolp, PR_TRUE);
        return NULL;
    }

    /* encode the integer */
    dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->iteration,
                                  iteration);
    rv = (dummy) ? SECSuccess : SECFailure;

    if (rv != SECSuccess) {
        PORT_FreeArena(poolp, PR_FALSE);
        return NULL;
    }

    /*
     * for PKCS5 v2 Add the keylength and the prf
     */
    if (algorithm == SEC_OID_PKCS5_PBKDF2) {
        dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->keyLength,
                                      keyLength);
        rv = (dummy) ? SECSuccess : SECFailure;
        if (rv != SECSuccess) {
            PORT_FreeArena(poolp, PR_FALSE);
            return NULL;
        }
        rv = SECOID_SetAlgorithmID(poolp, &pbe_param->prfAlgId, prfAlg, NULL);
        if (rv != SECSuccess) {
            PORT_FreeArena(poolp, PR_FALSE);
            return NULL;
        }
        pbe_param->pPrfAlgId = &pbe_param->prfAlgId;
    }

    return pbe_param;
}

/* creates a algorithm ID containing the PBE algorithm and appropriate
 * parameters.  the required parameter is the algorithm.  if salt is
 * not specified, it is generated randomly.
 *
 * the returned SECAlgorithmID should be destroyed using
 * SECOID_DestroyAlgorithmID
 */
SECAlgorithmID *
sec_pkcs5CreateAlgorithmID(SECOidTag algorithm,
                           SECOidTag cipherAlgorithm,
                           SECOidTag prfAlg,
                           SECOidTag *pPbeAlgorithm,
                           int keyLength,
                           SECItem *salt,
                           int iteration)
{
    PLArenaPool *poolp = NULL;
    SECAlgorithmID *algid, *ret_algid = NULL;
    SECOidTag pbeAlgorithm = algorithm;
    SECItem der_param;
    void *dummy;
    SECStatus rv = SECFailure;
    SEC_PKCS5PBEParameter *pbe_param = NULL;
    sec_pkcs5V2Parameter pbeV2_param;

    if (iteration <= 0) {
        return NULL;
    }

    poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
    if (!poolp) {
        goto loser;
    }

    if (!SEC_PKCS5IsAlgorithmPBEAlgTag(algorithm) ||
        sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm)) {
        /* use PKCS 5 v2 */
        SECItem *cipherParams;

        /*
         * if we ask for pkcs5 Algorithms directly, then the
         * application needs to supply the cipher algorithm,
         * otherwise we are implicitly using pkcs5 v2 and the
         * passed in algorithm is the encryption algorithm.
         */
        if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm)) {
            if (cipherAlgorithm == SEC_OID_UNKNOWN) {
                goto loser;
            }
        } else {
            cipherAlgorithm = algorithm;
            /* force algorithm to be chosen below */
            algorithm = SEC_OID_PKCS5_PBKDF2;
        }

        pbeAlgorithm = SEC_OID_PKCS5_PBKDF2;
        /*
         * 'algorithm' is the overall algorithm oid tag used to wrap the
         * entire algoithm ID block. For PKCS5v1 and PKCS12, this
         * algorithm OID has encoded in it both the PBE KDF function
         * and the encryption algorithm. For PKCS 5v2, PBE KDF and
         * encryption/macing oids are encoded as parameters in
         * the algorithm ID block.
         *
         * Thus in PKCS5 v1 and PKCS12, this algorithm maps to a pkcs #11
         * mechanism, where as in PKCS 5v2, this alogithm tag does not map
         * directly to a PKCS #11 mechanim, instead the 2 oids in the
         * algorithm ID block map the the actual PKCS #11 mechanism.
         * gorithm is). We use choose this algorithm oid based on the
         * cipherAlgorithm to determine what this should be (MAC1 or PBES2).
         */
        if (algorithm == SEC_OID_PKCS5_PBKDF2) {
            /* choose mac or pbes */
            algorithm = sec_pkcs5v2_get_pbe(cipherAlgorithm);
        }

        /* set the PKCS5v2 specific parameters */
        if (keyLength == 0) {
            SECOidTag hashAlg = HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm);
            if (hashAlg != SEC_OID_UNKNOWN) {
                keyLength = HASH_ResultLenByOidTag(hashAlg);
            } else if (sec_pkcs5_is_algorithm_v2_aes_algorithm(cipherAlgorithm)) {
                keyLength = sec_pkcs5v2_aes_key_length(cipherAlgorithm);
            } else {
                CK_MECHANISM_TYPE cryptoMech;
                cryptoMech = PK11_AlgtagToMechanism(cipherAlgorithm);
                if (cryptoMech == CKM_INVALID_MECHANISM) {
                    goto loser;
                }
                keyLength = PK11_GetMaxKeyLength(cryptoMech);
            }
            if (keyLength == 0) {
                goto loser;
            }
        }
        /* currently SEC_OID_HMAC_SHA1 is the default */
        if (prfAlg == SEC_OID_UNKNOWN) {
            prfAlg = SEC_OID_HMAC_SHA1;
        }

        /* build the PKCS5v2 cipher algorithm id */
        cipherParams = pk11_GenerateNewParamWithKeyLen(
            PK11_AlgtagToMechanism(cipherAlgorithm), keyLength);
        if (!cipherParams) {
            goto loser;
        }

        PORT_Memset(&pbeV2_param, 0, sizeof(pbeV2_param));

        rv = PK11_ParamToAlgid(cipherAlgorithm, cipherParams,
                               poolp, &pbeV2_param.cipherAlgId);
        SECITEM_FreeItem(cipherParams, PR_TRUE);
        if (rv != SECSuccess) {
            goto loser;
        }
    }

    /* generate the parameter */
    pbe_param = sec_pkcs5_create_pbe_parameter(pbeAlgorithm, salt, iteration,
                                               keyLength, prfAlg);
    if (!pbe_param) {
        goto loser;
    }

    /* generate the algorithm id */
    algid = (SECAlgorithmID *)PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID));
    if (algid == NULL) {
        goto loser;
    }

    der_param.data = NULL;
    der_param.len = 0;
    if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm)) {
        /* first encode the PBE algorithm ID */
        dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
                                   SEC_PKCS5V2PBEParameterTemplate);
        if (dummy == NULL) {
            goto loser;
        }
        rv = SECOID_SetAlgorithmID(poolp, &pbeV2_param.pbeAlgId,
                                   pbeAlgorithm, &der_param);
        if (rv != SECSuccess) {
            goto loser;
        }

        /* now encode the Full PKCS 5 parameter */
        der_param.data = NULL;
        der_param.len = 0;
        dummy = SEC_ASN1EncodeItem(poolp, &der_param, &pbeV2_param,
                                   SEC_PKCS5V2ParameterTemplate);
    } else if (!sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
        dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
                                   SEC_PKCS5PBEParameterTemplate);
    } else {
        dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
                                   SEC_V2PKCS12PBEParameterTemplate);
    }
    if (dummy == NULL) {
        goto loser;
    }

    rv = SECOID_SetAlgorithmID(poolp, algid, algorithm, &der_param);
    if (rv != SECSuccess) {
        goto loser;
    }

    ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID));
    if (ret_algid == NULL) {
        goto loser;
    }

    rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid);
    if (rv != SECSuccess) {
        SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE);
        ret_algid = NULL;
    } else if (pPbeAlgorithm) {
        *pPbeAlgorithm = pbeAlgorithm;
    }

loser:
    if (poolp != NULL) {
        PORT_FreeArena(poolp, PR_TRUE);
        algid = NULL;
    }

    if (pbe_param) {
        sec_pkcs5_destroy_pbe_param(pbe_param);
    }

    return ret_algid;
}

SECStatus
pbe_PK11AlgidToParam(SECAlgorithmID *algid, SECItem *mech)
{
    SEC_PKCS5PBEParameter p5_param;
    SECItem *salt = NULL;
    SECOidTag algorithm = SECOID_GetAlgorithmTag(algid);
    PLArenaPool *arena = NULL;
    SECStatus rv = SECFailure;
    unsigned char *paramData = NULL;
    unsigned char *pSalt = NULL;
    CK_ULONG iterations;
    int paramLen = 0;
    int iv_len;

    arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
    if (arena == NULL) {
        goto loser;
    }

    /*
     * decode the algid based on the pbe type
     */
    PORT_Memset(&p5_param, 0, sizeof(p5_param));
    if (sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
        iv_len = PK11_GetIVLength(PK11_AlgtagToMechanism(algorithm));
        rv = SEC_ASN1DecodeItem(arena, &p5_param,
                                SEC_V2PKCS12PBEParameterTemplate, &algid->parameters);
    } else if (algorithm == SEC_OID_PKCS5_PBKDF2) {
        iv_len = 0;
        rv = SEC_ASN1DecodeItem(arena, &p5_param,
                                SEC_PKCS5V2PBEParameterTemplate, &algid->parameters);
    } else {
        iv_len = PK11_GetIVLength(PK11_AlgtagToMechanism(algorithm));
        rv = SEC_ASN1DecodeItem(arena, &p5_param, SEC_PKCS5PBEParameterTemplate,
                                &algid->parameters);
    }

    if (iv_len < 0) {
        goto loser;
    }

    if (rv != SECSuccess) {
        goto loser;
    }

    /* get salt */
    salt = &p5_param.salt;
    iterations = (CK_ULONG)DER_GetInteger(&p5_param.iteration);

    /* allocate and fill in the PKCS #11 parameters
     * based on the algorithm. */
    if (algorithm == SEC_OID_PKCS5_PBKDF2) {
        SECOidTag prfAlgTag;
        CK_PKCS5_PBKD2_PARAMS *pbeV2_params =
            (CK_PKCS5_PBKD2_PARAMS *)PORT_ZAlloc(
                sizeof(CK_PKCS5_PBKD2_PARAMS) + salt->len);

        if (pbeV2_params == NULL) {
            goto loser;
        }
        paramData = (unsigned char *)pbeV2_params;
        paramLen = sizeof(CK_PKCS5_PBKD2_PARAMS);

        /* set the prf */
        prfAlgTag = SEC_OID_HMAC_SHA1;
        if (p5_param.pPrfAlgId &&
            p5_param.pPrfAlgId->algorithm.data != 0) {
            prfAlgTag = SECOID_GetAlgorithmTag(p5_param.pPrfAlgId);
        }
        switch (prfAlgTag) {
            case SEC_OID_HMAC_SHA1:
                pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA1;
                break;
            case SEC_OID_HMAC_SHA224:
                pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA224;
                break;
            case SEC_OID_HMAC_SHA256:
                pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA256;
                break;
            case SEC_OID_HMAC_SHA384:
                pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA384;
                break;
            case SEC_OID_HMAC_SHA512:
                pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA512;
                break;
            default:
                PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
                goto loser;
        }

        /* probably should fetch these from the prfAlgid */
        pbeV2_params->pPrfData = NULL;
        pbeV2_params->ulPrfDataLen = 0;
        pbeV2_params->saltSource = CKZ_SALT_SPECIFIED;
        pSalt = ((CK_CHAR_PTR)pbeV2_params) + sizeof(CK_PKCS5_PBKD2_PARAMS);
        PORT_Memcpy(pSalt, salt->data, salt->len);
        pbeV2_params->pSaltSourceData = pSalt;
        pbeV2_params->ulSaltSourceDataLen = salt->len;
        pbeV2_params->iterations = iterations;
    } else {
        CK_PBE_PARAMS *pbe_params = NULL;
        pbe_params = (CK_PBE_PARAMS *)PORT_ZAlloc(sizeof(CK_PBE_PARAMS) +
                                                  salt->len + iv_len);
        if (pbe_params == NULL) {
            goto loser;
        }
        paramData = (unsigned char *)pbe_params;
        paramLen = sizeof(CK_PBE_PARAMS);

        pSalt = ((CK_CHAR_PTR)pbe_params) + sizeof(CK_PBE_PARAMS);
        pbe_params->pSalt = pSalt;
        PORT_Memcpy(pSalt, salt->data, salt->len);
        pbe_params->ulSaltLen = salt->len;
        if (iv_len) {
            pbe_params->pInitVector =
                ((CK_CHAR_PTR)pbe_params) + sizeof(CK_PBE_PARAMS) + salt->len;
        }
        pbe_params->ulIteration = iterations;
    }

    /* copy into the mechanism sec item */
    mech->data = paramData;
    mech->len = paramLen;
    if (arena) {
        PORT_FreeArena(arena, PR_TRUE);
    }
    return SECSuccess;

loser:
    if (paramData) {
        PORT_Free(paramData);
    }
    if (arena) {
        PORT_FreeArena(arena, PR_TRUE);
    }
    return SECFailure;
}

/*
 * public, deprecated, not valid for pkcs5 v2
 *
 * use PK11_CreatePBEV2AlgorithmID or PK11_CreatePBEAlgorithmID to create
 * PBE algorithmID's directly.
 */
SECStatus
PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param, PLArenaPool *arena,
                     SECAlgorithmID *algId)
{
    CK_PBE_PARAMS *pbe_param;
    SECItem pbeSalt;
    SECAlgorithmID *pbeAlgID = NULL;
    SECStatus rv;

    if (!param || !algId) {
        return SECFailure;
    }

    pbe_param = (CK_PBE_PARAMS *)param->data;
    pbeSalt.data = (unsigned char *)pbe_param->pSalt;
    pbeSalt.len = pbe_param->ulSaltLen;
    pbeAlgID = sec_pkcs5CreateAlgorithmID(algTag, SEC_OID_UNKNOWN,
                                          SEC_OID_UNKNOWN, NULL, 0,
                                          &pbeSalt, (int)pbe_param->ulIteration);
    if (!pbeAlgID) {
        return SECFailure;
    }

    rv = SECOID_CopyAlgorithmID(arena, algId, pbeAlgID);
    SECOID_DestroyAlgorithmID(pbeAlgID, PR_TRUE);
    return rv;
}

/*
 * public, Deprecated, This function is only for binary compatibility with
 * older applications. Does not support PKCS5v2.
 *
 * Applications should use PK11_PBEKeyGen() for keys and PK11_GetPBEIV() for
 * iv values rather than generating PBE bits directly.
 */
PBEBitGenContext *
PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
                  SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
                  unsigned int iterations)
{
    SECItem *context = NULL;
    SECItem mechItem;
    CK_PBE_PARAMS pbe_params;
    CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM;
    PK11SlotInfo *slot;
    PK11SymKey *symKey = NULL;
    unsigned char ivData[8];

    /* use the purpose to select the low level keygen algorithm */
    switch (bitGenPurpose) {
        case pbeBitGenIntegrityKey:
            switch (hashAlgorithm) {
                case SEC_OID_SHA1:
                    mechanism = CKM_PBA_SHA1_WITH_SHA1_HMAC;
                    break;
                case SEC_OID_MD2:
                    mechanism = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN;
                    break;
                case SEC_OID_MD5:
                    mechanism = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN;
                    break;
                default:
                    break;
            }
            break;
        case pbeBitGenCipherIV:
            if (bitsNeeded > 64) {
                break;
            }
            if (hashAlgorithm != SEC_OID_SHA1) {
                break;
            }
            mechanism = CKM_PBE_SHA1_DES3_EDE_CBC;
            break;
        case pbeBitGenCipherKey:
            if (hashAlgorithm != SEC_OID_SHA1) {
                break;
            }
            switch (bitsNeeded) {
                case 40:
                    mechanism = CKM_PBE_SHA1_RC4_40;
                    break;
                case 128:
                    mechanism = CKM_PBE_SHA1_RC4_128;
                    break;
                default:
                    break;
            }
        case pbeBitGenIDNull:
            break;
    }

    if (mechanism == CKM_INVALID_MECHANISM) {
        /* we should set an error, but this is a deprecated function, and
         * we are keeping bug for bug compatibility;)... */
        return NULL;
    }

    pbe_params.pInitVector = ivData;
    pbe_params.pPassword = pwitem->data;
    pbe_params.ulPasswordLen = pwitem->len;
    pbe_params.pSalt = salt->data;
    pbe_params.ulSaltLen = salt->len;
    pbe_params.ulIteration = iterations;
    mechItem.data = (unsigned char *)&pbe_params;
    mechItem.len = sizeof(pbe_params);

    slot = PK11_GetInternalSlot();
    symKey = PK11_RawPBEKeyGen(slot, mechanism,
                               &mechItem, pwitem, PR_FALSE, NULL);
    PK11_FreeSlot(slot);
    if (symKey != NULL) {
        if (bitGenPurpose == pbeBitGenCipherIV) {
            /* NOTE: this assumes that bitsNeeded is a multiple of 8! */
            SECItem ivItem;

            ivItem.data = ivData;
            ivItem.len = bitsNeeded / 8;
            context = SECITEM_DupItem(&ivItem);
        } else {
            SECItem *keyData;
            PK11_ExtractKeyValue(symKey);
            keyData = PK11_GetKeyData(symKey);

            /* assert bitsNeeded with length? */
            if (keyData) {
                context = SECITEM_DupItem(keyData);
            }
        }
        PK11_FreeSymKey(symKey);
    }

    return (PBEBitGenContext *)context;
}

/*
 * public, Deprecated, This function is only for binary compatibility with
 * older applications. Does not support PKCS5v2.
 *
 * Applications should use PK11_PBEKeyGen() for keys and PK11_GetIV() for
 * iv values rather than generating PBE bits directly.
 */
SECItem *
PBE_GenerateBits(PBEBitGenContext *context)
{
    return (SECItem *)context;
}

/*
 * public, Deprecated, This function is only for binary compatibility with
 * older applications. Does not support PKCS5v2.
 *
 * Applications should use PK11_PBEKeyGen() for keys and PK11_GetPBEIV() for
 * iv values rather than generating PBE bits directly.
 */
void
PBE_DestroyContext(PBEBitGenContext *context)
{
    SECITEM_FreeItem((SECItem *)context, PR_TRUE);
}

/*
 * public, deprecated. Replaced with PK11_GetPBEIV().
 */
SECItem *
SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES)
{
    /* pbe stuff */
    CK_MECHANISM_TYPE type;
    SECItem *param = NULL;
    SECItem *iv = NULL;
    SECItem src;
    int iv_len = 0;
    PK11SymKey *symKey;
    PK11SlotInfo *slot;
    CK_PBE_PARAMS_PTR pPBEparams;
    SECOidTag pbeAlg;

    pbeAlg = SECOID_GetAlgorithmTag(algid);
    if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(pbeAlg)) {
        unsigned char *ivData;
        sec_pkcs5V2Parameter *pbeV2_param = NULL;

        /* can only return the IV if the crypto Algorithm exists */
        if (pbeAlg == SEC_OID_PKCS5_PBKDF2) {
            PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
            goto loser;
        }
        pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid);
        if (pbeV2_param == NULL) {
            goto loser;
        }
        /* extract the IV from the cipher algid portion of our pkcs 5 v2
         * algorithm id */
        type = PK11_AlgtagToMechanism(
            SECOID_GetAlgorithmTag(&pbeV2_param->cipherAlgId));
        param = PK11_ParamFromAlgid(&pbeV2_param->cipherAlgId);
        sec_pkcs5_v2_destroy_v2_param(pbeV2_param);
        if (!param) {
            goto loser;
        }
        /* NOTE: NULL is a permissible return here */
        ivData = PK11_IVFromParam(type, param, &iv_len);
        src.data = ivData;
        src.len = iv_len;
        goto done;
    }

    type = PK11_AlgtagToMechanism(pbeAlg);
    param = PK11_ParamFromAlgid(algid);
    if (param == NULL) {
        goto done;
    }
    slot = PK11_GetInternalSlot();
    symKey = PK11_RawPBEKeyGen(slot, type, param, pwitem, faulty3DES, NULL);
    PK11_FreeSlot(slot);
    if (symKey == NULL) {
        goto loser;
    }
    PK11_FreeSymKey(symKey);
    pPBEparams = (CK_PBE_PARAMS_PTR)param->data;
    iv_len = PK11_GetIVLength(type);

    src.data = (unsigned char *)pPBEparams->pInitVector;
    src.len = iv_len;

done:
    iv = SECITEM_DupItem(&src);

loser:
    if (param) {
        SECITEM_ZfreeItem(param, PR_TRUE);
    }
    return iv;
}

/*
 * Subs from nss 3.x that are deprecated
 */
PBEBitGenContext *
__PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
                    SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
                    unsigned int iterations)
{
    PORT_Assert("__PBE_CreateContext is Deprecated" == NULL);
    return NULL;
}

SECItem *
__PBE_GenerateBits(PBEBitGenContext *context)
{
    PORT_Assert("__PBE_GenerateBits is Deprecated" == NULL);
    return NULL;
}

void
__PBE_DestroyContext(PBEBitGenContext *context)
{
    PORT_Assert("__PBE_DestroyContext is Deprecated" == NULL);
}

SECStatus
RSA_FormatBlock(SECItem *result, unsigned modulusLen,
                int blockType, SECItem *data)
{
    PORT_Assert("RSA_FormatBlock is Deprecated" == NULL);
    return SECFailure;
}

/****************************************************************************
 *
 * Now Do The PBE Functions Here...
 *
 ****************************************************************************/

static void
pk11_destroy_ck_pbe_params(CK_PBE_PARAMS *pbe_params)
{
    if (pbe_params) {
        if (pbe_params->pPassword)
            PORT_ZFree(pbe_params->pPassword, pbe_params->ulPasswordLen);
        if (pbe_params->pSalt)
            PORT_ZFree(pbe_params->pSalt, pbe_params->ulSaltLen);
        PORT_ZFree(pbe_params, sizeof(CK_PBE_PARAMS));
    }
}

/*
 * public, deprecated.  use PK11_CreatePBEAlgorithmID or
 * PK11_CreatePBEV2AlgorithmID instead. If you needthe pkcs #11 parameters,
 * use PK11_ParamFromAlgid from the algorithm id you created using
 * PK11_CreatePBEAlgorithmID or PK11_CreatePBEV2AlgorithmID.
 */
SECItem *
PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations)
{
    CK_PBE_PARAMS *pbe_params = NULL;
    SECItem *paramRV = NULL;

    paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS));
    if (!paramRV) {
        goto loser;
    }
    /* init paramRV->data with zeros. SECITEM_AllocItem does not do it */
    PORT_Memset(paramRV->data, 0, sizeof(CK_PBE_PARAMS));

    pbe_params = (CK_PBE_PARAMS *)paramRV->data;
    pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwd->len);
    if (!pbe_params->pPassword) {
        goto loser;
    }
    PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len);
    pbe_params->ulPasswordLen = pwd->len;

    pbe_params->pSalt = (CK_CHAR_PTR)PORT_ZAlloc(salt->len);
    if (!pbe_params->pSalt) {
        goto loser;
    }
    PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len);
    pbe_params->ulSaltLen = salt->len;

    pbe_params->ulIteration = (CK_ULONG)iterations;
    return paramRV;

loser:
    if (pbe_params)
        pk11_destroy_ck_pbe_params(pbe_params);
    if (paramRV)
        PORT_ZFree(paramRV, sizeof(SECItem));
    return NULL;
}

/*
 * public, deprecated.
 */
void
PK11_DestroyPBEParams(SECItem *pItem)
{
    if (pItem) {
        CK_PBE_PARAMS *params = (CK_PBE_PARAMS *)(pItem->data);
        if (params)
            pk11_destroy_ck_pbe_params(params);
        PORT_ZFree(pItem, sizeof(SECItem));
    }
}

/*
 * public, Partially supports PKCS5 V2 (some parameters are not controllable
 * through this interface). Use PK11_CreatePBEV2AlgorithmID() if you need
 * finer control these.
 */
SECAlgorithmID *
PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt)
{
    SECAlgorithmID *algid = NULL;
    algid = sec_pkcs5CreateAlgorithmID(algorithm,
                                       SEC_OID_UNKNOWN, SEC_OID_UNKNOWN, NULL,
                                       0, salt, iteration);
    return algid;
}

/*
 * public, fully support pkcs5v2.
 */
SECAlgorithmID *
PK11_CreatePBEV2AlgorithmID(SECOidTag pbeAlgTag, SECOidTag cipherAlgTag,
                            SECOidTag prfAlgTag, int keyLength, int iteration,
                            SECItem *salt)
{
    SECAlgorithmID *algid = NULL;
    algid = sec_pkcs5CreateAlgorithmID(pbeAlgTag, cipherAlgTag, prfAlgTag,
                                       NULL, keyLength, salt, iteration);
    return algid;
}

/*
 * private.
 */
PK11SymKey *
pk11_RawPBEKeyGenWithKeyType(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
                             SECItem *params, CK_KEY_TYPE keyType, int keyLen,
                             SECItem *pwitem, void *wincx)
{
    CK_ULONG pwLen;
    /* do some sanity checks */
    if ((params == NULL) || (params->data == NULL)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    if (type == CKM_INVALID_MECHANISM) {
        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
        return NULL;
    }

    /* set the password pointer in the parameters... */
    if (type == CKM_PKCS5_PBKD2) {
        CK_PKCS5_PBKD2_PARAMS *pbev2_params;
        if (params->len < sizeof(CK_PKCS5_PBKD2_PARAMS)) {
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            return NULL;
        }
        pbev2_params = (CK_PKCS5_PBKD2_PARAMS *)params->data;
        pbev2_params->pPassword = pwitem->data;
        pwLen = pwitem->len;
        pbev2_params->ulPasswordLen = &pwLen;
    } else {
        CK_PBE_PARAMS *pbe_params;
        if (params->len < sizeof(CK_PBE_PARAMS)) {
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            return NULL;
        }
        pbe_params = (CK_PBE_PARAMS *)params->data;
        pbe_params->pPassword = pwitem->data;
        pbe_params->ulPasswordLen = pwitem->len;
    }

    /* generate the key (and sometimes the IV as a side effect...) */
    return pk11_TokenKeyGenWithFlagsAndKeyType(slot, type, params, keyType,
                                               keyLen, NULL,
                                               CKF_SIGN | CKF_ENCRYPT | CKF_DECRYPT | CKF_UNWRAP | CKF_WRAP,
                                               0, wincx);
}

/*
 * public, deprecated. use PK11_PBEKeyGen instead.
 */
PK11SymKey *
PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *mech,
                  SECItem *pwitem, PRBool faulty3DES, void *wincx)
{
    if (faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) {
        type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC;
    }
    return pk11_RawPBEKeyGenWithKeyType(slot, type, mech, -1, 0, pwitem, wincx);
}

/*
 * pubic, supports pkcs5 v2.
 *
 * Create symkey from a PBE key. The algid can be created with
 *  PK11_CreatePBEV2AlgorithmID and PK11_CreatePBEAlgorithmID, or by
 *  extraction of der data.
 */
PK11SymKey *
PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem,
               PRBool faulty3DES, void *wincx)
{
    CK_MECHANISM_TYPE type;
    SECItem *param = NULL;
    PK11SymKey *symKey = NULL;
    SECOidTag pbeAlg;
    CK_KEY_TYPE keyType = -1;
    int keyLen = 0;

    pbeAlg = SECOID_GetAlgorithmTag(algid);
    /* if we're using PKCS5v2, extract the additional information we need
     * (key length, key type, and pbeAlg). */
    if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(pbeAlg)) {
        CK_MECHANISM_TYPE cipherMech;
        sec_pkcs5V2Parameter *pbeV2_param;

        pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid);
        if (pbeV2_param == NULL) {
            return NULL;
        }
        cipherMech = PK11_AlgtagToMechanism(
            SECOID_GetAlgorithmTag(&pbeV2_param->cipherAlgId));
        pbeAlg = SECOID_GetAlgorithmTag(&pbeV2_param->pbeAlgId);
        param = PK11_ParamFromAlgid(&pbeV2_param->pbeAlgId);
        sec_pkcs5_v2_destroy_v2_param(pbeV2_param);
        keyLen = SEC_PKCS5GetKeyLength(algid);
        if (keyLen == -1) {
            keyLen = 0;
        }
        keyType = PK11_GetKeyType(cipherMech, keyLen);
    } else {
        param = PK11_ParamFromAlgid(algid);
    }

    if (param == NULL) {
        goto loser;
    }

    type = PK11_AlgtagToMechanism(pbeAlg);
    if (type == CKM_INVALID_MECHANISM) {
        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
        goto loser;
    }
    if (faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) {
        type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC;
    }
    symKey = pk11_RawPBEKeyGenWithKeyType(slot, type, param, keyType, keyLen,
                                          pwitem, wincx);

loser:
    if (param) {
        SECITEM_ZfreeItem(param, PR_TRUE);
    }
    return symKey;
}

/*
 * public, supports pkcs5v2
 */
SECItem *
PK11_GetPBEIV(SECAlgorithmID *algid, SECItem *pwitem)
{
    return SEC_PKCS5GetIV(algid, pwitem, PR_FALSE);
}

CK_MECHANISM_TYPE
pk11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param,
                           SECItem *pbe_pwd, PRBool faulty3DES)
{
    int keyLen = 0;
    SECOidTag algTag = SEC_PKCS5GetCryptoAlgorithm(algid);
    CK_MECHANISM_TYPE mech = PK11_AlgtagToMechanism(algTag);
    CK_MECHANISM_TYPE returnedMechanism = CKM_INVALID_MECHANISM;
    SECItem *iv = NULL;

    if (mech == CKM_INVALID_MECHANISM) {
        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
        goto loser;
    }
    if (PK11_GetIVLength(mech)) {
        iv = SEC_PKCS5GetIV(algid, pbe_pwd, faulty3DES);
        if (iv == NULL) {
            goto loser;
        }
    }

    keyLen = SEC_PKCS5GetKeyLength(algid);

    *param = pk11_ParamFromIVWithLen(mech, iv, keyLen);
    if (*param == NULL) {
        goto loser;
    }
    returnedMechanism = mech;

loser:
    if (iv) {
        SECITEM_FreeItem(iv, PR_TRUE);
    }
    return returnedMechanism;
}

/*
 * Public, supports pkcs5 v2
 *
 * Get the crypto mechanism directly from the pbe algorithmid.
 *
 * It's important to go directly from the algorithm id so that we can
 * handle both the PKCS #5 v1, PKCS #12, and PKCS #5 v2 cases.
 *
 * This function returns both the mechanism and the parameter for the mechanism.
 * The caller is responsible for freeing the parameter.
 */
CK_MECHANISM_TYPE
PK11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param,
                           SECItem *pbe_pwd)
{
    return pk11_GetPBECryptoMechanism(algid, param, pbe_pwd, PR_FALSE);
}
