Пример #1
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;
}
Пример #2
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:
        if (qatInstanceHandles == NULL) {
            /*
             * It is possible to call this ctrl function while the engine is
             * in a state where there are no instances available. This
             * happens for example immediately when the engine is waiting
             * for get_next_inst() to be called.
             *
             * To avoid this condition we call get_next_inst()
             */
            get_next_inst();
            BREAK_IF(qatInstanceHandles == NULL, "POLL failed as no instances are available\n");
        }

        BREAK_IF(!engine_inited, "POLL failed as engine is not initialized\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("[%s] Enabled external polling\n", __func__);
        enable_external_polling = 1;
        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");
        if (qatInstanceHandles == NULL) {
            get_next_inst();
            BREAK_IF(qatInstanceHandles == NULL, \
                    "GET_EXTERNAL_POLLING_FD failed as no instances are available\n");
        }
        BREAK_IF(!engine_inited, \
                "GET_EXTERNAL_POLLING_FD failed as the engine is not initialized\n");
        BREAK_IF(p == NULL, "GET_EXTERNAL_POLLING_FD failed as the input parameter was NULL\n");
        BREAK_IF(i >= numInstances, \
                "GET_EXTERNAL_POLLING_FD failed as the instance does not exist\n");

        /* Get the file descriptor for the instance */
        status = icp_sal_CyGetFileDescriptor(qatInstanceHandles[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("[%s] External polling FD for instance[%d] = %d\n", __func__, i, fd);
        *(int *)p = fd;
        break;

    case QAT_CMD_ENABLE_EVENT_DRIVEN_POLLING_MODE:
        DEBUG("[%s] Enabled event driven polling mode\n", __func__);
        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("[%s] Disabled event driven polling mode\n", __func__);
        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:
        if (qatInstanceHandles == NULL) {
            get_next_inst();
            BREAK_IF(qatInstanceHandles == NULL, \
                    "SET_INSTANCE_FOR_THREAD failed as no instances are available\n");
        }
        BREAK_IF(!engine_inited, \
                "SET_INSTANCE_FOR_THREAD failed as the engine is not initialized\n");
        DEBUG("[%s] Set instance for thread = %d\n", __func__, 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("[%s] Set max retry counter = %d\n", __func__, 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("[%s] Set internal poll interval = %d ns\n", __func__, 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("[%s] Set epoll_wait timeout = %d ms\n", __func__, 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");
        if (qatInstanceHandles == NULL) {
            get_next_inst();
            BREAK_IF(qatInstanceHandles == NULL, \
                    "GET_NUM_CRYPTO_INSTANCES failed as no instances are available\n");
        }
        BREAK_IF(!engine_inited, \
                "GET_NUM_CRYPTO_INSTANCES failed as the engine is not initialized\n");
        DEBUG("[%s] Get number of crypto instances = %d\n", __func__, numInstances);
        *(int *)p = numInstances;
        break;

    case QAT_CMD_SET_CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD:
#ifndef OPENSSL_ENABLE_QAT_SMALL_PACKET_CIPHER_OFFLOADS
        if(p) {
            char *token;
            while((token = strsep((char **)&p, ","))) {
                char *name_token = strsep(&token,":");
                char *value_token = strsep(&token,":");
                if(name_token && value_token) {
                    retVal = setQatSmallPacketThreshold(name_token, atoi(value_token));
                } else {
                    WARN("Invalid parameter!\n");
                    retVal = 0;
                }
            }
        } else {
            WARN("Invalid 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;
    }
    return retVal;
}
Пример #3
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;
}