Copyright consolidation 02/10
[openssl.git] / engines / e_dasync.c
1 /*
2  * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stdio.h>
11 #include <string.h>
12
13 #include <openssl/engine.h>
14 #include <openssl/sha.h>
15 #include <openssl/aes.h>
16 #include <openssl/rsa.h>
17 #include <openssl/evp.h>
18 #include <openssl/async.h>
19 #include <openssl/bn.h>
20 #include <openssl/crypto.h>
21 #include <openssl/ssl.h>
22 #include <openssl/modes.h>
23
24 #if (defined(OPENSSL_SYS_UNIX) || defined(OPENSSL_SYS_CYGWIN)) && defined(OPENSSL_THREADS)
25 # undef ASYNC_POSIX
26 # define ASYNC_POSIX
27 # include <unistd.h>
28 #elif defined(_WIN32)
29 # undef ASYNC_WIN
30 # define ASYNC_WIN
31 # include <windows.h>
32 #endif
33
34 #define DASYNC_LIB_NAME "DASYNC"
35 #include "e_dasync_err.c"
36
37 /* Engine Id and Name */
38 static const char *engine_dasync_id = "dasync";
39 static const char *engine_dasync_name = "Dummy Async engine support";
40
41
42 /* Engine Lifetime functions */
43 static int dasync_destroy(ENGINE *e);
44 static int dasync_init(ENGINE *e);
45 static int dasync_finish(ENGINE *e);
46 void engine_load_dasync_int(void);
47
48
49 /* Set up digests. Just SHA1 for now */
50 static int dasync_digests(ENGINE *e, const EVP_MD **digest,
51                           const int **nids, int nid);
52
53 static void dummy_pause_job(void);
54
55 /* SHA1 */
56 static int dasync_sha1_init(EVP_MD_CTX *ctx);
57 static int dasync_sha1_update(EVP_MD_CTX *ctx, const void *data,
58                              size_t count);
59 static int dasync_sha1_final(EVP_MD_CTX *ctx, unsigned char *md);
60
61 /*
62  * Holds the EVP_MD object for sha1 in this engine. Set up once only during
63  * engine bind and can then be reused many times.
64  */
65 static EVP_MD *_hidden_sha1_md = NULL;
66 static const EVP_MD *dasync_sha1(void)
67 {
68     return _hidden_sha1_md;
69 }
70 static void destroy_digests(void)
71 {
72     EVP_MD_meth_free(_hidden_sha1_md);
73     _hidden_sha1_md = NULL;
74 }
75
76 static int dasync_digest_nids(const int **nids)
77 {
78     static int digest_nids[2] = { 0, 0 };
79     static int pos = 0;
80     static int init = 0;
81
82     if (!init) {
83         const EVP_MD *md;
84         if ((md = dasync_sha1()) != NULL)
85             digest_nids[pos++] = EVP_MD_type(md);
86         digest_nids[pos] = 0;
87         init = 1;
88     }
89     *nids = digest_nids;
90     return pos;
91 }
92
93 /* RSA */
94
95 static int dasync_pub_enc(int flen, const unsigned char *from,
96                     unsigned char *to, RSA *rsa, int padding);
97 static int dasync_pub_dec(int flen, const unsigned char *from,
98                     unsigned char *to, RSA *rsa, int padding);
99 static int dasync_rsa_priv_enc(int flen, const unsigned char *from,
100                       unsigned char *to, RSA *rsa, int padding);
101 static int dasync_rsa_priv_dec(int flen, const unsigned char *from,
102                       unsigned char *to, RSA *rsa, int padding);
103 static int dasync_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
104                               BN_CTX *ctx);
105
106 static int dasync_rsa_init(RSA *rsa);
107 static int dasync_rsa_finish(RSA *rsa);
108
109 static RSA_METHOD *dasync_rsa_method = NULL;
110
111 /* AES */
112
113 static int dasync_aes128_cbc_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
114                                   void *ptr);
115 static int dasync_aes128_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
116                                   const unsigned char *iv, int enc);
117 static int dasync_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
118                                     const unsigned char *in, size_t inl);
119 static int dasync_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx);
120
121 static int dasync_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,
122                                              int arg, void *ptr);
123 static int dasync_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
124                                                  const unsigned char *key,
125                                                  const unsigned char *iv,
126                                                  int enc);
127 static int dasync_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx,
128                                                unsigned char *out,
129                                                const unsigned char *in,
130                                                size_t inl);
131 static int dasync_aes128_cbc_hmac_sha1_cleanup(EVP_CIPHER_CTX *ctx);
132
133 struct dasync_pipeline_ctx {
134     void *inner_cipher_data;
135     unsigned int numpipes;
136     unsigned char **inbufs;
137     unsigned char **outbufs;
138     size_t *lens;
139     int enc;
140     unsigned char tlsaad[SSL_MAX_PIPELINES][EVP_AEAD_TLS1_AAD_LEN];
141     unsigned int aadctr;
142 };
143
144 /*
145  * Holds the EVP_CIPHER object for aes_128_cbc in this engine. Set up once only
146  * during engine bind and can then be reused many times.
147  */
148 static EVP_CIPHER *_hidden_aes_128_cbc = NULL;
149 static const EVP_CIPHER *dasync_aes_128_cbc(void)
150 {
151     return _hidden_aes_128_cbc;
152 }
153
154 /*
155  * Holds the EVP_CIPHER object for aes_128_cbc_hmac_sha1 in this engine. Set up
156  * once only during engine bind and can then be reused many times.
157  */
158 static EVP_CIPHER *_hidden_aes_128_cbc_hmac_sha1 = NULL;
159 static const EVP_CIPHER *dasync_aes_128_cbc_hmac_sha1(void)
160 {
161     return _hidden_aes_128_cbc_hmac_sha1;
162 }
163
164 static void destroy_ciphers(void)
165 {
166     EVP_CIPHER_meth_free(_hidden_aes_128_cbc);
167     EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1);
168     _hidden_aes_128_cbc = NULL;
169     _hidden_aes_128_cbc_hmac_sha1 = NULL;
170 }
171
172 static int dasync_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
173                                    const int **nids, int nid);
174
175 static int dasync_cipher_nids[] = {
176     NID_aes_128_cbc,
177     NID_aes_128_cbc_hmac_sha1,
178     0
179 };
180
181 static int bind_dasync(ENGINE *e)
182 {
183     /* Setup RSA_METHOD */
184     if ((dasync_rsa_method = RSA_meth_new("Dummy Async RSA method", 0)) == NULL
185         || RSA_meth_set_pub_enc(dasync_rsa_method, dasync_pub_enc) == 0
186         || RSA_meth_set_pub_dec(dasync_rsa_method, dasync_pub_dec) == 0
187         || RSA_meth_set_priv_enc(dasync_rsa_method, dasync_rsa_priv_enc) == 0
188         || RSA_meth_set_priv_dec(dasync_rsa_method, dasync_rsa_priv_dec) == 0
189         || RSA_meth_set_mod_exp(dasync_rsa_method, dasync_rsa_mod_exp) == 0
190         || RSA_meth_set_bn_mod_exp(dasync_rsa_method, BN_mod_exp_mont) == 0
191         || RSA_meth_set_init(dasync_rsa_method, dasync_rsa_init) == 0
192         || RSA_meth_set_finish(dasync_rsa_method, dasync_rsa_finish) == 0) {
193         DASYNCerr(DASYNC_F_BIND_DASYNC, DASYNC_R_INIT_FAILED);
194         return 0;
195     }
196
197     /* Ensure the dasync error handling is set up */
198     ERR_load_DASYNC_strings();
199
200     if (!ENGINE_set_id(e, engine_dasync_id)
201         || !ENGINE_set_name(e, engine_dasync_name)
202         || !ENGINE_set_RSA(e, dasync_rsa_method)
203         || !ENGINE_set_digests(e, dasync_digests)
204         || !ENGINE_set_ciphers(e, dasync_ciphers)
205         || !ENGINE_set_destroy_function(e, dasync_destroy)
206         || !ENGINE_set_init_function(e, dasync_init)
207         || !ENGINE_set_finish_function(e, dasync_finish)) {
208         DASYNCerr(DASYNC_F_BIND_DASYNC, DASYNC_R_INIT_FAILED);
209         return 0;
210     }
211
212     /*
213      * Set up the EVP_CIPHER and EVP_MD objects for the ciphers/digests
214      * supplied by this engine
215      */
216     _hidden_sha1_md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption);
217     if (_hidden_sha1_md == NULL
218         || !EVP_MD_meth_set_result_size(_hidden_sha1_md, SHA_DIGEST_LENGTH)
219         || !EVP_MD_meth_set_input_blocksize(_hidden_sha1_md, SHA_CBLOCK)
220         || !EVP_MD_meth_set_app_datasize(_hidden_sha1_md,
221                                          sizeof(EVP_MD *) + sizeof(SHA_CTX))
222         || !EVP_MD_meth_set_flags(_hidden_sha1_md, EVP_MD_FLAG_DIGALGID_ABSENT)
223         || !EVP_MD_meth_set_init(_hidden_sha1_md, dasync_sha1_init)
224         || !EVP_MD_meth_set_update(_hidden_sha1_md, dasync_sha1_update)
225         || !EVP_MD_meth_set_final(_hidden_sha1_md, dasync_sha1_final)) {
226         EVP_MD_meth_free(_hidden_sha1_md);
227         _hidden_sha1_md = NULL;
228     }
229
230     _hidden_aes_128_cbc = EVP_CIPHER_meth_new(NID_aes_128_cbc,
231                                               16 /* block size */,
232                                               16 /* key len */);
233     if (_hidden_aes_128_cbc == NULL
234             || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc,16)
235             || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc,
236                                           EVP_CIPH_FLAG_DEFAULT_ASN1
237                                           | EVP_CIPH_CBC_MODE
238                                           | EVP_CIPH_FLAG_PIPELINE)
239             || !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc,
240                                          dasync_aes128_init_key)
241             || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc,
242                                               dasync_aes128_cbc_cipher)
243             || !EVP_CIPHER_meth_set_cleanup(_hidden_aes_128_cbc,
244                                             dasync_aes128_cbc_cleanup)
245             || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_cbc,
246                                          dasync_aes128_cbc_ctrl)
247             || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc,
248                                 sizeof(struct dasync_pipeline_ctx))) {
249         EVP_CIPHER_meth_free(_hidden_aes_128_cbc);
250         _hidden_aes_128_cbc = NULL;
251     }
252
253     _hidden_aes_128_cbc_hmac_sha1 = EVP_CIPHER_meth_new(
254                                                 NID_aes_128_cbc_hmac_sha1,
255                                                 16 /* block size */,
256                                                 16 /* key len */);
257     if (_hidden_aes_128_cbc_hmac_sha1 == NULL
258             || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc_hmac_sha1,16)
259             || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc_hmac_sha1,
260                                             EVP_CIPH_CBC_MODE
261                                           | EVP_CIPH_FLAG_DEFAULT_ASN1
262                                           | EVP_CIPH_FLAG_AEAD_CIPHER
263                                           | EVP_CIPH_FLAG_PIPELINE)
264             || !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc_hmac_sha1,
265                                          dasync_aes128_cbc_hmac_sha1_init_key)
266             || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc_hmac_sha1,
267                                             dasync_aes128_cbc_hmac_sha1_cipher)
268             || !EVP_CIPHER_meth_set_cleanup(_hidden_aes_128_cbc_hmac_sha1,
269                                             dasync_aes128_cbc_hmac_sha1_cleanup)
270             || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_cbc_hmac_sha1,
271                                          dasync_aes128_cbc_hmac_sha1_ctrl)
272             || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc_hmac_sha1,
273                                 sizeof(struct dasync_pipeline_ctx))) {
274         EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1);
275         _hidden_aes_128_cbc_hmac_sha1 = NULL;
276     }
277
278     return 1;
279 }
280
281 # ifndef OPENSSL_NO_DYNAMIC_ENGINE
282 static int bind_helper(ENGINE *e, const char *id)
283 {
284     if (id && (strcmp(id, engine_dasync_id) != 0))
285         return 0;
286     if (!bind_dasync(e))
287         return 0;
288     return 1;
289 }
290
291 IMPLEMENT_DYNAMIC_CHECK_FN()
292     IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
293 # endif
294
295 static ENGINE *engine_dasync(void)
296 {
297     ENGINE *ret = ENGINE_new();
298     if (!ret)
299         return NULL;
300     if (!bind_dasync(ret)) {
301         ENGINE_free(ret);
302         return NULL;
303     }
304     return ret;
305 }
306
307 void engine_load_dasync_int(void)
308 {
309     ENGINE *toadd = engine_dasync();
310     if (!toadd)
311         return;
312     ENGINE_add(toadd);
313     ENGINE_free(toadd);
314     ERR_clear_error();
315 }
316
317 static int dasync_init(ENGINE *e)
318 {
319     return 1;
320 }
321
322
323 static int dasync_finish(ENGINE *e)
324 {
325     return 1;
326 }
327
328
329 static int dasync_destroy(ENGINE *e)
330 {
331     destroy_digests();
332     destroy_ciphers();
333     RSA_meth_free(dasync_rsa_method);
334     ERR_unload_DASYNC_strings();
335     return 1;
336 }
337
338 static int dasync_digests(ENGINE *e, const EVP_MD **digest,
339                           const int **nids, int nid)
340 {
341     int ok = 1;
342     if (!digest) {
343         /* We are returning a list of supported nids */
344         return dasync_digest_nids(nids);
345     }
346     /* We are being asked for a specific digest */
347     switch (nid) {
348     case NID_sha1:
349         *digest = dasync_sha1();
350         break;
351     default:
352         ok = 0;
353         *digest = NULL;
354         break;
355     }
356     return ok;
357 }
358
359 static int dasync_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
360                                    const int **nids, int nid)
361 {
362     int ok = 1;
363     if (cipher == NULL) {
364         /* We are returning a list of supported nids */
365         *nids = dasync_cipher_nids;
366         return (sizeof(dasync_cipher_nids) -
367                 1) / sizeof(dasync_cipher_nids[0]);
368     }
369     /* We are being asked for a specific cipher */
370     switch (nid) {
371     case NID_aes_128_cbc:
372         *cipher = dasync_aes_128_cbc();
373         break;
374     case NID_aes_128_cbc_hmac_sha1:
375         *cipher = dasync_aes_128_cbc_hmac_sha1();
376         break;
377     default:
378         ok = 0;
379         *cipher = NULL;
380         break;
381     }
382     return ok;
383 }
384
385 static void wait_cleanup(ASYNC_WAIT_CTX *ctx, const void *key,
386                          OSSL_ASYNC_FD readfd, void *pvwritefd)
387 {
388     OSSL_ASYNC_FD *pwritefd = (OSSL_ASYNC_FD *)pvwritefd;
389 #if defined(ASYNC_WIN)
390     CloseHandle(readfd);
391     CloseHandle(*pwritefd);
392 #elif defined(ASYNC_POSIX)
393     close(readfd);
394     close(*pwritefd);
395 #endif
396     OPENSSL_free(pwritefd);
397 }
398
399 #define DUMMY_CHAR 'X'
400
401 static void dummy_pause_job(void) {
402     ASYNC_JOB *job;
403     ASYNC_WAIT_CTX *waitctx;
404     OSSL_ASYNC_FD pipefds[2] = {0, 0};
405     OSSL_ASYNC_FD *writefd;
406 #if defined(ASYNC_WIN)
407     DWORD numwritten, numread;
408     char buf = DUMMY_CHAR;
409 #elif defined(ASYNC_POSIX)
410     char buf = DUMMY_CHAR;
411 #endif
412
413     if ((job = ASYNC_get_current_job()) == NULL)
414         return;
415
416     waitctx = ASYNC_get_wait_ctx(job);
417
418     if (ASYNC_WAIT_CTX_get_fd(waitctx, engine_dasync_id, &pipefds[0],
419                               (void **)&writefd)) {
420         pipefds[1] = *writefd;
421     } else {
422         writefd = OPENSSL_malloc(sizeof(*writefd));
423         if (writefd == NULL)
424             return;
425 #if defined(ASYNC_WIN)
426         if (CreatePipe(&pipefds[0], &pipefds[1], NULL, 256) == 0) {
427             OPENSSL_free(writefd);
428             return;
429         }
430 #elif defined(ASYNC_POSIX)
431         if (pipe(pipefds) != 0) {
432             OPENSSL_free(writefd);
433             return;
434         }
435 #endif
436         *writefd = pipefds[1];
437
438         if(!ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_dasync_id, pipefds[0],
439                                        writefd, wait_cleanup)) {
440             wait_cleanup(waitctx, engine_dasync_id, pipefds[0], writefd);
441             return;
442         }
443     }
444     /*
445      * In the Dummy async engine we are cheating. We signal that the job
446      * is complete by waking it before the call to ASYNC_pause_job(). A real
447      * async engine would only wake when the job was actually complete
448      */
449 #if defined(ASYNC_WIN)
450     WriteFile(pipefds[1], &buf, 1, &numwritten, NULL);
451 #elif defined(ASYNC_POSIX)
452     if (write(pipefds[1], &buf, 1) < 0)
453         return;
454 #endif
455
456     /* Ignore errors - we carry on anyway */
457     ASYNC_pause_job();
458
459     /* Clear the wake signal */
460 #if defined(ASYNC_WIN)
461     ReadFile(pipefds[0], &buf, 1, &numread, NULL);
462 #elif defined(ASYNC_POSIX)
463     if (read(pipefds[0], &buf, 1) < 0)
464         return;
465 #endif
466 }
467
468 /*
469  * SHA1 implementation. At the moment we just defer to the standard
470  * implementation
471  */
472 #undef data
473 #define data(ctx) ((SHA_CTX *)EVP_MD_CTX_md_data(ctx))
474 static int dasync_sha1_init(EVP_MD_CTX *ctx)
475 {
476     dummy_pause_job();
477
478     return SHA1_Init(data(ctx));
479 }
480
481 static int dasync_sha1_update(EVP_MD_CTX *ctx, const void *data,
482                              size_t count)
483 {
484     dummy_pause_job();
485
486     return SHA1_Update(data(ctx), data, (size_t)count);
487 }
488
489 static int dasync_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)
490 {
491     dummy_pause_job();
492
493     return SHA1_Final(md, data(ctx));
494 }
495
496 /*
497  * RSA implementation
498  */
499
500 static int dasync_pub_enc(int flen, const unsigned char *from,
501                     unsigned char *to, RSA *rsa, int padding) {
502     /* Ignore errors - we carry on anyway */
503     dummy_pause_job();
504     return RSA_meth_get_pub_enc(RSA_PKCS1_OpenSSL())
505         (flen, from, to, rsa, padding);
506 }
507
508 static int dasync_pub_dec(int flen, const unsigned char *from,
509                     unsigned char *to, RSA *rsa, int padding) {
510     /* Ignore errors - we carry on anyway */
511     dummy_pause_job();
512     return RSA_meth_get_pub_dec(RSA_PKCS1_OpenSSL())
513         (flen, from, to, rsa, padding);
514 }
515
516 static int dasync_rsa_priv_enc(int flen, const unsigned char *from,
517                       unsigned char *to, RSA *rsa, int padding)
518 {
519     /* Ignore errors - we carry on anyway */
520     dummy_pause_job();
521     return RSA_meth_get_priv_enc(RSA_PKCS1_OpenSSL())
522         (flen, from, to, rsa, padding);
523 }
524
525 static int dasync_rsa_priv_dec(int flen, const unsigned char *from,
526                       unsigned char *to, RSA *rsa, int padding)
527 {
528     /* Ignore errors - we carry on anyway */
529     dummy_pause_job();
530     return RSA_meth_get_priv_dec(RSA_PKCS1_OpenSSL())
531         (flen, from, to, rsa, padding);
532 }
533
534 static int dasync_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
535 {
536     /* Ignore errors - we carry on anyway */
537     dummy_pause_job();
538     return RSA_meth_get_mod_exp(RSA_PKCS1_OpenSSL())(r0, I, rsa, ctx);
539 }
540
541 static int dasync_rsa_init(RSA *rsa)
542 {
543     return RSA_meth_get_init(RSA_PKCS1_OpenSSL())(rsa);
544 }
545 static int dasync_rsa_finish(RSA *rsa)
546 {
547     return RSA_meth_get_finish(RSA_PKCS1_OpenSSL())(rsa);
548 }
549
550 /* Cipher helper functions */
551
552 static int dasync_cipher_ctrl_helper(EVP_CIPHER_CTX *ctx, int type, int arg,
553                                      void *ptr, int aeadcapable)
554 {
555     int ret;
556     struct dasync_pipeline_ctx *pipe_ctx =
557         (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
558
559     if (pipe_ctx == NULL)
560         return 0;
561
562     switch (type) {
563         case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS:
564             pipe_ctx->numpipes = arg;
565             pipe_ctx->outbufs = (unsigned char **)ptr;
566             break;
567
568         case EVP_CTRL_SET_PIPELINE_INPUT_BUFS:
569             pipe_ctx->numpipes = arg;
570             pipe_ctx->inbufs = (unsigned char **)ptr;
571             break;
572
573         case EVP_CTRL_SET_PIPELINE_INPUT_LENS:
574             pipe_ctx->numpipes = arg;
575             pipe_ctx->lens = (size_t *)ptr;
576             break;
577
578         case EVP_CTRL_AEAD_SET_MAC_KEY:
579             if (!aeadcapable)
580                 return -1;
581             EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data);
582             ret = EVP_CIPHER_meth_get_ctrl(EVP_aes_128_cbc_hmac_sha1())
583                                           (ctx, type, arg, ptr);
584             EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx);
585             return ret;
586
587         case EVP_CTRL_AEAD_TLS1_AAD:
588         {
589             unsigned char *p = ptr;
590             unsigned int len;
591
592             if (!aeadcapable || arg != EVP_AEAD_TLS1_AAD_LEN)
593                 return -1;
594
595             if (pipe_ctx->aadctr >= SSL_MAX_PIPELINES)
596                 return -1;
597
598             memcpy(pipe_ctx->tlsaad[pipe_ctx->aadctr], ptr,
599                    EVP_AEAD_TLS1_AAD_LEN);
600             pipe_ctx->aadctr++;
601
602             len = p[arg - 2] << 8 | p[arg - 1];
603
604             if (pipe_ctx->enc) {
605                 if ((p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
606                     len -= AES_BLOCK_SIZE;
607                 }
608
609                 return ((len + SHA_DIGEST_LENGTH + AES_BLOCK_SIZE)
610                         & -AES_BLOCK_SIZE) - len;
611             } else {
612                 return SHA_DIGEST_LENGTH;
613             }
614         }
615
616         default:
617             return 0;
618     }
619
620     return 1;
621 }
622
623 static int dasync_cipher_init_key_helper(EVP_CIPHER_CTX *ctx,
624                                          const unsigned char *key,
625                                          const unsigned char *iv, int enc,
626                                          const EVP_CIPHER *cipher)
627 {
628     int ret;
629     struct dasync_pipeline_ctx *pipe_ctx =
630         (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
631
632     if (pipe_ctx->inner_cipher_data == NULL
633             && EVP_CIPHER_impl_ctx_size(cipher) != 0) {
634         pipe_ctx->inner_cipher_data = OPENSSL_zalloc(
635             EVP_CIPHER_impl_ctx_size(cipher));
636         if (pipe_ctx->inner_cipher_data == NULL) {
637             DASYNCerr(DASYNC_F_DASYNC_CIPHER_INIT_KEY_HELPER,
638                         ERR_R_MALLOC_FAILURE);
639             return 0;
640         }
641     }
642
643     pipe_ctx->numpipes = 0;
644     pipe_ctx->aadctr = 0;
645
646     EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data);
647     ret = EVP_CIPHER_meth_get_init(cipher)(ctx, key, iv, enc);
648     EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx);
649
650     return ret;
651 }
652
653 static int dasync_cipher_helper(EVP_CIPHER_CTX *ctx, unsigned char *out,
654                                 const unsigned char *in, size_t inl,
655                                 const EVP_CIPHER *cipher)
656 {
657     int ret = 1;
658     unsigned int i, pipes;
659     struct dasync_pipeline_ctx *pipe_ctx =
660         (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
661
662     pipes = pipe_ctx->numpipes;
663     EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data);
664     if (pipes == 0) {
665         if (pipe_ctx->aadctr != 0) {
666             if (pipe_ctx->aadctr != 1)
667                 return -1;
668             EVP_CIPHER_meth_get_ctrl(cipher)
669                                     (ctx, EVP_CTRL_AEAD_TLS1_AAD,
670                                      EVP_AEAD_TLS1_AAD_LEN,
671                                      pipe_ctx->tlsaad[0]);
672         }
673         ret = EVP_CIPHER_meth_get_do_cipher(cipher)
674                                            (ctx, out, in, inl);
675     } else {
676         if (pipe_ctx->aadctr > 0 && pipe_ctx->aadctr != pipes)
677             return -1;
678         for (i = 0; i < pipes; i++) {
679             if (pipe_ctx->aadctr > 0) {
680                 EVP_CIPHER_meth_get_ctrl(cipher)
681                                         (ctx, EVP_CTRL_AEAD_TLS1_AAD,
682                                          EVP_AEAD_TLS1_AAD_LEN,
683                                          pipe_ctx->tlsaad[i]);
684             }
685             ret = ret && EVP_CIPHER_meth_get_do_cipher(cipher)
686                                 (ctx, pipe_ctx->outbufs[i], pipe_ctx->inbufs[i],
687                                  pipe_ctx->lens[i]);
688         }
689         pipe_ctx->numpipes = 0;
690     }
691     pipe_ctx->aadctr = 0;
692     EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx);
693     return ret;
694 }
695
696 static int dasync_cipher_cleanup_helper(EVP_CIPHER_CTX *ctx,
697                                         const EVP_CIPHER *cipher)
698 {
699     struct dasync_pipeline_ctx *pipe_ctx =
700         (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
701
702     OPENSSL_clear_free(pipe_ctx->inner_cipher_data,
703                        EVP_CIPHER_impl_ctx_size(cipher));
704
705     return 1;
706 }
707
708 /*
709  * AES128 CBC Implementation
710  */
711
712 static int dasync_aes128_cbc_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
713                                   void *ptr)
714 {
715     return dasync_cipher_ctrl_helper(ctx, type, arg, ptr, 0);
716 }
717
718 static int dasync_aes128_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
719                              const unsigned char *iv, int enc)
720 {
721     return dasync_cipher_init_key_helper(ctx, key, iv, enc, EVP_aes_128_cbc());
722 }
723
724 static int dasync_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
725                                const unsigned char *in, size_t inl)
726 {
727     return dasync_cipher_helper(ctx, out, in, inl, EVP_aes_128_cbc());
728 }
729
730 static int dasync_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx)
731 {
732     return dasync_cipher_cleanup_helper(ctx, EVP_aes_128_cbc());
733 }
734
735
736 /*
737  * AES128 CBC HMAC SHA1 Implementation
738  */
739
740 static int dasync_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,
741                                              int arg, void *ptr)
742 {
743     return dasync_cipher_ctrl_helper(ctx, type, arg, ptr, 1);
744 }
745
746 static int dasync_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
747                                                 const unsigned char *key,
748                                                 const unsigned char *iv,
749                                                 int enc)
750 {
751     return dasync_cipher_init_key_helper(ctx, key, iv, enc,
752                                          EVP_aes_128_cbc_hmac_sha1());
753 }
754
755 static int dasync_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx,
756                                                unsigned char *out,
757                                                const unsigned char *in,
758                                                size_t inl)
759 {
760     return dasync_cipher_helper(ctx, out, in, inl, EVP_aes_128_cbc_hmac_sha1());
761 }
762
763 static int dasync_aes128_cbc_hmac_sha1_cleanup(EVP_CIPHER_CTX *ctx)
764 {
765     return dasync_cipher_cleanup_helper(ctx, EVP_aes_128_cbc_hmac_sha1());
766 }