cipher-ctr-mt.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. /*
  2. * OpenSSH Multi-threaded AES-CTR Cipher
  3. *
  4. * Author: Benjamin Bennett <ben@psc.edu>
  5. * Author: Mike Tasota <tasota@gmail.com>
  6. * Author: Chris Rapier <rapier@psc.edu>
  7. * Copyright (c) 2008-2013 Pittsburgh Supercomputing Center. All rights reserved.
  8. *
  9. * Based on original OpenSSH AES-CTR cipher. Small portions remain unchanged,
  10. * Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
  11. *
  12. * Permission to use, copy, modify, and distribute this software for any
  13. * purpose with or without fee is hereby granted, provided that the above
  14. * copyright notice and this permission notice appear in all copies.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  17. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  18. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  19. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  20. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  21. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  22. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  23. */
  24. #include "includes.h"
  25. #if defined(WITH_OPENSSL)
  26. #include <sys/types.h>
  27. #include <stdarg.h>
  28. #include <string.h>
  29. #include <openssl/evp.h>
  30. #include "xmalloc.h"
  31. #include "log.h"
  32. #include <unistd.h>
  33. /* compatibility with old or broken OpenSSL versions */
  34. #include "openbsd-compat/openssl-compat.h"
  35. #ifndef USE_BUILTIN_RIJNDAEL
  36. #include <openssl/aes.h>
  37. #endif
  38. #include <pthread.h>
  39. /*-------------------- TUNABLES --------------------*/
  40. /* maximum number of threads and queues */
  41. #define MAX_THREADS 32
  42. #define MAX_NUMKQ (MAX_THREADS * 2)
  43. /* Number of pregen threads to use */
  44. int cipher_threads = 2;
  45. /* Number of keystream queues */
  46. int numkq = 4;
  47. /* Length of a keystream queue */
  48. #define KQLEN 4096
  49. /* Processor cacheline length */
  50. #define CACHELINE_LEN 64
  51. /* Collect thread stats and print at cancellation when in debug mode */
  52. #define CIPHER_THREAD_STATS
  53. /* Can the system do unaligned loads natively? */
  54. #if defined(__aarch64__) || \
  55. defined(__i386__) || \
  56. defined(__powerpc__) || \
  57. defined(__x86_64__)
  58. # define CIPHER_UNALIGNED_OK
  59. #endif
  60. #if defined(__SIZEOF_INT128__)
  61. # define CIPHER_INT128_OK
  62. #endif
  63. /*-------------------- END TUNABLES --------------------*/
  64. const EVP_CIPHER *evp_aes_ctr_mt(void);
  65. #ifdef CIPHER_THREAD_STATS
  66. /*
  67. * Struct to collect thread stats
  68. */
  69. struct thread_stats {
  70. u_int fills;
  71. u_int skips;
  72. u_int waits;
  73. u_int drains;
  74. };
  75. /*
  76. * Debug print the thread stats
  77. * Use with pthread_cleanup_push for displaying at thread cancellation
  78. */
  79. static void
  80. thread_loop_stats(void *x)
  81. {
  82. struct thread_stats *s = x;
  83. debug("AES-CTR MT tid %lu - %u fills, %u skips, %u waits", pthread_self(),
  84. s->fills, s->skips, s->waits);
  85. }
  86. # define STATS_STRUCT(s) struct thread_stats s
  87. # define STATS_INIT(s) { memset(&s, 0, sizeof(s)); }
  88. # define STATS_FILL(s) { s.fills++; }
  89. # define STATS_SKIP(s) { s.skips++; }
  90. # define STATS_WAIT(s) { s.waits++; }
  91. # define STATS_DRAIN(s) { s.drains++; }
  92. #else
  93. # define STATS_STRUCT(s)
  94. # define STATS_INIT(s)
  95. # define STATS_FILL(s)
  96. # define STATS_SKIP(s)
  97. # define STATS_WAIT(s)
  98. # define STATS_DRAIN(s)
  99. #endif
  100. /* Keystream Queue state */
  101. enum {
  102. KQINIT,
  103. KQEMPTY,
  104. KQFILLING,
  105. KQFULL,
  106. KQDRAINING
  107. };
  108. /* Keystream Queue struct */
  109. struct kq {
  110. u_char keys[KQLEN][AES_BLOCK_SIZE];
  111. u_char ctr[AES_BLOCK_SIZE];
  112. u_char pad0[CACHELINE_LEN];
  113. int qstate;
  114. pthread_mutex_t lock;
  115. pthread_cond_t cond;
  116. u_char pad1[CACHELINE_LEN];
  117. };
  118. /* Context struct */
  119. struct ssh_aes_ctr_ctx_mt
  120. {
  121. int struct_id;
  122. struct kq q[MAX_NUMKQ];
  123. AES_KEY aes_ctx;
  124. STATS_STRUCT(stats);
  125. u_char aes_counter[AES_BLOCK_SIZE];
  126. pthread_t tid[MAX_THREADS];
  127. int id[MAX_THREADS];
  128. pthread_rwlock_t tid_lock;
  129. #ifdef __APPLE__
  130. pthread_rwlock_t stop_lock;
  131. int exit_flag;
  132. #endif /* __APPLE__ */
  133. int state;
  134. int qidx;
  135. int ridx;
  136. };
  137. /* <friedl>
  138. * increment counter 'ctr',
  139. * the counter is of size 'len' bytes and stored in network-byte-order.
  140. * (LSB at ctr[len-1], MSB at ctr[0])
  141. */
  142. static void
  143. ssh_ctr_inc(u_char *ctr, size_t len)
  144. {
  145. int i;
  146. for (i = len - 1; i >= 0; i--)
  147. if (++ctr[i]) /* continue on overflow */
  148. return;
  149. }
  150. /*
  151. * Add num to counter 'ctr'
  152. */
  153. static void
  154. ssh_ctr_add(u_char *ctr, uint32_t num, u_int len)
  155. {
  156. int i;
  157. uint16_t n;
  158. for (n = 0, i = len - 1; i >= 0 && (num || n); i--) {
  159. n = ctr[i] + (num & 0xff) + n;
  160. num >>= 8;
  161. ctr[i] = n & 0xff;
  162. n >>= 8;
  163. }
  164. }
  165. /*
  166. * Threads may be cancelled in a pthread_cond_wait, we must free the mutex
  167. */
  168. static void
  169. thread_loop_cleanup(void *x)
  170. {
  171. pthread_mutex_unlock((pthread_mutex_t *)x);
  172. }
  173. #ifdef __APPLE__
  174. /* Check if we should exit, we are doing both cancel and exit condition
  175. * since on OSX threads seem to occasionally fail to notice when they have
  176. * been cancelled. We want to have a backup to make sure that we won't hang
  177. * when the main process join()-s the cancelled thread.
  178. */
  179. static void
  180. thread_loop_check_exit(struct ssh_aes_ctr_ctx_mt *c)
  181. {
  182. int exit_flag;
  183. pthread_rwlock_rdlock(&c->stop_lock);
  184. exit_flag = c->exit_flag;
  185. pthread_rwlock_unlock(&c->stop_lock);
  186. if (exit_flag)
  187. pthread_exit(NULL);
  188. }
  189. #else
  190. # define thread_loop_check_exit(s)
  191. #endif /* __APPLE__ */
  192. /*
  193. * Helper function to terminate the helper threads
  194. */
  195. static void
  196. stop_and_join_pregen_threads(struct ssh_aes_ctr_ctx_mt *c)
  197. {
  198. int i;
  199. #ifdef __APPLE__
  200. /* notify threads that they should exit */
  201. pthread_rwlock_wrlock(&c->stop_lock);
  202. c->exit_flag = TRUE;
  203. pthread_rwlock_unlock(&c->stop_lock);
  204. #endif /* __APPLE__ */
  205. /* Cancel pregen threads */
  206. for (i = 0; i < cipher_threads; i++) {
  207. debug ("Canceled %lu (%d,%d)", c->tid[i], c->struct_id, c->id[i]);
  208. pthread_cancel(c->tid[i]);
  209. }
  210. /* shouldn't need this - see commit logs for hpn-7_7_P1 -cjr 11/7/19*/
  211. /* for (i = 0; i < numkq; i++) { */
  212. /* pthread_mutex_lock(&c->q[i].lock); */
  213. /* pthread_cond_broadcast(&c->q[i].cond); */
  214. /* pthread_mutex_unlock(&c->q[i].lock); */
  215. /* } */
  216. for (i = 0; i < cipher_threads; i++) {
  217. if (pthread_kill(c->tid[i], 0) != 0)
  218. debug3("AES-CTR MT pthread_join failure: Invalid thread id %lu in %s", c->tid[i], __FUNCTION__);
  219. else {
  220. debug ("Joining %lu (%d, %d)", c->tid[i], c->struct_id, c->id[i]);
  221. pthread_join(c->tid[i], NULL);
  222. }
  223. }
  224. }
  225. /*
  226. * The life of a pregen thread:
  227. * Find empty keystream queues and fill them using their counter.
  228. * When done, update counter for the next fill.
  229. */
  230. static void *
  231. thread_loop(void *x)
  232. {
  233. AES_KEY key;
  234. STATS_STRUCT(stats);
  235. struct ssh_aes_ctr_ctx_mt *c = x;
  236. struct kq *q;
  237. int i;
  238. int qidx;
  239. pthread_t first_tid;
  240. /* Threads stats on cancellation */
  241. STATS_INIT(stats);
  242. #ifdef CIPHER_THREAD_STATS
  243. pthread_cleanup_push(thread_loop_stats, &stats);
  244. #endif
  245. /* Thread local copy of AES key */
  246. memcpy(&key, &c->aes_ctx, sizeof(key));
  247. pthread_rwlock_rdlock(&c->tid_lock);
  248. first_tid = c->tid[0];
  249. pthread_rwlock_unlock(&c->tid_lock);
  250. /*
  251. * Handle the special case of startup, one thread must fill
  252. * the first KQ then mark it as draining. Lock held throughout.
  253. */
  254. if (pthread_equal(pthread_self(), first_tid)) {
  255. q = &c->q[0];
  256. pthread_mutex_lock(&q->lock);
  257. if (q->qstate == KQINIT) {
  258. for (i = 0; i < KQLEN; i++) {
  259. AES_encrypt(q->ctr, q->keys[i], &key);
  260. ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
  261. }
  262. ssh_ctr_add(q->ctr, KQLEN * (numkq - 1), AES_BLOCK_SIZE);
  263. q->qstate = KQDRAINING;
  264. STATS_FILL(stats);
  265. pthread_cond_broadcast(&q->cond);
  266. }
  267. pthread_mutex_unlock(&q->lock);
  268. } else
  269. STATS_SKIP(stats);
  270. /*
  271. * Normal case is to find empty queues and fill them, skipping over
  272. * queues already filled by other threads and stopping to wait for
  273. * a draining queue to become empty.
  274. *
  275. * Multiple threads may be waiting on a draining queue and awoken
  276. * when empty. The first thread to wake will mark it as filling,
  277. * others will move on to fill, skip, or wait on the next queue.
  278. */
  279. for (qidx = 1;; qidx = (qidx + 1) % numkq) {
  280. /* Check if I was cancelled, also checked in cond_wait */
  281. pthread_testcancel();
  282. /* Check if we should exit as well */
  283. thread_loop_check_exit(c);
  284. /* Lock queue and block if its draining */
  285. q = &c->q[qidx];
  286. pthread_mutex_lock(&q->lock);
  287. pthread_cleanup_push(thread_loop_cleanup, &q->lock);
  288. while (q->qstate == KQDRAINING || q->qstate == KQINIT) {
  289. STATS_WAIT(stats);
  290. thread_loop_check_exit(c);
  291. pthread_cond_wait(&q->cond, &q->lock);
  292. }
  293. pthread_cleanup_pop(0);
  294. /* If filling or full, somebody else got it, skip */
  295. if (q->qstate != KQEMPTY) {
  296. pthread_mutex_unlock(&q->lock);
  297. STATS_SKIP(stats);
  298. continue;
  299. }
  300. /*
  301. * Empty, let's fill it.
  302. * Queue lock is relinquished while we do this so others
  303. * can see that it's being filled.
  304. */
  305. q->qstate = KQFILLING;
  306. pthread_cond_broadcast(&q->cond);
  307. pthread_mutex_unlock(&q->lock);
  308. for (i = 0; i < KQLEN; i++) {
  309. AES_encrypt(q->ctr, q->keys[i], &key);
  310. ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
  311. }
  312. /* Re-lock, mark full and signal consumer */
  313. pthread_mutex_lock(&q->lock);
  314. ssh_ctr_add(q->ctr, KQLEN * (numkq - 1), AES_BLOCK_SIZE);
  315. q->qstate = KQFULL;
  316. STATS_FILL(stats);
  317. pthread_cond_broadcast(&q->cond);
  318. pthread_mutex_unlock(&q->lock);
  319. }
  320. #ifdef CIPHER_THREAD_STATS
  321. /* Stats */
  322. pthread_cleanup_pop(1);
  323. #endif
  324. return NULL;
  325. }
  326. static int
  327. ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
  328. LIBCRYPTO_EVP_INL_TYPE len)
  329. {
  330. typedef union {
  331. #ifdef CIPHER_INT128_OK
  332. __uint128_t *u128;
  333. #endif
  334. uint64_t *u64;
  335. uint32_t *u32;
  336. uint8_t *u8;
  337. const uint8_t *cu8;
  338. uintptr_t u;
  339. } ptrs_t;
  340. ptrs_t destp, srcp, bufp;
  341. uintptr_t align;
  342. struct ssh_aes_ctr_ctx_mt *c;
  343. struct kq *q, *oldq;
  344. int ridx;
  345. u_char *buf;
  346. if (len == 0)
  347. return 1;
  348. if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
  349. return 0;
  350. q = &c->q[c->qidx];
  351. ridx = c->ridx;
  352. /* src already padded to block multiple */
  353. srcp.cu8 = src;
  354. destp.u8 = dest;
  355. while (len > 0) {
  356. buf = q->keys[ridx];
  357. bufp.u8 = buf;
  358. /* figure out the alignment on the fly */
  359. #ifdef CIPHER_UNALIGNED_OK
  360. align = 0;
  361. #else
  362. align = destp.u | srcp.u | bufp.u;
  363. #endif
  364. #ifdef CIPHER_INT128_OK
  365. if ((align & 0xf) == 0) {
  366. destp.u128[0] = srcp.u128[0] ^ bufp.u128[0];
  367. } else
  368. #endif
  369. if ((align & 0x7) == 0) {
  370. destp.u64[0] = srcp.u64[0] ^ bufp.u64[0];
  371. destp.u64[1] = srcp.u64[1] ^ bufp.u64[1];
  372. } else if ((align & 0x3) == 0) {
  373. destp.u32[0] = srcp.u32[0] ^ bufp.u32[0];
  374. destp.u32[1] = srcp.u32[1] ^ bufp.u32[1];
  375. destp.u32[2] = srcp.u32[2] ^ bufp.u32[2];
  376. destp.u32[3] = srcp.u32[3] ^ bufp.u32[3];
  377. } else {
  378. size_t i;
  379. for (i = 0; i < AES_BLOCK_SIZE; ++i)
  380. dest[i] = src[i] ^ buf[i];
  381. }
  382. destp.u += AES_BLOCK_SIZE;
  383. srcp.u += AES_BLOCK_SIZE;
  384. len -= AES_BLOCK_SIZE;
  385. ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);
  386. /* Increment read index, switch queues on rollover */
  387. if ((ridx = (ridx + 1) % KQLEN) == 0) {
  388. oldq = q;
  389. /* Mark next queue draining, may need to wait */
  390. c->qidx = (c->qidx + 1) % numkq;
  391. q = &c->q[c->qidx];
  392. pthread_mutex_lock(&q->lock);
  393. while (q->qstate != KQFULL) {
  394. STATS_WAIT(c->stats);
  395. pthread_cond_wait(&q->cond, &q->lock);
  396. }
  397. q->qstate = KQDRAINING;
  398. pthread_cond_broadcast(&q->cond);
  399. pthread_mutex_unlock(&q->lock);
  400. /* Mark consumed queue empty and signal producers */
  401. pthread_mutex_lock(&oldq->lock);
  402. oldq->qstate = KQEMPTY;
  403. STATS_DRAIN(c->stats);
  404. pthread_cond_broadcast(&oldq->cond);
  405. pthread_mutex_unlock(&oldq->lock);
  406. }
  407. }
  408. c->ridx = ridx;
  409. return 1;
  410. }
  411. #define HAVE_NONE 0
  412. #define HAVE_KEY 1
  413. #define HAVE_IV 2
  414. int X = 0;
  415. static int
  416. ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
  417. int enc)
  418. {
  419. struct ssh_aes_ctr_ctx_mt *c;
  420. int i;
  421. /* get the number of cores in the system */
  422. /* if it's not linux it currently defaults to 2 */
  423. /* divide by 2 to get threads for each direction (MODE_IN||MODE_OUT) */
  424. #ifdef __linux__
  425. cipher_threads = sysconf(_SC_NPROCESSORS_ONLN) / 2;
  426. #endif /*__linux__*/
  427. #ifdef __APPLE__
  428. cipher_threads = sysconf(_SC_NPROCESSORS_ONLN) / 2;
  429. #endif /*__APPLE__*/
  430. #ifdef __FREEBSD__
  431. int req[2];
  432. size_t len;
  433. req[0] = CTL_HW;
  434. req[1] = HW_NCPU;
  435. len = sizeof(ncpu);
  436. sysctl(req, 2, &cipher_threads, &len, NULL, 0);
  437. cipher_threads = cipher_threads / 2;
  438. #endif /*__FREEBSD__*/
  439. /* if they have less than 4 cores spin up 4 threads anyway */
  440. if (cipher_threads < 2)
  441. cipher_threads = 2;
  442. /* assure that we aren't trying to create more threads */
  443. /* than we have in the struct. cipher_threads is half the */
  444. /* total of allowable threads hence the odd looking math here */
  445. if (cipher_threads * 2 > MAX_THREADS)
  446. cipher_threads = MAX_THREADS / 2;
  447. /* set the number of keystream queues */
  448. numkq = cipher_threads * 2;
  449. if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
  450. c = xmalloc(sizeof(*c));
  451. pthread_rwlock_init(&c->tid_lock, NULL);
  452. #ifdef __APPLE__
  453. pthread_rwlock_init(&c->stop_lock, NULL);
  454. c->exit_flag = FALSE;
  455. #endif /* __APPLE__ */
  456. c->state = HAVE_NONE;
  457. for (i = 0; i < numkq; i++) {
  458. pthread_mutex_init(&c->q[i].lock, NULL);
  459. pthread_cond_init(&c->q[i].cond, NULL);
  460. }
  461. STATS_INIT(c->stats);
  462. EVP_CIPHER_CTX_set_app_data(ctx, c);
  463. }
  464. if (c->state == (HAVE_KEY | HAVE_IV)) {
  465. /* tell the pregen threads to exit */
  466. stop_and_join_pregen_threads(c);
  467. #ifdef __APPLE__
  468. /* reset the exit flag */
  469. c->exit_flag = FALSE;
  470. #endif /* __APPLE__ */
  471. /* Start over getting key & iv */
  472. c->state = HAVE_NONE;
  473. }
  474. if (key != NULL) {
  475. AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
  476. &c->aes_ctx);
  477. c->state |= HAVE_KEY;
  478. }
  479. if (iv != NULL) {
  480. memcpy(c->aes_counter, iv, AES_BLOCK_SIZE);
  481. c->state |= HAVE_IV;
  482. }
  483. if (c->state == (HAVE_KEY | HAVE_IV)) {
  484. /* Clear queues */
  485. memcpy(c->q[0].ctr, c->aes_counter, AES_BLOCK_SIZE);
  486. c->q[0].qstate = KQINIT;
  487. for (i = 1; i < numkq; i++) {
  488. memcpy(c->q[i].ctr, c->aes_counter, AES_BLOCK_SIZE);
  489. ssh_ctr_add(c->q[i].ctr, i * KQLEN, AES_BLOCK_SIZE);
  490. c->q[i].qstate = KQEMPTY;
  491. }
  492. c->qidx = 0;
  493. c->ridx = 0;
  494. /* Start threads */
  495. for (i = 0; i < cipher_threads; i++) {
  496. pthread_rwlock_wrlock(&c->tid_lock);
  497. if (pthread_create(&c->tid[i], NULL, thread_loop, c) != 0)
  498. debug ("AES-CTR MT Could not create thread in %s", __FUNCTION__); /*should die here */
  499. else {
  500. if (!c->struct_id)
  501. c->struct_id = X++;
  502. c->id[i] = i;
  503. debug ("AES-CTR MT spawned a thread with id %lu in %s (%d, %d)", c->tid[i], __FUNCTION__, c->struct_id, c->id[i]);
  504. }
  505. pthread_rwlock_unlock(&c->tid_lock);
  506. }
  507. pthread_mutex_lock(&c->q[0].lock);
  508. while (c->q[0].qstate == KQINIT)
  509. pthread_cond_wait(&c->q[0].cond, &c->q[0].lock);
  510. pthread_mutex_unlock(&c->q[0].lock);
  511. }
  512. return 1;
  513. }
  514. /* this function is no longer used but might prove handy in the future
  515. * this comment also applies to ssh_aes_ctr_thread_reconstruction
  516. */
  517. void
  518. ssh_aes_ctr_thread_destroy(EVP_CIPHER_CTX *ctx)
  519. {
  520. struct ssh_aes_ctr_ctx_mt *c;
  521. c = EVP_CIPHER_CTX_get_app_data(ctx);
  522. stop_and_join_pregen_threads(c);
  523. }
  524. void
  525. ssh_aes_ctr_thread_reconstruction(EVP_CIPHER_CTX *ctx)
  526. {
  527. struct ssh_aes_ctr_ctx_mt *c;
  528. int i;
  529. c = EVP_CIPHER_CTX_get_app_data(ctx);
  530. /* reconstruct threads */
  531. for (i = 0; i < cipher_threads; i++) {
  532. pthread_rwlock_wrlock(&c->tid_lock);
  533. if (pthread_create(&c->tid[i], NULL, thread_loop, c) !=0 )
  534. debug("AES-CTR MT could not create thread in %s", __FUNCTION__);
  535. else {
  536. c->struct_id = X++;
  537. c->id[i] = i;
  538. debug ("AES-CTR MT spawned a thread with id %lu in %s (%d, %d)", c->tid[i], __FUNCTION__, c->struct_id, c->id[i]);
  539. debug("AES-CTR MT spawned a thread with id %lu in %s", c->tid[i], __FUNCTION__);
  540. }
  541. pthread_rwlock_unlock(&c->tid_lock);
  542. }
  543. }
  544. static int
  545. ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
  546. {
  547. struct ssh_aes_ctr_ctx_mt *c;
  548. if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
  549. #ifdef CIPHER_THREAD_STATS
  550. debug("AES-CTR MT main thread: %u drains, %u waits", c->stats.drains,
  551. c->stats.waits);
  552. #endif
  553. stop_and_join_pregen_threads(c);
  554. memset(c, 0, sizeof(*c));
  555. free(c);
  556. EVP_CIPHER_CTX_set_app_data(ctx, NULL);
  557. }
  558. return 1;
  559. }
  560. /* <friedl> */
  561. const EVP_CIPHER *
  562. evp_aes_ctr_mt(void)
  563. {
  564. # if OPENSSL_VERSION_NUMBER >= 0x10100000UL
  565. static EVP_CIPHER *aes_ctr;
  566. aes_ctr = EVP_CIPHER_meth_new(NID_undef, 16/*block*/, 16/*key*/);
  567. EVP_CIPHER_meth_set_iv_length(aes_ctr, AES_BLOCK_SIZE);
  568. EVP_CIPHER_meth_set_init(aes_ctr, ssh_aes_ctr_init);
  569. EVP_CIPHER_meth_set_cleanup(aes_ctr, ssh_aes_ctr_cleanup);
  570. EVP_CIPHER_meth_set_do_cipher(aes_ctr, ssh_aes_ctr);
  571. # ifndef SSH_OLD_EVP
  572. EVP_CIPHER_meth_set_flags(aes_ctr, EVP_CIPH_CBC_MODE
  573. | EVP_CIPH_VARIABLE_LENGTH
  574. | EVP_CIPH_ALWAYS_CALL_INIT
  575. | EVP_CIPH_CUSTOM_IV);
  576. # endif /*SSH_OLD_EVP*/
  577. return (aes_ctr);
  578. # else /*earlier versions of openssl*/
  579. static EVP_CIPHER aes_ctr;
  580. memset(&aes_ctr, 0, sizeof(EVP_CIPHER));
  581. aes_ctr.nid = NID_undef;
  582. aes_ctr.block_size = AES_BLOCK_SIZE;
  583. aes_ctr.iv_len = AES_BLOCK_SIZE;
  584. aes_ctr.key_len = 16;
  585. aes_ctr.init = ssh_aes_ctr_init;
  586. aes_ctr.cleanup = ssh_aes_ctr_cleanup;
  587. aes_ctr.do_cipher = ssh_aes_ctr;
  588. # ifndef SSH_OLD_EVP
  589. aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
  590. EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
  591. # endif /*SSH_OLD_EVP*/
  592. return &aes_ctr;
  593. # endif /*OPENSSH_VERSION_NUMBER*/
  594. }
  595. #endif /* defined(WITH_OPENSSL) */