Exemplo n.º 1
0
static ENGINE *engine_qat(void)
{
    ENGINE *ret = NULL;
    unsigned int devmasks[] = { 0, 0, 0 };
    DEBUG("[%s] engine_qat\n", __func__);

    if (access(QAT_DEV, F_OK) != 0) {
        QATerr(QAT_F_ENGINE_QAT, QAT_R_MEM_DRV_NOT_PRESENT);
        return ret;
    }

    if (!getDevices(devmasks)) {
        QATerr(QAT_F_ENGINE_QAT, QAT_R_QAT_DEV_NOT_PRESENT);
        return ret;
    }

    ret = ENGINE_new();

    if (!ret)
        return NULL;

    if (!bind_qat(ret, engine_qat_id)) {
        WARN("qat engine bind failed!\n");
        ENGINE_free(ret);
        return NULL;
    }

    return ret;
}
Exemplo n.º 2
0
RSA_METHOD *qat_get_RSA_methods(void)
{
#ifndef OPENSSL_DISABLE_QAT_RSA
    int res = 1;
#endif

    if (qat_rsa_method != NULL)
        return qat_rsa_method;

#ifndef OPENSSL_DISABLE_QAT_RSA
    if ((qat_rsa_method = RSA_meth_new("QAT RSA method", 0)) == NULL) {
        WARN("Failed to allocate QAT RSA methods\n");
        QATerr(QAT_F_QAT_GET_RSA_METHODS, QAT_R_ALLOC_QAT_RSA_METH_FAILURE);
        return NULL;
    }

    res &= RSA_meth_set_pub_enc(qat_rsa_method, qat_rsa_pub_enc);
    res &= RSA_meth_set_pub_dec(qat_rsa_method, qat_rsa_pub_dec);
    res &= RSA_meth_set_priv_enc(qat_rsa_method, qat_rsa_priv_enc);
    res &= RSA_meth_set_priv_dec(qat_rsa_method, qat_rsa_priv_dec);
    res &= RSA_meth_set_mod_exp(qat_rsa_method, qat_rsa_mod_exp);
    res &= RSA_meth_set_bn_mod_exp(qat_rsa_method, qat_bn_mod_exp);

    if (res == 0) {
        WARN("Failed to set QAT RSA methods\n");
        QATerr(QAT_F_QAT_GET_RSA_METHODS, QAT_R_SET_QAT_RSA_METH_FAILURE);
        return NULL;
    }
#else
    qat_rsa_method = (RSA_METHOD *)RSA_get_default_method();
#endif

    return qat_rsa_method;
}
Exemplo n.º 3
0
/******************************************************************************
* function:
*         qat_rsa_priv_enc (int flen,
*                           const unsigned char *from,
*                           unsigned char *to,
*                           RSA *rsa,
*                           int padding)
*
* @param flen    [IN]  - length in bytes of input file
* @param from    [IN]  - pointer to the input file
* @param to      [OUT] - pointer to output signature
* @param rsa     [IN]  - pointer to private key structure
* @param padding [IN]  - Padding scheme
*
* description: Perform an RSA private encrypt (RSA Sign)
*              We use the decrypt implementation to achieve this.
******************************************************************************/
int
qat_rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to,
                 RSA *rsa, int padding)
{
    int rsa_len = 0;
    CpaCyRsaDecryptOpData *dec_op_data = NULL;
    CpaFlatBuffer *output_buffer = NULL;
    int sts = 1;
#ifndef OPENSSL_DISABLE_QAT_LENSTRA_PROTECTION
    unsigned char *ver_msg = NULL;
    const BIGNUM *n = NULL;
    const BIGNUM *e = NULL;
    const BIGNUM *d = NULL;
#endif

    DEBUG("- Started.\n");

    /* Parameter Checking */
    /*
     * The input message length should less than RSA size and also have
     * minimum space of PKCS1 padding(4 bytes)
     */
    if (rsa == NULL || from == NULL || to == NULL ||
        (flen > ((rsa_len = RSA_size(rsa)) - 4))
        || flen == 0) {
        WARN("RSA key, input or output is NULL or invalid length, \
              flen = %d, rsa_len = %d\n", flen, rsa_len);
        QATerr(QAT_F_QAT_RSA_PRIV_ENC, QAT_R_RSA_FROM_TO_NULL);
        goto exit;
    }
Exemplo n.º 4
0
/******************************************************************************
* function:
*         qat_remove_pad(unsigned char *out
*                        unsigned char *in,
*                        int r_len,
*                        int out_len,
*                        int sign,
*                        int padding)
*
* @param out     [OUT] - pointer to a Flat Buffer
* @param in      [IN] -  pointer to a Flat Buffer
* @param r_len   [IN] -  length of the RSA data
* @param out_len [OUT] - length of the output data after the padding has
                         been removed
* @param sign    [IN] -  1 for sign operation and 0 for decryption
* @param padding [IN] -  type of padding
*
* description:
*   This function is used to remove PKCS#1 padding from outputBuffer
*   after cpaCyRsaEncrypt() function during RSA verify if that is the type of
*   padding passed in.  However, if the type of padding is RSA_NO_PADDING, then
*   all the data in the 'in' buffer is copied to the 'out' buffer.
******************************************************************************/
static int qat_remove_pad(unsigned char *out, unsigned char *in,
                          int r_len, int *out_len, int sign, int padding)
{
    int p_len = 0;
    int d_len = 0;

    DEBUG("- Started\n");

    if (padding == RSA_NO_PADDING) {
        memcpy(out, in, r_len);
        *out_len = r_len;
    }
    else { /* should be RSA_PKCS1_PADDING */
        if (0 == (d_len = qat_data_len(in, r_len, sign))) {
            WARN("Unable to get Data Length\n");
            QATerr(QAT_F_QAT_REMOVE_PAD, ERR_R_INTERNAL_ERROR);
            return 0;
        }
        p_len = r_len - d_len;

        /* shift actual data to the beginning of out buffer */
        memcpy(out, in + p_len, d_len);
        *out_len = d_len;
    }

    DEBUG("- Finished\n");
    return 1;
}
Exemplo n.º 5
0
/******************************************************************************
* function:
*         qat_data_len(unsigned char *in
*                      int  rLen, int sign)
*
* @param in   [IN] - pointer to Flat Buffer
* @param rLen [IN] - length of RSA
* @param sign [IN] - 1 for sign operation and 0 for decryption
*
* description:
*   This function is used to calculate the length of actual data
*   and padding size inside of outputBuffer returned from cpaCyRsaEncrypt() function.
*   The function counts the padding length (i) and return the length
*   of actual data (dLen) contained in the outputBuffer
******************************************************************************/
static int qat_data_len(unsigned char *in, int rLen, int sign)
{
    /* first two bytes are 0x00, 0x01 */
    int i = 0;
    int dLen = 0;
    int pLen = 0;

    DEBUG("- Started\n");

    /* First two char of padding should be 0x00, 0x01 */
    if (sign) {
        /* First two char of padding should be 0x00, 0x01 */
        if (in[0] != 0x00 || in[1] != 0x01) {
            WARN("Sign: Padding format unknown\n");
            QATerr(QAT_F_QAT_DATA_LEN, ERR_R_INTERNAL_ERROR);
            return 0;
        }
    } else {
        /* First two char of padding should be 0x00, 0x02 for decryption */
        if (in[0] != 0x00 || in[1] != 0x02) {
            WARN("Decryption: Padding format unknown\n");
            QATerr(QAT_F_QAT_DATA_LEN, ERR_R_INTERNAL_ERROR);
            return 0;
        }
    }

    /*
     * while loop is design to reach the 0x00 value and count all the 0xFF
     * value where filled by PKCS#1 padding
     */
    while (in[i + 2] != 0x00 && i < rLen)
        i++;

    /* padding length = 2 + length of 0xFF + 0x00 */
    pLen = 2 + i + 1;
    dLen = rLen - pLen;

    if (dLen < 0) {
        dLen = 0;
    }

    DEBUG("- Finished\n");
    return dLen;
}
Exemplo n.º 6
0
void qat_free_RSA_methods(void)
{
#ifndef OPENSSL_DISABLE_QAT_RSA
    if (qat_rsa_method != NULL) {
        RSA_meth_free(qat_rsa_method);
        qat_rsa_method = NULL;
    } else {
        WARN("qat_rsa_method is NULL\n");
        QATerr(QAT_F_QAT_FREE_RSA_METHODS, QAT_R_FREE_QAT_RSA_METH_FAILURE);
    }
#endif
}
Exemplo n.º 7
0
/******************************************************************************
* function:
*         qat_alloc_pad(unsigned char *in,
*                       int len,
*                       int rLen,
*                       int sign)
*
* @param in   [IN] - pointer to Flat Buffer
* @param len  [IN] - length of input data (hash)
* @param rLen [IN] - length of RSA
* @param sign [IN] - 1 for sign operation and 0 for decryption
*
* description:
*   This function is used to add PKCS#1 padding into input data buffer
*   before it pass to cpaCyRsaDecrypt() function.
*   The function returns a pointer to unsigned char buffer
******************************************************************************/
static unsigned char *qat_alloc_pad(unsigned char *in, int len,
                                    int rLen, int sign)
{
    int i = 0;

    /* out data buffer should have fix length */
    unsigned char *out = qaeCryptoMemAlloc(rLen, __FILE__, __LINE__);

    DEBUG("- Started\n");

    if (NULL == out) {
        WARN("out buffer malloc failed\n");
        QATerr(QAT_F_QAT_ALLOC_PAD, QAT_R_OUT_MALLOC_FAILURE);
        return NULL;
    }

    /* First two char are (0x00, 0x01) or (0x00, 0x02) */
    out[0] = 0x00;

    if (sign) {
        out[1] = 0x01;
    } else {
        out[1] = 0x02;
    }

    /*
     * Fill 0xff and end up with 0x00 in out buffer until the length of
     * actual data space left
     */
    for (i = 2; i < (rLen - len - 1); i++) {
        out[i] = 0xff;
    }
    /*
     * i has been incremented on beyond the last padding byte to exit for
     * loop
     */
    out[i] = 0x00;

    /* shift actual data to the end of out buffer */
    memcpy((out + rLen - len), in, len);

    DEBUG("- Finished\n");
    return out;
}
Exemplo n.º 8
0
static ENGINE *engine_qat(void)
{
    ENGINE *ret = NULL;
    DEBUG("- Starting\n");

    ret = ENGINE_new();

    if (!ret) {
        WARN("Failed to create Engine\n");
        QATerr(QAT_F_ENGINE_QAT, QAT_R_QAT_CREATE_ENGINE_FAILURE);
        return NULL;
    }

    if (!bind_qat(ret, engine_qat_id)) {
        WARN("Qat engine bind failed\n");
        ENGINE_free(ret);
        return NULL;
    }

    return ret;
}
Exemplo n.º 9
0
static int
build_encrypt_op(int flen, const unsigned char *from, unsigned char *to,
                 RSA *rsa, int padding,
                 CpaCyRsaEncryptOpData ** enc_op_data,
                 CpaFlatBuffer ** output_buffer, int alloc_pad)
{
    CpaCyRsaPublicKey *cpa_pub_key = NULL;
    int rsa_len = 0;
    const BIGNUM *n = NULL;
    const BIGNUM *e = NULL;
    const BIGNUM *d = NULL;

    DEBUG("- Started\n");

    RSA_get0_key((const RSA*)rsa, &n, &e, &d);

    /* Note: not checking 'd' as it is not used */
    if (n == NULL || e == NULL) {
        WARN("RSA key values n = %p or e = %p are NULL\n", n, e);
        QATerr(QAT_F_BUILD_ENCRYPT_OP, QAT_R_N_E_NULL);
        return 0;
    }

    if (padding != RSA_PKCS1_PADDING) {
        WARN("Unknown Padding %d\n", padding);
        QATerr(QAT_F_BUILD_ENCRYPT_OP, QAT_R_UNKNOWN_PADDING);
        return 0;
    }

    cpa_pub_key = OPENSSL_zalloc(sizeof(CpaCyRsaPublicKey));
    if (NULL == cpa_pub_key) {
        WARN("Public Key zalloc failed\n");
        QATerr(QAT_F_BUILD_ENCRYPT_OP, QAT_R_PUB_KEY_MALLOC_FAILURE);
        return 0;
    }

    rsa_len = RSA_size(rsa);

    /* Output and input data MUST allocate memory for RSA verify process */
    /* Memory allocation for EncOpData[IN] */
    *enc_op_data = OPENSSL_zalloc(sizeof(CpaCyRsaEncryptOpData));
    if (NULL == *enc_op_data) {
        WARN("Failed to allocate enc_op_data\n");
        QATerr(QAT_F_BUILD_ENCRYPT_OP, QAT_R_ENC_OP_DATA_MALLOC_FAILURE);
        OPENSSL_free(cpa_pub_key);
        return 0;
    }

    /* Setup the Encrypt operation Data structure */
    (*enc_op_data)->pPublicKey = cpa_pub_key;

    DEBUG("flen=%d padding=%d\n", flen, padding);

    /* Passing Public key from big number format to big endian order binary */
    if (qat_BN_to_FB(&cpa_pub_key->modulusN, n) != 1 ||
        qat_BN_to_FB(&cpa_pub_key->publicExponentE, e) != 1) {
        WARN("Failed to convert cpa_pub_key elements to flatbuffer\n");
        QATerr(QAT_F_BUILD_ENCRYPT_OP, QAT_R_N_E_CONVERT_TO_FB_FAILURE);
        return 0;
    }

    if (alloc_pad) {
        (*enc_op_data)->inputData.pData =
            qat_alloc_pad((Cpa8U *) from, flen, rsa_len, 0);
    } else {
        (*enc_op_data)->inputData.pData =
            (Cpa8U *) copyAllocPinnedMemory((void *)from, flen, __FILE__,
                                            __LINE__);
    }

    if (NULL == (*enc_op_data)->inputData.pData) {
        WARN("Failed to allocate (*enc_op_data)->inputData.pData\n");
        QATerr(QAT_F_BUILD_ENCRYPT_OP, QAT_R_INPUT_DATA_MALLOC_FAILURE);
        return 0;
    }

    if (alloc_pad)
        (*enc_op_data)->inputData.dataLenInBytes = rsa_len;
    else
        (*enc_op_data)->inputData.dataLenInBytes = flen;

    /*
     * Memory allocation for outputBuffer[OUT] OutputBuffer size initialize
     * as the size of rsa size
     */
    (*output_buffer) =
        (CpaFlatBuffer *) OPENSSL_malloc(sizeof(CpaFlatBuffer));
    if (NULL == (*output_buffer)) {
        WARN("Failed to allocate output_buffer\n");
        QATerr(QAT_F_BUILD_ENCRYPT_OP, QAT_R_OUTPUT_BUF_MALLOC_FAILURE);
        return 0;
    }

    /*
     * outputBuffer size should large enough to hold the Hash value but
     * smaller than (RSA_size(rsa)-11)
     */
    (*output_buffer)->dataLenInBytes = rsa_len;
    (*output_buffer)->pData = qaeCryptoMemAlloc(rsa_len, __FILE__, __LINE__);
    if (NULL == (*output_buffer)->pData) {
        WARN("Failed to allocate (*output_buffer)->pData\n");
        QATerr(QAT_F_BUILD_ENCRYPT_OP, QAT_R_OUTPUT_BUF_PDATA_MALLOC_FAILURE);
        return 0;;
    }

    DEBUG("- Finished\n");
    return 1;
}
Exemplo n.º 10
0
int
qat_rsa_encrypt(CpaCyRsaEncryptOpData * enc_op_data,
                CpaFlatBuffer * output_buf)
{
    /* Used for RSA Encrypt and RSA Verify */
    struct op_done op_done;
    CpaStatus sts = CPA_STATUS_FAIL;
    int qatPerformOpRetries = 0;
    CpaInstanceHandle instance_handle = NULL;
    int job_ret = 0;
    int pthread_kill_ret;

    int iMsgRetry = getQatMsgRetryCount();
    useconds_t ulPollInterval = getQatPollInterval();

    DEBUG("- Started\n");

    if (qat_use_signals()) {
        qat_atomic_inc(num_requests_in_flight);
        pthread_kill_ret = pthread_kill(timer_poll_func_thread, SIGUSR1);
        if (pthread_kill_ret != 0) {
            WARN("pthread_kill error\n");
            QATerr(QAT_F_QAT_RSA_ENCRYPT, ERR_R_INTERNAL_ERROR);
            qat_atomic_dec(num_requests_in_flight);
            return 0;
        }
    }
    qat_init_op_done(&op_done);
    if (op_done.job != NULL) {
        if (qat_setup_async_event_notification(0) == 0) {
            WARN("Failed to setup async event notification\n");
            QATerr(QAT_F_QAT_RSA_ENCRYPT, ERR_R_INTERNAL_ERROR);
            qat_cleanup_op_done(&op_done);
            qat_atomic_dec_if_polling(num_requests_in_flight);
            return 0;
        }
    }
    /*
     * cpaCyRsaEncrypt() is the function called for RSA verify in the API.
     * For that particular case the enc_op_data [IN] contains both the
     * public key value and the signature value. The output_buf [OUT]
     * stores the message as the output once the request is fully completed.
     * The sts return value contains 0 (CPA_STATUS_SUCCESS) if the request
     * was successfully submitted.
     */
    CRYPTO_QAT_LOG("RSA - %s\n", __func__);
    do {
        if (NULL == (instance_handle = get_next_inst())) {
            WARN("Failed to get an instance\n");
            QATerr(QAT_F_QAT_RSA_ENCRYPT, ERR_R_INTERNAL_ERROR);
            if (op_done.job != NULL) {
                qat_clear_async_event_notification();
            }
            qat_cleanup_op_done(&op_done);
            qat_atomic_dec_if_polling(num_requests_in_flight);
            return 0;
        }

        DUMP_RSA_ENCRYPT(instance_handle, &op_done, enc_op_data, output_buf);
        sts = cpaCyRsaEncrypt(instance_handle, qat_rsaCallbackFn, &op_done,
                              enc_op_data, output_buf);
        if (sts == CPA_STATUS_RETRY) {
            if (op_done.job == NULL) {
                usleep(ulPollInterval +
                       (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR));
                qatPerformOpRetries++;
                if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) {
                    if (qatPerformOpRetries >= iMsgRetry) {
                        WARN("No. of retries exceeded max retry : %d\n", iMsgRetry);
                        break;
                    }
                }
            } else {
                if ((qat_wake_job(op_done.job, 0) == 0) ||
                    (qat_pause_job(op_done.job, 0) == 0)) {
                    WARN("qat_wake_job or qat_pause_job failed\n");
                    break;
                }
            }
        }
    }
    while (sts == CPA_STATUS_RETRY);

    if (sts != CPA_STATUS_SUCCESS) {
        WARN("Failed to submit request to qat - status = %d\n", sts);
        QATerr(QAT_F_QAT_RSA_ENCRYPT, ERR_R_INTERNAL_ERROR);
        if (op_done.job != NULL) {
            qat_clear_async_event_notification();
        }
        qat_cleanup_op_done(&op_done);
        qat_atomic_dec_if_polling(num_requests_in_flight);
        return 0;
    }

    do {
        if(op_done.job != NULL) {
            /* If we get a failure on qat_pause_job then we will
               not flag an error here and quit because we have
               an asynchronous request in flight.
               We don't want to start cleaning up data
               structures that are still being used. If
               qat_pause_job fails we will just yield and
               loop around and try again until the request
               completes and we can continue. */
            if ((job_ret = qat_pause_job(op_done.job, 0)) == 0)
                pthread_yield();
        } else {
            if(getEnableInlinePolling()) {
                icp_sal_CyPollInstance(instance_handle, 0);
            } else {
                pthread_yield();
            }
        }
    } while (!op_done.flag ||
             QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret));

    DUMP_RSA_ENCRYPT_OUTPUT(output_buf);
    qat_cleanup_op_done(&op_done);
    qat_atomic_dec_if_polling(num_requests_in_flight);

    if (op_done.verifyResult != CPA_TRUE) {
        WARN("Verification of result failed\n");
        QATerr(QAT_F_QAT_RSA_ENCRYPT, ERR_R_INTERNAL_ERROR);
        return 0;
    }

    return 1;
}
Exemplo n.º 11
0
static int
build_decrypt_op_buf(int flen, const unsigned char *from, unsigned char *to,
                     RSA *rsa, int padding,
                     CpaCyRsaDecryptOpData ** dec_op_data,
                     CpaFlatBuffer ** output_buffer, int alloc_pad)
{
    int rsa_len = 0;
    CpaCyRsaPrivateKey *cpa_prv_key = NULL;
    const BIGNUM *p = NULL;
    const BIGNUM *q = NULL;
    const BIGNUM *dmp1 = NULL;
    const BIGNUM *dmq1 = NULL;
    const BIGNUM *iqmp = NULL;

    DEBUG("- Started\n");

    RSA_get0_factors((const RSA*)rsa, &p, &q);
    RSA_get0_crt_params((const RSA*)rsa, &dmp1, &dmq1, &iqmp);

    if (p == NULL || q == NULL || dmp1 == NULL || dmq1 == NULL || iqmp == NULL) {
        WARN("Either p %p, q %p, dmp1 %p, dmq1 %p, iqmp %p are NULL\n",
              p, q, dmp1, dmq1, iqmp);
        QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_P_Q_DMP_DMQ_IQMP_NULL);
        return 0;
    }

    /* Padding check */
    if ((padding != RSA_NO_PADDING) && (padding != RSA_PKCS1_PADDING)) {
        WARN("Unknown Padding %d\n", padding);
        QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_PADDING_UNKNOWN);
        return 0;
    }

    cpa_prv_key =
        (CpaCyRsaPrivateKey *) OPENSSL_zalloc(sizeof(CpaCyRsaPrivateKey));
    if (NULL == cpa_prv_key) {
        WARN("Failed to allocate cpa_prv_key\n");
        QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_PRIV_KEY_MALLOC_FAILURE);
        return 0;
    }

    DEBUG("flen =%d, padding = %d \n", flen, padding);
    /* output signature should have same length as RSA(128) */
    rsa_len = RSA_size(rsa);

    /* output and input data MUST allocate memory for sign process */
    /* memory allocation for DecOpdata[IN] */
    *dec_op_data = OPENSSL_zalloc(sizeof(CpaCyRsaDecryptOpData));
    if (NULL == *dec_op_data) {
        WARN("Failed to allocate dec_op_data\n");
        QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_DEC_OP_DATA_MALLOC_FAILURE);
        OPENSSL_free(cpa_prv_key);
        return 0;
    }

    /* Setup the DecOpData structure */
    (*dec_op_data)->pRecipientPrivateKey = cpa_prv_key;

    cpa_prv_key->version = CPA_CY_RSA_VERSION_TWO_PRIME;

    /* Setup the private key rep type 2 structure */
    cpa_prv_key->privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
    if (qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.prime1P, p) != 1 ||
        qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.prime2Q, q) != 1 ||
        qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.exponent1Dp, dmp1) != 1 ||
        qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.exponent2Dq, dmq1) != 1 ||
        qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.coefficientQInv, iqmp) != 1) {
        WARN("Failed to convert privateKeyRep2 elements to flatbuffer\n");
        QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_P_Q_DMP_DMQ_CONVERT_TO_FB_FAILURE);
        return 0;
    }

    if (alloc_pad) {
        (*dec_op_data)->inputData.pData =
            qat_alloc_pad((Cpa8U *) from, flen, rsa_len, 1);
    } else {
        (*dec_op_data)->inputData.pData =
            (Cpa8U *) copyAllocPinnedMemory((void *)from, flen, __FILE__,
                                            __LINE__);
    }

    if (NULL == (*dec_op_data)->inputData.pData) {
        WARN("Failed to allocate (*dec_op_data)->inputData.pData\n");
        QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_INPUT_DATA_MALLOC_FAILURE);
        return 0;
    }

    if (alloc_pad)
        (*dec_op_data)->inputData.dataLenInBytes = rsa_len;
    else
        (*dec_op_data)->inputData.dataLenInBytes = flen;

    *output_buffer = OPENSSL_malloc(sizeof(CpaFlatBuffer));
    if (NULL == *output_buffer) {
        WARN("Failed to allocate output_buffer\n");
        QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_OUTPUT_BUF_MALLOC_FAILURE);
        return 0;
    }

    /*
     * Memory allocation for DecOpdata[IN] the size of outputBuffer
     * should big enough to contain RSA_size
     */
    (*output_buffer)->pData =
        (Cpa8U *) qaeCryptoMemAlloc(rsa_len, __FILE__, __LINE__);

    if (NULL == (*output_buffer)->pData) {
        WARN("Failed to allocate output_buffer->pData\n");
        QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_RSA_OUTPUT_BUF_PDATA_MALLOC_FAILURE);
        return 0;
    }
    (*output_buffer)->dataLenInBytes = rsa_len;

    DEBUG("- Finished\n");
    return 1;
}
Exemplo n.º 12
0
int
qat_rsa_decrypt(CpaCyRsaDecryptOpData * dec_op_data, int rsa_len,
                CpaFlatBuffer * output_buf)
{
    /* Used for RSA Decrypt and RSA Sign */
    struct op_done op_done;
    CpaStatus sts = CPA_STATUS_FAIL;
    CpaInstanceHandle instance_handle = NULL;
    int job_ret = 0;
    int sync_mode_ret = 0;
    int pthread_kill_ret;

    DEBUG("- Started\n");

    if (qat_use_signals()) {
        qat_atomic_inc(num_requests_in_flight);
        pthread_kill_ret = pthread_kill(timer_poll_func_thread, SIGUSR1);
        if (pthread_kill_ret != 0) {
            WARN("pthread_kill error\n");
            QATerr(QAT_F_QAT_RSA_DECRYPT, ERR_R_INTERNAL_ERROR);
            qat_atomic_dec(num_requests_in_flight);
            return 0;
        }
    }
    qat_init_op_done(&op_done);
    if (op_done.job != NULL) {
        if (qat_setup_async_event_notification(0) == 0) {
            WARN("Failed to setup async event notifications\n");
            QATerr(QAT_F_QAT_RSA_DECRYPT, ERR_R_INTERNAL_ERROR);
            qat_cleanup_op_done(&op_done);
            qat_atomic_dec_if_polling(num_requests_in_flight);
            return 0;
        }
    } else {
        /*
         *  Sync mode
         */
        qat_cleanup_op_done(&op_done);
        sync_mode_ret = qat_rsa_decrypt_CRT(dec_op_data, rsa_len, output_buf);
        qat_atomic_dec_if_polling(num_requests_in_flight);
        return sync_mode_ret;
    }
    /*
     * cpaCyRsaDecrypt() is the function called for RSA Sign in the API.
     * For that particular case the dec_op_data [IN] contains both the
     * private key value and the message (hash) value. The output_buf [OUT]
     * stores the signature as the output once the request is fully completed.
     * The sts return value contains 0 (CPA_STATUS_SUCCESS) if the request
     * was successfully submitted.
     */
    CRYPTO_QAT_LOG("- RSA\n");
    do {
        if (NULL == (instance_handle = get_next_inst())) {
            WARN("Failed to get an instance\n");
            QATerr(QAT_F_QAT_RSA_DECRYPT, ERR_R_INTERNAL_ERROR);
            qat_clear_async_event_notification();
            qat_cleanup_op_done(&op_done);
            qat_atomic_dec_if_polling(num_requests_in_flight);
            return 0;
        }
        DUMP_RSA_DECRYPT(instance_handle, &op_done, dec_op_data, output_buf);
        sts = cpaCyRsaDecrypt(instance_handle, qat_rsaCallbackFn, &op_done,
                              dec_op_data, output_buf);
        if (sts == CPA_STATUS_RETRY) {
            if ((qat_wake_job(op_done.job, 0) == 0) ||
                (qat_pause_job(op_done.job, 0) == 0)) {
                WARN("qat_wake_job or qat_pause_job failed\n");
                break;
            }
        }
    }
    while (sts == CPA_STATUS_RETRY);

    if (sts != CPA_STATUS_SUCCESS) {
        WARN("Failed to submit request to qat - status = %d\n", sts);
        QATerr(QAT_F_QAT_RSA_DECRYPT, ERR_R_INTERNAL_ERROR);
        qat_clear_async_event_notification();
        qat_cleanup_op_done(&op_done);
        qat_atomic_dec_if_polling(num_requests_in_flight);
        return 0;
    }

    do {
        /* If we get a failure on qat_pause_job then we will
           not flag an error here and quit because we have
           an asynchronous request in flight.
           We don't want to start cleaning up data
           structures that are still being used. If
           qat_pause_job fails we will just yield and
           loop around and try again until the request
           completes and we can continue. */
        if ((job_ret = qat_pause_job(op_done.job, 0)) == 0)
            pthread_yield();
    }
    while (!op_done.flag ||
           QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret));

    DUMP_RSA_DECRYPT_OUTPUT(output_buf);
    qat_cleanup_op_done(&op_done);
    qat_atomic_dec_if_polling(num_requests_in_flight);

    if (op_done.verifyResult != CPA_TRUE) {
        WARN("Verification of result failed\n");
        QATerr(QAT_F_QAT_RSA_DECRYPT, ERR_R_INTERNAL_ERROR);
        return 0;
    }

    DEBUG("- Finished\n");
    return 1;
}
Exemplo n.º 13
0
/******************************************************************************
* function:
*         bind_qat(ENGINE *e,
*                  const char *id)
*
* @param e  [IN] - OpenSSL engine pointer
* @param id [IN] - engine id
*
* description:
*    Connect Qat engine to OpenSSL engine library
******************************************************************************/
static int bind_qat(ENGINE *e, const char *id)
{
    int ret = 0;
#ifndef OPENSSL_ENABLE_QAT_UPSTREAM_DRIVER
    int upstream_flags = 0;
    unsigned int devmasks[] = { 0, 0, 0, 0, 0 };
#endif

    QAT_DEBUG_LOG_INIT();

    WARN("QAT Warnings enabled.\n");
    DEBUG("QAT Debug enabled.\n");
    DEBUG("id=%s\n", id);

    if (access(QAT_DEV, F_OK) != 0) {
        WARN("Qat memory driver not present\n");
        QATerr(QAT_F_BIND_QAT, QAT_R_MEM_DRV_NOT_PRESENT);
        goto end;
    }

#ifndef OPENSSL_ENABLE_QAT_UPSTREAM_DRIVER
    if (!getDevices(devmasks, &upstream_flags)) {
        WARN("Qat device not present\n");
        QATerr(QAT_F_BIND_QAT, QAT_R_QAT_DEV_NOT_PRESENT);
        goto end;
    }
#endif

    if (id && (strcmp(id, engine_qat_id) != 0)) {
        WARN("ENGINE_id defined already!\n");
        QATerr(QAT_F_BIND_QAT, QAT_R_ENGINE_ID_ALREADY_DEFINED);
        goto end;
    }

    if (!ENGINE_set_id(e, engine_qat_id)) {
        WARN("ENGINE_set_id failed\n");
        QATerr(QAT_F_BIND_QAT, QAT_R_ENGINE_SET_ID_FAILURE);
        goto end;
    }

    if (!ENGINE_set_name(e, engine_qat_name)) {
        WARN("ENGINE_set_name failed\n");
        QATerr(QAT_F_BIND_QAT, QAT_R_ENGINE_SET_NAME_FAILURE);
        goto end;
    }

    /* Ensure the QAT error handling is set up */
    ERR_load_QAT_strings();

    /*
     * Create static structures for ciphers now
     * as this function will be called by a single thread.
     */
    qat_create_ciphers();

    if (!ENGINE_set_RSA(e, qat_get_RSA_methods())) {
        WARN("ENGINE_set_RSA failed\n");
        QATerr(QAT_F_BIND_QAT, QAT_R_ENGINE_SET_RSA_FAILURE);
        goto end;
    }

    if (!ENGINE_set_DSA(e, qat_get_DSA_methods())) {
        WARN("ENGINE_set_DSA failed\n");
        QATerr(QAT_F_BIND_QAT, QAT_R_ENGINE_SET_DSA_FAILURE);
        goto end;
    }

    if (!ENGINE_set_DH(e, qat_get_DH_methods())) {
        WARN("ENGINE_set_DH failed\n");
        QATerr(QAT_F_BIND_QAT, QAT_R_ENGINE_SET_DH_FAILURE);
        goto end;
    }

    if (!ENGINE_set_EC(e, qat_get_EC_methods())) {
        WARN("ENGINE_set_EC failed\n");
        QATerr(QAT_F_BIND_QAT, QAT_R_ENGINE_SET_EC_FAILURE);
        goto end;
    }

    if (!ENGINE_set_ciphers(e, qat_ciphers)) {
        WARN("ENGINE_set_ciphers failed\n");
        QATerr(QAT_F_BIND_QAT, QAT_R_ENGINE_SET_CIPHER_FAILURE);
        goto end;
    }

    if (!ENGINE_set_pkey_meths(e, qat_PRF_pkey_methods)) {
        WARN("ENGINE_set_pkey_meths failed\n");
        QATerr(QAT_F_BIND_QAT, QAT_R_ENGINE_SET_PKEY_FAILURE);
        goto end;
    }

    pthread_atfork(engine_finish_before_fork_handler, NULL,
                   engine_init_child_at_fork_handler);

    ret = 1;
    ret &= ENGINE_set_destroy_function(e, qat_engine_destroy);
    ret &= ENGINE_set_init_function(e, qat_engine_init);
    ret &= ENGINE_set_finish_function(e, qat_engine_finish);
    ret &= ENGINE_set_ctrl_function(e, qat_engine_ctrl);
    ret &= ENGINE_set_cmd_defns(e, qat_cmd_defns);
    if (ret == 0) {
        WARN("Engine failed to register init, finish or destroy functions\n");
        QATerr(QAT_F_BIND_QAT, QAT_R_ENGINE_REGISTER_FUNC_FAILURE);
    }

 end:
    return ret;

}
Exemplo n.º 14
0
int qat_engine_finish_int(ENGINE *e, int reset_globals)
{

    int i;
    int ret = 1;
    CpaStatus status = CPA_STATUS_SUCCESS;
    ENGINE_EPOLL_ST *epollst = NULL;
    int pthread_kill_ret;

    DEBUG("---- Engine Finishing...\n\n");

    pthread_mutex_lock(&qat_engine_mutex);
    keep_polling = 0;
    if (qat_use_signals()) {
        pthread_kill_ret = pthread_kill(timer_poll_func_thread, SIGUSR1);
        if (pthread_kill_ret != 0) {
            WARN("pthread_kill error\n");
            QATerr(QAT_F_QAT_ENGINE_FINISH_INT, QAT_R_PTHREAD_KILL_FAILURE);
            ret = 0;
        }
    }

    if (qat_instance_handles) {
        for (i = 0; i < qat_num_instances; i++) {
            if(instance_started[i]) {
                status = cpaCyStopInstance(qat_instance_handles[i]);

                if (CPA_STATUS_SUCCESS != status) {
                    WARN("cpaCyStopInstance failed, status=%d\n", status);
                    QATerr(QAT_F_QAT_ENGINE_FINISH_INT, QAT_R_STOP_INSTANCE_FAILURE);
                    ret = 0;
                }

                instance_started[i] = 0;
            }
        }
    }

    /* If polling thread is different from the main thread, wait for polling
     * thread to finish. pthread_equal returns 0 when threads are different.
     */
    if (!enable_external_polling && !enable_inline_polling &&
        pthread_equal(polling_thread, pthread_self()) == 0) {
        if (qat_join_thread(polling_thread, NULL) != 0) {
            WARN("Polling thread join failed with status: %d\n", ret);
            QATerr(QAT_F_QAT_ENGINE_FINISH_INT, QAT_R_PTHREAD_JOIN_FAILURE);
            ret = 0;
        }
    }

    polling_thread = pthread_self();

    if (qat_instance_handles) {
        OPENSSL_free(qat_instance_handles);
        qat_instance_handles = NULL;
    }

    if (!enable_external_polling && !enable_inline_polling &&
        qat_is_event_driven()) {
        for (i = 0; i < qat_num_instances; i++) {
            epollst = (ENGINE_EPOLL_ST*)eng_epoll_events[i].data.ptr;
            if (epollst) {
                if (-1 ==
                    epoll_ctl(internal_efd, EPOLL_CTL_DEL,
                              epollst->eng_fd,
                              &eng_epoll_events[i])) {
                    WARN("Error removing fd from epoll\n");
                    QATerr(QAT_F_QAT_ENGINE_FINISH_INT, QAT_R_EPOLL_CTL_FAILURE);
                    ret = 0;
                }
                close(epollst->eng_fd);
            }
        }
    }


    /* Reset global variables */
    qat_num_instances = 0;
    icp_sal_userStop();
    engine_inited = 0;
    internal_efd = 0;
    qat_instance_handles = NULL;
    keep_polling = 1;
    curr_inst = 0;
    qatPerformOpRetries = 0;

    /* Reset the configuration global variables (to their default values) only
     * if requested, i.e. when we are not re-initializing the engine after
     * forking
     */
    if (reset_globals) {
        enable_external_polling = 0;
        enable_inline_polling = 0;
        enable_event_driven_polling = 0;
        enable_instance_for_thread = 0;
        qat_poll_interval = QAT_POLL_PERIOD_IN_NS;
        qat_max_retry_count = QAT_CRYPTO_NUM_POLLING_RETRIES;
    }

    pthread_mutex_unlock(&qat_engine_mutex);

    CRYPTO_CLOSE_QAT_LOG();

    return ret;
}
Exemplo n.º 15
0
static int
qat_engine_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
{
    unsigned int retVal = 1;
    CpaStatus status = CPA_STATUS_SUCCESS;
    int flags = 0;
    int fd = 0;

    switch (cmd) {
    case QAT_CMD_POLL:
        BREAK_IF(!engine_inited, "POLL failed as engine is not initialized\n");
        BREAK_IF(qat_instance_handles == NULL, "POLL failed as no instances are available\n");
        BREAK_IF(!enable_external_polling, "POLL failed as external polling is not enabled\n");
        BREAK_IF(p == NULL, "POLL failed as the input parameter was NULL\n");

        *(int *)p = (int)poll_instances();
        break;

    case QAT_CMD_ENABLE_EXTERNAL_POLLING:
        BREAK_IF(engine_inited, \
                "ENABLE_EXTERNAL_POLLING failed as the engine is already initialized\n");
        DEBUG("Enabled external polling\n");
        enable_external_polling = 1;
        enable_inline_polling = 0;
        break;

    case QAT_CMD_ENABLE_INLINE_POLLING:
        BREAK_IF(engine_inited, \
                "ENABLE_INLINE_POLLING failed as the engine is already initialized\n");
        DEBUG("Enabled inline polling\n");
        enable_inline_polling = 1;
        enable_external_polling = 0;
        break;

    case QAT_CMD_GET_EXTERNAL_POLLING_FD:
        BREAK_IF(!enable_event_driven_polling || !enable_external_polling, \
                "GET_EXTERNAL_POLLING_FD failed as this engine message is only supported \
                when running in Event Driven Mode with External Polling enabled\n");
        BREAK_IF(!engine_inited, \
                "GET_EXTERNAL_POLLING_FD failed as the engine is not initialized\n");
        BREAK_IF(qat_instance_handles == NULL,                          \
                 "GET_EXTERNAL_POLLING_FD failed as no instances are available\n");
        BREAK_IF(p == NULL, "GET_EXTERNAL_POLLING_FD failed as the input parameter was NULL\n");
        BREAK_IF(i >= qat_num_instances, \
                "GET_EXTERNAL_POLLING_FD failed as the instance does not exist\n");

        /* Get the file descriptor for the instance */
        status = icp_sal_CyGetFileDescriptor(qat_instance_handles[i], &fd);
        BREAK_IF(CPA_STATUS_FAIL == status, \
                "GET_EXTERNAL_POLLING_FD failed as there was an error retrieving the fd\n");
        /* Make the file descriptor non-blocking */
        flags = fcntl(fd, F_GETFL, 0);
        fcntl(fd, F_SETFL, flags | O_NONBLOCK);

        DEBUG("External polling FD for instance[%ld] = %d\n", i, fd);
        *(int *)p = fd;
        break;

    case QAT_CMD_ENABLE_EVENT_DRIVEN_POLLING_MODE:
        DEBUG("Enabled event driven polling mode\n");
        BREAK_IF(engine_inited, \
                "ENABLE_EVENT_DRIVEN_POLLING_MODE failed as the engine is already initialized\n");
        enable_event_driven_polling = 1;
        break;

    case QAT_CMD_DISABLE_EVENT_DRIVEN_POLLING_MODE:
        DEBUG("Disabled event driven polling mode\n");
        BREAK_IF(engine_inited, \
                "DISABLE_EVENT_DRIVEN_POLLING_MODE failed as the engine is already initialized\n");
        enable_event_driven_polling = 0;
        break;

    case QAT_CMD_SET_INSTANCE_FOR_THREAD:
        BREAK_IF(!engine_inited, \
                "SET_INSTANCE_FOR_THREAD failed as the engine is not initialized\n");
        BREAK_IF(qat_instance_handles == NULL,                          \
                 "SET_INSTANCE_FOR_THREAD failed as no instances are available\n");
        DEBUG("Set instance for thread = %ld\n", i);
        qat_set_instance_for_thread(i);
        break;

    case QAT_CMD_GET_NUM_OP_RETRIES:
        BREAK_IF(p == NULL, "GET_NUM_OP_RETRIES failed as the input parameter was NULL\n");
        BREAK_IF(!engine_inited, "GET_NUM_OP_RETRIES failed as the engine is not initialized\n");
        *(int *)p = qatPerformOpRetries;
        break;

    case QAT_CMD_SET_MAX_RETRY_COUNT:
        BREAK_IF(i < -1 || i > 100000,
            "The Message retry count value is out of range, using default value\n");
        DEBUG("Set max retry counter = %ld\n", i);
        qat_max_retry_count = (int)i;
        break;

    case QAT_CMD_SET_INTERNAL_POLL_INTERVAL:
        BREAK_IF(i < 1 || i > 1000000,
               "The polling interval value is out of range, using default value\n");
        DEBUG("Set internal poll interval = %ld ns\n", i);
        qat_poll_interval = (useconds_t) i;
        break;

    case QAT_CMD_SET_EPOLL_TIMEOUT:
        BREAK_IF(i < 1 || i > 10000,
                "The epoll timeout value is out of range, using default value\n")
        DEBUG("Set epoll_wait timeout = %ld ms\n", i);
        qat_epoll_timeout = (int) i;
        break;

    case QAT_CMD_GET_NUM_CRYPTO_INSTANCES:
        BREAK_IF(p == NULL, \
                "GET_NUM_CRYPTO_INSTANCES failed as the input parameter was NULL\n");
        BREAK_IF(!engine_inited, \
                "GET_NUM_CRYPTO_INSTANCES failed as the engine is not initialized\n");
        BREAK_IF(qat_instance_handles == NULL,                          \
                 "GET_NUM_CRYPTO_INSTANCES failed as no instances are available\n");
        DEBUG("Get number of crypto instances = %d\n", qat_num_instances);
        *(int *)p = qat_num_instances;
        break;

    case QAT_CMD_SET_CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD:
#ifndef OPENSSL_ENABLE_QAT_SMALL_PACKET_CIPHER_OFFLOADS
        if(p) {
            char *token;
            char str_p[1024];
            char *itr = str_p;
            strncpy(str_p, (const char *)p, 1024);
            while((token = strsep(&itr, ","))) {
                char *name_token = strsep(&token,":");
                char *value_token = strsep(&token,":");
                if(name_token && value_token) {
                    retVal = qat_pkt_threshold_table_set_threshold(
                                name_token, atoi(value_token));
                } else {
                    WARN("Invalid name_token or value_token\n");
                    retVal = 0;
                }
            }
        } else {
            WARN("Invalid p parameter\n");
            retVal = 0;
        }
#else
        WARN("QAT_CMD_SET_CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD is not supported\n");
        retVal = 0;
#endif
        break;

    default:
        WARN("CTRL command not implemented\n");
        retVal = 0;
        break;
    }
    if(!retVal) {
     QATerr(QAT_F_QAT_ENGINE_CTRL, QAT_R_ENGINE_CTRL_CMD_FAILURE);
    }
    return retVal;
}
Exemplo n.º 16
0
int qat_engine_init(ENGINE *e)
{
    int instNum, err;
    CpaStatus status = CPA_STATUS_SUCCESS;
    CpaBoolean limitDevAccess = CPA_FALSE;
    int ret_pthread_sigmask;

    pthread_mutex_lock(&qat_engine_mutex);
    if(engine_inited) {
        pthread_mutex_unlock(&qat_engine_mutex);
        return 1;
    }

    DEBUG("QAT Engine initialization:\n");
    DEBUG("- External polling: %s\n", enable_external_polling ? "ON": "OFF");
    DEBUG("- Inline polling: %s\n", enable_inline_polling ? "ON": "OFF");
    DEBUG("- Internal poll interval: %dns\n", qat_poll_interval);
    DEBUG("- Epoll timeout: %dms\n", qat_epoll_timeout);
    DEBUG("- Event driven polling mode: %s\n", enable_event_driven_polling ? "ON": "OFF");
    DEBUG("- Instance for thread: %s\n", enable_instance_for_thread ? "ON": "OFF");
    DEBUG("- Max retry count: %d\n", qat_max_retry_count);

    CRYPTO_INIT_QAT_LOG();

    polling_thread = pthread_self();

    if ((err = pthread_key_create(&qatInstanceForThread, NULL)) != 0) {
        WARN("pthread_key_create failed: %s\n", strerror(err));
        QATerr(QAT_F_QAT_ENGINE_INIT, QAT_R_PTHREAD_CREATE_FAILURE);
        pthread_mutex_unlock(&qat_engine_mutex);
        return 0;
    }

#ifndef OPENSSL_ENABLE_QAT_UPSTREAM_DRIVER
    /* limitDevAccess is passed as an input to icp_sal_userStartMultiProcess().
     * However, in upstream driver the value is ignored and read directly from
     * the configuration file -> No need to parse the file here.
     */
    if (!checkLimitDevAccessValue((int *)&limitDevAccess,
                                    ICPConfigSectionName_libcrypto)) {
        WARN("Could not load driver config file. Assuming LimitDevAccess = 0\n");
    }
#endif

    /* Initialise the QAT hardware */
    if (CPA_STATUS_SUCCESS !=
        icp_sal_userStartMultiProcess(ICPConfigSectionName_libcrypto,
                                      limitDevAccess)) {
        WARN("icp_sal_userStart failed\n");
        QATerr(QAT_F_QAT_ENGINE_INIT, QAT_R_ICP_SAL_USERSTART_FAIL);
        pthread_mutex_unlock(&qat_engine_mutex);
        return 0;
    }

    /* Get the number of available instances */
    status = cpaCyGetNumInstances(&qat_num_instances);
    if (CPA_STATUS_SUCCESS != status) {
        WARN("cpaCyGetNumInstances failed, status=%d\n", status);
        QATerr(QAT_F_QAT_ENGINE_INIT, QAT_R_GET_NUM_INSTANCE_FAILURE);
        pthread_mutex_unlock(&qat_engine_mutex);
        qat_engine_finish(e);
        return 0;
    }
    if (!qat_num_instances) {
        WARN("No crypto instances found\n");
        QATerr(QAT_F_QAT_ENGINE_INIT, QAT_R_INSTANCE_UNAVAILABLE);
        pthread_mutex_unlock(&qat_engine_mutex);
        qat_engine_finish(e);
        return 0;
    }

    DEBUG("Found %d Cy instances\n", qat_num_instances);

    /* Allocate memory for the instance handle array */
    qat_instance_handles =
        (CpaInstanceHandle *) OPENSSL_zalloc(((int)qat_num_instances) *
                                             sizeof(CpaInstanceHandle));
    if (NULL == qat_instance_handles) {
        WARN("OPENSSL_zalloc() failed for instance handles.\n");
        QATerr(QAT_F_QAT_ENGINE_INIT, QAT_R_INSTANCE_HANDLE_MALLOC_FAILURE);
        pthread_mutex_unlock(&qat_engine_mutex);
        qat_engine_finish(e);
        return 0;
    }

    /* Get the Cy instances */
    status = cpaCyGetInstances(qat_num_instances, qat_instance_handles);
    if (CPA_STATUS_SUCCESS != status) {
        WARN("cpaCyGetInstances failed, status=%d\n", status);
        QATerr(QAT_F_QAT_ENGINE_INIT, QAT_R_GET_INSTANCE_FAILURE);
        pthread_mutex_unlock(&qat_engine_mutex);
        qat_engine_finish(e);
        return 0;
    }

    if (!enable_external_polling && !enable_inline_polling) {
        if (qat_is_event_driven()) {
            CpaStatus status;
            int flags;
            int engine_fd;

            /*   Add the file descriptor to an epoll event list */
            internal_efd = epoll_create1(0);
            if (-1 == internal_efd) {
                WARN("Error creating epoll fd\n");
                QATerr(QAT_F_QAT_ENGINE_INIT, QAT_R_EPOLL_CREATE_FAILURE);
                pthread_mutex_unlock(&qat_engine_mutex);
                qat_engine_finish(e);
                return 0;
            }

            for (instNum = 0; instNum < qat_num_instances; instNum++) {
                /*   Get the file descriptor for the instance */
                status =
                    icp_sal_CyGetFileDescriptor(qat_instance_handles[instNum],
                                                &engine_fd);
                if (CPA_STATUS_FAIL == status) {
                    WARN("Error getting file descriptor for instance\n");
                    QATerr(QAT_F_QAT_ENGINE_INIT, QAT_R_GET_FILE_DESCRIPTOR_FAILURE);
                    pthread_mutex_unlock(&qat_engine_mutex);
                    qat_engine_finish(e);
                    return 0;
                }
                /*   Make the file descriptor non-blocking */
                eng_poll_st[instNum].eng_fd = engine_fd;
                eng_poll_st[instNum].inst_index = instNum;

                flags = fcntl(engine_fd, F_GETFL, 0);
                fcntl(engine_fd, F_SETFL, flags | O_NONBLOCK);

                eng_epoll_events[instNum].data.ptr = &eng_poll_st[instNum];
                eng_epoll_events[instNum].events = EPOLLIN | EPOLLET;
                if (-1 ==
                    epoll_ctl(internal_efd, EPOLL_CTL_ADD, engine_fd,
                              &eng_epoll_events[instNum])) {
                    WARN("Error adding fd to epoll\n");
                    QATerr(QAT_F_QAT_ENGINE_INIT, QAT_R_EPOLL_CTL_FAILURE);
                    pthread_mutex_unlock(&qat_engine_mutex);
                    qat_engine_finish(e);
                    return 0;
                }
            }
        }
    }

    /* Set translation function and start each instance */
    for (instNum = 0; instNum < qat_num_instances; instNum++) {
        /* Set the address translation function */
        status = cpaCySetAddressTranslation(qat_instance_handles[instNum],
                                            virtualToPhysical);
        if (CPA_STATUS_SUCCESS != status) {
            WARN("cpaCySetAddressTranslation failed, status=%d\n", status);
            QATerr(QAT_F_QAT_ENGINE_INIT, QAT_R_SET_ADDRESS_TRANSLATION_FAILURE);
            pthread_mutex_unlock(&qat_engine_mutex);
            qat_engine_finish(e);
            return 0;
        }

        /* Start the instances */
        status = cpaCyStartInstance(qat_instance_handles[instNum]);
        if (CPA_STATUS_SUCCESS != status) {
            WARN("cpaCyStartInstance failed, status=%d\n", status);
            QATerr(QAT_F_QAT_ENGINE_INIT, QAT_R_START_INSTANCE_FAILURE);
            pthread_mutex_unlock(&qat_engine_mutex);
            qat_engine_finish(e);
            return 0;
        }

        instance_started[instNum] = 1;
    }

    if (!enable_external_polling && !enable_inline_polling) {
        if (!qat_is_event_driven()) {
            sigemptyset(&set);
            sigaddset(&set, SIGUSR1);
            ret_pthread_sigmask = pthread_sigmask(SIG_BLOCK, &set, NULL);
            if (ret_pthread_sigmask != 0) {
                WARN("pthread_sigmask error\n");
                QATerr(QAT_F_QAT_ENGINE_INIT, QAT_R_POLLING_THREAD_SIGMASK_FAILURE);
                pthread_mutex_unlock(&qat_engine_mutex);
                qat_engine_finish(e);
                return 0;
            }
        }

        if (qat_create_thread(&polling_thread, NULL,
                    qat_is_event_driven() ? event_poll_func : timer_poll_func, NULL)) {
            WARN("Creation of polling thread failed\n");
            QATerr(QAT_F_QAT_ENGINE_INIT, QAT_R_POLLING_THREAD_CREATE_FAILURE);
            polling_thread = pthread_self();
            pthread_mutex_unlock(&qat_engine_mutex);
            qat_engine_finish(e);
            return 0;
        }
        if (qat_adjust_thread_affinity(polling_thread) == 0) {
            WARN("Setting polling thread affinity failed\n");
            QATerr(QAT_F_QAT_ENGINE_INIT, QAT_R_SET_POLLING_THREAD_AFFINITY_FAILURE);
            pthread_mutex_unlock(&qat_engine_mutex);
            qat_engine_finish(e);
            return 0;
        }
        if (!qat_is_event_driven()) {
            while (!cleared_to_start)
                sleep(1);
        }
    }
    /* Reset curr_inst */
    curr_inst = 0;
    engine_inited = 1;
    pthread_mutex_unlock(&qat_engine_mutex);
    return 1;
}