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