[openssl-dev] Adding async support

Matt Caswell matt at openssl.org
Thu Oct 8 19:06:21 UTC 2015



On 08/10/15 18:56, Dmitry Belyavsky wrote:

>     The second problem is entirely engine dependant. It will be a different
>     solution for different hardware. These patches do not provide a solution
>     to that problem.
> 
> 
> So I do not understand what you mean by "offload" :-(
> 
> I understand that it's an engine-dependent, but I can't imagine a
> corresponding pseudo code.

Ok. So this is the pseudo code I posted before for how an engine might
be implemented:

static int myengine_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx,
    unsigned char *out, const unsigned char *in, size_t inl)
{
    int jobid;

    jobid = offload_cipher_to_hardware(ctx, out, in , inl);

    /*
     * jobid holds a reference in the engine back to the work we just
     * started
     */

    while(work_not_finished_yet(jobid)) {
        /* Return control back to the calling application */
        ASYNC_pause_job();
    }

    return get_results_from_hardware(jobid);
}


So lets imagine an engine that works via threads and how those pseudo
code function call might be implemented. It could be something like this:

void initialise_engine(void)
{
    start_thread(worker_main);
}

static int nextjobid = 0;

struct work_st {
    int jobid;
    EVP_CIPHER_CTX *ctx;
    unsigned char *out;
    unsigned char *in;
    size_t inl;
    int ret;
}

int worker_main(void)
{
    struct work_st *work;

    while(true) {
        work = get_work_off_in_queue();
        /* This is a long running operation */
        work->ret = do_aes128_cbc_cipher(work->ctx, work->out, work->in,
work->inl);
	put_work_in_finished_set(work);
    }
}

int offload_cipher_to_hardware(EVP_CIPHER_CTX *ctx, unsigned char *out,
unsigned char *in, size_t inl) {
    struct work_st *work;

    work = malloc(sizeof *work);
    work->ctx = ctx;
    work->out = out;
    work->in = in;
    work->inl = inl;
    work->jobid = nextjobid++;

    add_work_to_in_queue(work);

    return work->jobid;
}

int work_not_finished_yet(int jobid)
{
    return !is_work_in_finished_set(jobid);
}

int get_results_from_hardware(int jobid)
{
    struct work_st *work;

    work = get_work_out_of_finished_set(jobid);

    return work->ret;
}

In a hardware based engine everything in "worker_main" would be
implemented in the hardware. So the hardware gets on with the long
running crypto operation, whilst in the software control has returned
back to the application.

Does that make more sense?

Matt


More information about the openssl-dev mailing list