forked from openssh/openssh-portable
-
-
Notifications
You must be signed in to change notification settings - Fork 45
/
Copy pathcipher-switch.c
73 lines (66 loc) · 2.64 KB
/
cipher-switch.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*
* Copyright (c) 2023 The Board of Trustees of Carnegie Mellon University.
*
* Author: Chris Rapier <[email protected]>
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MIT License.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the MIT License for more details.
*
* You should have received a copy of the MIT License along with this library;
* if not, see http://opensource.org/licenses/MIT.
*
*/
/* This provides the function to switch from a serial to parallel
* cipher. This has been moved into it's own file in order to make it
* available to both the client and server without having to clutter
* up other files.
*/
#include "includes.h"
#include <sys/types.h>
#include <string.h>
#include "cipher.h"
#include "log.h"
#include "packet.h"
/* if we are using a parallel cipher there can be issues in either
* a fork or sandbox. Essentially, if we switch too early the
* threads get lost and the application hangs. So what we do is
* test if either the send or receive context cipher name
* matches the known available parallel ciphers. If it does
* then we force a rekey which automatically loads the parallel
* cipher. */
void
cipher_switch(struct ssh *ssh) {
#ifdef WITH_OPENSSL
/* get the send and receive context and extract the cipher name */
const void *send_cc = ssh_packet_get_send_context(ssh);
const void *recv_cc = ssh_packet_get_receive_context(ssh);
const char *send = cipher_ctx_name(send_cc);
const char *recv = cipher_ctx_name(recv_cc);
debug_f("Send: %s Recv: %s", send, recv);
/* if the name of the cipher matches then we set the context
* to authenticated (it likely already is though) and then
* force the rekey. Either side can do this. One downside of
* this method is that both sides can request a rekey so you
* can end up duplicating work. This is annoying but the
* performance gains make it worthwhile. Also I
* use strstr here because strcmp would require a 6 part
* if statement */
if (strstr(send, "ctr") || strstr(recv, "ctr")) {
debug("Serial to parallel AES-CTR cipher swap");
/* cipher_reset_multithreaded(); */
ssh_packet_set_authenticated(ssh);
packet_request_rekeying();
}
/* do the same for multithreaded chacha20 but with strcmp */
if ((strcmp(send, "[email protected]") == 0) ||
(strcmp(recv, "[email protected]") == 0)) {
debug("Serial to parallel Chacha20-poly1305 cipher swap");
ssh_packet_set_authenticated(ssh);
packet_request_rekeying();
}
#endif
}