<div dir="ltr">Dear  Matt, <div class="gmail_extra"><br><div class="gmail_quote">On Thu, Oct 8, 2015 at 10:06 PM, Matt Caswell <span dir="ltr"><<a href="mailto:matt@openssl.org" target="_blank">matt@openssl.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
<br>
On 08/10/15 18:56, Dmitry Belyavsky wrote:<br>
<br>
>     The second problem is entirely engine dependant. It will be a different<br>
>     solution for different hardware. These patches do not provide a solution<br>
>     to that problem.<br>
><br>
><br>
> So I do not understand what you mean by "offload" :-(<br>
><br>
> I understand that it's an engine-dependent, but I can't imagine a<br>
> corresponding pseudo code.<br>
<br>
</span>Ok. So this is the pseudo code I posted before for how an engine might<br>
be implemented:<br>
<span class=""><br>
static int myengine_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx,<br>
    unsigned char *out, const unsigned char *in, size_t inl)<br>
{<br>
    int jobid;<br>
<br>
    jobid = offload_cipher_to_hardware(ctx, out, in , inl);<br>
<br>
    /*<br>
     * jobid holds a reference in the engine back to the work we just<br>
     * started<br>
     */<br>
<br>
    while(work_not_finished_yet(jobid)) {<br>
        /* Return control back to the calling application */<br>
        ASYNC_pause_job();<br>
    }<br>
<br>
    return get_results_from_hardware(jobid);<br>
}<br>
<br>
<br>
</span>So lets imagine an engine that works via threads and how those pseudo<br>
code function call might be implemented. It could be something like this:<br>
<br>
void initialise_engine(void)<br>
{<br>
    start_thread(worker_main);<br>
}<br>
<br>
static int nextjobid = 0;<br>
<br>
struct work_st {<br>
    int jobid;<br>
    EVP_CIPHER_CTX *ctx;<br>
    unsigned char *out;<br>
    unsigned char *in;<br>
    size_t inl;<br>
    int ret;<br>
}<br>
<br>
int worker_main(void)<br>
{<br>
    struct work_st *work;<br>
<br>
    while(true) {<br>
        work = get_work_off_in_queue();<br>
        /* This is a long running operation */<br>
        work->ret = do_aes128_cbc_cipher(work->ctx, work->out, work->in,<br>
work->inl);<br>
        put_work_in_finished_set(work);<br>
    }<br>
}<br>
<br>
int offload_cipher_to_hardware(EVP_CIPHER_CTX *ctx, unsigned char *out,<br>
<span class="">unsigned char *in, size_t inl) {<br>
</span>    struct work_st *work;<br>
<br>
    work = malloc(sizeof *work);<br>
    work->ctx = ctx;<br>
    work->out = out;<br>
    work->in = in;<br>
    work->inl = inl;<br>
    work->jobid = nextjobid++;<br>
<br>
    add_work_to_in_queue(work);<br>
<br>
    return work->jobid;<br>
}<br>
<br>
int work_not_finished_yet(int jobid)<br>
{<br>
    return !is_work_in_finished_set(jobid);<br>
}<br>
<br>
int get_results_from_hardware(int jobid)<br>
{<br>
    struct work_st *work;<br>
<br>
    work = get_work_out_of_finished_set(jobid);<br>
<br>
    return work->ret;<br>
}<br>
<br>
In a hardware based engine everything in "worker_main" would be<br>
implemented in the hardware. So the hardware gets on with the long<br>
running crypto operation, whilst in the software control has returned<br>
back to the application.<br>
<br>
Does that make more sense?<br></blockquote><div><br></div><div>Thank you! I finally got it.</div></div><br clear="all"><div><br></div>-- <br><div class="gmail_signature">SY, Dmitry Belyavsky</div>
</div></div>