File: plutoalg.c

package info (click to toggle)
libreswan 5.2-2.3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 81,644 kB
  • sloc: ansic: 129,988; sh: 32,018; xml: 20,646; python: 10,303; makefile: 3,022; javascript: 1,506; sed: 574; yacc: 511; perl: 264; awk: 52
file content (184 lines) | stat: -rw-r--r-- 5,065 bytes parent folder | download | duplicates (2)
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
 * Kernel runtime algorithm handling interface definitions
 * Originally by: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
 * Reworked into openswan 2.x by Michael Richardson <mcr@xelerance.com>
 *
 * Copyright (C) 2012-2019 Paul Wouters <pwouters@redhat.com>
 * Copyright (C) 2012-2013 Paul Wouters <paul@libreswan.org>
 * Copyright (C) 2012-2013 D. Hugh Redelmeier
 * Copyright (C) 2015-2017 Andrew Cagney <cagney@gnu.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.  See <https://www.gnu.org/licenses/gpl2.txt>.
 *
 * This program 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 GNU General Public License
 * for more details.
 */

#include <sys/types.h>
#include <stdlib.h>

#include "passert.h"
#include "sysdep.h"
#include "constants.h"
#include "defs.h"
#include "log.h"
#include "lswalloc.h"
#include "id.h"
#include "connections.h"
#include "state.h"
#include "kernel_alg.h"
#include "ike_alg.h"
#include "ike_alg_integ.h"
#include "ike_alg_encrypt.h"
#include "plutoalg.h"
#include "crypto.h"
#include "ikev1_db_ops.h"
#include "log.h"
#include "whack.h"
#include "ikev1.h"	/* for ikev1_quick_dh() */
#include "show.h"

void show_kernel_alg_status(struct show *s)
{
	show_separator(s);
	show(s, "Kernel algorithms supported:");
	show_separator(s);

	for (const struct encrypt_desc **alg_p = next_kernel_encrypt_desc(NULL);
	     alg_p != NULL; alg_p = next_kernel_encrypt_desc(alg_p)) {
		const struct encrypt_desc *alg = *alg_p;
		if (alg != NULL) /* nostack gives us no algos */
			show(s,
				"algorithm ESP encrypt: name=%s, keysizemin=%d, keysizemax=%d",
				alg->common.fqn,
				encrypt_min_key_bit_length(alg),
				encrypt_max_key_bit_length(alg));
	}

	for (const struct integ_desc **alg_p = next_kernel_integ_desc(NULL);
	     alg_p != NULL; alg_p = next_kernel_integ_desc(alg_p)) {
		const struct integ_desc *alg = *alg_p;
		if (alg != NULL) /* nostack doesn't give us algos */
			show(s,
				"algorithm AH/ESP auth: name=%s, key-length=%zu",
				alg->common.fqn,
				alg->integ_keymat_size * BITS_IN_BYTE);
	}
}

void show_kernel_alg_connection(struct show *s,
				const struct connection *c)
{
	const char *satype;

	switch (c->config->child_sa.encap_proto) {
	case ENCAP_PROTO_UNSET:
		satype = "noESPnoAH";
		break;

	case ENCAP_PROTO_ESP:
		satype = "ESP";
		break;

	case ENCAP_PROTO_AH:
		satype = "AH";
		break;
	default:
		bad_case(c->config->child_sa.encap_proto);
	}

	const char *pfsbuf;

	if (c->config->child_sa.pfs) {
		/*
		 * Get the DH algorithm specified for the child (ESP or AH).
		 *
		 * If this is NULL and PFS is required then callers fall back to using
		 * the parent's DH algorithm.
		 */
		switch (c->config->ike_version) {
#ifdef USE_IKEv1
		case IKEv1:
		{
			const struct dh_desc *dh = ikev1_quick_pfs(c->config->child_sa.proposals);
			if (dh != NULL) {
				pfsbuf = dh->common.fqn;
			} else {
				pfsbuf = "<Phase1>";
			}
			break;
		}
#endif
		case IKEv2:
		default:
			pfsbuf = "<Phase1>";
			break;
		}
	} else {
		pfsbuf = "<N/A>";
	}

	/*
	 * XXX: don't show the default proposal suite (assuming it is
	 * known).  Mainly so that test output doesn't get churned
	 * (originally it wasn't shown because it wasn't known).
	 */
	if (c->config->child_sa.proposals.p != NULL &&
	    !default_proposals(c->config->child_sa.proposals.p)) {
		SHOW_JAMBUF(s, buf) {
			/*
			 * If DH (PFS) was specified in the esp= or
			 * ah= line then the below will display it
			 * in-line for each crypto suite.  For
			 * instance:
			 *
			 *    AES_GCM-NULL-DH22
			 *
			 * This output can be fed straight back into
			 * the parser.  This is not true of the old
			 * style output:
			 *
			 *    AES_GCM-NULL; pfsgroup=DH22
			 *
			 * The real PFS is displayed in the 'algorithm
			 * newest' line further down.
			 */
			jam_connection_short(buf, c);
			jam_string(buf, ":  ");
			/* algs */
			jam(buf, " %s algorithms: ", satype);
			jam_proposals(buf, c->config->child_sa.proposals.p);
		}
	}

	const struct state *st = state_by_serialno(c->established_child_sa);

	if (st != NULL && st->st_esp.protocol == &ip_protocol_esp) {
		SHOW_JAMBUF(s, buf) {
			jam_connection_short(buf, c);
			jam_string(buf, ":  ");
			jam(buf, " %s algorithm newest: %s_%03d-%s;",
			    satype,
			    st->st_esp.trans_attrs.ta_encrypt->common.fqn,
			    st->st_esp.trans_attrs.enckeylen,
			    st->st_esp.trans_attrs.ta_integ->common.fqn);
			jam(buf, " pfsgroup=%s", pfsbuf);
		}
	}

	if (st != NULL && st->st_ah.protocol == &ip_protocol_ah) {
		SHOW_JAMBUF(s, buf) {
			jam_connection_short(buf, c);
			jam_string(buf, ":  ");
			jam(buf, " %s algorithm newest: %s;",
			    satype,
			    st->st_ah.trans_attrs.ta_integ->common.fqn);
			jam(buf, " pfsgroup=%s", pfsbuf);
		}
	}
}