Home | History | Annotate | Line # | Download | only in dist
cipher-ctr-mt.c revision 1.2
      1  1.1  christos /*
      2  1.1  christos  * OpenSSH Multi-threaded AES-CTR Cipher
      3  1.1  christos  *
      4  1.1  christos  * Author: Benjamin Bennett <ben (at) psc.edu>
      5  1.1  christos  * Copyright (c) 2008 Pittsburgh Supercomputing Center. All rights reserved.
      6  1.1  christos  *
      7  1.1  christos  * Based on original OpenSSH AES-CTR cipher. Small portions remain unchanged,
      8  1.1  christos  * Copyright (c) 2003 Markus Friedl <markus (at) openbsd.org>
      9  1.1  christos  *
     10  1.1  christos  * Permission to use, copy, modify, and distribute this software for any
     11  1.1  christos  * purpose with or without fee is hereby granted, provided that the above
     12  1.1  christos  * copyright notice and this permission notice appear in all copies.
     13  1.1  christos  *
     14  1.1  christos  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     15  1.1  christos  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     16  1.1  christos  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     17  1.1  christos  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     18  1.1  christos  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     19  1.1  christos  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     20  1.1  christos  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     21  1.1  christos  */
     22  1.1  christos #include "includes.h"
     23  1.1  christos 
     24  1.1  christos #include <sys/types.h>
     25  1.1  christos 
     26  1.1  christos #include <stdarg.h>
     27  1.1  christos #include <string.h>
     28  1.1  christos 
     29  1.1  christos #include <openssl/evp.h>
     30  1.1  christos 
     31  1.1  christos #include "xmalloc.h"
     32  1.1  christos #include "log.h"
     33  1.1  christos 
     34  1.1  christos #ifndef USE_BUILTIN_RIJNDAEL
     35  1.1  christos #include <openssl/aes.h>
     36  1.1  christos #endif
     37  1.1  christos 
     38  1.1  christos #include <pthread.h>
     39  1.1  christos 
     40  1.1  christos /*-------------------- TUNABLES --------------------*/
     41  1.1  christos /* Number of pregen threads to use */
     42  1.1  christos #define CIPHER_THREADS	2
     43  1.1  christos 
     44  1.1  christos /* Number of keystream queues */
     45  1.1  christos #define NUMKQ		(CIPHER_THREADS + 2)
     46  1.1  christos 
     47  1.1  christos /* Length of a keystream queue */
     48  1.1  christos #define KQLEN		4096
     49  1.1  christos 
     50  1.1  christos /* Processor cacheline length */
     51  1.1  christos #define CACHELINE_LEN	64
     52  1.1  christos 
     53  1.1  christos /* Collect thread stats and print at cancellation when in debug mode */
     54  1.1  christos /* #define CIPHER_THREAD_STATS */
     55  1.1  christos 
     56  1.1  christos /* Use single-byte XOR instead of 8-byte XOR */
     57  1.1  christos /* #define CIPHER_BYTE_XOR */
     58  1.1  christos /*-------------------- END TUNABLES --------------------*/
     59  1.1  christos 
     60  1.1  christos #ifdef AES_CTR_MT
     61  1.1  christos 
     62  1.1  christos 
     63  1.1  christos const EVP_CIPHER *evp_aes_ctr_mt(void);
     64  1.1  christos 
     65  1.1  christos #ifdef CIPHER_THREAD_STATS
     66  1.1  christos /*
     67  1.1  christos  * Struct to collect thread stats
     68  1.1  christos  */
     69  1.1  christos struct thread_stats {
     70  1.1  christos 	u_int	fills;
     71  1.1  christos 	u_int	skips;
     72  1.1  christos 	u_int	waits;
     73  1.1  christos 	u_int	drains;
     74  1.1  christos };
     75  1.1  christos 
     76  1.1  christos /*
     77  1.1  christos  * Debug print the thread stats
     78  1.1  christos  * Use with pthread_cleanup_push for displaying at thread cancellation
     79  1.1  christos  */
     80  1.1  christos static void
     81  1.1  christos thread_loop_stats(void *x)
     82  1.1  christos {
     83  1.1  christos 	struct thread_stats *s = x;
     84  1.1  christos 
     85  1.1  christos 	debug("tid %lu - %u fills, %u skips, %u waits", pthread_self(),
     86  1.1  christos 			s->fills, s->skips, s->waits);
     87  1.1  christos }
     88  1.1  christos 
     89  1.2      adam  #define STATS_STRUCT(s)	struct thread_stats s
     90  1.2      adam  #define STATS_INIT(s)		{ memset(&s, 0, sizeof(s)); }
     91  1.2      adam  #define STATS_FILL(s)		{ s.fills++; }
     92  1.2      adam  #define STATS_SKIP(s)		{ s.skips++; }
     93  1.2      adam  #define STATS_WAIT(s)		{ s.waits++; }
     94  1.2      adam  #define STATS_DRAIN(s)		{ s.drains++; }
     95  1.1  christos #else
     96  1.1  christos  #define STATS_STRUCT(s)
     97  1.1  christos  #define STATS_INIT(s)
     98  1.1  christos  #define STATS_FILL(s)
     99  1.1  christos  #define STATS_SKIP(s)
    100  1.1  christos  #define STATS_WAIT(s)
    101  1.1  christos  #define STATS_DRAIN(s)
    102  1.1  christos #endif
    103  1.1  christos 
    104  1.1  christos /* Keystream Queue state */
    105  1.1  christos enum {
    106  1.1  christos 	KQINIT,
    107  1.1  christos 	KQEMPTY,
    108  1.1  christos 	KQFILLING,
    109  1.1  christos 	KQFULL,
    110  1.1  christos 	KQDRAINING
    111  1.1  christos };
    112  1.1  christos 
    113  1.1  christos /* Keystream Queue struct */
    114  1.1  christos struct kq {
    115  1.1  christos 	u_char		keys[KQLEN][AES_BLOCK_SIZE];
    116  1.1  christos 	u_char		ctr[AES_BLOCK_SIZE];
    117  1.1  christos 	u_char		pad0[CACHELINE_LEN];
    118  1.1  christos 	volatile int	qstate;
    119  1.1  christos 	pthread_mutex_t	lock;
    120  1.1  christos 	pthread_cond_t	cond;
    121  1.1  christos 	u_char		pad1[CACHELINE_LEN];
    122  1.1  christos };
    123  1.1  christos 
    124  1.1  christos /* Context struct */
    125  1.1  christos struct ssh_aes_ctr_ctx
    126  1.1  christos {
    127  1.1  christos 	struct kq	q[NUMKQ];
    128  1.1  christos 	AES_KEY		aes_ctx;
    129  1.2      adam 	STATS_STRUCT(stats);
    130  1.1  christos 	u_char		aes_counter[AES_BLOCK_SIZE];
    131  1.1  christos 	pthread_t	tid[CIPHER_THREADS];
    132  1.1  christos 	int		state;
    133  1.1  christos 	int		qidx;
    134  1.1  christos 	int		ridx;
    135  1.1  christos };
    136  1.1  christos 
    137  1.1  christos /* <friedl>
    138  1.1  christos  * increment counter 'ctr',
    139  1.1  christos  * the counter is of size 'len' bytes and stored in network-byte-order.
    140  1.1  christos  * (LSB at ctr[len-1], MSB at ctr[0])
    141  1.1  christos  */
    142  1.1  christos static void
    143  1.1  christos ssh_ctr_inc(u_char *ctr, u_int len)
    144  1.1  christos {
    145  1.1  christos 	int i;
    146  1.1  christos 
    147  1.1  christos 	for (i = len - 1; i >= 0; i--)
    148  1.1  christos 		if (++ctr[i])	/* continue on overflow */
    149  1.1  christos 			return;
    150  1.1  christos }
    151  1.1  christos 
    152  1.1  christos /*
    153  1.1  christos  * Add num to counter 'ctr'
    154  1.1  christos  */
    155  1.1  christos static void
    156  1.1  christos ssh_ctr_add(u_char *ctr, uint32_t num, u_int len)
    157  1.1  christos {
    158  1.1  christos 	int i;
    159  1.1  christos 	uint16_t n;
    160  1.1  christos 
    161  1.1  christos 	for (n = 0, i = len - 1; i >= 0 && (num || n); i--) {
    162  1.1  christos 		n = ctr[i] + (num & 0xff) + n;
    163  1.1  christos 		num >>= 8;
    164  1.1  christos 		ctr[i] = n & 0xff;
    165  1.1  christos 		n >>= 8;
    166  1.1  christos 	}
    167  1.1  christos }
    168  1.1  christos 
    169  1.1  christos /*
    170  1.1  christos  * Threads may be cancelled in a pthread_cond_wait, we must free the mutex
    171  1.1  christos  */
    172  1.1  christos static void
    173  1.1  christos thread_loop_cleanup(void *x)
    174  1.1  christos {
    175  1.1  christos 	pthread_mutex_unlock((pthread_mutex_t *)x);
    176  1.1  christos }
    177  1.1  christos 
    178  1.1  christos /*
    179  1.1  christos  * The life of a pregen thread:
    180  1.1  christos  *    Find empty keystream queues and fill them using their counter.
    181  1.1  christos  *    When done, update counter for the next fill.
    182  1.1  christos  */
    183  1.1  christos static void *
    184  1.1  christos thread_loop(void *x)
    185  1.1  christos {
    186  1.1  christos 	AES_KEY key;
    187  1.2      adam 	STATS_STRUCT(stats);
    188  1.1  christos 	struct ssh_aes_ctr_ctx *c = x;
    189  1.1  christos 	struct kq *q;
    190  1.1  christos 	int i;
    191  1.1  christos 	int qidx;
    192  1.1  christos 
    193  1.1  christos 	/* Threads stats on cancellation */
    194  1.1  christos 	STATS_INIT(stats);
    195  1.1  christos #ifdef CIPHER_THREAD_STATS
    196  1.1  christos 	pthread_cleanup_push(thread_loop_stats, &stats);
    197  1.1  christos #endif
    198  1.1  christos 
    199  1.1  christos 	/* Thread local copy of AES key */
    200  1.1  christos 	memcpy(&key, &c->aes_ctx, sizeof(key));
    201  1.1  christos 
    202  1.1  christos 	/*
    203  1.1  christos 	 * Handle the special case of startup, one thread must fill
    204  1.1  christos  	 * the first KQ then mark it as draining. Lock held throughout.
    205  1.1  christos  	 */
    206  1.1  christos 	if (pthread_equal(pthread_self(), c->tid[0])) {
    207  1.1  christos 		q = &c->q[0];
    208  1.1  christos 		pthread_mutex_lock(&q->lock);
    209  1.1  christos 		if (q->qstate == KQINIT) {
    210  1.1  christos 			for (i = 0; i < KQLEN; i++) {
    211  1.1  christos 				AES_encrypt(q->ctr, q->keys[i], &key);
    212  1.1  christos 				ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
    213  1.1  christos 			}
    214  1.1  christos 			ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
    215  1.1  christos 			q->qstate = KQDRAINING;
    216  1.1  christos 			STATS_FILL(stats);
    217  1.1  christos 			pthread_cond_broadcast(&q->cond);
    218  1.1  christos 		}
    219  1.1  christos 		pthread_mutex_unlock(&q->lock);
    220  1.1  christos 	}
    221  1.1  christos 	else
    222  1.1  christos 		STATS_SKIP(stats);
    223  1.1  christos 
    224  1.1  christos 	/*
    225  1.1  christos  	 * Normal case is to find empty queues and fill them, skipping over
    226  1.1  christos  	 * queues already filled by other threads and stopping to wait for
    227  1.1  christos  	 * a draining queue to become empty.
    228  1.1  christos  	 *
    229  1.1  christos  	 * Multiple threads may be waiting on a draining queue and awoken
    230  1.1  christos  	 * when empty.  The first thread to wake will mark it as filling,
    231  1.1  christos  	 * others will move on to fill, skip, or wait on the next queue.
    232  1.1  christos  	 */
    233  1.1  christos 	for (qidx = 1;; qidx = (qidx + 1) % NUMKQ) {
    234  1.1  christos 		/* Check if I was cancelled, also checked in cond_wait */
    235  1.1  christos 		pthread_testcancel();
    236  1.1  christos 
    237  1.1  christos 		/* Lock queue and block if its draining */
    238  1.1  christos 		q = &c->q[qidx];
    239  1.1  christos 		pthread_mutex_lock(&q->lock);
    240  1.1  christos 		pthread_cleanup_push(thread_loop_cleanup, &q->lock);
    241  1.1  christos 		while (q->qstate == KQDRAINING || q->qstate == KQINIT) {
    242  1.1  christos 			STATS_WAIT(stats);
    243  1.1  christos 			pthread_cond_wait(&q->cond, &q->lock);
    244  1.1  christos 		}
    245  1.1  christos 		pthread_cleanup_pop(0);
    246  1.1  christos 
    247  1.1  christos 		/* If filling or full, somebody else got it, skip */
    248  1.1  christos 		if (q->qstate != KQEMPTY) {
    249  1.1  christos 			pthread_mutex_unlock(&q->lock);
    250  1.1  christos 			STATS_SKIP(stats);
    251  1.1  christos 			continue;
    252  1.1  christos 		}
    253  1.1  christos 
    254  1.1  christos 		/*
    255  1.1  christos  		 * Empty, let's fill it.
    256  1.1  christos  		 * Queue lock is relinquished while we do this so others
    257  1.1  christos  		 * can see that it's being filled.
    258  1.1  christos  		 */
    259  1.1  christos 		q->qstate = KQFILLING;
    260  1.1  christos 		pthread_mutex_unlock(&q->lock);
    261  1.1  christos 		for (i = 0; i < KQLEN; i++) {
    262  1.1  christos 			AES_encrypt(q->ctr, q->keys[i], &key);
    263  1.1  christos 			ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
    264  1.1  christos 		}
    265  1.1  christos 
    266  1.1  christos 		/* Re-lock, mark full and signal consumer */
    267  1.1  christos 		pthread_mutex_lock(&q->lock);
    268  1.1  christos 		ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
    269  1.1  christos 		q->qstate = KQFULL;
    270  1.1  christos 		STATS_FILL(stats);
    271  1.1  christos 		pthread_cond_signal(&q->cond);
    272  1.1  christos 		pthread_mutex_unlock(&q->lock);
    273  1.1  christos 	}
    274  1.1  christos 
    275  1.1  christos #ifdef CIPHER_THREAD_STATS
    276  1.1  christos 	/* Stats */
    277  1.1  christos 	pthread_cleanup_pop(1);
    278  1.1  christos #endif
    279  1.1  christos 
    280  1.1  christos 	return NULL;
    281  1.1  christos }
    282  1.1  christos 
    283  1.1  christos static int
    284  1.1  christos ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
    285  1.1  christos     u_int len)
    286  1.1  christos {
    287  1.1  christos 	struct ssh_aes_ctr_ctx *c;
    288  1.1  christos 	struct kq *q, *oldq;
    289  1.1  christos 	int ridx;
    290  1.1  christos 	u_char *buf;
    291  1.1  christos 
    292  1.1  christos 	if (len == 0)
    293  1.1  christos 		return (1);
    294  1.1  christos 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
    295  1.1  christos 		return (0);
    296  1.1  christos 
    297  1.1  christos 	q = &c->q[c->qidx];
    298  1.1  christos 	ridx = c->ridx;
    299  1.1  christos 
    300  1.1  christos 	/* src already padded to block multiple */
    301  1.1  christos 	while (len > 0) {
    302  1.1  christos 		buf = q->keys[ridx];
    303  1.1  christos 
    304  1.1  christos #ifdef CIPHER_BYTE_XOR
    305  1.1  christos 		dest[0] = src[0] ^ buf[0];
    306  1.1  christos 		dest[1] = src[1] ^ buf[1];
    307  1.1  christos 		dest[2] = src[2] ^ buf[2];
    308  1.1  christos 		dest[3] = src[3] ^ buf[3];
    309  1.1  christos 		dest[4] = src[4] ^ buf[4];
    310  1.1  christos 		dest[5] = src[5] ^ buf[5];
    311  1.1  christos 		dest[6] = src[6] ^ buf[6];
    312  1.1  christos 		dest[7] = src[7] ^ buf[7];
    313  1.1  christos 		dest[8] = src[8] ^ buf[8];
    314  1.1  christos 		dest[9] = src[9] ^ buf[9];
    315  1.1  christos 		dest[10] = src[10] ^ buf[10];
    316  1.1  christos 		dest[11] = src[11] ^ buf[11];
    317  1.1  christos 		dest[12] = src[12] ^ buf[12];
    318  1.1  christos 		dest[13] = src[13] ^ buf[13];
    319  1.1  christos 		dest[14] = src[14] ^ buf[14];
    320  1.1  christos 		dest[15] = src[15] ^ buf[15];
    321  1.1  christos #else
    322  1.1  christos 		*(uint64_t *)dest = *(uint64_t *)src ^ *(uint64_t *)buf;
    323  1.1  christos 		*(uint64_t *)(dest + 8) = *(uint64_t *)(src + 8) ^
    324  1.1  christos 						*(uint64_t *)(buf + 8);
    325  1.1  christos #endif
    326  1.1  christos 
    327  1.1  christos 		dest += 16;
    328  1.1  christos 		src += 16;
    329  1.1  christos 		len -= 16;
    330  1.1  christos 		ssh_ctr_inc(ctx->iv, AES_BLOCK_SIZE);
    331  1.1  christos 
    332  1.1  christos 		/* Increment read index, switch queues on rollover */
    333  1.1  christos 		if ((ridx = (ridx + 1) % KQLEN) == 0) {
    334  1.1  christos 			oldq = q;
    335  1.1  christos 
    336  1.1  christos 			/* Mark next queue draining, may need to wait */
    337  1.1  christos 			c->qidx = (c->qidx + 1) % NUMKQ;
    338  1.1  christos 			q = &c->q[c->qidx];
    339  1.1  christos 			pthread_mutex_lock(&q->lock);
    340  1.1  christos 			while (q->qstate != KQFULL) {
    341  1.1  christos 				STATS_WAIT(c->stats);
    342  1.1  christos 				pthread_cond_wait(&q->cond, &q->lock);
    343  1.1  christos 			}
    344  1.1  christos 			q->qstate = KQDRAINING;
    345  1.1  christos 			pthread_mutex_unlock(&q->lock);
    346  1.1  christos 
    347  1.1  christos 			/* Mark consumed queue empty and signal producers */
    348  1.1  christos 			pthread_mutex_lock(&oldq->lock);
    349  1.1  christos 			oldq->qstate = KQEMPTY;
    350  1.1  christos 			STATS_DRAIN(c->stats);
    351  1.1  christos 			pthread_cond_broadcast(&oldq->cond);
    352  1.1  christos 			pthread_mutex_unlock(&oldq->lock);
    353  1.1  christos 		}
    354  1.1  christos 	}
    355  1.1  christos 	c->ridx = ridx;
    356  1.1  christos 	return (1);
    357  1.1  christos }
    358  1.1  christos 
    359  1.1  christos #define HAVE_NONE       0
    360  1.1  christos #define HAVE_KEY        1
    361  1.1  christos #define HAVE_IV         2
    362  1.1  christos static int
    363  1.1  christos ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
    364  1.1  christos     int enc)
    365  1.1  christos {
    366  1.1  christos 	struct ssh_aes_ctr_ctx *c;
    367  1.1  christos 	int i;
    368  1.1  christos 
    369  1.1  christos 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
    370  1.1  christos 		c = xmalloc(sizeof(*c));
    371  1.1  christos 
    372  1.1  christos 		c->state = HAVE_NONE;
    373  1.1  christos 		for (i = 0; i < NUMKQ; i++) {
    374  1.1  christos 			pthread_mutex_init(&c->q[i].lock, NULL);
    375  1.1  christos 			pthread_cond_init(&c->q[i].cond, NULL);
    376  1.1  christos 		}
    377  1.1  christos 
    378  1.1  christos 		STATS_INIT(c->stats);
    379  1.1  christos 
    380  1.1  christos 		EVP_CIPHER_CTX_set_app_data(ctx, c);
    381  1.1  christos 	}
    382  1.1  christos 
    383  1.1  christos 	if (c->state == (HAVE_KEY | HAVE_IV)) {
    384  1.1  christos 		/* Cancel pregen threads */
    385  1.1  christos 		for (i = 0; i < CIPHER_THREADS; i++)
    386  1.1  christos 			pthread_cancel(c->tid[i]);
    387  1.1  christos 		for (i = 0; i < CIPHER_THREADS; i++)
    388  1.1  christos 			pthread_join(c->tid[i], NULL);
    389  1.1  christos 		/* Start over getting key & iv */
    390  1.1  christos 		c->state = HAVE_NONE;
    391  1.1  christos 	}
    392  1.1  christos 
    393  1.1  christos 	if (key != NULL) {
    394  1.1  christos 		AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
    395  1.1  christos 		    &c->aes_ctx);
    396  1.1  christos 		c->state |= HAVE_KEY;
    397  1.1  christos 	}
    398  1.1  christos 
    399  1.1  christos 	if (iv != NULL) {
    400  1.1  christos 		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
    401  1.1  christos 		c->state |= HAVE_IV;
    402  1.1  christos 	}
    403  1.1  christos 
    404  1.1  christos 	if (c->state == (HAVE_KEY | HAVE_IV)) {
    405  1.1  christos 		/* Clear queues */
    406  1.1  christos 		memcpy(c->q[0].ctr, ctx->iv, AES_BLOCK_SIZE);
    407  1.1  christos 		c->q[0].qstate = KQINIT;
    408  1.1  christos 		for (i = 1; i < NUMKQ; i++) {
    409  1.1  christos 			memcpy(c->q[i].ctr, ctx->iv, AES_BLOCK_SIZE);
    410  1.1  christos 			ssh_ctr_add(c->q[i].ctr, i * KQLEN, AES_BLOCK_SIZE);
    411  1.1  christos 			c->q[i].qstate = KQEMPTY;
    412  1.1  christos 		}
    413  1.1  christos 		c->qidx = 0;
    414  1.1  christos 		c->ridx = 0;
    415  1.1  christos 
    416  1.1  christos 		/* Start threads */
    417  1.1  christos 		for (i = 0; i < CIPHER_THREADS; i++) {
    418  1.1  christos 			pthread_create(&c->tid[i], NULL, thread_loop, c);
    419  1.1  christos 		}
    420  1.1  christos 		pthread_mutex_lock(&c->q[0].lock);
    421  1.1  christos 		while (c->q[0].qstate != KQDRAINING)
    422  1.1  christos 			pthread_cond_wait(&c->q[0].cond, &c->q[0].lock);
    423  1.1  christos 		pthread_mutex_unlock(&c->q[0].lock);
    424  1.1  christos 
    425  1.1  christos 	}
    426  1.1  christos 	return (1);
    427  1.1  christos }
    428  1.1  christos 
    429  1.1  christos static int
    430  1.1  christos ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
    431  1.1  christos {
    432  1.1  christos 	struct ssh_aes_ctr_ctx *c;
    433  1.1  christos 	int i;
    434  1.1  christos 
    435  1.1  christos 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
    436  1.1  christos #ifdef CIPHER_THREAD_STATS
    437  1.1  christos 		debug("main thread: %u drains, %u waits", c->stats.drains,
    438  1.1  christos 				c->stats.waits);
    439  1.1  christos #endif
    440  1.1  christos 		/* Cancel pregen threads */
    441  1.1  christos 		for (i = 0; i < CIPHER_THREADS; i++)
    442  1.1  christos 			pthread_cancel(c->tid[i]);
    443  1.1  christos 		for (i = 0; i < CIPHER_THREADS; i++)
    444  1.1  christos 			pthread_join(c->tid[i], NULL);
    445  1.1  christos 
    446  1.1  christos 		memset(c, 0, sizeof(*c));
    447  1.1  christos 		xfree(c);
    448  1.1  christos 		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
    449  1.1  christos 	}
    450  1.1  christos 	return (1);
    451  1.1  christos }
    452  1.1  christos 
    453  1.1  christos /* <friedl> */
    454  1.1  christos const EVP_CIPHER *
    455  1.1  christos evp_aes_ctr_mt(void)
    456  1.1  christos {
    457  1.1  christos 	static EVP_CIPHER aes_ctr;
    458  1.1  christos 
    459  1.1  christos 	memset(&aes_ctr, 0, sizeof(EVP_CIPHER));
    460  1.1  christos 	aes_ctr.nid = NID_undef;
    461  1.1  christos 	aes_ctr.block_size = AES_BLOCK_SIZE;
    462  1.1  christos 	aes_ctr.iv_len = AES_BLOCK_SIZE;
    463  1.1  christos 	aes_ctr.key_len = 16;
    464  1.1  christos 	aes_ctr.init = ssh_aes_ctr_init;
    465  1.1  christos 	aes_ctr.cleanup = ssh_aes_ctr_cleanup;
    466  1.1  christos 	aes_ctr.do_cipher = ssh_aes_ctr;
    467  1.1  christos #ifndef SSH_OLD_EVP
    468  1.1  christos 	aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
    469  1.1  christos 	    EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
    470  1.1  christos #endif
    471  1.1  christos 	return (&aes_ctr);
    472  1.1  christos }
    473  1.2      adam #endif /* AES_CTR_MT */
    474