static int openssl_import_keypair(const keymaster_device_t* dev,
        const uint8_t* key, const size_t key_length,
        uint8_t** key_blob, size_t* key_blob_length) {
    int response = -1;

    if (key == NULL) {
        ALOGW("input key == NULL");
        return -1;
    } else if (key_blob == NULL || key_blob_length == NULL) {
        ALOGW("output key blob or length == NULL");
        return -1;
    }

    Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &key, key_length));
    if (pkcs8.get() == NULL) {
        logOpenSSLError("openssl_import_keypair");
        return -1;
    }

    /* assign to EVP */
    Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
    if (pkey.get() == NULL) {
        logOpenSSLError("openssl_import_keypair");
        return -1;
    }
    OWNERSHIP_TRANSFERRED(pkcs8);

    if (wrap_key(pkey.get(), EVP_PKEY_type(pkey->type), key_blob, key_blob_length)) {
        return -1;
    }

    return 0;
}
static int openssl_generate_keypair(const keymaster_device_t* dev,
        const keymaster_keypair_t key_type, const void* key_params,
        uint8_t** keyBlob, size_t* keyBlobLength) {
    ssize_t privateLen, publicLen;

    if (key_type != TYPE_RSA) {
        ALOGW("Unsupported key type %d", key_type);
        return -1;
    } else if (key_params == NULL) {
        ALOGW("key_params == null");
        return -1;
    }

    keymaster_rsa_keygen_params_t* rsa_params = (keymaster_rsa_keygen_params_t*) key_params;

    Unique_BIGNUM bn(BN_new());
    if (bn.get() == NULL) {
        logOpenSSLError("openssl_generate_keypair");
        return -1;
    }

    if (BN_set_word(bn.get(), rsa_params->public_exponent) == 0) {
        logOpenSSLError("openssl_generate_keypair");
        return -1;
    }

    /* initialize RSA */
    Unique_RSA rsa(RSA_new());
    if (rsa.get() == NULL) {
        logOpenSSLError("openssl_generate_keypair");
        return -1;
    }

    if (!RSA_generate_key_ex(rsa.get(), rsa_params->modulus_size, bn.get(), NULL)
            || RSA_check_key(rsa.get()) < 0) {
        logOpenSSLError("openssl_generate_keypair");
        return -1;
    }

    /* assign to EVP */
    Unique_EVP_PKEY pkey(EVP_PKEY_new());
    if (pkey.get() == NULL) {
        logOpenSSLError("openssl_generate_keypair");
        return -1;
    }

    if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) == 0) {
        logOpenSSLError("openssl_generate_keypair");
        return -1;
    }
    OWNERSHIP_TRANSFERRED(rsa);

    if (wrap_key(pkey.get(), EVP_PKEY_RSA, keyBlob, keyBlobLength)) {
        return -1;
    }

    return 0;
}
static int qcom_km_get_keypair_public(const keymaster_device* dev,
        const uint8_t* keyBlob, const size_t keyBlobLength,
        uint8_t** x509_data, size_t* x509_data_length) {

    struct qcom_km_key_blob * keyblob_ptr = (struct qcom_km_key_blob *)keyBlob;

    if (x509_data == NULL || x509_data_length == NULL) {
        ALOGE("Output public key buffer == NULL");
        return -1;
    }

    if (keyBlob == NULL) {
        ALOGE("Supplied key blob was NULL");
        return -1;
    }

    // Should be large enough for keyblob data:
    if (keyBlobLength < (sizeof(qcom_km_key_blob_t))) {
        ALOGE("key blob appears to be truncated");
        return -1;
    }

    if (keyblob_ptr->magic_num != KM_MAGIC_NUM) {
        ALOGE("Cannot read key; it was not made by this keymaster");
        return -1;
    }

    if (keyblob_ptr->public_exponent_size == 0 ) {
        ALOGE("Key blob appears to have incorrect exponent length");
        return -1;
    }
    if (keyblob_ptr->modulus_size == 0 ) {
        ALOGE("Key blob appears to have incorrect modulus length");
        return -1;
    }

    Unique_RSA rsa(RSA_new());
    if (rsa.get() == NULL) {
        ALOGE("Could not allocate RSA structure");
        return -1;
    }

    rsa->n = BN_bin2bn(reinterpret_cast<const unsigned char*>(keyblob_ptr->modulus),
                               keyblob_ptr->modulus_size, NULL);
    if (rsa->n == NULL) {
       ALOGE("Failed to initialize  modulus");
        return -1;
    }

    rsa->e = BN_bin2bn(reinterpret_cast<const unsigned char*>(&keyblob_ptr->public_exponent),
                               keyblob_ptr->public_exponent_size, NULL);
    if (rsa->e == NULL) {
        ALOGE("Failed to initialize public exponent");
        return -1;
    }

    Unique_EVP_PKEY pkey(EVP_PKEY_new());
    if (pkey.get() == NULL) {
        ALOGE("Could not allocate EVP_PKEY structure");
        return -1;
    }
    if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) != 1) {
        ALOGE("Failed to assign rsa  parameters \n");
        return -1;
    }
    OWNERSHIP_TRANSFERRED(rsa);

    int len = i2d_PUBKEY(pkey.get(), NULL);
    if (len <= 0) {
        ALOGE("Len returned is < 0 len = %d", len);
        return -1;
    }

    UniquePtr<uint8_t> key(static_cast<uint8_t*>(malloc(len)));
    if (key.get() == NULL) {
        ALOGE("Could not allocate memory for public key data");
        return -1;
    }

    unsigned char* tmp = reinterpret_cast<unsigned char*>(key.get());
    if (i2d_PUBKEY(pkey.get(), &tmp) != len) {
        ALOGE("Len 2 returned is < 0 len = %d", len);
        return -1;
    }
    *x509_data_length = len;
    *x509_data = key.release();

    return 0;
}