<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>