/*
 * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/*
 * Support for PVK format keys and related structures (such a PUBLICKEYBLOB
 * and PRIVATEKEYBLOB).
 */

/*
 * RSA and DSA low level APIs are deprecated for public use, but still ok for
 * internal use.
 */
#include "internal/deprecated.h"

#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/bn.h>
#include <openssl/dsa.h>
#include <openssl/rsa.h>
#include <openssl/kdf.h>
#include <openssl/core_names.h>
#include "internal/cryptlib.h"
#include "crypto/pem.h"
#include "crypto/evp.h"

/*
 * Utility function: read a DWORD (4 byte unsigned integer) in little endian
 * format
 */

static unsigned int read_ledword(const unsigned char **in)
{
    const unsigned char *p = *in;
    unsigned int ret;

    ret = (unsigned int)*p++;
    ret |= (unsigned int)*p++ << 8;
    ret |= (unsigned int)*p++ << 16;
    ret |= (unsigned int)*p++ << 24;
    *in = p;
    return ret;
}

/*
 * Read a BIGNUM in little endian format. The docs say that this should take
 * up bitlen/8 bytes.
 */

static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r)
{
    *r = BN_lebin2bn(*in, nbyte, NULL);
    if (*r == NULL)
        return 0;
    *in += nbyte;
    return 1;
}

/*
 * Create an EVP_PKEY from a type specific key.
 * This takes ownership of |key|, as long as the |evp_type| is acceptable
 * (EVP_PKEY_RSA or EVP_PKEY_DSA), even if the resulting EVP_PKEY wasn't
 * created.
 */
#define isdss_to_evp_type(isdss)                                \
    (isdss == 0 ? EVP_PKEY_RSA : isdss == 1 ? EVP_PKEY_DSA : EVP_PKEY_NONE)
static EVP_PKEY *evp_pkey_new0_key(void *key, int evp_type)
{
    EVP_PKEY *pkey = NULL;

    /*
     * It's assumed that if |key| is NULL, something went wrong elsewhere
     * and suitable errors are already reported.
     */
    if (key == NULL)
        return NULL;

    if (!ossl_assert(evp_type == EVP_PKEY_RSA || evp_type == EVP_PKEY_DSA)) {
        ERR_raise(ERR_LIB_PEM, ERR_R_INTERNAL_ERROR);
        return NULL;
    }

    if ((pkey = EVP_PKEY_new()) != NULL) {
        switch (evp_type) {
        case EVP_PKEY_RSA:
            if (EVP_PKEY_set1_RSA(pkey, key))
                break;
            EVP_PKEY_free(pkey);
            pkey = NULL;
            break;
#ifndef OPENSSL_NO_DSA
        case EVP_PKEY_DSA:
            if (EVP_PKEY_set1_DSA(pkey, key))
                break;
            EVP_PKEY_free(pkey);
            pkey = NULL;
            break;
#endif
        }
    }

    switch (evp_type) {
    case EVP_PKEY_RSA:
        RSA_free(key);
        break;
#ifndef OPENSSL_NO_DSA
    case EVP_PKEY_DSA:
        DSA_free(key);
        break;
#endif
    }

    if (pkey == NULL)
        ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
    return pkey;
}

/* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */

# define MS_PUBLICKEYBLOB        0x6
# define MS_PRIVATEKEYBLOB       0x7
# define MS_RSA1MAGIC            0x31415352L
# define MS_RSA2MAGIC            0x32415352L
# define MS_DSS1MAGIC            0x31535344L
# define MS_DSS2MAGIC            0x32535344L

# define MS_KEYALG_RSA_KEYX      0xa400
# define MS_KEYALG_DSS_SIGN      0x2200

# define MS_KEYTYPE_KEYX         0x1
# define MS_KEYTYPE_SIGN         0x2

/* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */
# define MS_PVKMAGIC             0xb0b5f11eL
/* Salt length for PVK files */
# define PVK_SALTLEN             0x10
/* Maximum length in PVK header */
# define PVK_MAX_KEYLEN          102400
/* Maximum salt length */
# define PVK_MAX_SALTLEN         10240

/*
 * Read the MSBLOB header and get relevant data from it.
 *
 * |pisdss| and |pispub| have a double role, as they can be used for
 * discovery as well as to check the the blob meets expectations.
 * |*pisdss| is the indicator for whether the key is a DSA key or not.
 * |*pispub| is the indicator for whether the key is public or not.
 * In both cases, the following input values apply:
 *
 * 0    Expected to not be what the variable indicates.
 * 1    Expected to be what the variable indicates.
 * -1   No expectations, this function will assign 0 or 1 depending on
 *      header data.
 */
int ossl_do_blob_header(const unsigned char **in, unsigned int length,
                        unsigned int *pmagic, unsigned int *pbitlen,
                        int *pisdss, int *pispub)
{
    const unsigned char *p = *in;

    if (length < 16)
        return 0;
    /* bType */
    switch (*p) {
    case MS_PUBLICKEYBLOB:
        if (*pispub == 0) {
            ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
            return 0;
        }
        *pispub = 1;
        break;

    case MS_PRIVATEKEYBLOB:
        if (*pispub == 1) {
            ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
            return 0;
        }
        *pispub = 0;
        break;

    default:
        return 0;
    }
    p++;
    /* Version */
    if (*p++ != 0x2) {
        ERR_raise(ERR_LIB_PEM, PEM_R_BAD_VERSION_NUMBER);
        return 0;
    }
    /* Ignore reserved, aiKeyAlg */
    p += 6;
    *pmagic = read_ledword(&p);
    *pbitlen = read_ledword(&p);

    /* Consistency check for private vs public */
    switch (*pmagic) {
    case MS_DSS1MAGIC:
    case MS_RSA1MAGIC:
        if (*pispub == 0) {
            ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
            return 0;
        }
        break;

    case MS_DSS2MAGIC:
    case MS_RSA2MAGIC:
        if (*pispub == 1) {
            ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
            return 0;
        }
        break;

    default:
        ERR_raise(ERR_LIB_PEM, PEM_R_BAD_MAGIC_NUMBER);
        return -1;
    }

    /* Check that we got the expected type */
    switch (*pmagic) {
    case MS_DSS1MAGIC:
    case MS_DSS2MAGIC:
        if (*pisdss == 0) {
            ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_DSS_KEY_BLOB);
            return 0;
        }
        *pisdss = 1;
        break;
    case MS_RSA1MAGIC:
    case MS_RSA2MAGIC:
        if (*pisdss == 1) {
            ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_RSA_KEY_BLOB);
            return 0;
        }
        *pisdss = 0;
        break;

    default:
        ERR_raise(ERR_LIB_PEM, PEM_R_BAD_MAGIC_NUMBER);
        return -1;
    }
    *in = p;
    return 1;
}

unsigned int ossl_blob_length(unsigned bitlen, int isdss, int ispub)
{
    unsigned int nbyte = (bitlen + 7) >> 3;
    unsigned int hnbyte = (bitlen + 15) >> 4;

    if (isdss) {

        /*
         * Expected length: 20 for q + 3 components bitlen each + 24 for seed
         * structure.
         */
        if (ispub)
            return 44 + 3 * nbyte;
        /*
         * Expected length: 20 for q, priv, 2 bitlen components + 24 for seed
         * structure.
         */
        else
            return 64 + 2 * nbyte;
    } else {
        /* Expected length: 4 for 'e' + 'n' */
        if (ispub)
            return 4 + nbyte;
        else
            /*
             * Expected length: 4 for 'e' and 7 other components. 2
             * components are bitlen size, 5 are bitlen/2
             */
            return 4 + 2 * nbyte + 5 * hnbyte;
    }

}

static void *do_b2i_key(const unsigned char **in, unsigned int length,
                        int *isdss, int *ispub)
{
    const unsigned char *p = *in;
    unsigned int bitlen, magic;
    void *key = NULL;

    if (ossl_do_blob_header(&p, length, &magic, &bitlen, isdss, ispub) <= 0) {
        ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_HEADER_PARSE_ERROR);
        return NULL;
    }
    length -= 16;
    if (length < ossl_blob_length(bitlen, *isdss, *ispub)) {
        ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT);
        return NULL;
    }
    if (!*isdss)
        key = ossl_b2i_RSA_after_header(&p, bitlen, *ispub);
#ifndef OPENSSL_NO_DSA
    else
        key = ossl_b2i_DSA_after_header(&p, bitlen, *ispub);
#endif

    if (key == NULL) {
        ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
        return NULL;
    }

    return key;
}

EVP_PKEY *ossl_b2i(const unsigned char **in, unsigned int length, int *ispub)
{
    int isdss = -1;
    void *key = do_b2i_key(in, length, &isdss, ispub);

    return evp_pkey_new0_key(key, isdss_to_evp_type(isdss));
}

EVP_PKEY *ossl_b2i_bio(BIO *in, int *ispub)
{
    const unsigned char *p;
    unsigned char hdr_buf[16], *buf = NULL;
    unsigned int bitlen, magic, length;
    int isdss = -1;
    void *key = NULL;
    EVP_PKEY *pkey = NULL;

    if (BIO_read(in, hdr_buf, 16) != 16) {
        ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT);
        return NULL;
    }
    p = hdr_buf;
    if (ossl_do_blob_header(&p, 16, &magic, &bitlen, &isdss, ispub) <= 0)
        return NULL;

    length = ossl_blob_length(bitlen, isdss, *ispub);
    if (length > BLOB_MAX_LENGTH) {
        ERR_raise(ERR_LIB_PEM, PEM_R_HEADER_TOO_LONG);
        return NULL;
    }
    buf = OPENSSL_malloc(length);
    if (buf == NULL) {
        ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    p = buf;
    if (BIO_read(in, buf, length) != (int)length) {
        ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT);
        goto err;
    }

    if (!isdss)
        key = ossl_b2i_RSA_after_header(&p, bitlen, *ispub);
#ifndef OPENSSL_NO_DSA
    else
        key = ossl_b2i_DSA_after_header(&p, bitlen, *ispub);
#endif

    if (key == NULL) {
        ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
        goto err;
    }

    pkey = evp_pkey_new0_key(key, isdss_to_evp_type(isdss));
 err:
    OPENSSL_free(buf);
    return pkey;
}

#ifndef OPENSSL_NO_DSA
DSA *ossl_b2i_DSA_after_header(const unsigned char **in, unsigned int bitlen,
                               int ispub)
{
    const unsigned char *p = *in;
    DSA *dsa = NULL;
    BN_CTX *ctx = NULL;
    BIGNUM *pbn = NULL, *qbn = NULL, *gbn = NULL, *priv_key = NULL;
    BIGNUM *pub_key = NULL;
    unsigned int nbyte = (bitlen + 7) >> 3;

    dsa = DSA_new();
    if (dsa == NULL)
        goto memerr;
    if (!read_lebn(&p, nbyte, &pbn))
        goto memerr;

    if (!read_lebn(&p, 20, &qbn))
        goto memerr;

    if (!read_lebn(&p, nbyte, &gbn))
        goto memerr;

    if (ispub) {
        if (!read_lebn(&p, nbyte, &pub_key))
            goto memerr;
    } else {
        if (!read_lebn(&p, 20, &priv_key))
            goto memerr;

        /* Set constant time flag before public key calculation */
        BN_set_flags(priv_key, BN_FLG_CONSTTIME);

        /* Calculate public key */
        pub_key = BN_new();
        if (pub_key == NULL)
            goto memerr;
        if ((ctx = BN_CTX_new()) == NULL)
            goto memerr;

        if (!BN_mod_exp(pub_key, gbn, priv_key, pbn, ctx))
            goto memerr;

        BN_CTX_free(ctx);
        ctx = NULL;
    }
    if (!DSA_set0_pqg(dsa, pbn, qbn, gbn))
        goto memerr;
    pbn = qbn = gbn = NULL;
    if (!DSA_set0_key(dsa, pub_key, priv_key))
        goto memerr;
    pub_key = priv_key = NULL;

    *in = p;
    return dsa;

 memerr:
    ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
    DSA_free(dsa);
    BN_free(pbn);
    BN_free(qbn);
    BN_free(gbn);
    BN_free(pub_key);
    BN_free(priv_key);
    BN_CTX_free(ctx);
    return NULL;
}
#endif

RSA *ossl_b2i_RSA_after_header(const unsigned char **in, unsigned int bitlen,
                               int ispub)
{
    const unsigned char *pin = *in;
    BIGNUM *e = NULL, *n = NULL, *d = NULL;
    BIGNUM *p = NULL, *q = NULL, *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
    RSA *rsa = NULL;
    unsigned int nbyte = (bitlen + 7) >> 3;
    unsigned int hnbyte = (bitlen + 15) >> 4;

    rsa = RSA_new();
    if (rsa == NULL)
        goto memerr;
    e = BN_new();
    if (e == NULL)
        goto memerr;
    if (!BN_set_word(e, read_ledword(&pin)))
        goto memerr;
    if (!read_lebn(&pin, nbyte, &n))
        goto memerr;
    if (!ispub) {
        if (!read_lebn(&pin, hnbyte, &p))
            goto memerr;
        if (!read_lebn(&pin, hnbyte, &q))
            goto memerr;
        if (!read_lebn(&pin, hnbyte, &dmp1))
            goto memerr;
        if (!read_lebn(&pin, hnbyte, &dmq1))
            goto memerr;
        if (!read_lebn(&pin, hnbyte, &iqmp))
            goto memerr;
        if (!read_lebn(&pin, nbyte, &d))
            goto memerr;
        if (!RSA_set0_factors(rsa, p, q))
            goto memerr;
        p = q = NULL;
        if (!RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp))
            goto memerr;
        dmp1 = dmq1 = iqmp = NULL;
    }
    if (!RSA_set0_key(rsa, n, e, d))
        goto memerr;
    n = e = d = NULL;

    *in = pin;
    return rsa;
 memerr:
    ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
    BN_free(e);
    BN_free(n);
    BN_free(p);
    BN_free(q);
    BN_free(dmp1);
    BN_free(dmq1);
    BN_free(iqmp);
    BN_free(d);
    RSA_free(rsa);
    return NULL;
}

EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length)
{
    int ispub = 0;

    return ossl_b2i(in, length, &ispub);
}

EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length)
{
    int ispub = 1;

    return ossl_b2i(in, length, &ispub);
}

EVP_PKEY *b2i_PrivateKey_bio(BIO *in)
{
    int ispub = 0;

    return ossl_b2i_bio(in, &ispub);
}

EVP_PKEY *b2i_PublicKey_bio(BIO *in)
{
    int ispub = 1;

    return ossl_b2i_bio(in, &ispub);
}

static void write_ledword(unsigned char **out, unsigned int dw)
{
    unsigned char *p = *out;

    *p++ = dw & 0xff;
    *p++ = (dw >> 8) & 0xff;
    *p++ = (dw >> 16) & 0xff;
    *p++ = (dw >> 24) & 0xff;
    *out = p;
}

static void write_lebn(unsigned char **out, const BIGNUM *bn, int len)
{
    BN_bn2lebinpad(bn, *out, len);
    *out += len;
}

static int check_bitlen_rsa(const RSA *rsa, int ispub, unsigned int *magic);
static void write_rsa(unsigned char **out, const RSA *rsa, int ispub);

#ifndef OPENSSL_NO_DSA
static int check_bitlen_dsa(const DSA *dsa, int ispub, unsigned int *magic);
static void write_dsa(unsigned char **out, const DSA *dsa, int ispub);
#endif

static int do_i2b(unsigned char **out, const EVP_PKEY *pk, int ispub)
{
    unsigned char *p;
    unsigned int bitlen = 0, magic = 0, keyalg = 0;
    int outlen = -1, noinc = 0;

    if (EVP_PKEY_is_a(pk, "RSA")) {
        bitlen = check_bitlen_rsa(EVP_PKEY_get0_RSA(pk), ispub, &magic);
        keyalg = MS_KEYALG_RSA_KEYX;
#ifndef OPENSSL_NO_DSA
    } else if (EVP_PKEY_is_a(pk, "DSA")) {
        bitlen = check_bitlen_dsa(EVP_PKEY_get0_DSA(pk), ispub, &magic);
        keyalg = MS_KEYALG_DSS_SIGN;
#endif
    }
    if (bitlen == 0) {
        goto end;
    }
    outlen = 16
        + ossl_blob_length(bitlen, keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub);
    if (out == NULL)
        goto end;
    if (*out)
        p = *out;
    else {
        if ((p = OPENSSL_malloc(outlen)) == NULL) {
            ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
            outlen = -1;
            goto end;
        }
        *out = p;
        noinc = 1;
    }
    if (ispub)
        *p++ = MS_PUBLICKEYBLOB;
    else
        *p++ = MS_PRIVATEKEYBLOB;
    *p++ = 0x2;
    *p++ = 0;
    *p++ = 0;
    write_ledword(&p, keyalg);
    write_ledword(&p, magic);
    write_ledword(&p, bitlen);
    if (keyalg == MS_KEYALG_RSA_KEYX)
        write_rsa(&p, EVP_PKEY_get0_RSA(pk), ispub);
#ifndef OPENSSL_NO_DSA
    else
        write_dsa(&p, EVP_PKEY_get0_DSA(pk), ispub);
#endif
    if (!noinc)
        *out += outlen;
 end:
    return outlen;
}

static int do_i2b_bio(BIO *out, const EVP_PKEY *pk, int ispub)
{
    unsigned char *tmp = NULL;
    int outlen, wrlen;

    outlen = do_i2b(&tmp, pk, ispub);
    if (outlen < 0)
        return -1;
    wrlen = BIO_write(out, tmp, outlen);
    OPENSSL_free(tmp);
    if (wrlen == outlen)
        return outlen;
    return -1;
}

static int check_bitlen_rsa(const RSA *rsa, int ispub, unsigned int *pmagic)
{
    int nbyte, hnbyte, bitlen;
    const BIGNUM *e;

    RSA_get0_key(rsa, NULL, &e, NULL);
    if (BN_num_bits(e) > 32)
        goto badkey;
    bitlen = RSA_bits(rsa);
    nbyte = RSA_size(rsa);
    hnbyte = (bitlen + 15) >> 4;
    if (ispub) {
        *pmagic = MS_RSA1MAGIC;
        return bitlen;
    } else {
        const BIGNUM *d, *p, *q, *iqmp, *dmp1, *dmq1;

        *pmagic = MS_RSA2MAGIC;

        /*
         * For private key each component must fit within nbyte or hnbyte.
         */
        RSA_get0_key(rsa, NULL, NULL, &d);
        if (BN_num_bytes(d) > nbyte)
            goto badkey;
        RSA_get0_factors(rsa, &p, &q);
        RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
        if ((BN_num_bytes(iqmp) > hnbyte)
            || (BN_num_bytes(p) > hnbyte)
            || (BN_num_bytes(q) > hnbyte)
            || (BN_num_bytes(dmp1) > hnbyte)
            || (BN_num_bytes(dmq1) > hnbyte))
            goto badkey;
    }
    return bitlen;
 badkey:
    ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
    return 0;
}

static void write_rsa(unsigned char **out, const RSA *rsa, int ispub)
{
    int nbyte, hnbyte;
    const BIGNUM *n, *d, *e, *p, *q, *iqmp, *dmp1, *dmq1;

    nbyte = RSA_size(rsa);
    hnbyte = (RSA_bits(rsa) + 15) >> 4;
    RSA_get0_key(rsa, &n, &e, &d);
    write_lebn(out, e, 4);
    write_lebn(out, n, nbyte);
    if (ispub)
        return;
    RSA_get0_factors(rsa, &p, &q);
    RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
    write_lebn(out, p, hnbyte);
    write_lebn(out, q, hnbyte);
    write_lebn(out, dmp1, hnbyte);
    write_lebn(out, dmq1, hnbyte);
    write_lebn(out, iqmp, hnbyte);
    write_lebn(out, d, nbyte);
}

#ifndef OPENSSL_NO_DSA
static int check_bitlen_dsa(const DSA *dsa, int ispub, unsigned int *pmagic)
{
    int bitlen;
    const BIGNUM *p = NULL, *q = NULL, *g = NULL;
    const BIGNUM *pub_key = NULL, *priv_key = NULL;

    DSA_get0_pqg(dsa, &p, &q, &g);
    DSA_get0_key(dsa, &pub_key, &priv_key);
    bitlen = BN_num_bits(p);
    if ((bitlen & 7) || (BN_num_bits(q) != 160)
        || (BN_num_bits(g) > bitlen))
        goto badkey;
    if (ispub) {
        if (BN_num_bits(pub_key) > bitlen)
            goto badkey;
        *pmagic = MS_DSS1MAGIC;
    } else {
        if (BN_num_bits(priv_key) > 160)
            goto badkey;
        *pmagic = MS_DSS2MAGIC;
    }

    return bitlen;
 badkey:
    ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
    return 0;
}

static void write_dsa(unsigned char **out, const DSA *dsa, int ispub)
{
    int nbyte;
    const BIGNUM *p = NULL, *q = NULL, *g = NULL;
    const BIGNUM *pub_key = NULL, *priv_key = NULL;

    DSA_get0_pqg(dsa, &p, &q, &g);
    DSA_get0_key(dsa, &pub_key, &priv_key);
    nbyte = BN_num_bytes(p);
    write_lebn(out, p, nbyte);
    write_lebn(out, q, 20);
    write_lebn(out, g, nbyte);
    if (ispub)
        write_lebn(out, pub_key, nbyte);
    else
        write_lebn(out, priv_key, 20);
    /* Set "invalid" for seed structure values */
    memset(*out, 0xff, 24);
    *out += 24;
    return;
}
#endif

int i2b_PrivateKey_bio(BIO *out, const EVP_PKEY *pk)
{
    return do_i2b_bio(out, pk, 0);
}

int i2b_PublicKey_bio(BIO *out, const EVP_PKEY *pk)
{
    return do_i2b_bio(out, pk, 1);
}

int ossl_do_PVK_header(const unsigned char **in, unsigned int length,
                       int skip_magic,
                       unsigned int *psaltlen, unsigned int *pkeylen)
{
    const unsigned char *p = *in;
    unsigned int pvk_magic, is_encrypted;

    if (skip_magic) {
        if (length < 20) {
            ERR_raise(ERR_LIB_PEM, PEM_R_PVK_TOO_SHORT);
            return 0;
        }
    } else {
        if (length < 24) {
            ERR_raise(ERR_LIB_PEM, PEM_R_PVK_TOO_SHORT);
            return 0;
        }
        pvk_magic = read_ledword(&p);
        if (pvk_magic != MS_PVKMAGIC) {
            ERR_raise(ERR_LIB_PEM, PEM_R_BAD_MAGIC_NUMBER);
            return 0;
        }
    }
    /* Skip reserved */
    p += 4;
    /*
     * keytype =
     */ read_ledword(&p);
    is_encrypted = read_ledword(&p);
    *psaltlen = read_ledword(&p);
    *pkeylen = read_ledword(&p);

    if (*pkeylen > PVK_MAX_KEYLEN || *psaltlen > PVK_MAX_SALTLEN)
        return 0;

    if (is_encrypted && *psaltlen == 0) {
        ERR_raise(ERR_LIB_PEM, PEM_R_INCONSISTENT_HEADER);
        return 0;
    }

    *in = p;
    return 1;
}

#ifndef OPENSSL_NO_RC4
static int derive_pvk_key(unsigned char *key, size_t keylen,
                          const unsigned char *salt, unsigned int saltlen,
                          const unsigned char *pass, int passlen,
                          OSSL_LIB_CTX *libctx, const char *propq)
{
    EVP_KDF *kdf;
    EVP_KDF_CTX *ctx;
    OSSL_PARAM params[5], *p = params;
    int rv;

    if ((kdf = EVP_KDF_fetch(libctx, "PVKKDF", propq)) == NULL)
        return 0;
    ctx = EVP_KDF_CTX_new(kdf);
    EVP_KDF_free(kdf);
    if (ctx == NULL)
        return 0;

    *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
                                             (void *)salt, saltlen);
    *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD,
                                             (void *)pass, passlen);
    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, SN_sha1, 0);
    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_PROPERTIES,
                                            (char *)propq, 0);
    *p = OSSL_PARAM_construct_end();

    rv = EVP_KDF_derive(ctx, key, keylen, params);
    EVP_KDF_CTX_free(ctx);
    return rv;
}
#endif

static void *do_PVK_body_key(const unsigned char **in,
                             unsigned int saltlen, unsigned int keylen,
                             pem_password_cb *cb, void *u,
                             int *isdss, int *ispub,
                             OSSL_LIB_CTX *libctx, const char *propq)
{
    const unsigned char *p = *in;
    unsigned char *enctmp = NULL;
    unsigned char keybuf[20];
    void *key = NULL;
#ifndef OPENSSL_NO_RC4
    EVP_CIPHER *rc4 = NULL;
#endif
    EVP_CIPHER_CTX *cctx = EVP_CIPHER_CTX_new();

    if (cctx == NULL) {
        ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (saltlen) {
#ifndef OPENSSL_NO_RC4
        unsigned int magic;
        char psbuf[PEM_BUFSIZE];
        int enctmplen, inlen;
        unsigned char *q;

        if (cb)
            inlen = cb(psbuf, PEM_BUFSIZE, 0, u);
        else
            inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
        if (inlen < 0) {
            ERR_raise(ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ);
            goto err;
        }
        enctmp = OPENSSL_malloc(keylen + 8);
        if (enctmp == NULL) {
            ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
            goto err;
        }
        if (!derive_pvk_key(keybuf, sizeof(keybuf), p, saltlen,
                            (unsigned char *)psbuf, inlen, libctx, propq))
            goto err;
        p += saltlen;
        /* Copy BLOBHEADER across, decrypt rest */
        memcpy(enctmp, p, 8);
        p += 8;
        if (keylen < 8) {
            ERR_raise(ERR_LIB_PEM, PEM_R_PVK_TOO_SHORT);
            goto err;
        }
        inlen = keylen - 8;
        q = enctmp + 8;
        if ((rc4 = EVP_CIPHER_fetch(libctx, "RC4", propq)) == NULL)
            goto err;
        if (!EVP_DecryptInit_ex(cctx, rc4, NULL, keybuf, NULL))
            goto err;
        if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen))
            goto err;
        if (!EVP_DecryptFinal_ex(cctx, q + enctmplen, &enctmplen))
            goto err;
        magic = read_ledword((const unsigned char **)&q);
        if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
            q = enctmp + 8;
            memset(keybuf + 5, 0, 11);
            if (!EVP_DecryptInit_ex(cctx, rc4, NULL, keybuf, NULL))
                goto err;
            if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen))
                goto err;
            if (!EVP_DecryptFinal_ex(cctx, q + enctmplen, &enctmplen))
                goto err;
            magic = read_ledword((const unsigned char **)&q);
            if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
                ERR_raise(ERR_LIB_PEM, PEM_R_BAD_DECRYPT);
                goto err;
            }
        }
        p = enctmp;
#else
        ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_CIPHER);
        goto err;
#endif
    }

    key = do_b2i_key(&p, keylen, isdss, ispub);
 err:
    EVP_CIPHER_CTX_free(cctx);
#ifndef OPENSSL_NO_RC4
    EVP_CIPHER_free(rc4);
#endif
    if (enctmp != NULL) {
        OPENSSL_cleanse(keybuf, sizeof(keybuf));
        OPENSSL_free(enctmp);
    }
    return key;
}

static void *do_PVK_key_bio(BIO *in, pem_password_cb *cb, void *u,
                            int *isdss, int *ispub,
                            OSSL_LIB_CTX *libctx, const char *propq)
{
    unsigned char pvk_hdr[24], *buf = NULL;
    const unsigned char *p;
    int buflen;
    void *key = NULL;
    unsigned int saltlen, keylen;

    if (BIO_read(in, pvk_hdr, 24) != 24) {
        ERR_raise(ERR_LIB_PEM, PEM_R_PVK_DATA_TOO_SHORT);
        return NULL;
    }
    p = pvk_hdr;

    if (!ossl_do_PVK_header(&p, 24, 0, &saltlen, &keylen))
        return 0;
    buflen = (int)keylen + saltlen;
    buf = OPENSSL_malloc(buflen);
    if (buf == NULL) {
        ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    p = buf;
    if (BIO_read(in, buf, buflen) != buflen) {
        ERR_raise(ERR_LIB_PEM, PEM_R_PVK_DATA_TOO_SHORT);
        goto err;
    }
    key = do_PVK_body_key(&p, saltlen, keylen, cb, u, isdss, ispub, libctx, propq);

 err:
    OPENSSL_clear_free(buf, buflen);
    return key;
}

#ifndef OPENSSL_NO_DSA
DSA *b2i_DSA_PVK_bio_ex(BIO *in, pem_password_cb *cb, void *u,
                        OSSL_LIB_CTX *libctx, const char *propq)
{
    int isdss = 1;
    int ispub = 0;               /* PVK keys are always private */

    return do_PVK_key_bio(in, cb, u, &isdss, &ispub, libctx, propq);
}

DSA *b2i_DSA_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
{
    return b2i_DSA_PVK_bio_ex(in, cb, u, NULL, NULL);
}
#endif

RSA *b2i_RSA_PVK_bio_ex(BIO *in, pem_password_cb *cb, void *u,
                        OSSL_LIB_CTX *libctx, const char *propq)
{
    int isdss = 0;
    int ispub = 0;               /* PVK keys are always private */

    return do_PVK_key_bio(in, cb, u, &isdss, &ispub, libctx, propq);
}

RSA *b2i_RSA_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
{
    return b2i_RSA_PVK_bio_ex(in, cb, u, NULL, NULL);
}

EVP_PKEY *b2i_PVK_bio_ex(BIO *in, pem_password_cb *cb, void *u,
                         OSSL_LIB_CTX *libctx, const char *propq)
{
    int isdss = -1;
    int ispub = -1;
    void *key = do_PVK_key_bio(in, cb, u, &isdss, &ispub, NULL, NULL);

    return evp_pkey_new0_key(key, isdss_to_evp_type(isdss));
}

EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
{
    return b2i_PVK_bio_ex(in, cb, u, NULL, NULL);
}

static int i2b_PVK(unsigned char **out, const EVP_PKEY *pk, int enclevel,
                   pem_password_cb *cb, void *u, OSSL_LIB_CTX *libctx,
                   const char *propq)
{
    int ret = -1;
    int outlen = 24, pklen;
    unsigned char *p = NULL, *start = NULL;
    EVP_CIPHER_CTX *cctx = NULL;
#ifndef OPENSSL_NO_RC4
    unsigned char *salt = NULL;
    EVP_CIPHER *rc4 = NULL;
#endif

    if (enclevel)
        outlen += PVK_SALTLEN;
    pklen = do_i2b(NULL, pk, 0);
    if (pklen < 0)
        return -1;
    outlen += pklen;
    if (out == NULL)
        return outlen;
    if (*out != NULL) {
        p = *out;
    } else {
        start = p = OPENSSL_malloc(outlen);
        if (p == NULL) {
            ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
            return -1;
        }
    }

    cctx = EVP_CIPHER_CTX_new();
    if (cctx == NULL)
        goto error;

    write_ledword(&p, MS_PVKMAGIC);
    write_ledword(&p, 0);
    if (EVP_PKEY_get_id(pk) == EVP_PKEY_RSA)
        write_ledword(&p, MS_KEYTYPE_KEYX);
#ifndef OPENSSL_NO_DSA
    else
        write_ledword(&p, MS_KEYTYPE_SIGN);
#endif
    write_ledword(&p, enclevel ? 1 : 0);
    write_ledword(&p, enclevel ? PVK_SALTLEN : 0);
    write_ledword(&p, pklen);
    if (enclevel) {
#ifndef OPENSSL_NO_RC4
        if (RAND_bytes_ex(libctx, p, PVK_SALTLEN, 0) <= 0)
            goto error;
        salt = p;
        p += PVK_SALTLEN;
#endif
    }
    do_i2b(&p, pk, 0);
    if (enclevel != 0) {
#ifndef OPENSSL_NO_RC4
        char psbuf[PEM_BUFSIZE];
        unsigned char keybuf[20];
        int enctmplen, inlen;
        if (cb)
            inlen = cb(psbuf, PEM_BUFSIZE, 1, u);
        else
            inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u);
        if (inlen <= 0) {
            ERR_raise(ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ);
            goto error;
        }
        if (!derive_pvk_key(keybuf, sizeof(keybuf), salt, PVK_SALTLEN,
                            (unsigned char *)psbuf, inlen, libctx, propq))
            goto error;
        if ((rc4 = EVP_CIPHER_fetch(libctx, "RC4", propq)) == NULL)
            goto error;
        if (enclevel == 1)
            memset(keybuf + 5, 0, 11);
        p = salt + PVK_SALTLEN + 8;
        if (!EVP_EncryptInit_ex(cctx, rc4, NULL, keybuf, NULL))
            goto error;
        OPENSSL_cleanse(keybuf, 20);
        if (!EVP_EncryptUpdate(cctx, p, &enctmplen, p, pklen - 8))
            goto error;
        if (!EVP_EncryptFinal_ex(cctx, p + enctmplen, &enctmplen))
            goto error;
#else
        ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_CIPHER);
        goto error;
#endif
    }

    if (*out == NULL)
        *out = start;
    ret = outlen;
 error:
    EVP_CIPHER_CTX_free(cctx);
#ifndef OPENSSL_NO_RC4
    EVP_CIPHER_free(rc4);
#endif
    if (*out == NULL)
        OPENSSL_free(start);

    return ret;
}

int i2b_PVK_bio_ex(BIO *out, const EVP_PKEY *pk, int enclevel,
                   pem_password_cb *cb, void *u, OSSL_LIB_CTX *libctx,
                   const char *propq)
{
    unsigned char *tmp = NULL;
    int outlen, wrlen;

    outlen = i2b_PVK(&tmp, pk, enclevel, cb, u, libctx, propq);
    if (outlen < 0)
        return -1;
    wrlen = BIO_write(out, tmp, outlen);
    OPENSSL_free(tmp);
    if (wrlen == outlen) {
        return outlen;
    }
    ERR_raise(ERR_LIB_PEM, PEM_R_BIO_WRITE_FAILURE);
    return -1;
}

int i2b_PVK_bio(BIO *out, const EVP_PKEY *pk, int enclevel,
                pem_password_cb *cb, void *u)
{
    return i2b_PVK_bio_ex(out, pk, enclevel, cb, u, NULL, NULL);
}

