Bug Summary

File:programs/pluto/ikev2_message.c
Warning:line 746, column 3
The right operand of '+' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ikev2_message.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -pic-is-pie -mthread-model posix -mdisable-fp-elim -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -resource-dir /usr/lib64/clang/8.0.0 -D TimeZoneOffset=timezone -D linux -D PIE -D NSS_IPSEC_PROFILE -D XFRM_SUPPORT -D USE_XFRM_INTERFACE -D USE_DNSSEC -D DEFAULT_DNSSEC_ROOTKEY_FILE="/var/lib/unbound/root.key" -D HAVE_LABELED_IPSEC -D HAVE_SECCOMP -D LIBCURL -D USE_LINUX_AUDIT -D USE_SYSTEMD_WATCHDOG -D HAVE_NM -D XAUTH_HAVE_PAM -D USE_3DES -D USE_AES -D USE_CAMELLIA -D USE_CHACHA -D USE_DH31 -D USE_MD5 -D USE_SHA1 -D USE_SHA2 -D USE_PRF_AES_XCBC -D DEFAULT_RUNDIR="/run/pluto" -D IPSEC_CONF="/etc/ipsec.conf" -D IPSEC_CONFDDIR="/etc/ipsec.d" -D IPSEC_NSSDIR="/etc/ipsec.d" -D IPSEC_CONFDIR="/etc" -D IPSEC_EXECDIR="/usr/local/libexec/ipsec" -D IPSEC_SBINDIR="/usr/local/sbin" -D IPSEC_VARDIR="/var" -D POLICYGROUPSDIR="/etc/ipsec.d/policies" -D IPSEC_SECRETS_FILE="/etc/ipsec.secrets" -D FORCE_PR_ASSERT -D USE_FORK=1 -D USE_VFORK=0 -D USE_DAEMON=0 -D USE_PTHREAD_SETSCHEDPRIO=1 -D GCC_LINT -D HAVE_LIBCAP_NG -I . -I ../../OBJ.linux.x86_64/programs/pluto -I ../../include -I /usr/include/nss3 -I /usr/include/nspr4 -I /home/build/libreswan/programs/pluto/linux-copy -D HERE_BASENAME="ikev2_message.c" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/8.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-missing-field-initializers -std=gnu99 -fdebug-compilation-dir /home/build/libreswan/programs/pluto -ferror-limit 19 -fmessage-length 0 -stack-protector 3 -fobjc-runtime=gcc -fdiagnostics-show-option -analyzer-output=html -o /tmp/scan-build-2020-09-09-193337-25440-1 -x c /home/build/libreswan/programs/pluto/ikev2_message.c -faddrsig
1/* IKEv2 message routines, for Libreswan
2 *
3 * Copyright (C) 2007-2008 Michael Richardson <mcr@xelerance.com>
4 * Copyright (C) 2008-2011 Paul Wouters <paul@xelerance.com>
5 * Copyright (C) 2008 Antony Antony <antony@xelerance.com>
6 * Copyright (C) 2008-2009 David McCullough <david_mccullough@securecomputing.com>
7 * Copyright (C) 2010,2012 Avesh Agarwal <avagarwa@redhat.com>
8 * Copyright (C) 2010 Tuomo Soini <tis@foobar.fi
9 * Copyright (C) 2012-2019 Paul Wouters <pwouters@redhat.com>
10 * Copyright (C) 2012-2017 Antony Antony <antony@phenome.org>
11 * Copyright (C) 2013-2019 D. Hugh Redelmeier <hugh@mimosa.com>
12 * Copyright (C) 2013 David McCullough <ucdevel@gmail.com>
13 * Copyright (C) 2013 Matt Rogers <mrogers@redhat.com>
14 * Copyright (C) 2015-2019 Andrew Cagney <cagney@gnu.org>
15 * Copyright (C) 2017 Sahana Prasad <sahana.prasad07@gmail.com>
16 * Copyright (C) 2017 Vukasin Karadzic <vukasin.karadzic@gmail.com>
17 * Copyright (C) 2017 Mayank Totale <mtotale@gmail.com>
18 *
19 * This program is free software; you can redistribute it and/or modify it
20 * under the terms of the GNU General Public License as published by the
21 * Free Software Foundation; either version 2 of the License, or (at your
22 * option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>.
23 *
24 * This program is distributed in the hope that it will be useful, but
25 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 * for more details.
28 */
29
30
31#include "defs.h"
32
33#include "log.h"
34#include "ikev2_message.h"
35#include "server.h"
36#include "state.h"
37#include "connections.h"
38#include "ike_alg.h"
39#include "ike_alg_encrypt_ops.h" /* XXX: oops */
40#include "pluto_stats.h"
41#include "demux.h" /* for struct msg_digest */
42#include "rnd.h"
43#include "crypt_prf.h"
44#include "send.h" /* record_outbound_ike_message() */
45#include "ip_info.h"
46#include "iface.h"
47#include "ip_protocol.h"
48#include "ikev2_send.h"
49
50/*
51 * Determine the IKE version we will use for the IKE packet
52 * Normally, this is "2.0", but in the future we might need to
53 * change that. Version used is the minimum 2.x version both
54 * sides support. So if we support 2.1, and they support 2.0,
55 * we should sent 2.0 (not implemented until we hit 2.1 ourselves)
56 * We also have some impair functions that modify the major/minor
57 * version on purpose - for testing
58 *
59 * rcv_version: the received IKE version, 0 if we don't know
60 *
61 * top 4 bits are major version, lower 4 bits are minor version
62 */
63static uint8_t build_ikev2_version(void)
64{
65 /* TODO: if bumping, we should also set the Version flag in the ISAKMP header */
66 return ((IKEv2_MAJOR_VERSION0x2 + (impair.major_version_bump ? 1 : 0))
67 << ISA_MAJ_SHIFT4) |
68 (IKEv2_MINOR_VERSION0x0 + (impair.minor_version_bump ? 1 : 0));
69}
70
71uint8_t build_ikev2_critical(bool_Bool impaired)
72{
73 uint8_t octet = 0;
74 if (impaired) {
75 /* flip the expected bit */
76 libreswan_log("IMPAIR: setting (should be off) critical payload bit")loglog(RC_LOG, "IMPAIR: setting (should be off) critical payload bit"
)
;
77 octet = ISAKMP_PAYLOAD_CRITICAL0x80;
78 } else {
79 octet = ISAKMP_PAYLOAD_NONCRITICAL0x00;
80 }
81 if (impair.send_bogus_payload_flag) {
82 libreswan_log("IMPAIR: adding bogus bit to critical octet")loglog(RC_LOG, "IMPAIR: adding bogus bit to critical octet");
83 octet |= ISAKMP_PAYLOAD_LIBRESWAN_BOGUS0x01;
84 }
85 return octet;
86}
87
88/*
89 * Open an IKEv2 message.
90 *
91 * Request: IKE, which must be non-NULL, is used to determine the IKE
92 * SA Initiator / Responder role; MD must be NULL (after all a request
93 * has no response).
94 *
95 * Response: If IKE is non-NULL then it is used to determine the IKE
96 * SA Initiator / Responder role (NULL implies IKE SA Initiator); MD
97 * must be non-NULL (the message being responded to).
98 */
99
100pb_stream open_v2_message(pb_stream *reply,
101 struct ike_sa *ike, struct msg_digest *md,
102 enum isakmp_xchg_types exchange_type)
103{
104 /* at least one, possibly both */
105 passert(ike != NULL || md != NULL){ _Bool assertion__ = ike != ((void*)0) || md != ((void*)0); if
(!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev2_message.c" , .line = 105}, "%s", "ike != NULL || md != NULL"
); } }
;
106
107 struct isakmp_hdr hdr = {
108 .isa_flags = impair.send_bogus_isakmp_flag ? ISAKMP_FLAGS_RESERVED_BIT6(1 << 6) : LEMPTY((lset_t)0),
109 .isa_version = build_ikev2_version(),
110 .isa_xchg = exchange_type,
111 .isa_length = 0, /* filled in when PBS is closed */
112 };
113
114 /*
115 * I (Initiator) flag
116 *
117 * If there is an IKE SA, the sa_role can be used.
118 *
119 * If there is no IKE SA, then, presumably, this is a response
120 * to an initial exchange and the flag should be clear.
121 *
122 * The other possability is that this is a response to an
123 * IKEv++ message, just assume this is the initial exchange
124 * and the I flag should be clear (see 1.5. Informational
125 * Messages outside of an IKE SA). The other option would be
126 * to flip MD's I bit, but since this is IKEv++, there may not
127 * even be an I bit.
128 */
129 enum sa_role sa_role = (ike != NULL((void*)0) ? ike->sa.st_sa_role : SA_RESPONDER);
130 if (sa_role == SA_INITIATOR) {
131 hdr.isa_flags |= ISAKMP_FLAGS_v2_IKE_I(1 << 3);
132 }
133
134 /*
135 * R (Response) flag
136 *
137 * If there's no MD, then this must be a new exchange request
138 * - R(Responder) flag clear.
139 *
140 * If there is an MD, then this must be a response -
141 * R(Responder) flag set.
142 *
143 * Note that when MD!= NULL, v2_msg_role() can't be called (as
144 * a cross check) as this code used to force a response to a
145 * message that is close to bogus requests (1.5.
146 * Informational Messages outside of an IKE SA - where the
147 * response is forced.
148 */
149 enum message_role message_role = (md != NULL((void*)0) ? MESSAGE_RESPONSE : MESSAGE_REQUEST);
150 if (message_role == MESSAGE_RESPONSE) {
151 hdr.isa_flags |= ISAKMP_FLAGS_v2_MSG_R(1 << 5);
152 }
153
154 /*
155 * SPI (aka cookies).
156 */
157 if (ike != NULL((void*)0)) {
158 /*
159 * Note that when the original initiator sends the
160 * IKE_SA_INIT request, the still zero SPIr will be
161 * copied.
162 */
163 hdr.isa_ike_initiator_spiisa_ike_spis.initiator = ike->sa.st_ike_spis.initiator;
164 hdr.isa_ike_responder_spiisa_ike_spis.responder = ike->sa.st_ike_spis.responder;
165 } else {
166 /*
167 * Either error response notification to IKE_SA_INIT
168 * or "Informational Messages outside of an IKE SA".
169 * Use the IKE SPIs from the request.
170 */
171 passert(md != NULL){ _Bool assertion__ = md != ((void*)0); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev2_message.c" ,
.line = 171}, "%s", "md != NULL"); } }
;
172 hdr.isa_ike_initiator_spiisa_ike_spis.initiator = md->hdr.isa_ike_initiator_spiisa_ike_spis.initiator;
173 hdr.isa_ike_responder_spiisa_ike_spis.responder = md->hdr.isa_ike_responder_spiisa_ike_spis.responder;
174 }
175
176 /*
177 * Message ID
178 */
179 if (md != NULL((void*)0)) {
180 /*
181 * Since there is a message digest (MD) it is assumed
182 * to contain a message request. Presumably this open
183 * is for the message response - use the Message ID
184 * from the request. A better choice would be
185 * .st_v2_msgid_windows.responder.recv+1, but it isn't
186 * clear if/when that value is updated and the IKE SA
187 * isn't always available.
188 */
189 hdr.isa_msgid = md->hdr.isa_msgid;
190 } else {
191 /*
192 * If it isn't a response then use the IKE SA's
193 * .st_v2_msgid_windows.initiator.sent+1. The field
194 * will be updated as part of finishing the state
195 * transition and sending the message.
196 */
197 passert(ike != NULL){ _Bool assertion__ = ike != ((void*)0); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev2_message.c" ,
.line = 197}, "%s", "ike != NULL"); } }
;
198 hdr.isa_msgid = ike->sa.st_v2_msgid_windows.initiator.sent + 1;
199 }
200
201 if (impair.bad_ike_auth_xchg) {
202 libreswan_log("IMPAIR: Instead of replying with IKE_AUTH, forging an INFORMATIONAL reply")loglog(RC_LOG, "IMPAIR: Instead of replying with IKE_AUTH, forging an INFORMATIONAL reply"
)
;
203 if ((hdr.isa_flags & ISAKMP_FLAGS_v2_MSG_R(1 << 5)) && exchange_type == ISAKMP_v2_IKE_AUTH) {
204 hdr.isa_xchg = ISAKMP_v2_INFORMATIONAL;
205 }
206 }
207
208 struct pbs_outpacket_byte_stream rbody;
209 diag_t d = pbs_out_struct(reply, &isakmp_hdr_desc, &hdr, sizeof(hdr), &rbody);
210 if (d != NULL((void*)0)) {
211 log_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, "%s", "");
212 return empty_pbs;
213 }
214 if (impair.add_unknown_v2_payload_to == exchange_type &&
215 !emit_v2UNKNOWN("request", exchange_type, &rbody)) {
216 return empty_pbs;
217 }
218
219 return rbody;
220}
221
222/*
223 * This code assumes that the encrypted part of an IKE message starts
224 * with an Initialization Vector (IV) of enc_blocksize of random
225 * octets. The IV will subsequently be discarded after decryption.
226 * This is true of Cipher Block Chaining mode (CBC).
227 */
228static bool_Bool emit_v2SK_iv(v2SK_payload_t *sk)
229{
230 /* compute location/size */
231 sk->iv = chunk2(sk->pbs.cur, sk->ike->sa.st_oakley.ta_encrypt->wire_iv_size);
232 /* make space */
233 diag_t d = pbs_out_zero(&sk->pbs, sk->iv.len, "IV");
234 if (d != NULL((void*)0)) {
235 log_diag(RC_LOG_SERIOUS, sk->logger, &d, "%s", "");
236 return false0;
237 }
238 /* scribble on it */
239 fill_rnd_chunk(sk->iv);
240 return true1;
241}
242
243v2SK_payload_t open_v2SK_payload(struct logger *logger,
244 pb_stream *container,
245 struct ike_sa *ike)
246{
247 static const v2SK_payload_t empty_sk;
248 v2SK_payload_t sk = {
249 .logger = logger,
250 .ike = ike,
251 .payload = {
252 .ptr = container->cur,
253 .len = 0, /* computed at end; set here to silence GCC 6.10 */
254 }
255 };
256
257 /* emit Encryption Payload header */
258
259 struct ikev2_generic e = {
260 .isag_length = 0, /* filled in later */
261 .isag_critical = build_ikev2_critical(false0),
262 };
263 if (!out_struct(&e, &ikev2_sk_desc, container, &sk.pbs)) {
264 log_message(RC_LOG, logger,
265 "error initializing SK header for encrypted %s message",
266 container->name);
267 return empty_sk;
268 }
269
270 /* emit IV and save location */
271
272 if (!emit_v2SK_iv(&sk)) {
273 log_message(RC_LOG, logger,
274 "error initializing IV for encrypted %s message",
275 container->name);
276 return empty_sk;
277 }
278
279 /* save cleartext start */
280
281 sk.cleartext.ptr = sk.pbs.cur;
282 passert(sk.iv.ptr <= sk.cleartext.ptr){ _Bool assertion__ = sk.iv.ptr <= sk.cleartext.ptr; if (!
assertion__) { lsw_passert_fail((where_t) { .func = __func__,
.basename = "ikev2_message.c" , .line = 282}, "%s", "sk.iv.ptr <= sk.cleartext.ptr"
); } }
;
283 passert(sk.pbs.container->name == container->name){ _Bool assertion__ = sk.pbs.container->name == container->
name; if (!assertion__) { lsw_passert_fail((where_t) { .func =
__func__, .basename = "ikev2_message.c" , .line = 283}, "%s"
, "sk.pbs.container->name == container->name"); } }
;
284
285 return sk;
286}
287
288bool_Bool close_v2SK_payload(v2SK_payload_t *sk)
289{
290 /* save cleartext end */
291
292 sk->cleartext.len = sk->pbs.cur - sk->cleartext.ptr;
293
294 /* emit padding + pad-length */
295
296 size_t padding;
297 if (sk->ike->sa.st_oakley.ta_encrypt->pad_to_blocksize) {
298 const size_t blocksize = sk->ike->sa.st_oakley.ta_encrypt->enc_blocksize;
299 padding = pad_up(sk->pbs.cur - sk->cleartext.ptr, blocksize)(((blocksize) - 1) - (((sk->pbs.cur - sk->cleartext.ptr
) + (blocksize) - 1) % (blocksize)))
;
300 if (padding == 0) {
301 padding = blocksize;
302 }
303 } else {
304 padding = 1;
305 }
306 dbg("adding %zd bytes of padding (including 1 byte padding-length)",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("adding %zd bytes of padding (including 1 byte padding-length)"
, padding); } }
307 padding){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("adding %zd bytes of padding (including 1 byte padding-length)"
, padding); } }
;
308 for (unsigned i = 0; i < padding; i++) {
309 diag_t d = pbs_out_repeated_byte(&sk->pbs, i, 1, "padding and length");
310 if (d != NULL((void*)0)) {
311 log_diag(RC_LOG_SERIOUS, sk->logger, &d,
312 "error initializing padding for encrypted %s payload: ",
313 sk->pbs.container->name);
314 return false0;
315 }
316 }
317
318 /* emit space for integrity checksum data; save location */
319
320 size_t integ_size = (encrypt_desc_is_aead(sk->ike->sa.st_oakley.ta_encrypt)
321 ? sk->ike->sa.st_oakley.ta_encrypt->aead_tag_size
322 : sk->ike->sa.st_oakley.ta_integ->integ_output_size);
323 if (integ_size == 0) {
324 pexpect_fail(sk->logger, HERE(where_t) { .func = __func__, .basename = "ikev2_message.c" ,
.line = 324}
,
325 "error initializing integrity checksum for encrypted %s payload",
326 sk->pbs.container->name);
327 return false0;
328 }
329 sk->integrity = chunk2(sk->pbs.cur, integ_size);
330 diag_t d = pbs_out_zero(&sk->pbs, integ_size, "length of truncated HMAC/KEY");
331 if (d != NULL((void*)0)) {
332 log_diag(RC_LOG_SERIOUS, sk->logger, &d, "%s", "");
333 return false0;
334 }
335
336 /* close the SK payload */
337
338 sk->payload.len = sk->pbs.cur - sk->payload.ptr;
339 close_output_pbs(&sk->pbs);
340
341 return true1;
342}
343
344/*
345 * Form the encryption IV (a.k.a. starting variable) from the salt
346 * (a.k.a. nonce) wire-iv and a counter set to 1.
347 *
348 * note: no iv is longer than MAX_CBC_BLOCK_SIZE
349 */
350static void construct_enc_iv(const char *name,
351 u_char enc_iv[],
352 u_char *wire_iv, chunk_t salt,
353 const struct encrypt_desc *encrypter)
354{
355 DBG(DBG_CRYPT, DBG_log("construct_enc_iv: %s: salt-size=%zd wire-IV-size=%zd block-size %zd",{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_log("construct_enc_iv: %s: salt-size=%zd wire-IV-size=%zd block-size %zd"
, name, encrypter->salt_size, encrypter->wire_iv_size, encrypter
->enc_blocksize); } }
356 name, encrypter->salt_size, encrypter->wire_iv_size,{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_log("construct_enc_iv: %s: salt-size=%zd wire-IV-size=%zd block-size %zd"
, name, encrypter->salt_size, encrypter->wire_iv_size, encrypter
->enc_blocksize); } }
357 encrypter->enc_blocksize)){ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_log("construct_enc_iv: %s: salt-size=%zd wire-IV-size=%zd block-size %zd"
, name, encrypter->salt_size, encrypter->wire_iv_size, encrypter
->enc_blocksize); } }
;
358 passert(salt.len == encrypter->salt_size){ _Bool assertion__ = salt.len == encrypter->salt_size; if
(!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev2_message.c" , .line = 358}, "%s", "salt.len == encrypter->salt_size"
); } }
;
359 passert(encrypter->enc_blocksize <= MAX_CBC_BLOCK_SIZE){ _Bool assertion__ = encrypter->enc_blocksize <= (((128
) + 8 - 1) / 8); if (!assertion__) { lsw_passert_fail((where_t
) { .func = __func__, .basename = "ikev2_message.c" , .line =
359}, "%s", "encrypter->enc_blocksize <= MAX_CBC_BLOCK_SIZE"
); } }
;
360 passert(encrypter->enc_blocksize >= encrypter->salt_size + encrypter->wire_iv_size){ _Bool assertion__ = encrypter->enc_blocksize >= encrypter
->salt_size + encrypter->wire_iv_size; if (!assertion__
) { lsw_passert_fail((where_t) { .func = __func__, .basename =
"ikev2_message.c" , .line = 360}, "%s", "encrypter->enc_blocksize >= encrypter->salt_size + encrypter->wire_iv_size"
); } }
;
361 size_t counter_size = encrypter->enc_blocksize - encrypter->salt_size - encrypter->wire_iv_size;
362 DBG(DBG_CRYPT, DBG_log("construct_enc_iv: %s: computed counter-size=%zd",{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_log("construct_enc_iv: %s: computed counter-size=%zd"
, name, counter_size); } }
363 name, counter_size)){ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_log("construct_enc_iv: %s: computed counter-size=%zd"
, name, counter_size); } }
;
364
365 memcpy(enc_iv, salt.ptr, salt.len);
366 memcpy(enc_iv + salt.len, wire_iv, encrypter->wire_iv_size);
367 if (counter_size > 0) {
368 memset(enc_iv + encrypter->enc_blocksize - counter_size, 0,
369 counter_size - 1);
370 enc_iv[encrypter->enc_blocksize - 1] = 1;
371 }
372 DBG(DBG_CRYPT, DBG_dump(name, enc_iv, encrypter->enc_blocksize)){ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump(name, enc_iv, encrypter->enc_blocksize); }
}
;
373}
374
375
376stf_status encrypt_v2SK_payload(v2SK_payload_t *sk)
377{
378 struct ike_sa *ike = sk->ike;
379 uint8_t *auth_start = sk->pbs.container->start;
380 uint8_t *wire_iv_start = sk->iv.ptr;
381 uint8_t *enc_start = sk->cleartext.ptr;
382 uint8_t *integ_start = sk->integrity.ptr;
383 size_t integ_size = sk->integrity.len;
384
385 passert(auth_start <= wire_iv_start){ _Bool assertion__ = auth_start <= wire_iv_start; if (!assertion__
) { lsw_passert_fail((where_t) { .func = __func__, .basename =
"ikev2_message.c" , .line = 385}, "%s", "auth_start <= wire_iv_start"
); } }
;
386 passert(wire_iv_start <= enc_start){ _Bool assertion__ = wire_iv_start <= enc_start; if (!assertion__
) { lsw_passert_fail((where_t) { .func = __func__, .basename =
"ikev2_message.c" , .line = 386}, "%s", "wire_iv_start <= enc_start"
); } }
;
387 passert(enc_start <= integ_start){ _Bool assertion__ = enc_start <= integ_start; if (!assertion__
) { lsw_passert_fail((where_t) { .func = __func__, .basename =
"ikev2_message.c" , .line = 387}, "%s", "enc_start <= integ_start"
); } }
;
388
389 chunk_t salt;
390 PK11SymKey *cipherkey;
391 PK11SymKey *authkey;
392 /* encrypt with our end's key */
393 switch (ike->sa.st_sa_role) {
394 case SA_INITIATOR:
395 cipherkey = ike->sa.st_skey_ei_nss;
396 authkey = ike->sa.st_skey_ai_nss;
397 salt = ike->sa.st_skey_initiator_salt;
398 break;
399 case SA_RESPONDER:
400 cipherkey = ike->sa.st_skey_er_nss;
401 authkey = ike->sa.st_skey_ar_nss;
402 salt = ike->sa.st_skey_responder_salt;
403 break;
404 default:
405 bad_case(ike->sa.st_sa_role)libreswan_bad_case("ike->sa.st_sa_role", (ike->sa.st_sa_role
), (where_t) { .func = __func__, .basename = "ikev2_message.c"
, .line = 405})
;
406 }
407
408 /* size of plain or cipher text. */
409 size_t enc_size = integ_start - enc_start;
410
411 /* encrypt and authenticate the block */
412 if (encrypt_desc_is_aead(ike->sa.st_oakley.ta_encrypt)) {
413 /*
414 * Additional Authenticated Data - AAD - size.
415 * RFC5282 says: The Initialization Vector and Ciphertext
416 * fields [...] MUST NOT be included in the associated
417 * data.
418 */
419 size_t wire_iv_size = ike->sa.st_oakley.ta_encrypt->wire_iv_size;
420 pexpect(integ_size == ike->sa.st_oakley.ta_encrypt->aead_tag_size)({ _Bool assertion__ = integ_size == ike->sa.st_oakley.ta_encrypt
->aead_tag_size; if (!assertion__) { log_pexpect((where_t)
{ .func = __func__, .basename = "ikev2_message.c" , .line = 420
}, "%s", "integ_size == ike->sa.st_oakley.ta_encrypt->aead_tag_size"
); } assertion__; })
;
421 unsigned char *aad_start = auth_start;
422 size_t aad_size = enc_start - aad_start - wire_iv_size;
423
424 DBG(DBG_CRYPT,{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated encryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated encryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated encryption:"
, aad_start, aad_size); DBG_dump("data before authenticated encryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated encryption:"
, integ_start, integ_size); } }
425 DBG_dump_hunk("Salt before authenticated encryption:", salt);{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated encryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated encryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated encryption:"
, aad_start, aad_size); DBG_dump("data before authenticated encryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated encryption:"
, integ_start, integ_size); } }
426 DBG_dump("IV before authenticated encryption:",{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated encryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated encryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated encryption:"
, aad_start, aad_size); DBG_dump("data before authenticated encryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated encryption:"
, integ_start, integ_size); } }
427 wire_iv_start, wire_iv_size);{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated encryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated encryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated encryption:"
, aad_start, aad_size); DBG_dump("data before authenticated encryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated encryption:"
, integ_start, integ_size); } }
428 DBG_dump("AAD before authenticated encryption:",{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated encryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated encryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated encryption:"
, aad_start, aad_size); DBG_dump("data before authenticated encryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated encryption:"
, integ_start, integ_size); } }
429 aad_start, aad_size);{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated encryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated encryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated encryption:"
, aad_start, aad_size); DBG_dump("data before authenticated encryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated encryption:"
, integ_start, integ_size); } }
430 DBG_dump("data before authenticated encryption:",{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated encryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated encryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated encryption:"
, aad_start, aad_size); DBG_dump("data before authenticated encryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated encryption:"
, integ_start, integ_size); } }
431 enc_start, enc_size);{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated encryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated encryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated encryption:"
, aad_start, aad_size); DBG_dump("data before authenticated encryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated encryption:"
, integ_start, integ_size); } }
432 DBG_dump("integ before authenticated encryption:",{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated encryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated encryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated encryption:"
, aad_start, aad_size); DBG_dump("data before authenticated encryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated encryption:"
, integ_start, integ_size); } }
433 integ_start, integ_size)){ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated encryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated encryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated encryption:"
, aad_start, aad_size); DBG_dump("data before authenticated encryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated encryption:"
, integ_start, integ_size); } }
;
434 if (!ike->sa.st_oakley.ta_encrypt->encrypt_ops
435 ->do_aead(ike->sa.st_oakley.ta_encrypt,
436 salt.ptr, salt.len,
437 wire_iv_start, wire_iv_size,
438 aad_start, aad_size,
439 enc_start, enc_size, integ_size,
440 cipherkey, true1, sk->logger)) {
441 return STF_FAIL;
442 }
443 DBG(DBG_CRYPT,{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump("data after authenticated encryption:", enc_start
, enc_size); DBG_dump("integ after authenticated encryption:"
, integ_start, integ_size); } }
444 DBG_dump("data after authenticated encryption:",{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump("data after authenticated encryption:", enc_start
, enc_size); DBG_dump("integ after authenticated encryption:"
, integ_start, integ_size); } }
445 enc_start, enc_size);{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump("data after authenticated encryption:", enc_start
, enc_size); DBG_dump("integ after authenticated encryption:"
, integ_start, integ_size); } }
446 DBG_dump("integ after authenticated encryption:",{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump("data after authenticated encryption:", enc_start
, enc_size); DBG_dump("integ after authenticated encryption:"
, integ_start, integ_size); } }
447 integ_start, integ_size)){ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump("data after authenticated encryption:", enc_start
, enc_size); DBG_dump("integ after authenticated encryption:"
, integ_start, integ_size); } }
;
448 } else {
449 /* note: no iv is longer than MAX_CBC_BLOCK_SIZE */
450 unsigned char enc_iv[MAX_CBC_BLOCK_SIZE(((128) + 8 - 1) / 8)];
451 construct_enc_iv("encryption IV/starting-variable", enc_iv,
452 wire_iv_start, salt,
453 ike->sa.st_oakley.ta_encrypt);
454
455 DBG(DBG_CRYPT,{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump("data before encryption:", enc_start, enc_size
); } }
456 DBG_dump("data before encryption:", enc_start, enc_size)){ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump("data before encryption:", enc_start, enc_size
); } }
;
457
458 /* now, encrypt */
459 ike->sa.st_oakley.ta_encrypt->encrypt_ops
460 ->do_crypt(ike->sa.st_oakley.ta_encrypt,
461 enc_start, enc_size,
462 cipherkey,
463 enc_iv, TRUE1,
464 sk->logger);
465
466 DBG(DBG_CRYPT,{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump("data after encryption:", enc_start, enc_size
); } }
467 DBG_dump("data after encryption:", enc_start, enc_size)){ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump("data after encryption:", enc_start, enc_size
); } }
;
468 /* note: saved_iv's updated value is discarded */
469
470 /* okay, authenticate from beginning of IV */
471 struct crypt_prf *ctx = crypt_prf_init_symkey("integ", ike->sa.st_oakley.ta_integ->prf,
472 "authkey", authkey, sk->logger);
473 crypt_prf_update_bytes(ctx, "message", auth_start, integ_start - auth_start);
474 passert(integ_size == ike->sa.st_oakley.ta_integ->integ_output_size){ _Bool assertion__ = integ_size == ike->sa.st_oakley.ta_integ
->integ_output_size; if (!assertion__) { lsw_passert_fail(
(where_t) { .func = __func__, .basename = "ikev2_message.c" ,
.line = 474}, "%s", "integ_size == ike->sa.st_oakley.ta_integ->integ_output_size"
); } }
;
475 struct crypt_mac mac = crypt_prf_final_mac(&ctx, ike->sa.st_oakley.ta_integ);
476 memcpy_hunk(integ_start, mac, integ_size)({ const typeof(mac) hunk_ = mac; { _Bool assertion__ = hunk_
.len == integ_size; if (!assertion__) { lsw_passert_fail((where_t
) { .func = __func__, .basename = "ikev2_message.c" , .line =
476}, "%s", "hunk_.len == integ_size"); } }; memcpy(integ_start
, hunk_.ptr, integ_size); })
;
477
478 DBG(DBG_CRYPT, {{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { DBG_dump("data being hmac:", auth_start, integ_start
- auth_start); DBG_dump("out calculated auth:", integ_start,
integ_size); }; } }
479 DBG_dump("data being hmac:", auth_start,{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { DBG_dump("data being hmac:", auth_start, integ_start
- auth_start); DBG_dump("out calculated auth:", integ_start,
integ_size); }; } }
480 integ_start - auth_start);{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { DBG_dump("data being hmac:", auth_start, integ_start
- auth_start); DBG_dump("out calculated auth:", integ_start,
integ_size); }; } }
481 DBG_dump("out calculated auth:", integ_start, integ_size);{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { DBG_dump("data being hmac:", auth_start, integ_start
- auth_start); DBG_dump("out calculated auth:", integ_start,
integ_size); }; } }
482 }){ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { DBG_dump("data being hmac:", auth_start, integ_start
- auth_start); DBG_dump("out calculated auth:", integ_start,
integ_size); }; } }
;
483 }
484
485 return STF_OK;
486}
487
488/*
489 * ikev2_decrypt_msg: decode the payload.
490 * The result is stored in-place.
491 * Calls ikev2_process_payloads to decode the payloads within.
492 *
493 * This code assumes that the encrypted part of an IKE message starts
494 * with an Initialization Vector (IV) of WIRE_IV_SIZE random octets.
495 * We will discard the IV after decryption.
496 *
497 * The (optional) salt, wire-iv, and (optional) 1 are combined to form
498 * the actual starting-variable (a.k.a. IV).
499 */
500
501static bool_Bool ikev2_verify_and_decrypt_sk_payload(struct ike_sa *ike,
502 struct msg_digest *md,
503 chunk_t *chunk,
504 unsigned int iv)
505{
506 if (!ike->sa.hidden_variables.st_skeyid_calculated) {
507 endpoint_buf b;
508 pexpect_fail(ike->sa.st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2_message.c" ,
.line = 508}
,
509 "received encrypted packet from %s but no exponents for state #%lu to decrypt it",
510 str_endpoint(&md->sender, &b),
511 ike->sa.st_serialno);
512 return false0;
513 }
514
515 u_char *wire_iv_start = chunk->ptr + iv;
516 size_t wire_iv_size = ike->sa.st_oakley.ta_encrypt->wire_iv_size;
517 size_t integ_size = (encrypt_desc_is_aead(ike->sa.st_oakley.ta_encrypt)
518 ? ike->sa.st_oakley.ta_encrypt->aead_tag_size
519 : ike->sa.st_oakley.ta_integ->integ_output_size);
520
521 /*
522 * check to see if length is plausible:
523 * - wire-IV
524 * - encoded data (possibly empty)
525 * - at least one padding-length byte
526 * - truncated integrity digest / tag
527 */
528 u_char *payload_end = chunk->ptr + chunk->len;
529 if (payload_end < (wire_iv_start + wire_iv_size + 1 + integ_size)) {
530 libreswan_log("encrypted payload impossibly short (%tu)",loglog(RC_LOG, "encrypted payload impossibly short (%tu)", payload_end
- wire_iv_start)
531 payload_end - wire_iv_start)loglog(RC_LOG, "encrypted payload impossibly short (%tu)", payload_end
- wire_iv_start)
;
532 return false0;
533 }
534
535 u_char *auth_start = chunk->ptr;
536 u_char *enc_start = wire_iv_start + wire_iv_size;
537 u_char *integ_start = payload_end - integ_size;
538 size_t enc_size = integ_start - enc_start;
539
540 /*
541 * Check that the payload is block-size aligned.
542 *
543 * Per rfc7296 "the recipient MUST accept any length that
544 * results in proper alignment".
545 *
546 * Do this before the payload's integrity has been verified as
547 * block-alignment requirements aren't exactly secret
548 * (originally this was being done between integrity and
549 * decrypt).
550 */
551 size_t enc_blocksize = ike->sa.st_oakley.ta_encrypt->enc_blocksize;
552 bool_Bool pad_to_blocksize = ike->sa.st_oakley.ta_encrypt->pad_to_blocksize;
553 if (pad_to_blocksize) {
554 if (enc_size % enc_blocksize != 0) {
555 libreswan_log("discarding invalid packet: %zu octet payload length is not a multiple of encryption block-size (%zu)",loglog(RC_LOG, "discarding invalid packet: %zu octet payload length is not a multiple of encryption block-size (%zu)"
, enc_size, enc_blocksize)
556 enc_size, enc_blocksize)loglog(RC_LOG, "discarding invalid packet: %zu octet payload length is not a multiple of encryption block-size (%zu)"
, enc_size, enc_blocksize)
;
557 return false0;
558 }
559 }
560
561 chunk_t salt;
562 PK11SymKey *cipherkey;
563 PK11SymKey *authkey;
564 switch (ike->sa.st_sa_role) {
565 case SA_INITIATOR:
566 /* need responders key */
567 cipherkey = ike->sa.st_skey_er_nss;
568 authkey = ike->sa.st_skey_ar_nss;
569 salt = ike->sa.st_skey_responder_salt;
570 break;
571 case SA_RESPONDER:
572 /* need initiators key */
573 cipherkey = ike->sa.st_skey_ei_nss;
574 authkey = ike->sa.st_skey_ai_nss;
575 salt = ike->sa.st_skey_initiator_salt;
576 break;
577 default:
578 bad_case(ike->sa.st_sa_role)libreswan_bad_case("ike->sa.st_sa_role", (ike->sa.st_sa_role
), (where_t) { .func = __func__, .basename = "ikev2_message.c"
, .line = 578})
;
579 }
580
581 /* authenticate and decrypt the block. */
582 if (encrypt_desc_is_aead(ike->sa.st_oakley.ta_encrypt)) {
583 /*
584 * Additional Authenticated Data - AAD - size.
585 * RFC5282 says: The Initialization Vector and Ciphertext
586 * fields [...] MUST NOT be included in the associated
587 * data.
588 */
589 unsigned char *aad_start = auth_start;
590 size_t aad_size = enc_start - auth_start - wire_iv_size;
591
592 DBG(DBG_CRYPT,{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated decryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated decryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated decryption:"
, aad_start, aad_size); DBG_dump("data before authenticated decryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated decryption:"
, integ_start, integ_size); } }
593 DBG_dump_hunk("Salt before authenticated decryption:", salt);{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated decryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated decryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated decryption:"
, aad_start, aad_size); DBG_dump("data before authenticated decryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated decryption:"
, integ_start, integ_size); } }
594 DBG_dump("IV before authenticated decryption:",{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated decryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated decryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated decryption:"
, aad_start, aad_size); DBG_dump("data before authenticated decryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated decryption:"
, integ_start, integ_size); } }
595 wire_iv_start, wire_iv_size);{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated decryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated decryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated decryption:"
, aad_start, aad_size); DBG_dump("data before authenticated decryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated decryption:"
, integ_start, integ_size); } }
596 DBG_dump("AAD before authenticated decryption:",{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated decryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated decryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated decryption:"
, aad_start, aad_size); DBG_dump("data before authenticated decryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated decryption:"
, integ_start, integ_size); } }
597 aad_start, aad_size);{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated decryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated decryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated decryption:"
, aad_start, aad_size); DBG_dump("data before authenticated decryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated decryption:"
, integ_start, integ_size); } }
598 DBG_dump("data before authenticated decryption:",{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated decryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated decryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated decryption:"
, aad_start, aad_size); DBG_dump("data before authenticated decryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated decryption:"
, integ_start, integ_size); } }
599 enc_start, enc_size);{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated decryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated decryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated decryption:"
, aad_start, aad_size); DBG_dump("data before authenticated decryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated decryption:"
, integ_start, integ_size); } }
600 DBG_dump("integ before authenticated decryption:",{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated decryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated decryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated decryption:"
, aad_start, aad_size); DBG_dump("data before authenticated decryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated decryption:"
, integ_start, integ_size); } }
601 integ_start, integ_size)){ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { { typeof(salt) hunk_ = salt; DBG_dump("Salt before authenticated decryption:"
, hunk_.ptr, hunk_.len); }; DBG_dump("IV before authenticated decryption:"
, wire_iv_start, wire_iv_size); DBG_dump("AAD before authenticated decryption:"
, aad_start, aad_size); DBG_dump("data before authenticated decryption:"
, enc_start, enc_size); DBG_dump("integ before authenticated decryption:"
, integ_start, integ_size); } }
;
602 if (!ike->sa.st_oakley.ta_encrypt->encrypt_ops
603 ->do_aead(ike->sa.st_oakley.ta_encrypt,
604 salt.ptr, salt.len,
605 wire_iv_start, wire_iv_size,
606 aad_start, aad_size,
607 enc_start, enc_size, integ_size,
608 cipherkey, false0, ike->sa.st_logger)) {
609 return false0;
610 }
611 DBG(DBG_CRYPT,{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump("data after authenticated decryption:", enc_start
, enc_size + integ_size); } }
612 DBG_dump("data after authenticated decryption:",{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump("data after authenticated decryption:", enc_start
, enc_size + integ_size); } }
613 enc_start, enc_size + integ_size)){ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump("data after authenticated decryption:", enc_start
, enc_size + integ_size); } }
;
614 } else {
615 /*
616 * check authenticator. The last INTEG_SIZE bytes are
617 * the truncated digest.
618 */
619 struct crypt_prf *ctx = crypt_prf_init_symkey("auth", ike->sa.st_oakley.ta_integ->prf,
620 "authkey", authkey, ike->sa.st_logger);
621 crypt_prf_update_bytes(ctx, "message", auth_start, integ_start - auth_start);
622 struct crypt_mac td = crypt_prf_final_mac(&ctx, ike->sa.st_oakley.ta_integ);
623
624 if (!hunk_memeq(td, integ_start, integ_size)({ const typeof(td) hunk_ = td; const void *mem_ = integ_start
; size_t size_ = integ_size; bytes_eq(hunk_.ptr, hunk_.len, mem_
, size_); })
) {
625 libreswan_log("failed to match authenticator")loglog(RC_LOG, "failed to match authenticator");
626 return false0;
627 }
628
629 dbg("authenticator matched"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("authenticator matched"); } }
;
630
631 /* decrypt */
632
633 /* note: no iv is longer than MAX_CBC_BLOCK_SIZE */
634 unsigned char enc_iv[MAX_CBC_BLOCK_SIZE(((128) + 8 - 1) / 8)];
635 construct_enc_iv("decryption IV/starting-variable", enc_iv,
636 wire_iv_start, salt,
637 ike->sa.st_oakley.ta_encrypt);
638
639 DBG(DBG_CRYPT,{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump("payload before decryption:", enc_start, enc_size
); } }
640 DBG_dump("payload before decryption:", enc_start, enc_size)){ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump("payload before decryption:", enc_start, enc_size
); } }
;
641 ike->sa.st_oakley.ta_encrypt->encrypt_ops
642 ->do_crypt(ike->sa.st_oakley.ta_encrypt,
643 enc_start, enc_size,
644 cipherkey,
645 enc_iv, FALSE0,
646 ike->sa.st_logger);
647 DBG(DBG_CRYPT,{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump("payload after decryption:", enc_start, enc_size
); } }
648 DBG_dump("payload after decryption:", enc_start, enc_size)){ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_dump("payload after decryption:", enc_start, enc_size
); } }
;
649 }
650
651 /*
652 * Check the padding.
653 *
654 * Per rfc7296 "The sender SHOULD set the Pad Length to the
655 * minimum value that makes the combination of the payloads,
656 * the Padding, and the Pad Length a multiple of the block
657 * size, but the recipient MUST accept any length that results
658 * in proper alignment."
659 *
660 * Notice the "should". RACOON, for instance, sends extra
661 * blocks of padding that contain random bytes.
662 */
663 uint8_t padlen = enc_start[enc_size - 1] + 1;
664 if (padlen > enc_size) {
665 libreswan_log("discarding invalid packet: padding-length %u (octet 0x%02x) is larger than %zu octet payload length",loglog(RC_LOG, "discarding invalid packet: padding-length %u (octet 0x%02x) is larger than %zu octet payload length"
, padlen, padlen - 1, enc_size)
666 padlen, padlen - 1, enc_size)loglog(RC_LOG, "discarding invalid packet: padding-length %u (octet 0x%02x) is larger than %zu octet payload length"
, padlen, padlen - 1, enc_size)
;
667 return false0;
668 }
669 if (pad_to_blocksize) {
670 if (padlen > enc_blocksize) {
671 /* probably racoon */
672 DBG(DBG_CRYPT,{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_log("payload contains %zu blocks of extra padding (padding-length: %d (octet 0x%2x), encryption block-size: %zu)"
, (padlen - 1) / enc_blocksize, padlen, padlen - 1, enc_blocksize
); } }
673 DBG_log("payload contains %zu blocks of extra padding (padding-length: %d (octet 0x%2x), encryption block-size: %zu)",{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_log("payload contains %zu blocks of extra padding (padding-length: %d (octet 0x%2x), encryption block-size: %zu)"
, (padlen - 1) / enc_blocksize, padlen, padlen - 1, enc_blocksize
); } }
674 (padlen - 1) / enc_blocksize,{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_log("payload contains %zu blocks of extra padding (padding-length: %d (octet 0x%2x), encryption block-size: %zu)"
, (padlen - 1) / enc_blocksize, padlen, padlen - 1, enc_blocksize
); } }
675 padlen, padlen - 1, enc_blocksize)){ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_log("payload contains %zu blocks of extra padding (padding-length: %d (octet 0x%2x), encryption block-size: %zu)"
, (padlen - 1) / enc_blocksize, padlen, padlen - 1, enc_blocksize
); } }
;
676 }
677 } else {
678 if (padlen > 1) {
679 DBG(DBG_CRYPT,{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_log("payload contains %u octets of extra padding (padding-length: %u (octet 0x%2x))"
, padlen - 1, padlen, padlen - 1); } }
680 DBG_log("payload contains %u octets of extra padding (padding-length: %u (octet 0x%2x))",{ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_log("payload contains %u octets of extra padding (padding-length: %u (octet 0x%2x))"
, padlen - 1, padlen, padlen - 1); } }
681 padlen - 1, padlen, padlen - 1)){ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_log("payload contains %u octets of extra padding (padding-length: %u (octet 0x%2x))"
, padlen - 1, padlen, padlen - 1); } }
;
682 }
683 }
684
685 /*
686 * Don't check the contents of the pad octets; racoon, for
687 * instance, sets them to random values.
688 */
689 DBG(DBG_CRYPT, DBG_log("stripping %u octets as pad", padlen)){ if ((cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX
))))) { DBG_log("stripping %u octets as pad", padlen); } }
;
690 *chunk = chunk2(enc_start, enc_size - padlen);
691
692 return true1;
693}
694
695/*
696 * Since the fragmented packet is intended for ST (either an IKE or
697 * CHILD SA), ST contains the fragments.
698 */
699static bool_Bool ikev2_reassemble_fragments(struct state *st,
700 struct msg_digest *md)
701{
702 if (md->chain[ISAKMP_NEXT_v2SK] != NULL((void*)0)) {
4
Assuming the condition is false
5
Taking false branch
703 pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2_message.c" ,
.line = 703}
,
704 "state #%lu has both SK ans SKF payloads",
705 st->st_serialno);
706 return false0;
707 }
708
709 if (md->digest_roof >= elemsof(md->digest)(sizeof(md->digest) / sizeof(*(md->digest)))) {
6
Assuming the condition is false
7
Taking false branch
710 libreswan_log("packet contains too many payloads; discarded")loglog(RC_LOG, "packet contains too many payloads; discarded"
)
;
711 return false0;
712 }
713
714 struct v2_incomming_fragments **frags = &st->st_v2_incomming[v2_msg_role(md)];
715 passert(*frags != NULL){ _Bool assertion__ = *frags != ((void*)0); if (!assertion__)
{ lsw_passert_fail((where_t) { .func = __func__, .basename =
"ikev2_message.c" , .line = 715}, "%s", "*frags != NULL"); }
}
;
8
Assuming 'assertion__' is not equal to 0
9
Taking false branch
716
717 chunk_t plain[MAX_IKE_FRAGMENTS32 + 1];
718 passert(elemsof(plain) == elemsof((*frags)->frags)){ _Bool assertion__ = (sizeof(plain) / sizeof(*(plain))) == (
sizeof((*frags)->frags) / sizeof(*((*frags)->frags))); if
(!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev2_message.c" , .line = 718}, "%s", "elemsof(plain) == elemsof((*frags)->frags)"
); } }
;
10
Taking false branch
719 unsigned int size = 0;
720 for (unsigned i = 1; i <= (*frags)->total; i++) {
11
Loop condition is false. Execution continues on line 742
721 struct v2_incomming_fragment *frag = &(*frags)->frags[i];
722 /*
723 * Point PLAIN at the encrypted fragment and then
724 * decrypt in-place. After the decryption, PLAIN will
725 * have been adjusted to just point at the data.
726 */
727 plain[i] = frag->cipher;
728 if (!ikev2_verify_and_decrypt_sk_payload(ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_message.c" ,
.line = 728}
), md,
729 &plain[i], frag->iv)) {
730 loglog(RC_LOG_SERIOUS, "fragment %u of %u invalid",
731 i, (*frags)->total);
732 free_v2_incomming_fragments(frags);
733 return false0;
734 }
735 size += plain[i].len;
736 }
737
738 /*
739 * All the fragments have been disassembled, re-assemble them
740 * into the .raw_packet buffer.
741 */
742 pexpect(md->raw_packet.ptr == NULL)({ _Bool assertion__ = md->raw_packet.ptr == ((void*)0); if
(!assertion__) { log_pexpect((where_t) { .func = __func__, .
basename = "ikev2_message.c" , .line = 742}, "%s", "md->raw_packet.ptr == NULL"
); } assertion__; })
; /* empty */
12
Assuming the condition is true
13
Taking false branch
743 md->raw_packet = alloc_chunk(size, "IKEv2 fragments buffer");
744 unsigned int offset = 0;
745 for (unsigned i = 1; i <= (*frags)->total; i++) {
14
Loop condition is true. Entering loop body
746 passert(offset + plain[i].len <= size){ _Bool assertion__ = offset + plain[i].len <= size; if (!
assertion__) { lsw_passert_fail((where_t) { .func = __func__,
.basename = "ikev2_message.c" , .line = 746}, "%s", "offset + plain[i].len <= size"
); } }
;
15
The right operand of '+' is a garbage value
747 memcpy(md->raw_packet.ptr + offset, plain[i].ptr,
748 plain[i].len);
749 offset += plain[i].len;
750 }
751
752 /*
753 * Fake up enough of an SK payload_digest to fool the caller
754 * and then use that to scribble all over the SKF
755 * payload_digest (remembering to also update the SK and SKF
756 * chains).
757 */
758 struct payload_digest sk = {
759 .pbs = same_chunk_as_in_pbs(md->raw_packet, "decrypted SFK payloads"),
760 .payload_type = ISAKMP_NEXT_v2SK,
761 .payload.generic.isag_np = (*frags)->first_np,
762 };
763 struct payload_digest *skf = md->chain[ISAKMP_NEXT_v2SKF];
764 md->chain[ISAKMP_NEXT_v2SKF] = NULL((void*)0);
765 md->chain[ISAKMP_NEXT_v2SK] = skf;
766 *skf = sk; /* scribble */
767
768 free_v2_incomming_fragments(frags);
769
770 return true1;
771}
772
773/*
774 * Decrypt the, possibly fragmented message intended for ST.
775 *
776 * Since the message fragments are stored in the recipient's ST
777 * (either IKE or CHILD SA), it, and not the IKE SA is needed.
778 */
779bool_Bool ikev2_decrypt_msg(struct state *st, struct msg_digest *md)
780{
781 bool_Bool ok;
782 if (md->chain[ISAKMP_NEXT_v2SKF] != NULL((void*)0)) {
1
Assuming the condition is true
2
Taking true branch
783 /*
784 * ST points at the state (parent or child) that has
785 * all the fragments.
786 */
787 ok = ikev2_reassemble_fragments(st, md);
3
Calling 'ikev2_reassemble_fragments'
788 } else {
789 pb_stream *e_pbs = &md->chain[ISAKMP_NEXT_v2SK]->pbs;
790 /*
791 * If so impaired, clone the encrypted message before
792 * it gets decrypted in-place (but only once).
793 */
794 if (impair.replay_encrypted && !md->fake_clone) {
795 libreswan_log("IMPAIR: cloning incoming encrypted message and scheduling its replay")loglog(RC_LOG, "IMPAIR: cloning incoming encrypted message and scheduling its replay"
)
;
796 schedule_md_event("replay encrypted message",
797 clone_raw_md(md, "copy of encrypted message"));
798 }
799 if (impair.corrupt_encrypted && !md->fake_clone) {
800 libreswan_log("IMPAIR: corrupting incoming encrypted message's SK payload's first byte")loglog(RC_LOG, "IMPAIR: corrupting incoming encrypted message's SK payload's first byte"
)
;
801 *e_pbs->cur = ~(*e_pbs->cur);
802 }
803
804 chunk_t c = chunk2(md->packet_pbs.start,
805 e_pbs->roof - md->packet_pbs.start);
806 ok = ikev2_verify_and_decrypt_sk_payload(ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_message.c" ,
.line = 806}
), md, &c,
807 e_pbs->cur - md->packet_pbs.start);
808 md->chain[ISAKMP_NEXT_v2SK]->pbs = same_chunk_as_in_pbs(c, "decrypted SK payload");
809 }
810
811 dbg("#%lu ikev2 %s decrypt %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("#%lu ikev2 %s decrypt %s", st->st_serialno
, enum_name(&ikev2_exchange_names, md->hdr.isa_xchg), ok
? "success" : "failed"); } }
812 st->st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("#%lu ikev2 %s decrypt %s", st->st_serialno
, enum_name(&ikev2_exchange_names, md->hdr.isa_xchg), ok
? "success" : "failed"); } }
813 enum_name(&ikev2_exchange_names, md->hdr.isa_xchg),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("#%lu ikev2 %s decrypt %s", st->st_serialno
, enum_name(&ikev2_exchange_names, md->hdr.isa_xchg), ok
? "success" : "failed"); } }
814 ok ? "success" : "failed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("#%lu ikev2 %s decrypt %s", st->st_serialno
, enum_name(&ikev2_exchange_names, md->hdr.isa_xchg), ok
? "success" : "failed"); } }
;
815
816 return ok;
817}
818
819/*
820 * IKEv2 fragments:
821 *
822 * 1 2 3
823 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
824 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
825 * | Next Payload |C| RESERVED | Payload Length |
826 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
827 * | Fragment Number | Total Fragments |
828 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
829 * | Initialization Vector |
830 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
831 * ~ Encrypted content ~
832 * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
833 * | | Padding (0-255 octets) |
834 * +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
835 * | | Pad Length |
836 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
837 * ~ Integrity Checksum Data ~
838 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
839 *
840
841 *
842 */
843
844static bool_Bool record_outbound_fragment(struct logger *logger,
845 struct ike_sa *ike,
846 const struct isakmp_hdr *hdr,
847 enum next_payload_types_ikev2 skf_np,
848 struct v2_outgoing_fragment **fragp,
849 chunk_t *fragment, /* read-only */
850 unsigned int number, unsigned int total,
851 const char *desc)
852{
853 /* make sure HDR is at start of a clean buffer */
854 unsigned char frag_buffer[PMAX(MIN_MAX_UDP_DATA_v4, MIN_MAX_UDP_DATA_v6)(((576 - 20)) >= ((1280 - 48)) ? ((576 - 20)) : ((1280 - 48
)))
];
855 struct pbs_outpacket_byte_stream frag_stream = open_pbs_out("reply frag packet",
856 frag_buffer, sizeof(frag_buffer),
857 logger);
858
859 /* HDR out */
860
861 pb_stream rbody;
862 if (!out_struct(hdr, &isakmp_hdr_desc, &frag_stream,
863 &rbody))
864 return false0;
865
866 /*
867 * Fake up an SK payload description sufficient to fool the
868 * encryption code.
869 *
870 * While things are close, they are not identical - an SKF
871 * payload header has extra fields and, for the first
872 * fragment, forces the Next Payload.
873 */
874
875 v2SK_payload_t skf = {
876 .ike = ike,
877 .payload = {
878 .ptr = rbody.cur,
879 .len = 0 /* computed at end; set here to silence GCC 4.8.5 */
880 }
881 };
882
883 /*
884 * emit SKF header, save location.
885 *
886 * In the first fragment, .NP is set to the SK payload's next
887 * payload type.
888 */
889
890 const struct ikev2_skf e = {
891 .isaskf_np = skf_np, /* needed */
892 .isaskf_critical = build_ikev2_critical(false0),
893 .isaskf_number = number,
894 .isaskf_total = total,
895 };
896 if (!out_struct(&e, &ikev2_skf_desc, &rbody, &skf.pbs))
897 return false0;
898
899 /* emit IV and save location */
900
901 if (!emit_v2SK_iv(&skf)) {
902 log_message(RC_LOG, logger,
903 "error initializing IV for encrypted %s message",
904 desc);
905 return false0;
906 }
907
908 /* save cleartext start */
909
910 skf.cleartext.ptr = skf.pbs.cur;
911
912 /* output the fragment */
913
914 if (!pbs_out_hunk(*fragment, &skf.pbs,({ typeof(*fragment) hunk_ = *fragment; struct packet_byte_stream
*outs_ = &skf.pbs; diag_t d_ = pbs_out_raw(outs_, hunk_.
ptr, hunk_.len, ("cleartext fragment")); if (d_ != ((void*)0)
) { log_diag(RC_LOG_SERIOUS, outs_->out_logger, &d_, "%s"
, ""); } d_ == ((void*)0); })
915 "cleartext fragment")({ typeof(*fragment) hunk_ = *fragment; struct packet_byte_stream
*outs_ = &skf.pbs; diag_t d_ = pbs_out_raw(outs_, hunk_.
ptr, hunk_.len, ("cleartext fragment")); if (d_ != ((void*)0)
) { log_diag(RC_LOG_SERIOUS, outs_->out_logger, &d_, "%s"
, ""); } d_ == ((void*)0); })
)
916 return false0;
917
918 if (!close_v2SK_payload(&skf)) {
919 return false0;
920 }
921
922 close_output_pbs(&rbody);
923 close_output_pbs(&frag_stream);
924
925 stf_status ret = encrypt_v2SK_payload(&skf);
926 if (ret != STF_OK) {
927 log_message(RC_LOG, logger, "error encrypting fragment %u", number);
928 return false0;
929 }
930
931 dbg("recording fragment %u", number){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("recording fragment %u", number); } }
;
932 record_v2_outgoing_fragment(&frag_stream, desc, fragp);
933 return true1;
934}
935
936static bool_Bool record_outbound_fragments(const pb_stream *rbody,
937 v2SK_payload_t *sk,
938 const char *desc,
939 struct v2_outgoing_fragment **frags)
940{
941 free_v2_outgoing_fragments(frags);
942
943 /*
944 * fragment contents:
945 * - sometimes: NON_ESP_MARKER (RFC3948) (NON_ESP_MARKER_SIZE) (4)
946 * - always: isakmp header (NSIZEOF_isakmp_hdr) (28)
947 * - always: ikev2_skf header (NSIZEOF_ikev2_skf) (8)
948 * - variable: IV (no IV is longer than SHA2_512_DIGEST_SIZE) (64 or less)
949 * - variable: fragment's data
950 * - variable: padding (no padding is longer than MAX_CBC_BLOCK_SIZE) (16 or less)
951 */
952
953 /*
954 * XXX: this math seems very contrived, can the fragment()
955 * function above be left to do the computation on-the-fly?
956 */
957
958 unsigned int len = endpoint_type(&sk->ike->sa.st_remote_endpoint)->ikev2_max_fragment_size;
959
960 /*
961 * If we are doing NAT, so that the other end doesn't mistake
962 * this message for ESP, each message needs a non-ESP_Marker
963 * prefix.
964 */
965 if (sk->ike->sa.st_interface != NULL((void*)0) && sk->ike->sa.st_interface->esp_encapsulation_enabled)
966 len -= NON_ESP_MARKER_SIZE4;
967
968 len -= NSIZEOF_isakmp_hdr28 + NSIZEOF_ikev2_skf8;
969
970 len -= (encrypt_desc_is_aead(sk->ike->sa.st_oakley.ta_encrypt)
971 ? sk->ike->sa.st_oakley.ta_encrypt->aead_tag_size
972 : sk->ike->sa.st_oakley.ta_integ->integ_output_size);
973
974 if (sk->ike->sa.st_oakley.ta_encrypt->pad_to_blocksize)
975 len &= ~(sk->ike->sa.st_oakley.ta_encrypt->enc_blocksize - 1);
976
977 len -= 2; /* ??? what's this? */
978
979 passert(sk->cleartext.len != 0){ _Bool assertion__ = sk->cleartext.len != 0; if (!assertion__
) { lsw_passert_fail((where_t) { .func = __func__, .basename =
"ikev2_message.c" , .line = 979}, "%s", "sk->cleartext.len != 0"
); } }
;
980
981 unsigned int nfrags = (sk->cleartext.len + len - 1) / len;
982
983 if (nfrags > MAX_IKE_FRAGMENTS32) {
984 log_message(RC_LOG_SERIOUS, sk->logger,
985 "fragmenting this %zu byte message into %u byte chunks leads to too many frags",
986 sk->cleartext.len, len);
987 return false0;
988 }
989
990 /*
991 * Extract the hdr from the original unfragmented message.
992 * Set it up for auto-update of it's next payload field chain.
993 */
994 struct isakmp_hdr hdr;
995 {
996 pb_stream pbs;
997 init_pbs(&pbs, rbody->start, pbs_offset(rbody)((size_t)((rbody)->cur - (rbody)->start)), "sk hdr");
998 if (!in_struct(&hdr, &isakmp_hdr_desc, &pbs, NULL((void*)0))) {
999 return false0;
1000 }
1001 }
1002 hdr.isa_np = ISAKMP_NEXT_v2NONE; /* clear NP */
1003
1004 /*
1005 * Extract the SK's next payload field from the original
1006 * unfragmented message. This is used as the first SKF's NP
1007 * field, the rest have NP=NONE(0).
1008 */
1009 enum next_payload_types_ikev2 skf_np;
1010 {
1011 pb_stream pbs = same_chunk_as_in_pbs(sk->payload, "sk");
1012 struct ikev2_generic e;
1013 if (!in_struct(&e, &ikev2_sk_desc, &pbs, NULL((void*)0))) {
1014 return false0;
1015 }
1016 skf_np = e.isag_np;
1017 }
1018
1019 unsigned int number = 1;
1020 unsigned int offset = 0;
1021
1022 struct v2_outgoing_fragment **frag = frags;
1023 while (true1) {
1024 passert(*frag == NULL){ _Bool assertion__ = *frag == ((void*)0); if (!assertion__) {
lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_message.c"
, .line = 1024}, "%s", "*frag == NULL"); } }
;
1025 chunk_t fragment = chunk2(sk->cleartext.ptr + offset,
1026 PMIN(sk->cleartext.len - offset, len)((sk->cleartext.len - offset) <= (len) ? (sk->cleartext
.len - offset) : (len))
);
1027 if (!record_outbound_fragment(sk->logger, sk->ike, &hdr, skf_np, frag,
1028 &fragment, number, nfrags, desc)) {
1029 return false0;
1030 }
1031 frag = &(*frag)->next;
1032
1033 offset += fragment.len;
1034 number++;
1035 skf_np = ISAKMP_NEXT_v2NONE;
1036
1037 if (offset >= sk->cleartext.len) {
1038 break;
1039 }
1040 }
1041
1042 return true1;
1043}
1044
1045/*
1046 * Record the message ready for sending. If needed, first fragment
1047 * it.
1048 *
1049 * ST is where to save the outgoing message. XXX: Currently it is
1050 * always the parent. But that breaks when trying to juggle multiple
1051 * children trying to exchange messages.
1052 */
1053
1054stf_status record_v2SK_message(pb_stream *msg,
1055 v2SK_payload_t *sk,
1056 const char *what,
1057 enum message_role message)
1058{
1059 size_t len = pbs_offset(msg)((size_t)((msg)->cur - (msg)->start));
1060
1061 /*
1062 * If we are doing NAT, so that the other end doesn't mistake
1063 * this message for ESP, each message needs a non-ESP_Marker
1064 * prefix.
1065 */
1066 if (!pexpect(sk->ike->sa.st_interface != NULL)({ _Bool assertion__ = sk->ike->sa.st_interface != ((void
*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__
, .basename = "ikev2_message.c" , .line = 1066}, "%s", "sk->ike->sa.st_interface != NULL"
); } assertion__; })
&&
1067 sk->ike->sa.st_interface->esp_encapsulation_enabled)
1068 len += NON_ESP_MARKER_SIZE4;
1069
1070 /* IPv4 and IPv6 have different fragment sizes */
1071 if (sk->ike->sa.st_interface->protocol == &ip_protocol_udp &&
1072 LIN(POLICY_IKE_FRAG_ALLOW, sk->ike->sa.st_connection->policy)(((((lset_t)1 << (POLICY_IKE_FRAG_ALLOW_IX))) & (sk
->ike->sa.st_connection->policy)) == (((lset_t)1 <<
(POLICY_IKE_FRAG_ALLOW_IX))))
&&
1073 sk->ike->sa.st_seen_fragmentation_supported &&
1074 len >= endpoint_type(&sk->ike->sa.st_remote_endpoint)->ikev2_max_fragment_size) {
1075 struct v2_outgoing_fragment **frags = &sk->ike->sa.st_v2_outgoing[message];
1076 if (!record_outbound_fragments(msg, sk, what, frags)) {
1077 dbg("record outbound fragments failed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("record outbound fragments failed"); } }
;
1078 return STF_INTERNAL_ERROR;
1079 }
1080 } else {
1081 if (encrypt_v2SK_payload(sk) != STF_OK) {
1082 log_message(RC_LOG, sk->logger,
1083 "error encrypting %s message", what);
1084 return STF_INTERNAL_ERROR;
1085 }
1086 dbg("recording outgoing fragment failed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("recording outgoing fragment failed"); } }
;
1087 record_v2_message(sk->ike, msg, what, message);
1088 }
1089 return STF_OK;
1090}
1091
1092struct ikev2_id build_v2_id_payload(const struct end *end, shunk_t *body,
1093 const char *what, struct logger *logger)
1094{
1095 struct ikev2_id id_header = {
1096 .isai_type = id_to_payload(&end->id, &end->host_addr, body),
1097 .isai_critical = build_ikev2_critical(false0),
1098 };
1099 if (impair.send_nonzero_reserved_id) {
1100 log_message(RC_LOG, logger, "IMPAIR: setting reserved byte 3 of %s to 0x%02x",
1101 what, ISAKMP_PAYLOAD_LIBRESWAN_BOGUS0x01);
1102 id_header.isai_res3 = ISAKMP_PAYLOAD_LIBRESWAN_BOGUS0x01;
1103 }
1104 return id_header;
1105}