|
|
d8e7ea |
diff -Naur libreswan-3.29-orig/include/impair.h libreswan-3.29/include/impair.h
|
|
|
d8e7ea |
--- libreswan-3.29-orig/include/impair.h 2019-06-10 10:22:04.000000000 -0400
|
|
|
d8e7ea |
+++ libreswan-3.29/include/impair.h 2019-06-11 19:22:39.786283961 -0400
|
|
|
d8e7ea |
@@ -1,6 +1,6 @@
|
|
|
d8e7ea |
-/* impair operation
|
|
|
d8e7ea |
+/* impair operation, for libreswan
|
|
|
d8e7ea |
*
|
|
|
d8e7ea |
- * Copyright (C) 2019 Andrew Cagney <cagney@gnu.org>
|
|
|
d8e7ea |
+ * Copyright (C) 2018-2019 Andrew Cagney
|
|
|
d8e7ea |
*
|
|
|
d8e7ea |
* This program is free software; you can redistribute it and/or modify it
|
|
|
d8e7ea |
* under the terms of the GNU General Public License as published by the
|
|
|
d8e7ea |
@@ -22,9 +22,7 @@
|
|
|
d8e7ea |
#include "lswcdefs.h"
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/*
|
|
|
d8e7ea |
- * How to impair something. This is just the start ...
|
|
|
d8e7ea |
- *
|
|
|
d8e7ea |
- * Extra enums go here.
|
|
|
d8e7ea |
+ * Meddle with the contents of a payload.
|
|
|
d8e7ea |
*/
|
|
|
d8e7ea |
|
|
|
d8e7ea |
enum send_impairment {
|
|
|
d8e7ea |
@@ -35,6 +33,21 @@
|
|
|
d8e7ea |
SEND_ROOF, /* >= ROOF -> <number> */
|
|
|
d8e7ea |
};
|
|
|
d8e7ea |
|
|
|
d8e7ea |
+/*
|
|
|
d8e7ea |
+ * Meddle with a specific exchange.
|
|
|
d8e7ea |
+ */
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+enum exchange_impairment {
|
|
|
d8e7ea |
+ NO_EXCHANGE = 0,
|
|
|
d8e7ea |
+ NOTIFICATION_EXCHANGE,
|
|
|
d8e7ea |
+ QUICK_EXCHANGE,
|
|
|
d8e7ea |
+ XAUTH_EXCHANGE,
|
|
|
d8e7ea |
+ DELETE_EXCHANGE,
|
|
|
d8e7ea |
+};
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+/*
|
|
|
d8e7ea |
+ * add more here
|
|
|
d8e7ea |
+ */
|
|
|
d8e7ea |
#if 0
|
|
|
d8e7ea |
enum xxx_impair ...;
|
|
|
d8e7ea |
#endif
|
|
|
d8e7ea |
@@ -53,6 +66,10 @@
|
|
|
d8e7ea |
extern enum send_impairment impair_ike_key_length_attribute;
|
|
|
d8e7ea |
extern enum send_impairment impair_child_key_length_attribute;
|
|
|
d8e7ea |
|
|
|
d8e7ea |
+extern enum send_impairment impair_v1_hash_payload;
|
|
|
d8e7ea |
+extern enum exchange_impairment impair_v1_hash_exchange;
|
|
|
d8e7ea |
+extern bool impair_v1_hash_check;
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
/*
|
|
|
d8e7ea |
* What whack sends across the wire for a impair.
|
|
|
d8e7ea |
*/
|
|
|
d8e7ea |
diff -Naur libreswan-3.29-orig/lib/libswan/impair.c libreswan-3.29/lib/libswan/impair.c
|
|
|
d8e7ea |
--- libreswan-3.29-orig/lib/libswan/impair.c 2019-06-10 10:22:04.000000000 -0400
|
|
|
d8e7ea |
+++ libreswan-3.29/lib/libswan/impair.c 2019-06-11 19:22:54.290445191 -0400
|
|
|
d8e7ea |
@@ -1,5 +1,4 @@
|
|
|
d8e7ea |
-/*
|
|
|
d8e7ea |
- * impair constants, for libreswan
|
|
|
d8e7ea |
+/* impair constants, for libreswan
|
|
|
d8e7ea |
*
|
|
|
d8e7ea |
* Copyright (C) 2017-2019 Andrew Cagney <cagney@gnu.org>
|
|
|
d8e7ea |
* Copyright (C) 2019-2019 Paul Wouters <pwouters@redhat.com>
|
|
|
d8e7ea |
@@ -125,6 +124,19 @@
|
|
|
d8e7ea |
static const struct keywords send_impairment_keywords =
|
|
|
d8e7ea |
DIRECT_KEYWORDS("send impaired content", send_impairment_value);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
+static const struct keyword exchange_impairment_value[] = {
|
|
|
d8e7ea |
+#define S(E, H) [E##_EXCHANGE] = { .name = "SEND_" #E, .sname = #E, .value = E##_EXCHANGE, .details = H, }
|
|
|
d8e7ea |
+ S(NO, "do not modify exchanges"),
|
|
|
d8e7ea |
+ S(QUICK, "modify IKEv1 QUICK exchanges"),
|
|
|
d8e7ea |
+ S(XAUTH, "modify IKEv1 XAUTH exchanges"),
|
|
|
d8e7ea |
+ S(NOTIFICATION, "modify notification (informational) exchanges"),
|
|
|
d8e7ea |
+ S(DELETE, "modify delete exchanges"),
|
|
|
d8e7ea |
+#undef S
|
|
|
d8e7ea |
+};
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+static const struct keywords exchange_impairment_keywords =
|
|
|
d8e7ea |
+ DIRECT_KEYWORDS("impaire exchange content", exchange_impairment_value);
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
struct impairment {
|
|
|
d8e7ea |
const char *what;
|
|
|
d8e7ea |
const char *help;
|
|
|
d8e7ea |
@@ -182,6 +194,27 @@
|
|
|
d8e7ea |
.how_keynum = &send_impairment_keywords,
|
|
|
d8e7ea |
V(impair_child_key_length_attribute),
|
|
|
d8e7ea |
},
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+ /*
|
|
|
d8e7ea |
+ * IKEv1: hash payloads
|
|
|
d8e7ea |
+ */
|
|
|
d8e7ea |
+ {
|
|
|
d8e7ea |
+ .what = "v1-hash-check",
|
|
|
d8e7ea |
+ .help = "disable check of incoming IKEv1 hash payload",
|
|
|
d8e7ea |
+ V(impair_emitting),
|
|
|
d8e7ea |
+ },
|
|
|
d8e7ea |
+ {
|
|
|
d8e7ea |
+ .what = "v1-hash-payload",
|
|
|
d8e7ea |
+ .help = "corrupt the outgoing HASH payload",
|
|
|
d8e7ea |
+ .how_keynum = &send_impairment_keywords,
|
|
|
d8e7ea |
+ V(impair_v1_hash_payload),
|
|
|
d8e7ea |
+ },
|
|
|
d8e7ea |
+ {
|
|
|
d8e7ea |
+ .what = "v1-hash-exchange",
|
|
|
d8e7ea |
+ .help = "the outgoing exchange that should contain the corrupted HASH payload",
|
|
|
d8e7ea |
+ .how_keynum = &exchange_impairment_keywords,
|
|
|
d8e7ea |
+ V(impair_v1_hash_exchange),
|
|
|
d8e7ea |
+ },
|
|
|
d8e7ea |
};
|
|
|
d8e7ea |
|
|
|
d8e7ea |
static void help(const char *prefix, const struct impairment *cr)
|
|
|
d8e7ea |
@@ -522,8 +555,9 @@
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/*
|
|
|
d8e7ea |
- * declare these last so that all references are forced to use the
|
|
|
d8e7ea |
- * declaration in the header.
|
|
|
d8e7ea |
+ * XXX: define these at the end of the file so that all references are
|
|
|
d8e7ea |
+ * forced to use the declaration in the header (help stop code
|
|
|
d8e7ea |
+ * refering to the wrong variable?).
|
|
|
d8e7ea |
*/
|
|
|
d8e7ea |
|
|
|
d8e7ea |
bool impair_revival;
|
|
|
d8e7ea |
@@ -531,3 +565,6 @@
|
|
|
d8e7ea |
enum send_impairment impair_ke_payload;
|
|
|
d8e7ea |
enum send_impairment impair_ike_key_length_attribute;
|
|
|
d8e7ea |
enum send_impairment impair_child_key_length_attribute;
|
|
|
d8e7ea |
+bool impair_v1_hash_check;
|
|
|
d8e7ea |
+enum send_impairment impair_v1_hash_payload;
|
|
|
d8e7ea |
+enum exchange_impairment impair_v1_hash_exchange;
|
|
|
d8e7ea |
diff -Naur libreswan-3.29-orig/programs/pluto/ikev1.c libreswan-3.29/programs/pluto/ikev1.c
|
|
|
d8e7ea |
--- libreswan-3.29-orig/programs/pluto/ikev1.c 2019-06-10 10:22:04.000000000 -0400
|
|
|
d8e7ea |
+++ libreswan-3.29/programs/pluto/ikev1.c 2019-06-11 19:27:44.516665524 -0400
|
|
|
d8e7ea |
@@ -157,6 +157,7 @@
|
|
|
d8e7ea |
#include "ikev1_dpd.h"
|
|
|
d8e7ea |
#include "hostpair.h"
|
|
|
d8e7ea |
#include "ip_address.h"
|
|
|
d8e7ea |
+#include "ikev1_hash.h"
|
|
|
d8e7ea |
|
|
|
d8e7ea |
#ifdef HAVE_NM
|
|
|
d8e7ea |
#include "kernel.h"
|
|
|
d8e7ea |
@@ -181,6 +182,8 @@
|
|
|
d8e7ea |
lset_t opt_payloads; /* optional payloads (any mumber) */
|
|
|
d8e7ea |
enum event_type timeout_event;
|
|
|
d8e7ea |
ikev1_state_transition_fn *processor;
|
|
|
d8e7ea |
+ const char *message;
|
|
|
d8e7ea |
+ enum v1_hash_type hash_type;
|
|
|
d8e7ea |
};
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* State Microcode Flags, in several groups */
|
|
|
d8e7ea |
@@ -255,6 +258,7 @@
|
|
|
d8e7ea |
static const struct state_v1_microcode v1_state_microcode_table[] = {
|
|
|
d8e7ea |
|
|
|
d8e7ea |
#define P(n) LELEM(ISAKMP_NEXT_ ##n)
|
|
|
d8e7ea |
+#define FM(F) .processor = F, .message = #F
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/***** Phase 1 Main Mode *****/
|
|
|
d8e7ea |
|
|
|
d8e7ea |
@@ -266,7 +270,9 @@
|
|
|
d8e7ea |
{ STATE_MAIN_R0, STATE_MAIN_R1,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_REPLY,
|
|
|
d8e7ea |
P(SA), P(VID) | P(CR),
|
|
|
d8e7ea |
- EVENT_SO_DISCARD, main_inI1_outR1 },
|
|
|
d8e7ea |
+ EVENT_SO_DISCARD,
|
|
|
d8e7ea |
+ FM(main_inI1_outR1),
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* STATE_MAIN_I1: R1 --> I2
|
|
|
d8e7ea |
* HDR, SA --> auth dependent
|
|
|
d8e7ea |
@@ -281,7 +287,9 @@
|
|
|
d8e7ea |
{ STATE_MAIN_I1, STATE_MAIN_I2,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_INITIATOR | SMF_REPLY,
|
|
|
d8e7ea |
P(SA), P(VID) | P(CR),
|
|
|
d8e7ea |
- EVENT_RETRANSMIT, main_inR1_outI2 },
|
|
|
d8e7ea |
+ EVENT_RETRANSMIT,
|
|
|
d8e7ea |
+ FM(main_inR1_outI2),
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* STATE_MAIN_R1: I2 --> R2
|
|
|
d8e7ea |
* SMF_PSK_AUTH, SMF_DS_AUTH: HDR, KE, Ni --> HDR, KE, Nr
|
|
|
d8e7ea |
@@ -294,17 +302,23 @@
|
|
|
d8e7ea |
{ STATE_MAIN_R1, STATE_MAIN_R2,
|
|
|
d8e7ea |
SMF_PSK_AUTH | SMF_DS_AUTH | SMF_REPLY | SMF_RETRANSMIT_ON_DUPLICATE,
|
|
|
d8e7ea |
P(KE) | P(NONCE), P(VID) | P(CR) | P(NATD_RFC),
|
|
|
d8e7ea |
- EVENT_RETRANSMIT, main_inI2_outR2 },
|
|
|
d8e7ea |
+ EVENT_RETRANSMIT,
|
|
|
d8e7ea |
+ FM(main_inI2_outR2),
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_MAIN_R1, STATE_UNDEFINED,
|
|
|
d8e7ea |
SMF_PKE_AUTH | SMF_REPLY | SMF_RETRANSMIT_ON_DUPLICATE,
|
|
|
d8e7ea |
P(KE) | P(ID) | P(NONCE), P(VID) | P(CR) | P(HASH),
|
|
|
d8e7ea |
- EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
|
|
|
d8e7ea |
+ EVENT_RETRANSMIT,
|
|
|
d8e7ea |
+ FM(unexpected) /* ??? not yet implemented */,
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_MAIN_R1, STATE_UNDEFINED,
|
|
|
d8e7ea |
SMF_RPKE_AUTH | SMF_REPLY | SMF_RETRANSMIT_ON_DUPLICATE,
|
|
|
d8e7ea |
P(NONCE) | P(KE) | P(ID), P(VID) | P(CR) | P(HASH) | P(CERT),
|
|
|
d8e7ea |
- EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
|
|
|
d8e7ea |
+ EVENT_RETRANSMIT,
|
|
|
d8e7ea |
+ FM(unexpected) /* ??? not yet implemented */,
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* for states from here on, output message must be encrypted */
|
|
|
d8e7ea |
|
|
|
d8e7ea |
@@ -319,17 +333,24 @@
|
|
|
d8e7ea |
{ STATE_MAIN_I2, STATE_MAIN_I3,
|
|
|
d8e7ea |
SMF_PSK_AUTH | SMF_DS_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY,
|
|
|
d8e7ea |
P(KE) | P(NONCE), P(VID) | P(CR) | P(NATD_RFC),
|
|
|
d8e7ea |
- EVENT_RETRANSMIT, main_inR2_outI3 },
|
|
|
d8e7ea |
+ EVENT_RETRANSMIT,
|
|
|
d8e7ea |
+ FM(main_inR2_outI3),
|
|
|
d8e7ea |
+ /* calls main_mode_hash() after DH */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_MAIN_I2, STATE_UNDEFINED,
|
|
|
d8e7ea |
SMF_PKE_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY,
|
|
|
d8e7ea |
P(KE) | P(ID) | P(NONCE), P(VID) | P(CR),
|
|
|
d8e7ea |
- EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
|
|
|
d8e7ea |
+ EVENT_RETRANSMIT,
|
|
|
d8e7ea |
+ FM(unexpected) /* ??? not yet implemented */,
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_MAIN_I2, STATE_UNDEFINED,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY,
|
|
|
d8e7ea |
P(NONCE) | P(KE) | P(ID), P(VID) | P(CR),
|
|
|
d8e7ea |
- EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
|
|
|
d8e7ea |
+ EVENT_RETRANSMIT,
|
|
|
d8e7ea |
+ FM(unexpected) /* ??? not yet implemented */,
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* for states from here on, input message must be encrypted */
|
|
|
d8e7ea |
|
|
|
d8e7ea |
@@ -342,20 +363,34 @@
|
|
|
d8e7ea |
SMF_PSK_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED |
|
|
|
d8e7ea |
SMF_REPLY | SMF_RELEASE_PENDING_P2,
|
|
|
d8e7ea |
P(ID) | P(HASH), P(VID) | P(CR),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, main_inI3_outR3 },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(main_inI3_outR3),
|
|
|
d8e7ea |
+ /* calls oakley_id_and_auth() which calls main_mode_hash() */
|
|
|
d8e7ea |
+ /* RFC 2409: 5. Exchanges & 5.2 Phase 1 Authenticated With Public Key Encryption
|
|
|
d8e7ea |
+ HASH_I = prf(SKEYID, g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b ) */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_MAIN_R2, STATE_MAIN_R3,
|
|
|
d8e7ea |
SMF_DS_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED |
|
|
|
d8e7ea |
SMF_REPLY | SMF_RELEASE_PENDING_P2,
|
|
|
d8e7ea |
P(ID) | P(SIG), P(VID) | P(CR) | P(CERT),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, main_inI3_outR3 },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(main_inI3_outR3),
|
|
|
d8e7ea |
+ /* calls oakley_id_and_auth() which calls main_mode_hash() */
|
|
|
d8e7ea |
+ /* RFC 2409: 5. Exchanges & 5.1 IKE Phase 1 Authenticated With Signatures
|
|
|
d8e7ea |
+ HASH_I = prf(SKEYID, g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b )
|
|
|
d8e7ea |
+ SIG_I = SIGN(HASH_I) *",
|
|
|
d8e7ea |
+ SIG_I = SIGN(HASH_I) */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_MAIN_R2, STATE_UNDEFINED,
|
|
|
d8e7ea |
SMF_PKE_AUTH | SMF_RPKE_AUTH | SMF_FIRST_ENCRYPTED_INPUT |
|
|
|
d8e7ea |
SMF_ENCRYPTED |
|
|
|
d8e7ea |
SMF_REPLY | SMF_RELEASE_PENDING_P2,
|
|
|
d8e7ea |
P(HASH), P(VID) | P(CR),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, unexpected /* ??? not yet implemented */ },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(unexpected) /* ??? not yet implemented */,
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* STATE_MAIN_I3: R3 --> done
|
|
|
d8e7ea |
* SMF_PSK_AUTH: HDR*, IDr1, HASH_R --> done
|
|
|
d8e7ea |
@@ -367,31 +402,48 @@
|
|
|
d8e7ea |
SMF_PSK_AUTH | SMF_INITIATOR |
|
|
|
d8e7ea |
SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2,
|
|
|
d8e7ea |
P(ID) | P(HASH), P(VID) | P(CR),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, main_inR3 },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(main_inR3),
|
|
|
d8e7ea |
+ /* calls oakley_id_and_auth() which calls main_mode_hash() */
|
|
|
d8e7ea |
+ /* RFC 2409: 5. Exchanges & 5.2 Phase 1 Authenticated With Public Key Encryption
|
|
|
d8e7ea |
+ HASH_R = prf(SKEYID, g^xr | g^xi | CKY-R | CKY-I | SAi_b | IDir_b ) */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_MAIN_I3, STATE_MAIN_I4,
|
|
|
d8e7ea |
SMF_DS_AUTH | SMF_INITIATOR |
|
|
|
d8e7ea |
SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2,
|
|
|
d8e7ea |
P(ID) | P(SIG), P(VID) | P(CR) | P(CERT),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, main_inR3 },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(main_inR3),
|
|
|
d8e7ea |
+ /* calls oakley_id_and_auth() which calls main_mode_hash() */
|
|
|
d8e7ea |
+ /* RFC 2409: 5. Exchanges & 5.1 IKE Phase 1 Authenticated With Signatures
|
|
|
d8e7ea |
+ HASH_R = prf(SKEYID, g^xr | g^xi | CKY-R | CKY-I | SAi_b | IDir_b )
|
|
|
d8e7ea |
+ SIG_R = SIGN(HASH_R) */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_MAIN_I3, STATE_UNDEFINED,
|
|
|
d8e7ea |
SMF_PKE_AUTH | SMF_RPKE_AUTH | SMF_INITIATOR |
|
|
|
d8e7ea |
SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2,
|
|
|
d8e7ea |
P(HASH), P(VID) | P(CR),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, unexpected /* ??? not yet implemented */ },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(unexpected) /* ??? not yet implemented */,
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* STATE_MAIN_R3: can only get here due to packet loss */
|
|
|
d8e7ea |
{ STATE_MAIN_R3, STATE_UNDEFINED,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RETRANSMIT_ON_DUPLICATE,
|
|
|
d8e7ea |
LEMPTY, LEMPTY,
|
|
|
d8e7ea |
- EVENT_NULL, unexpected },
|
|
|
d8e7ea |
+ EVENT_NULL,
|
|
|
d8e7ea |
+ FM(unexpected),
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* STATE_MAIN_I4: can only get here due to packet loss */
|
|
|
d8e7ea |
{ STATE_MAIN_I4, STATE_UNDEFINED,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED,
|
|
|
d8e7ea |
LEMPTY, LEMPTY,
|
|
|
d8e7ea |
- EVENT_NULL, unexpected },
|
|
|
d8e7ea |
+ EVENT_NULL,
|
|
|
d8e7ea |
+ FM(unexpected),
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/***** Phase 1 Aggressive Mode *****/
|
|
|
d8e7ea |
|
|
|
d8e7ea |
@@ -413,7 +465,10 @@
|
|
|
d8e7ea |
{ STATE_AGGR_R0, STATE_AGGR_R1,
|
|
|
d8e7ea |
SMF_PSK_AUTH | SMF_DS_AUTH | SMF_REPLY,
|
|
|
d8e7ea |
P(SA) | P(KE) | P(NONCE) | P(ID), P(VID) | P(NATD_RFC),
|
|
|
d8e7ea |
- EVENT_SO_DISCARD, aggr_inI1_outR1 },
|
|
|
d8e7ea |
+ EVENT_SO_DISCARD,
|
|
|
d8e7ea |
+ FM(aggr_inI1_outR1),
|
|
|
d8e7ea |
+ /* N/A */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* STATE_AGGR_I1:
|
|
|
d8e7ea |
* SMF_PSK_AUTH: HDR, SA, KE, Nr, IDir, HASH_R
|
|
|
d8e7ea |
@@ -425,13 +480,24 @@
|
|
|
d8e7ea |
SMF_PSK_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY |
|
|
|
d8e7ea |
SMF_RELEASE_PENDING_P2,
|
|
|
d8e7ea |
P(SA) | P(KE) | P(NONCE) | P(ID) | P(HASH), P(VID) | P(NATD_RFC),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, aggr_inR1_outI2 },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(aggr_inR1_outI2),
|
|
|
d8e7ea |
+ /* after DH calls oakley_id_and_auth() which calls main_mode_hash() */
|
|
|
d8e7ea |
+ /* RFC 2409: 5. Exchanges & 5.2 Phase 1 Authenticated With Public Key Encryption
|
|
|
d8e7ea |
+ HASH_R = prf(SKEYID, g^xr | g^xi | CKY-R | CKY-I | SAi_b | IDir_b ) */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_AGGR_I1, STATE_AGGR_I2,
|
|
|
d8e7ea |
SMF_DS_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY |
|
|
|
d8e7ea |
SMF_RELEASE_PENDING_P2,
|
|
|
d8e7ea |
P(SA) | P(KE) | P(NONCE) | P(ID) | P(SIG), P(VID) | P(NATD_RFC),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, aggr_inR1_outI2 },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(aggr_inR1_outI2),
|
|
|
d8e7ea |
+ /* after DH calls oakley_id_and_auth() which calls main_mode_hash() */
|
|
|
d8e7ea |
+ /* RFC 2409: 5. Exchanges & 5.1 IKE Phase 1 Authenticated With Signatures
|
|
|
d8e7ea |
+ HASH_R = prf(SKEYID, g^xr | g^xi | CKY-R | CKY-I | SAi_b | IDir_b )
|
|
|
d8e7ea |
+ SIG_R = SIGN(HASH_R) */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* STATE_AGGR_R1:
|
|
|
d8e7ea |
* SMF_PSK_AUTH: HDR*, HASH_I --> done
|
|
|
d8e7ea |
@@ -442,24 +508,39 @@
|
|
|
d8e7ea |
SMF_OUTPUT_ENCRYPTED | SMF_RELEASE_PENDING_P2 |
|
|
|
d8e7ea |
SMF_RETRANSMIT_ON_DUPLICATE,
|
|
|
d8e7ea |
P(HASH), P(VID) | P(NATD_RFC),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, aggr_inI2 },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(aggr_inI2),
|
|
|
d8e7ea |
+ /* calls oakley_id_and_auth() which calls main_mode_hash() */
|
|
|
d8e7ea |
+ /* RFC 2409: 5. Exchanges & 5.2 Phase 1 Authenticated With Public Key Encryption
|
|
|
d8e7ea |
+ HASH_I = prf(SKEYID, g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b ) */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_AGGR_R1, STATE_AGGR_R2,
|
|
|
d8e7ea |
SMF_DS_AUTH | SMF_FIRST_ENCRYPTED_INPUT |
|
|
|
d8e7ea |
SMF_OUTPUT_ENCRYPTED | SMF_RELEASE_PENDING_P2 |
|
|
|
d8e7ea |
SMF_RETRANSMIT_ON_DUPLICATE,
|
|
|
d8e7ea |
P(SIG), P(VID) | P(NATD_RFC),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, aggr_inI2 },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(aggr_inI2),
|
|
|
d8e7ea |
+ /* calls oakley_id_and_auth() which calls main_mode_hash() */
|
|
|
d8e7ea |
+ /* RFC 2409: 5. Exchanges & 5.1 IKE Phase 1 Authenticated With Signatures
|
|
|
d8e7ea |
+ HASH_I = prf(SKEYID, g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b )
|
|
|
d8e7ea |
+ SIG_I = SIGN(HASH_I) */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* STATE_AGGR_I2: can only get here due to packet loss */
|
|
|
d8e7ea |
{ STATE_AGGR_I2, STATE_UNDEFINED,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_INITIATOR | SMF_RETRANSMIT_ON_DUPLICATE,
|
|
|
d8e7ea |
- LEMPTY, LEMPTY, EVENT_NULL, unexpected },
|
|
|
d8e7ea |
+ LEMPTY, LEMPTY, EVENT_NULL,
|
|
|
d8e7ea |
+ FM(unexpected),
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* STATE_AGGR_R2: can only get here due to packet loss */
|
|
|
d8e7ea |
{ STATE_AGGR_R2, STATE_UNDEFINED,
|
|
|
d8e7ea |
SMF_ALL_AUTH,
|
|
|
d8e7ea |
- LEMPTY, LEMPTY, EVENT_NULL, unexpected },
|
|
|
d8e7ea |
+ LEMPTY, LEMPTY, EVENT_NULL,
|
|
|
d8e7ea |
+ FM(unexpected),
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/***** Phase 2 Quick Mode *****/
|
|
|
d8e7ea |
|
|
|
d8e7ea |
@@ -478,7 +559,11 @@
|
|
|
d8e7ea |
{ STATE_QUICK_R0, STATE_QUICK_R1,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY,
|
|
|
d8e7ea |
P(HASH) | P(SA) | P(NONCE), /* P(SA) | */ P(KE) | P(ID) | P(NATOA_RFC),
|
|
|
d8e7ea |
- EVENT_RETRANSMIT, quick_inI1_outR1 },
|
|
|
d8e7ea |
+ EVENT_RETRANSMIT,
|
|
|
d8e7ea |
+ FM(quick_inI1_outR1),
|
|
|
d8e7ea |
+ /* RFC 2409: 5.5 Phase 2 - Quick Mode:
|
|
|
d8e7ea |
+ HASH(1) = prf(SKEYID_a, M-ID | <rest>) */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_1, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* STATE_QUICK_I1:
|
|
|
d8e7ea |
* HDR*, HASH(2), SA, Nr [, KE ] [, IDci, IDcr ] -->
|
|
|
d8e7ea |
@@ -489,7 +574,11 @@
|
|
|
d8e7ea |
{ STATE_QUICK_I1, STATE_QUICK_I2,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED | SMF_REPLY,
|
|
|
d8e7ea |
P(HASH) | P(SA) | P(NONCE), /* P(SA) | */ P(KE) | P(ID) | P(NATOA_RFC),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, quick_inR1_outI2 },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(quick_inR1_outI2),
|
|
|
d8e7ea |
+ /* RFC 2409: 5.5 Phase 2 - Quick Mode:
|
|
|
d8e7ea |
+ HASH(2) = prf(SKEYID_a, M-ID | Ni_b | <rest>) */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_2, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* STATE_QUICK_R1: HDR*, HASH(3) --> done
|
|
|
d8e7ea |
* Installs outbound IPsec SAs, routing, etc.
|
|
|
d8e7ea |
@@ -497,20 +586,28 @@
|
|
|
d8e7ea |
{ STATE_QUICK_R1, STATE_QUICK_R2,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_ENCRYPTED,
|
|
|
d8e7ea |
P(HASH), LEMPTY,
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, quick_inI2 },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(quick_inI2),
|
|
|
d8e7ea |
+ /* RFC 2409: 5.5 Phase 2 - Quick Mode:
|
|
|
d8e7ea |
+ HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_3, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* STATE_QUICK_I2: can only happen due to lost packet */
|
|
|
d8e7ea |
{ STATE_QUICK_I2, STATE_UNDEFINED,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED |
|
|
|
d8e7ea |
SMF_RETRANSMIT_ON_DUPLICATE,
|
|
|
d8e7ea |
LEMPTY, LEMPTY,
|
|
|
d8e7ea |
- EVENT_NULL, unexpected },
|
|
|
d8e7ea |
+ EVENT_NULL,
|
|
|
d8e7ea |
+ FM(unexpected),
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* STATE_QUICK_R2: can only happen due to lost packet */
|
|
|
d8e7ea |
{ STATE_QUICK_R2, STATE_UNDEFINED,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_ENCRYPTED,
|
|
|
d8e7ea |
LEMPTY, LEMPTY,
|
|
|
d8e7ea |
- EVENT_NULL, unexpected },
|
|
|
d8e7ea |
+ EVENT_NULL,
|
|
|
d8e7ea |
+ FM(unexpected),
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/***** informational messages *****/
|
|
|
d8e7ea |
|
|
|
d8e7ea |
@@ -522,7 +619,9 @@
|
|
|
d8e7ea |
{ STATE_INFO, STATE_UNDEFINED,
|
|
|
d8e7ea |
SMF_ALL_AUTH,
|
|
|
d8e7ea |
LEMPTY, LEMPTY,
|
|
|
d8e7ea |
- EVENT_NULL, informational },
|
|
|
d8e7ea |
+ EVENT_NULL,
|
|
|
d8e7ea |
+ FM(informational),
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* Informational Exchange (RFC 2408 4.8):
|
|
|
d8e7ea |
* HDR* N/D
|
|
|
d8e7ea |
@@ -531,29 +630,41 @@
|
|
|
d8e7ea |
{ STATE_INFO_PROTECTED, STATE_UNDEFINED,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_ENCRYPTED,
|
|
|
d8e7ea |
P(HASH), LEMPTY,
|
|
|
d8e7ea |
- EVENT_NULL, informational },
|
|
|
d8e7ea |
+ EVENT_NULL,
|
|
|
d8e7ea |
+ FM(informational),
|
|
|
d8e7ea |
+ /* RFC 2409: 5.7 ISAKMP Informational Exchanges:
|
|
|
d8e7ea |
+ HASH(1) = prf(SKEYID_a, M-ID | N/D) */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_1, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_XAUTH_R0, STATE_XAUTH_R1,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_ENCRYPTED,
|
|
|
d8e7ea |
P(MCFG_ATTR) | P(HASH), P(VID),
|
|
|
d8e7ea |
- EVENT_NULL, xauth_inR0 }, /* Re-transmit may be done by previous state */
|
|
|
d8e7ea |
+ EVENT_NULL,
|
|
|
d8e7ea |
+ FM(xauth_inR0),
|
|
|
d8e7ea |
+ /* RFC ????: */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_1, }, /* Re-transmit may be done by previous state */
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_XAUTH_R1, STATE_MAIN_R3,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_ENCRYPTED,
|
|
|
d8e7ea |
P(MCFG_ATTR) | P(HASH), P(VID),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, xauth_inR1 },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(xauth_inR1),
|
|
|
d8e7ea |
+ /* RFC ????: */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_1, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
#if 0
|
|
|
d8e7ea |
/* for situation where there is XAUTH + ModeCFG */
|
|
|
d8e7ea |
{ STATE_XAUTH_R2, STATE_XAUTH_R3,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_ENCRYPTED,
|
|
|
d8e7ea |
P(MCFG_ATTR) | P(HASH), P(VID),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, xauth_inR2 },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(xauth_inR2), },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_XAUTH_R3, STATE_MAIN_R3,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_ENCRYPTED,
|
|
|
d8e7ea |
P(MCFG_ATTR) | P(HASH), P(VID),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, xauth_inR3 },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(xauth_inR3), },
|
|
|
d8e7ea |
#endif
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* MODE_CFG_x:
|
|
|
d8e7ea |
@@ -568,37 +679,57 @@
|
|
|
d8e7ea |
{ STATE_MODE_CFG_R0, STATE_MODE_CFG_R1,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY,
|
|
|
d8e7ea |
P(MCFG_ATTR) | P(HASH), P(VID),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, modecfg_inR0 },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(modecfg_inR0),
|
|
|
d8e7ea |
+ /* RFC ????: */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_1, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_MODE_CFG_R1, STATE_MODE_CFG_R2,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_ENCRYPTED,
|
|
|
d8e7ea |
P(MCFG_ATTR) | P(HASH), P(VID),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, modecfg_inR1 },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(modecfg_inR1),
|
|
|
d8e7ea |
+ /* RFC ????: */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_1, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_MODE_CFG_R2, STATE_UNDEFINED,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_ENCRYPTED,
|
|
|
d8e7ea |
LEMPTY, LEMPTY,
|
|
|
d8e7ea |
- EVENT_NULL, unexpected },
|
|
|
d8e7ea |
+ EVENT_NULL,
|
|
|
d8e7ea |
+ FM(unexpected),
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_MODE_CFG_I1, STATE_MAIN_I4,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2,
|
|
|
d8e7ea |
P(MCFG_ATTR) | P(HASH), P(VID),
|
|
|
d8e7ea |
- EVENT_SA_REPLACE, modecfg_inR1 },
|
|
|
d8e7ea |
+ EVENT_SA_REPLACE,
|
|
|
d8e7ea |
+ FM(modecfg_inR1),
|
|
|
d8e7ea |
+ /* RFC ????: */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_1, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_XAUTH_I0, STATE_XAUTH_I1,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2,
|
|
|
d8e7ea |
P(MCFG_ATTR) | P(HASH), P(VID),
|
|
|
d8e7ea |
- EVENT_RETRANSMIT, xauth_inI0 },
|
|
|
d8e7ea |
+ EVENT_RETRANSMIT,
|
|
|
d8e7ea |
+ FM(xauth_inI0),
|
|
|
d8e7ea |
+ /* RFC ????: */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_1, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_XAUTH_I1, STATE_MAIN_I4,
|
|
|
d8e7ea |
SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2,
|
|
|
d8e7ea |
P(MCFG_ATTR) | P(HASH), P(VID),
|
|
|
d8e7ea |
- EVENT_RETRANSMIT, xauth_inI1 },
|
|
|
d8e7ea |
+ EVENT_RETRANSMIT,
|
|
|
d8e7ea |
+ FM(xauth_inI1),
|
|
|
d8e7ea |
+ /* RFC ????: */
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_1, },
|
|
|
d8e7ea |
|
|
|
d8e7ea |
{ STATE_IKEv1_ROOF, STATE_IKEv1_ROOF,
|
|
|
d8e7ea |
LEMPTY,
|
|
|
d8e7ea |
LEMPTY, LEMPTY,
|
|
|
d8e7ea |
- EVENT_NULL, NULL },
|
|
|
d8e7ea |
+ EVENT_NULL, NULL,
|
|
|
d8e7ea |
+ .hash_type = V1_HASH_NONE, },
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+#undef FM
|
|
|
d8e7ea |
#undef P
|
|
|
d8e7ea |
};
|
|
|
d8e7ea |
|
|
|
d8e7ea |
@@ -748,6 +879,11 @@
|
|
|
d8e7ea |
DBGF(DBG_TMI, "processing IKEv1 state transition %s -> %s",
|
|
|
d8e7ea |
from->fs_short_name, to->fs_short_name);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
+ if (t->message == NULL) {
|
|
|
d8e7ea |
+ PEXPECT_LOG("transition %s -> %s missing .message",
|
|
|
d8e7ea |
+ from->fs_short_name, to->fs_short_name);
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
/*
|
|
|
d8e7ea |
* Point .fs_v1_transitions at to the first entry in
|
|
|
d8e7ea |
* v1_state_microcode_table for that state. All other
|
|
|
d8e7ea |
@@ -786,10 +922,32 @@
|
|
|
d8e7ea |
* always true of a state?
|
|
|
d8e7ea |
*/
|
|
|
d8e7ea |
if ((t->flags & from->fs_flags) != from->fs_flags) {
|
|
|
d8e7ea |
- DBGF(DBG_BASE, "transition %s -> %s missing flags 0x%"PRIxLSET,
|
|
|
d8e7ea |
- from->fs_short_name, to->fs_short_name, from->fs_flags);
|
|
|
d8e7ea |
+ DBGF(DBG_BASE, "transition %s -> %s (%s) missing flags 0x%"PRIxLSET,
|
|
|
d8e7ea |
+ from->fs_short_name, to->fs_short_name,
|
|
|
d8e7ea |
+ t->message, from->fs_flags);
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
from->fs_flags |= t->flags & SMF_RETRANSMIT_ON_DUPLICATE;
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+ if (!(t->flags & SMF_FIRST_ENCRYPTED_INPUT) &&
|
|
|
d8e7ea |
+ (t->flags & SMF_INPUT_ENCRYPTED) &&
|
|
|
d8e7ea |
+ t->processor != unexpected) {
|
|
|
d8e7ea |
+ /*
|
|
|
d8e7ea |
+ * The first encrypted message carries
|
|
|
d8e7ea |
+ * authentication information so isn't
|
|
|
d8e7ea |
+ * applicable. Other encrypted messages
|
|
|
d8e7ea |
+ * require integrity via the HASH payload.
|
|
|
d8e7ea |
+ */
|
|
|
d8e7ea |
+ if (!(t->req_payloads & LELEM(ISAKMP_NEXT_HASH))) {
|
|
|
d8e7ea |
+ PEXPECT_LOG("transition %s -> %s (%s) missing HASH payload",
|
|
|
d8e7ea |
+ from->fs_short_name, to->fs_short_name,
|
|
|
d8e7ea |
+ t->message);
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
+ if (t->hash_type == V1_HASH_NONE) {
|
|
|
d8e7ea |
+ PEXPECT_LOG("transition %s -> %s (%s) missing HASH protection",
|
|
|
d8e7ea |
+ from->fs_short_name, to->fs_short_name,
|
|
|
d8e7ea |
+ t->message);
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/*
|
|
|
d8e7ea |
@@ -2252,30 +2410,9 @@
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
- if (md->hdr.isa_xchg == ISAKMP_XCHG_INFO &&
|
|
|
d8e7ea |
- md->hdr.isa_np == ISAKMP_NEXT_HASH) {
|
|
|
d8e7ea |
- pb_stream *const hash_pbs = &(md)->chain[ISAKMP_NEXT_HASH]->pbs;
|
|
|
d8e7ea |
- u_char hash_val[MAX_DIGEST_LEN];
|
|
|
d8e7ea |
- size_t hash_len = quick_mode_hash12(hash_val, hash_pbs->roof,
|
|
|
d8e7ea |
- md->message_pbs.roof,
|
|
|
d8e7ea |
- st, &md->hdr.isa_msgid, FALSE);
|
|
|
d8e7ea |
- if (pbs_left(hash_pbs) != hash_len) {
|
|
|
d8e7ea |
- loglog(RC_LOG_SERIOUS,
|
|
|
d8e7ea |
- "received 'informational' message HASH(1) data is the wrong length (received %zu bytes but expected %zu)",
|
|
|
d8e7ea |
- pbs_left(hash_pbs), hash_len);
|
|
|
d8e7ea |
- return;
|
|
|
d8e7ea |
- }
|
|
|
d8e7ea |
- if (!memeq(hash_pbs->cur, hash_val, hash_len)) {
|
|
|
d8e7ea |
- if (DBGP(DBG_CRYPT)) {
|
|
|
d8e7ea |
- DBG_dump("received 'informational':",
|
|
|
d8e7ea |
- hash_pbs->cur, pbs_left(hash_pbs));
|
|
|
d8e7ea |
- }
|
|
|
d8e7ea |
- loglog(RC_LOG_SERIOUS,
|
|
|
d8e7ea |
- "received 'informational' message HASH(1) data does not match computed value");
|
|
|
d8e7ea |
- return;
|
|
|
d8e7ea |
- } else {
|
|
|
d8e7ea |
- dbg("received 'informational' message HASH(1) data ok");
|
|
|
d8e7ea |
- }
|
|
|
d8e7ea |
+ if (!check_v1_HASH(smc->hash_type, smc->message, st, md)) {
|
|
|
d8e7ea |
+ /*SEND_NOTIFICATION(INVALID_HASH_INFORMATION);*/
|
|
|
d8e7ea |
+ return;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* more sanity checking: enforce most ordering constraints */
|
|
|
d8e7ea |
diff -Naur libreswan-3.29-orig/programs/pluto/ikev1_hash.c libreswan-3.29/programs/pluto/ikev1_hash.c
|
|
|
d8e7ea |
--- libreswan-3.29-orig/programs/pluto/ikev1_hash.c 1969-12-31 19:00:00.000000000 -0500
|
|
|
d8e7ea |
+++ libreswan-3.29/programs/pluto/ikev1_hash.c 2019-06-11 19:24:00.543181473 -0400
|
|
|
d8e7ea |
@@ -0,0 +1,158 @@
|
|
|
d8e7ea |
+/* IKEv1 HASH payload wierdness, for Libreswan
|
|
|
d8e7ea |
+ *
|
|
|
d8e7ea |
+ * Copyright (C) 2019 Andrew Cagney
|
|
|
d8e7ea |
+ *
|
|
|
d8e7ea |
+ * This program is free software; you can redistribute it and/or modify it
|
|
|
d8e7ea |
+ * under the terms of the GNU General Public License as published by the
|
|
|
d8e7ea |
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
|
d8e7ea |
+ * option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>.
|
|
|
d8e7ea |
+ *
|
|
|
d8e7ea |
+ * This program is distributed in the hope that it will be useful, but
|
|
|
d8e7ea |
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
d8e7ea |
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
d8e7ea |
+ * for more details.
|
|
|
d8e7ea |
+ *
|
|
|
d8e7ea |
+ */
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+#include "ikev1_hash.h"
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+#include "state.h"
|
|
|
d8e7ea |
+#include "crypt_prf.h"
|
|
|
d8e7ea |
+#include "ike_alg.h"
|
|
|
d8e7ea |
+#include "lswlog.h"
|
|
|
d8e7ea |
+#include "demux.h"
|
|
|
d8e7ea |
+#include "impair.h"
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+bool emit_v1_HASH(enum v1_hash_type hash_type, const char *what,
|
|
|
d8e7ea |
+ enum exchange_impairment exchange,
|
|
|
d8e7ea |
+ struct state *st, struct v1_hash_fixup *fixup,
|
|
|
d8e7ea |
+ pb_stream *rbody)
|
|
|
d8e7ea |
+{
|
|
|
d8e7ea |
+ zero(fixup);
|
|
|
d8e7ea |
+ fixup->what = what;
|
|
|
d8e7ea |
+ fixup->hash_type = hash_type;
|
|
|
d8e7ea |
+ fixup->impair = (impair_v1_hash_exchange == exchange
|
|
|
d8e7ea |
+ ? impair_v1_hash_payload : SEND_NORMAL);
|
|
|
d8e7ea |
+ if (fixup->impair == SEND_OMIT) {
|
|
|
d8e7ea |
+ libreswan_log("IMPAIR: omitting HASH payload for %s", what);
|
|
|
d8e7ea |
+ return true;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
+ pb_stream hash_pbs;
|
|
|
d8e7ea |
+ if (!ikev1_out_generic(0, &isakmp_hash_desc, rbody, &hash_pbs)) {
|
|
|
d8e7ea |
+ return false;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
+ if (fixup->impair == SEND_EMPTY) {
|
|
|
d8e7ea |
+ libreswan_log("IMPAIR: sending HASH payload with no data for %s", what);
|
|
|
d8e7ea |
+ } else {
|
|
|
d8e7ea |
+ /* reserve space for HASH data */
|
|
|
d8e7ea |
+ fixup->hash_data = chunk(hash_pbs.cur, st->st_oakley.ta_prf->prf_output_size);
|
|
|
d8e7ea |
+ if (!out_zero(fixup->hash_data.len, &hash_pbs, "HASH DATA"))
|
|
|
d8e7ea |
+ return false;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
+ close_output_pbs(&hash_pbs);
|
|
|
d8e7ea |
+ /* save start of rest of message for later */
|
|
|
d8e7ea |
+ fixup->body = rbody->cur;
|
|
|
d8e7ea |
+ return true;
|
|
|
d8e7ea |
+}
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+void fixup_v1_HASH(struct state *st, const struct v1_hash_fixup *fixup,
|
|
|
d8e7ea |
+ msgid_t msgid, const uint8_t *roof)
|
|
|
d8e7ea |
+{
|
|
|
d8e7ea |
+ if (fixup->impair >= SEND_ROOF) {
|
|
|
d8e7ea |
+ libreswan_log("IMPAIR: setting HASH payload bytes to %02x",
|
|
|
d8e7ea |
+ fixup->impair - SEND_ROOF);
|
|
|
d8e7ea |
+ /* chunk_fill()? */
|
|
|
d8e7ea |
+ memset(fixup->hash_data.ptr, fixup->impair - SEND_ROOF,
|
|
|
d8e7ea |
+ fixup->hash_data.len);
|
|
|
d8e7ea |
+ return;
|
|
|
d8e7ea |
+ } else if (fixup->impair != SEND_NORMAL) {
|
|
|
d8e7ea |
+ /* already logged above? */
|
|
|
d8e7ea |
+ return;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
+ struct crypt_prf *hash =
|
|
|
d8e7ea |
+ crypt_prf_init_symkey("HASH(1)", st->st_oakley.ta_prf,
|
|
|
d8e7ea |
+ "SKEYID_a", st->st_skeyid_a_nss);
|
|
|
d8e7ea |
+ /* msgid */
|
|
|
d8e7ea |
+ passert(sizeof(msgid_t) == sizeof(uint32_t));
|
|
|
d8e7ea |
+ msgid_t raw_msgid = htonl(msgid);
|
|
|
d8e7ea |
+ switch (fixup->hash_type) {
|
|
|
d8e7ea |
+ case V1_HASH_1:
|
|
|
d8e7ea |
+ /* HASH(1) = prf(SKEYID_a, M-ID | payload ) */
|
|
|
d8e7ea |
+ crypt_prf_update_bytes(hash, "M-ID", &raw_msgid, sizeof(raw_msgid));
|
|
|
d8e7ea |
+ crypt_prf_update_bytes(hash, "payload",
|
|
|
d8e7ea |
+ fixup->body, roof - fixup->body);
|
|
|
d8e7ea |
+ break;
|
|
|
d8e7ea |
+ case V1_HASH_2:
|
|
|
d8e7ea |
+ /* HASH(2) = prf(SKEYID_a, M-ID | Ni_b | payload ) */
|
|
|
d8e7ea |
+ crypt_prf_update_bytes(hash, "M-ID", &raw_msgid, sizeof(raw_msgid));
|
|
|
d8e7ea |
+ crypt_prf_update_chunk(hash, "Ni_b", st->st_ni);
|
|
|
d8e7ea |
+ crypt_prf_update_bytes(hash, "payload",
|
|
|
d8e7ea |
+ fixup->body, roof - fixup->body);
|
|
|
d8e7ea |
+ break;
|
|
|
d8e7ea |
+ case V1_HASH_3:
|
|
|
d8e7ea |
+ /* HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */
|
|
|
d8e7ea |
+ crypt_prf_update_byte(hash, "0", 0);
|
|
|
d8e7ea |
+ crypt_prf_update_bytes(hash, "M-ID", &raw_msgid, sizeof(raw_msgid));
|
|
|
d8e7ea |
+ crypt_prf_update_chunk(hash, "Ni_b", st->st_ni);
|
|
|
d8e7ea |
+ crypt_prf_update_chunk(hash, "Nr_b", st->st_nr);
|
|
|
d8e7ea |
+ break;
|
|
|
d8e7ea |
+ default:
|
|
|
d8e7ea |
+ bad_case(fixup->hash_type);
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
+ /* stuff result into hash_data */
|
|
|
d8e7ea |
+ passert(fixup->hash_data.len == st->st_oakley.ta_prf->prf_output_size);
|
|
|
d8e7ea |
+ crypt_prf_final_bytes(&hash, fixup->hash_data.ptr, fixup->hash_data.len);
|
|
|
d8e7ea |
+ if (DBGP(DBG_BASE)) {
|
|
|
d8e7ea |
+ DBG_log("%s HASH(%u):", fixup->what, fixup->hash_type);
|
|
|
d8e7ea |
+ DBG_dump_chunk(NULL, fixup->hash_data);
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
+}
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+bool check_v1_HASH(enum v1_hash_type type, const char *what,
|
|
|
d8e7ea |
+ struct state *st, struct msg_digest *md)
|
|
|
d8e7ea |
+{
|
|
|
d8e7ea |
+ if (type == V1_HASH_NONE) {
|
|
|
d8e7ea |
+ dbg("message '%s' HASH payload not checked early", what);
|
|
|
d8e7ea |
+ return true;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
+ if (impair_v1_hash_check) {
|
|
|
d8e7ea |
+ libreswan_log("IMPAIR: skipping check of '%s' HASH payload", what);
|
|
|
d8e7ea |
+ return true;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
+ if (md->hdr.isa_np != ISAKMP_NEXT_HASH) {
|
|
|
d8e7ea |
+ loglog(RC_LOG_SERIOUS, "received '%s' message is missing a HASH(%u) payload",
|
|
|
d8e7ea |
+ what, type);
|
|
|
d8e7ea |
+ return false;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
+ pb_stream *hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs;
|
|
|
d8e7ea |
+ chunk_t received_hash = same_in_pbs_left_as_chunk(hash_pbs);
|
|
|
d8e7ea |
+ if (received_hash.len != st->st_oakley.ta_prf->prf_output_size) {
|
|
|
d8e7ea |
+ loglog(RC_LOG_SERIOUS,
|
|
|
d8e7ea |
+ "received '%s' message HASH(%u) data is the wrong length (received %zd bytes but expected %zd)",
|
|
|
d8e7ea |
+ what, type, received_hash.len, st->st_oakley.ta_prf->prf_output_size);
|
|
|
d8e7ea |
+ return false;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
+ /* compute the expected hash */
|
|
|
d8e7ea |
+ uint8_t hash_val[MAX_DIGEST_LEN];
|
|
|
d8e7ea |
+ passert(sizeof(hash_val) >= st->st_oakley.ta_prf->prf_output_size);
|
|
|
d8e7ea |
+ struct v1_hash_fixup expected = {
|
|
|
d8e7ea |
+ .hash_data = chunk(hash_val, st->st_oakley.ta_prf->prf_output_size),
|
|
|
d8e7ea |
+ .body = received_hash.ptr + received_hash.len,
|
|
|
d8e7ea |
+ .what = what,
|
|
|
d8e7ea |
+ .hash_type = type,
|
|
|
d8e7ea |
+ };
|
|
|
d8e7ea |
+ fixup_v1_HASH(st, &expected, md->hdr.isa_msgid, md->message_pbs.roof);
|
|
|
d8e7ea |
+ /* does it match? */
|
|
|
d8e7ea |
+ if (!chunk_eq(received_hash, expected.hash_data)) {
|
|
|
d8e7ea |
+ if (DBGP(DBG_BASE)) {
|
|
|
d8e7ea |
+ DBG_log("received %s HASH_DATA:", what);
|
|
|
d8e7ea |
+ DBG_dump_chunk(NULL, received_hash);
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
+ loglog(RC_LOG_SERIOUS,
|
|
|
d8e7ea |
+ "received '%s' message HASH(%u) data does not match computed value",
|
|
|
d8e7ea |
+ what, type);
|
|
|
d8e7ea |
+ return false;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
+ dbg("received '%s' message HASH(%u) data ok", what, type);
|
|
|
d8e7ea |
+ return true;
|
|
|
d8e7ea |
+}
|
|
|
d8e7ea |
diff -Naur libreswan-3.29-orig/programs/pluto/ikev1_hash.h libreswan-3.29/programs/pluto/ikev1_hash.h
|
|
|
d8e7ea |
--- libreswan-3.29-orig/programs/pluto/ikev1_hash.h 1969-12-31 19:00:00.000000000 -0500
|
|
|
d8e7ea |
+++ libreswan-3.29/programs/pluto/ikev1_hash.h 2019-06-11 19:24:00.543181473 -0400
|
|
|
d8e7ea |
@@ -0,0 +1,77 @@
|
|
|
d8e7ea |
+/* IKEv1 HASH payload wierdness, for Libreswan
|
|
|
d8e7ea |
+ *
|
|
|
d8e7ea |
+ * Copyright (C) 2019 Andrew Cagney
|
|
|
d8e7ea |
+ *
|
|
|
d8e7ea |
+ * This program is free software; you can redistribute it and/or modify it
|
|
|
d8e7ea |
+ * under the terms of the GNU General Public License as published by the
|
|
|
d8e7ea |
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
|
d8e7ea |
+ * option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>.
|
|
|
d8e7ea |
+ *
|
|
|
d8e7ea |
+ * This program is distributed in the hope that it will be useful, but
|
|
|
d8e7ea |
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
d8e7ea |
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
d8e7ea |
+ * for more details.
|
|
|
d8e7ea |
+ *
|
|
|
d8e7ea |
+ */
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+#ifndef IKEV1_HASH_H
|
|
|
d8e7ea |
+#define IKEV1_HASH_H
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+#include <stdint.h>
|
|
|
d8e7ea |
+#include <stdbool.h>
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+#include "chunk.h"
|
|
|
d8e7ea |
+#include "defs.h" /* for msgid_t */
|
|
|
d8e7ea |
+#include "packet.h" /* for pb_stream */
|
|
|
d8e7ea |
+#include "impair.h"
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+struct state;
|
|
|
d8e7ea |
+struct msg_digest;
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+/*
|
|
|
d8e7ea |
+ * RFC 2409: 5.5 Phase 2 - Quick Mode
|
|
|
d8e7ea |
+ *
|
|
|
d8e7ea |
+ * HASH(1) = prf(SKEYID_a, M-ID | SA | Ni [ | KE ] [ | IDci | IDcr )
|
|
|
d8e7ea |
+ * aka HASH(1) = prf(SKEYID_a, M-ID | payload )
|
|
|
d8e7ea |
+ *
|
|
|
d8e7ea |
+ * HASH(2) = prf(SKEYID_a, M-ID | Ni_b | SA | Nr [ | KE ] [ | IDci | IDcr )
|
|
|
d8e7ea |
+ * aka HASH(2) = prf(SKEYID_a, M-ID | Ni_b | payload )
|
|
|
d8e7ea |
+ *
|
|
|
d8e7ea |
+ * HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b)
|
|
|
d8e7ea |
+ */
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+enum v1_hash_type {
|
|
|
d8e7ea |
+ V1_HASH_NONE,
|
|
|
d8e7ea |
+ V1_HASH_1 = 1,
|
|
|
d8e7ea |
+ V1_HASH_2 = 2,
|
|
|
d8e7ea |
+ V1_HASH_3 = 3,
|
|
|
d8e7ea |
+};
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+/*
|
|
|
d8e7ea |
+ * Emit (saving where it is) and fixup (a previously saved) v1 HASH
|
|
|
d8e7ea |
+ * payload.
|
|
|
d8e7ea |
+ */
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+struct v1_hash_fixup {
|
|
|
d8e7ea |
+ chunk_t hash_data;
|
|
|
d8e7ea |
+ const uint8_t *body;
|
|
|
d8e7ea |
+ msgid_t msgid;
|
|
|
d8e7ea |
+ const char *what;
|
|
|
d8e7ea |
+ enum send_impairment impair;
|
|
|
d8e7ea |
+ enum v1_hash_type hash_type;
|
|
|
d8e7ea |
+};
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+bool emit_v1_HASH(enum v1_hash_type type, const char *what,
|
|
|
d8e7ea |
+ enum exchange_impairment exchange, struct state *st,
|
|
|
d8e7ea |
+ struct v1_hash_fixup *hash_fixup, pb_stream *out_pbs);
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+void fixup_v1_HASH(struct state *st, const struct v1_hash_fixup *data,
|
|
|
d8e7ea |
+ msgid_t msgid, const uint8_t *roof);
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+/*
|
|
|
d8e7ea |
+ * Check the IKEv1 HASH payload.
|
|
|
d8e7ea |
+ */
|
|
|
d8e7ea |
+bool check_v1_HASH(enum v1_hash_type type, const char *what,
|
|
|
d8e7ea |
+ struct state *st, struct msg_digest *md);
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+#endif
|
|
|
d8e7ea |
diff -Naur libreswan-3.29-orig/programs/pluto/ikev1_main.c libreswan-3.29/programs/pluto/ikev1_main.c
|
|
|
d8e7ea |
--- libreswan-3.29-orig/programs/pluto/ikev1_main.c 2019-06-10 10:22:04.000000000 -0400
|
|
|
d8e7ea |
+++ libreswan-3.29/programs/pluto/ikev1_main.c 2019-06-11 19:23:55.362124010 -0400
|
|
|
d8e7ea |
@@ -65,6 +65,7 @@
|
|
|
d8e7ea |
#include "fetch.h"
|
|
|
d8e7ea |
#include "asn1.h"
|
|
|
d8e7ea |
#include "pending.h"
|
|
|
d8e7ea |
+#include "ikev1_hash.h"
|
|
|
d8e7ea |
|
|
|
d8e7ea |
#include "crypto.h"
|
|
|
d8e7ea |
#include "secrets.h"
|
|
|
d8e7ea |
@@ -1547,6 +1548,10 @@
|
|
|
d8e7ea |
"received Hash Payload does not match computed value");
|
|
|
d8e7ea |
/* XXX Could send notification back */
|
|
|
d8e7ea |
r = STF_FAIL + INVALID_HASH_INFORMATION;
|
|
|
d8e7ea |
+ } else {
|
|
|
d8e7ea |
+ dbg("received '%s' message HASH_%s data ok",
|
|
|
d8e7ea |
+ aggrmode ? "Aggr" : "Main",
|
|
|
d8e7ea |
+ initiator ? "R" : "I" /*reverse*/);
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
break;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
@@ -1555,6 +1560,11 @@
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
r = RSA_check_signature(st, hash_val, hash_len,
|
|
|
d8e7ea |
&md->chain[ISAKMP_NEXT_SIG]->pbs, 0 /* for ikev2 only*/);
|
|
|
d8e7ea |
+ if (r != STF_OK) {
|
|
|
d8e7ea |
+ dbg("received '%s' message SIG_%s data did not match computed value",
|
|
|
d8e7ea |
+ aggrmode ? "Aggr" : "Main",
|
|
|
d8e7ea |
+ initiator ? "R" : "I" /*reverse*/);
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
break;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
/* These are the only IKEv1 AUTH methods we support */
|
|
|
d8e7ea |
@@ -1862,14 +1872,11 @@
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
stf_status send_isakmp_notification(struct state *st,
|
|
|
d8e7ea |
- uint16_t type, const void *data,
|
|
|
d8e7ea |
- size_t len)
|
|
|
d8e7ea |
+ uint16_t type, const void *data,
|
|
|
d8e7ea |
+ size_t len)
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
msgid_t msgid;
|
|
|
d8e7ea |
pb_stream rbody;
|
|
|
d8e7ea |
- u_char
|
|
|
d8e7ea |
- *r_hashval, /* where in reply to jam hash value */
|
|
|
d8e7ea |
- *r_hash_start; /* start of what is to be hashed */
|
|
|
d8e7ea |
|
|
|
d8e7ea |
msgid = generate_msgid(st);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
@@ -1879,7 +1886,6 @@
|
|
|
d8e7ea |
/* HDR* */
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
struct isakmp_hdr hdr = {
|
|
|
d8e7ea |
- .isa_np = ISAKMP_NEXT_HASH,
|
|
|
d8e7ea |
.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT |
|
|
|
d8e7ea |
ISAKMP_MINOR_VERSION,
|
|
|
d8e7ea |
.isa_xchg = ISAKMP_XCHG_INFO,
|
|
|
d8e7ea |
@@ -1891,8 +1897,13 @@
|
|
|
d8e7ea |
if (!out_struct(&hdr, &isakmp_hdr_desc, &reply_stream, &rbody))
|
|
|
d8e7ea |
return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
- /* HASH -- create and note space to be filled later */
|
|
|
d8e7ea |
- START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_N);
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+ struct v1_hash_fixup hash_fixup;
|
|
|
d8e7ea |
+ if (!emit_v1_HASH(V1_HASH_1, "notification",
|
|
|
d8e7ea |
+ NOTIFICATION_EXCHANGE,
|
|
|
d8e7ea |
+ st, &hash_fixup, &rbody)) {
|
|
|
d8e7ea |
+ return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* NOTIFY */
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
@@ -1919,23 +1930,8 @@
|
|
|
d8e7ea |
close_output_pbs(¬ify_pbs);
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
+ fixup_v1_HASH(st, &hash_fixup, msgid, rbody.cur);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
- {
|
|
|
d8e7ea |
- /* finish computing HASH */
|
|
|
d8e7ea |
- struct hmac_ctx ctx;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- hmac_init(&ctx, st->st_oakley.ta_prf, st->st_skeyid_a_nss);
|
|
|
d8e7ea |
- passert(sizeof(msgid_t) == sizeof(uint32_t));
|
|
|
d8e7ea |
- msgid_t raw_msgid = htonl(msgid);
|
|
|
d8e7ea |
- hmac_update(&ctx, (const void *)&raw_msgid, sizeof(raw_msgid));
|
|
|
d8e7ea |
- hmac_update(&ctx, r_hash_start, rbody.cur - r_hash_start);
|
|
|
d8e7ea |
- hmac_final(r_hashval, &ctx;;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- DBG(DBG_CRYPT, {
|
|
|
d8e7ea |
- DBG_log("HASH computed:");
|
|
|
d8e7ea |
- DBG_dump("", r_hashval, ctx.hmac_digest_len);
|
|
|
d8e7ea |
- });
|
|
|
d8e7ea |
- }
|
|
|
d8e7ea |
/*
|
|
|
d8e7ea |
* save old IV (this prevents from copying a whole new state object
|
|
|
d8e7ea |
* for NOTIFICATION / DELETE messages we don't need to maintain a state
|
|
|
d8e7ea |
@@ -1984,13 +1980,9 @@
|
|
|
d8e7ea |
pb_stream pbs;
|
|
|
d8e7ea |
|
|
|
d8e7ea |
pb_stream r_hdr_pbs;
|
|
|
d8e7ea |
- u_char *r_hashval, *r_hash_start;
|
|
|
d8e7ea |
static monotime_t last_malformed = MONOTIME_EPOCH;
|
|
|
d8e7ea |
monotime_t n = mononow();
|
|
|
d8e7ea |
|
|
|
d8e7ea |
- r_hashval = NULL;
|
|
|
d8e7ea |
- r_hash_start = NULL;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
switch (type) {
|
|
|
d8e7ea |
case PAYLOAD_MALFORMED:
|
|
|
d8e7ea |
/* only send one per second. */
|
|
|
d8e7ea |
@@ -2065,7 +2057,6 @@
|
|
|
d8e7ea |
struct isakmp_hdr hdr = {
|
|
|
d8e7ea |
.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT |
|
|
|
d8e7ea |
ISAKMP_MINOR_VERSION,
|
|
|
d8e7ea |
- .isa_np = encst ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_N,
|
|
|
d8e7ea |
.isa_xchg = ISAKMP_XCHG_INFO,
|
|
|
d8e7ea |
.isa_msgid = msgid,
|
|
|
d8e7ea |
.isa_flags = encst ? ISAKMP_FLAGS_v1_ENCRYPTION : 0,
|
|
|
d8e7ea |
@@ -2078,15 +2069,14 @@
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* HASH -- value to be filled later */
|
|
|
d8e7ea |
- if (encst) {
|
|
|
d8e7ea |
- pb_stream hash_pbs;
|
|
|
d8e7ea |
- passert(ikev1_out_generic(ISAKMP_NEXT_N, &isakmp_hash_desc, &r_hdr_pbs,
|
|
|
d8e7ea |
- &hash_pbs));
|
|
|
d8e7ea |
- r_hashval = hash_pbs.cur; /* remember where to plant value */
|
|
|
d8e7ea |
- passert(out_zero(encst->st_oakley.ta_prf->prf_output_size,
|
|
|
d8e7ea |
- &hash_pbs, "HASH(1)"));
|
|
|
d8e7ea |
- close_output_pbs(&hash_pbs);
|
|
|
d8e7ea |
- r_hash_start = r_hdr_pbs.cur; /* hash from after HASH(1) */
|
|
|
d8e7ea |
+ struct v1_hash_fixup hash_fixup;
|
|
|
d8e7ea |
+ if (encst != NULL) {
|
|
|
d8e7ea |
+ if (!emit_v1_HASH(V1_HASH_1, "send notification",
|
|
|
d8e7ea |
+ NOTIFICATION_EXCHANGE,
|
|
|
d8e7ea |
+ encst, &hash_fixup, &r_hdr_pbs)) {
|
|
|
d8e7ea |
+ /* return STF_INTERNAL_ERROR; */
|
|
|
d8e7ea |
+ return;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* Notification Payload */
|
|
|
d8e7ea |
@@ -2111,21 +2101,8 @@
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* calculate hash value and patch into Hash Payload */
|
|
|
d8e7ea |
- if (encst) {
|
|
|
d8e7ea |
- struct hmac_ctx ctx;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- hmac_init(&ctx, encst->st_oakley.ta_prf,
|
|
|
d8e7ea |
- encst->st_skeyid_a_nss);
|
|
|
d8e7ea |
- passert(sizeof(msgid_t) == sizeof(uint32_t));
|
|
|
d8e7ea |
- msgid_t raw_msgid = htonl(msgid);
|
|
|
d8e7ea |
- hmac_update(&ctx, (const void *)&raw_msgid, sizeof(raw_msgid));
|
|
|
d8e7ea |
- hmac_update(&ctx, r_hash_start, r_hdr_pbs.cur - r_hash_start);
|
|
|
d8e7ea |
- hmac_final(r_hashval, &ctx;;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- DBG(DBG_CRYPT, {
|
|
|
d8e7ea |
- DBG_log("HASH(1) computed:");
|
|
|
d8e7ea |
- DBG_dump("", r_hashval, ctx.hmac_digest_len);
|
|
|
d8e7ea |
- });
|
|
|
d8e7ea |
+ if (encst != NULL) {
|
|
|
d8e7ea |
+ fixup_v1_HASH(encst, &hash_fixup, msgid, r_hdr_pbs.cur);
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
if (encst != NULL) {
|
|
|
d8e7ea |
@@ -2242,9 +2219,6 @@
|
|
|
d8e7ea |
struct state *p1st;
|
|
|
d8e7ea |
ip_said said[EM_MAXRELSPIS];
|
|
|
d8e7ea |
ip_said *ns = said;
|
|
|
d8e7ea |
- u_char
|
|
|
d8e7ea |
- *r_hashval, /* where in reply to jam hash value */
|
|
|
d8e7ea |
- *r_hash_start; /* start of what is to be hashed */
|
|
|
d8e7ea |
bool isakmp_sa = FALSE;
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* If there are IPsec SA's related to this state struct... */
|
|
|
d8e7ea |
@@ -2288,7 +2262,6 @@
|
|
|
d8e7ea |
struct isakmp_hdr hdr = {
|
|
|
d8e7ea |
.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT |
|
|
|
d8e7ea |
ISAKMP_MINOR_VERSION,
|
|
|
d8e7ea |
- .isa_np = ISAKMP_NEXT_HASH,
|
|
|
d8e7ea |
.isa_xchg = ISAKMP_XCHG_INFO,
|
|
|
d8e7ea |
.isa_msgid = msgid,
|
|
|
d8e7ea |
.isa_flags = ISAKMP_FLAGS_v1_ENCRYPTION,
|
|
|
d8e7ea |
@@ -2300,16 +2273,10 @@
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* HASH -- value to be filled later */
|
|
|
d8e7ea |
- {
|
|
|
d8e7ea |
- pb_stream hash_pbs;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- passert(ikev1_out_generic(ISAKMP_NEXT_D, &isakmp_hash_desc, &r_hdr_pbs,
|
|
|
d8e7ea |
- &hash_pbs));
|
|
|
d8e7ea |
- r_hashval = hash_pbs.cur; /* remember where to plant value */
|
|
|
d8e7ea |
- passert(out_zero(p1st->st_oakley.ta_prf->prf_output_size,
|
|
|
d8e7ea |
- &hash_pbs, "HASH(1)"));
|
|
|
d8e7ea |
- close_output_pbs(&hash_pbs);
|
|
|
d8e7ea |
- r_hash_start = r_hdr_pbs.cur; /* hash from after HASH(1) */
|
|
|
d8e7ea |
+ struct v1_hash_fixup hash_fixup;
|
|
|
d8e7ea |
+ if (!emit_v1_HASH(V1_HASH_1, "send delete", DELETE_EXCHANGE,
|
|
|
d8e7ea |
+ p1st, &hash_fixup, &r_hdr_pbs)) {
|
|
|
d8e7ea |
+ return /* STF_INTERNAL_ERROR */;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* Delete Payloads */
|
|
|
d8e7ea |
@@ -2375,22 +2342,7 @@
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* calculate hash value and patch into Hash Payload */
|
|
|
d8e7ea |
- {
|
|
|
d8e7ea |
- struct hmac_ctx ctx;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- hmac_init(&ctx, p1st->st_oakley.ta_prf,
|
|
|
d8e7ea |
- p1st->st_skeyid_a_nss);
|
|
|
d8e7ea |
- passert(sizeof(msgid_t) == sizeof(uint32_t));
|
|
|
d8e7ea |
- msgid_t raw_msgid = htonl(msgid);
|
|
|
d8e7ea |
- hmac_update(&ctx, (const void *)&raw_msgid, sizeof(raw_msgid));
|
|
|
d8e7ea |
- hmac_update(&ctx, r_hash_start, r_hdr_pbs.cur - r_hash_start);
|
|
|
d8e7ea |
- hmac_final(r_hashval, &ctx;;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- DBG(DBG_CRYPT, {
|
|
|
d8e7ea |
- DBG_log("HASH(1) computed:");
|
|
|
d8e7ea |
- DBG_dump("", r_hashval, ctx.hmac_digest_len);
|
|
|
d8e7ea |
- });
|
|
|
d8e7ea |
- }
|
|
|
d8e7ea |
+ fixup_v1_HASH(p1st, &hash_fixup, msgid, r_hdr_pbs.cur);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/*
|
|
|
d8e7ea |
* Do a dance to avoid needing a new state object.
|
|
|
d8e7ea |
diff -Naur libreswan-3.29-orig/programs/pluto/ikev1_quick.c libreswan-3.29/programs/pluto/ikev1_quick.c
|
|
|
d8e7ea |
--- libreswan-3.29-orig/programs/pluto/ikev1_quick.c 2019-06-10 10:22:04.000000000 -0400
|
|
|
d8e7ea |
+++ libreswan-3.29/programs/pluto/ikev1_quick.c 2019-06-11 19:28:00.687844878 -0400
|
|
|
d8e7ea |
@@ -81,6 +81,7 @@
|
|
|
d8e7ea |
#include "pluto_x509.h"
|
|
|
d8e7ea |
#include "ip_address.h"
|
|
|
d8e7ea |
#include "af_info.h"
|
|
|
d8e7ea |
+#include "ikev1_hash.h"
|
|
|
d8e7ea |
|
|
|
d8e7ea |
#include <blapit.h>
|
|
|
d8e7ea |
|
|
|
d8e7ea |
@@ -660,69 +661,6 @@
|
|
|
d8e7ea |
return !bad_proposal;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
-/* Compute HASH(1), HASH(2) of Quick Mode.
|
|
|
d8e7ea |
- * HASH(1) is part of Quick I1 message.
|
|
|
d8e7ea |
- * HASH(2) is part of Quick R1 message.
|
|
|
d8e7ea |
- * Used by: quick_outI1, quick_inI1_outR1 (twice), quick_inR1_outI2
|
|
|
d8e7ea |
- * (see RFC 2409 "IKE" 5.5, pg. 18 or draft-ietf-ipsec-ike-01.txt 6.2 pg 25)
|
|
|
d8e7ea |
- */
|
|
|
d8e7ea |
-size_t quick_mode_hash12(u_char *dest, const u_char *start,
|
|
|
d8e7ea |
- const u_char *roof,
|
|
|
d8e7ea |
- const struct state *st, const msgid_t *msgid,
|
|
|
d8e7ea |
- bool hash2)
|
|
|
d8e7ea |
-{
|
|
|
d8e7ea |
- struct hmac_ctx ctx;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
-#if 0 /* if desperate to debug hashing */
|
|
|
d8e7ea |
-# define hmac_update(ctx, ptr, len) { \
|
|
|
d8e7ea |
- DBG_dump("hash input", (ptr), (len)); \
|
|
|
d8e7ea |
- (hmac_update)((ctx), (ptr), (len)); \
|
|
|
d8e7ea |
-}
|
|
|
d8e7ea |
- DBG_dump("hash key", st->st_skeyid_a.ptr, st->st_skeyid_a.len);
|
|
|
d8e7ea |
-#endif
|
|
|
d8e7ea |
- hmac_init(&ctx, st->st_oakley.ta_prf, st->st_skeyid_a_nss);
|
|
|
d8e7ea |
- passert(sizeof(msgid_t) == sizeof(uint32_t));
|
|
|
d8e7ea |
- msgid_t raw_msgid = htonl(*msgid);
|
|
|
d8e7ea |
- hmac_update(&ctx, (const void *)&raw_msgid, sizeof(raw_msgid));
|
|
|
d8e7ea |
- if (hash2)
|
|
|
d8e7ea |
- hmac_update_chunk(&ctx, st->st_ni); /* include Ni_b in the hash */
|
|
|
d8e7ea |
- hmac_update(&ctx, start, roof - start);
|
|
|
d8e7ea |
- hmac_final(dest, &ctx;;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- DBG(DBG_CRYPT, {
|
|
|
d8e7ea |
- DBG_log("HASH(%d) computed:", hash2 + 1);
|
|
|
d8e7ea |
- DBG_dump("", dest, ctx.hmac_digest_len);
|
|
|
d8e7ea |
- });
|
|
|
d8e7ea |
- return ctx.hmac_digest_len;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
-# undef hmac_update
|
|
|
d8e7ea |
-}
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
-/* Compute HASH(3) in Quick Mode (part of Quick I2 message).
|
|
|
d8e7ea |
- * Used by: quick_inR1_outI2, quick_inI2
|
|
|
d8e7ea |
- * See RFC2409 "The Internet Key Exchange (IKE)" 5.5.
|
|
|
d8e7ea |
- * NOTE: this hash (unlike HASH(1) and HASH(2)) ONLY covers the
|
|
|
d8e7ea |
- * Message ID and Nonces. This is a mistake.
|
|
|
d8e7ea |
- */
|
|
|
d8e7ea |
-static size_t quick_mode_hash3(u_char *dest, struct state *st)
|
|
|
d8e7ea |
-{
|
|
|
d8e7ea |
- struct hmac_ctx ctx;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- hmac_init(&ctx, st->st_oakley.ta_prf, st->st_skeyid_a_nss);
|
|
|
d8e7ea |
- hmac_update(&ctx, (const u_char *)"\0", 1);
|
|
|
d8e7ea |
- passert(sizeof(msgid_t) == sizeof(uint32_t));
|
|
|
d8e7ea |
- msgid_t raw_msgid = htonl(st->st_msgid);
|
|
|
d8e7ea |
- hmac_update(&ctx, (const void*)&raw_msgid, sizeof(raw_msgid));
|
|
|
d8e7ea |
- hmac_update_chunk(&ctx, st->st_ni);
|
|
|
d8e7ea |
- hmac_update_chunk(&ctx, st->st_nr);
|
|
|
d8e7ea |
- hmac_final(dest, &ctx;;
|
|
|
d8e7ea |
- if (DBGP(DBG_CRYPT)) {
|
|
|
d8e7ea |
- DBG_dump("HASH(3) computed:", dest,
|
|
|
d8e7ea |
- ctx.hmac_digest_len);
|
|
|
d8e7ea |
- }
|
|
|
d8e7ea |
- return ctx.hmac_digest_len;
|
|
|
d8e7ea |
-}
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
/* Compute Phase 2 IV.
|
|
|
d8e7ea |
* Uses Phase 1 IV from st_iv; puts result in st_new_iv.
|
|
|
d8e7ea |
*/
|
|
|
d8e7ea |
@@ -879,9 +817,6 @@
|
|
|
d8e7ea |
struct state *isakmp_sa = state_with_serialno(st->st_clonedfrom);
|
|
|
d8e7ea |
struct connection *c = st->st_connection;
|
|
|
d8e7ea |
pb_stream rbody;
|
|
|
d8e7ea |
- u_char /* set by START_HASH_PAYLOAD: */
|
|
|
d8e7ea |
- *r_hashval, /* where in reply to jam hash value */
|
|
|
d8e7ea |
- *r_hash_start; /* start of what is to be hashed */
|
|
|
d8e7ea |
bool has_client = c->spd.this.has_client || c->spd.that.has_client ||
|
|
|
d8e7ea |
c->spd.this.protocol != 0 || c->spd.that.protocol != 0 ||
|
|
|
d8e7ea |
c->spd.this.port != 0 || c->spd.that.port != 0;
|
|
|
d8e7ea |
@@ -915,7 +850,6 @@
|
|
|
d8e7ea |
struct isakmp_hdr hdr = {
|
|
|
d8e7ea |
.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT |
|
|
|
d8e7ea |
ISAKMP_MINOR_VERSION,
|
|
|
d8e7ea |
- .isa_np = ISAKMP_NEXT_HASH,
|
|
|
d8e7ea |
.isa_xchg = ISAKMP_XCHG_QUICK,
|
|
|
d8e7ea |
.isa_msgid = st->st_msgid,
|
|
|
d8e7ea |
.isa_flags = ISAKMP_FLAGS_v1_ENCRYPTION,
|
|
|
d8e7ea |
@@ -930,7 +864,11 @@
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* HASH(1) -- create and note space to be filled later */
|
|
|
d8e7ea |
- START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_SA);
|
|
|
d8e7ea |
+ struct v1_hash_fixup hash_fixup;
|
|
|
d8e7ea |
+ if (!emit_v1_HASH(V1_HASH_1, "outI1", QUICK_EXCHANGE,
|
|
|
d8e7ea |
+ st, &hash_fixup, &rbody)) {
|
|
|
d8e7ea |
+ return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* SA out */
|
|
|
d8e7ea |
|
|
|
d8e7ea |
@@ -1010,8 +948,7 @@
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* finish computing HASH(1), inserting it in output */
|
|
|
d8e7ea |
- (void) quick_mode_hash12(r_hashval, r_hash_start, rbody.cur,
|
|
|
d8e7ea |
- st, &st->st_msgid, FALSE);
|
|
|
d8e7ea |
+ fixup_v1_HASH(st, &hash_fixup, st->st_msgid, rbody.cur);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* encrypt message, except for fixed part of header */
|
|
|
d8e7ea |
|
|
|
d8e7ea |
@@ -1098,13 +1035,6 @@
|
|
|
d8e7ea |
struct payload_digest *const id_pd = md->chain[ISAKMP_NEXT_ID];
|
|
|
d8e7ea |
struct verify_oppo_bundle b;
|
|
|
d8e7ea |
|
|
|
d8e7ea |
- /* HASH(1) in */
|
|
|
d8e7ea |
- CHECK_QUICK_HASH(md,
|
|
|
d8e7ea |
- quick_mode_hash12(hash_val, hash_pbs->roof,
|
|
|
d8e7ea |
- md->message_pbs.roof,
|
|
|
d8e7ea |
- p1st, &md->hdr.isa_msgid, FALSE),
|
|
|
d8e7ea |
- "HASH(1)", "Quick I1");
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
/* [ IDci, IDcr ] in
|
|
|
d8e7ea |
* We do this now (probably out of physical order) because
|
|
|
d8e7ea |
* we wish to select the correct connection before we consult
|
|
|
d8e7ea |
@@ -1577,9 +1507,6 @@
|
|
|
d8e7ea |
struct state *st = md->st;
|
|
|
d8e7ea |
struct payload_digest *const id_pd = md->chain[ISAKMP_NEXT_ID];
|
|
|
d8e7ea |
struct payload_digest *const sapd = md->chain[ISAKMP_NEXT_SA];
|
|
|
d8e7ea |
- u_char /* set by START_HASH_PAYLOAD: */
|
|
|
d8e7ea |
- *r_hashval, /* where in reply to jam hash value */
|
|
|
d8e7ea |
- *r_hash_start; /* from where to start hashing */
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* Start the output packet.
|
|
|
d8e7ea |
*
|
|
|
d8e7ea |
@@ -1594,12 +1521,15 @@
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* HDR* out */
|
|
|
d8e7ea |
pb_stream rbody;
|
|
|
d8e7ea |
- ikev1_init_out_pbs_echo_hdr(md, TRUE, ISAKMP_NEXT_HASH,
|
|
|
d8e7ea |
+ ikev1_init_out_pbs_echo_hdr(md, TRUE, 0,
|
|
|
d8e7ea |
&reply_stream, reply_buffer, sizeof(reply_buffer),
|
|
|
d8e7ea |
&rbody);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
- /* HASH(2) out -- first pass */
|
|
|
d8e7ea |
- START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_SA);
|
|
|
d8e7ea |
+ struct v1_hash_fixup hash_fixup;
|
|
|
d8e7ea |
+ if (!emit_v1_HASH(V1_HASH_2, "quick inR1 outI2",
|
|
|
d8e7ea |
+ QUICK_EXCHANGE, st, &hash_fixup, &rbody)) {
|
|
|
d8e7ea |
+ return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
|
|
|
d8e7ea |
passert(st->st_connection != NULL);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
@@ -1720,8 +1650,7 @@
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* Compute reply HASH(2) and insert in output */
|
|
|
d8e7ea |
- (void)quick_mode_hash12(r_hashval, r_hash_start, rbody.cur,
|
|
|
d8e7ea |
- st, &st->st_msgid, TRUE);
|
|
|
d8e7ea |
+ fixup_v1_HASH(st, &hash_fixup, st->st_msgid, rbody.cur);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* Derive new keying material */
|
|
|
d8e7ea |
compute_keymats(st);
|
|
|
d8e7ea |
@@ -1758,13 +1687,6 @@
|
|
|
d8e7ea |
|
|
|
d8e7ea |
stf_status quick_inR1_outI2(struct state *st, struct msg_digest *md)
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
- /* HASH(2) in */
|
|
|
d8e7ea |
- CHECK_QUICK_HASH(md,
|
|
|
d8e7ea |
- quick_mode_hash12(hash_val, hash_pbs->roof,
|
|
|
d8e7ea |
- md->message_pbs.roof,
|
|
|
d8e7ea |
- st, &st->st_msgid, TRUE),
|
|
|
d8e7ea |
- "HASH(2)", "Quick R1");
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
/* SA in */
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
|
|
|
d8e7ea |
@@ -1812,7 +1734,7 @@
|
|
|
d8e7ea |
struct connection *c = st->st_connection;
|
|
|
d8e7ea |
|
|
|
d8e7ea |
pb_stream rbody;
|
|
|
d8e7ea |
- ikev1_init_out_pbs_echo_hdr(md, TRUE, ISAKMP_NEXT_HASH,
|
|
|
d8e7ea |
+ ikev1_init_out_pbs_echo_hdr(md, TRUE, 0,
|
|
|
d8e7ea |
&reply_stream, reply_buffer, sizeof(reply_buffer),
|
|
|
d8e7ea |
&rbody);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
@@ -1907,7 +1829,7 @@
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* HASH(3) out -- sometimes, we add more content */
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
- u_char *r_hashval; /* set by START_HASH_PAYLOAD */
|
|
|
d8e7ea |
+ struct v1_hash_fixup hash_fixup;
|
|
|
d8e7ea |
|
|
|
d8e7ea |
#ifdef IMPAIR_UNALIGNED_I2_MSG
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
@@ -1945,12 +1867,13 @@
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
#else
|
|
|
d8e7ea |
- START_HASH_PAYLOAD_NO_R_HASH_START(rbody,
|
|
|
d8e7ea |
- ISAKMP_NEXT_NONE);
|
|
|
d8e7ea |
+ if (!emit_v1_HASH(V1_HASH_3, "quick_inR1_outI2",
|
|
|
d8e7ea |
+ QUICK_EXCHANGE, st, &hash_fixup, &rbody)) {
|
|
|
d8e7ea |
+ return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
#endif
|
|
|
d8e7ea |
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- (void)quick_mode_hash3(r_hashval, st);
|
|
|
d8e7ea |
+ fixup_v1_HASH(st, &hash_fixup, st->st_msgid, NULL);
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* Derive new keying material */
|
|
|
d8e7ea |
@@ -1986,12 +1909,8 @@
|
|
|
d8e7ea |
* (see RFC 2409 "IKE" 5.5)
|
|
|
d8e7ea |
* Installs outbound IPsec SAs, routing, etc.
|
|
|
d8e7ea |
*/
|
|
|
d8e7ea |
-stf_status quick_inI2(struct state *st, struct msg_digest *md)
|
|
|
d8e7ea |
+stf_status quick_inI2(struct state *st, struct msg_digest *md UNUSED)
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
- /* HASH(3) in */
|
|
|
d8e7ea |
- CHECK_QUICK_HASH(md, quick_mode_hash3(hash_val, st),
|
|
|
d8e7ea |
- "HASH(3)", "Quick I2");
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
/* Tell the kernel to establish the outbound and routing part of the new SA
|
|
|
d8e7ea |
* (the previous state established inbound)
|
|
|
d8e7ea |
* (unless the commit bit is set -- which we don't support).
|
|
|
d8e7ea |
diff -Naur libreswan-3.29-orig/programs/pluto/ikev1_xauth.c libreswan-3.29/programs/pluto/ikev1_xauth.c
|
|
|
d8e7ea |
--- libreswan-3.29-orig/programs/pluto/ikev1_xauth.c 2019-06-10 10:22:04.000000000 -0400
|
|
|
d8e7ea |
+++ libreswan-3.29/programs/pluto/ikev1_xauth.c 2019-06-11 19:28:00.688844889 -0400
|
|
|
d8e7ea |
@@ -78,6 +78,8 @@
|
|
|
d8e7ea |
#include "send.h" /* for send without recording */
|
|
|
d8e7ea |
#include "ikev1_send.h"
|
|
|
d8e7ea |
#include "af_info.h"
|
|
|
d8e7ea |
+#include "ikev1_hash.h"
|
|
|
d8e7ea |
+#include "impair.h"
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* forward declarations */
|
|
|
d8e7ea |
static stf_status xauth_client_ackstatus(struct state *st,
|
|
|
d8e7ea |
@@ -198,25 +200,19 @@
|
|
|
d8e7ea |
* @param st State structure
|
|
|
d8e7ea |
* @return size_t Length of the HASH
|
|
|
d8e7ea |
*/
|
|
|
d8e7ea |
-static size_t xauth_mode_cfg_hash(u_char *dest,
|
|
|
d8e7ea |
- const u_char *start,
|
|
|
d8e7ea |
- const u_char *roof,
|
|
|
d8e7ea |
- const struct state *st)
|
|
|
d8e7ea |
-{
|
|
|
d8e7ea |
- struct hmac_ctx ctx;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- hmac_init(&ctx, st->st_oakley.ta_prf, st->st_skeyid_a_nss);
|
|
|
d8e7ea |
- passert(sizeof(msgid_t) == sizeof(uint32_t));
|
|
|
d8e7ea |
- msgid_t raw_msgid = htonl(st->st_msgid_phase15);
|
|
|
d8e7ea |
- hmac_update(&ctx, (const void *)&raw_msgid, sizeof(raw_msgid));
|
|
|
d8e7ea |
- hmac_update(&ctx, start, roof - start);
|
|
|
d8e7ea |
- hmac_final(dest, &ctx;;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- DBG(DBG_CRYPT|DBG_XAUTH, {
|
|
|
d8e7ea |
- DBG_log("XAUTH: HASH computed:");
|
|
|
d8e7ea |
- DBG_dump("", dest, ctx.hmac_digest_len);
|
|
|
d8e7ea |
- });
|
|
|
d8e7ea |
- return ctx.hmac_digest_len;
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+static bool emit_xauth_hash(const char *what, struct state *st,
|
|
|
d8e7ea |
+ struct v1_hash_fixup *hash_fixup, pb_stream *out)
|
|
|
d8e7ea |
+{
|
|
|
d8e7ea |
+ return emit_v1_HASH(V1_HASH_1, what, XAUTH_EXCHANGE,
|
|
|
d8e7ea |
+ st, hash_fixup, out);
|
|
|
d8e7ea |
+}
|
|
|
d8e7ea |
+
|
|
|
d8e7ea |
+static void fixup_xauth_hash(struct state *st,
|
|
|
d8e7ea |
+ struct v1_hash_fixup *hash_fixup,
|
|
|
d8e7ea |
+ const uint8_t *roof)
|
|
|
d8e7ea |
+{
|
|
|
d8e7ea |
+ fixup_v1_HASH(st, hash_fixup, st->st_msgid_phase15, roof);
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/**
|
|
|
d8e7ea |
@@ -383,23 +379,10 @@
|
|
|
d8e7ea |
bool use_modecfg_addr_as_client_addr,
|
|
|
d8e7ea |
uint16_t ap_id)
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
- unsigned char *r_hash_start, *r_hashval;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- /* START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_MCFG_ATTR); */
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- {
|
|
|
d8e7ea |
- pb_stream hash_pbs;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- if (!ikev1_out_generic(ISAKMP_NEXT_MCFG_ATTR, &isakmp_hash_desc, rbody, &hash_pbs))
|
|
|
d8e7ea |
- return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- r_hashval = hash_pbs.cur; /* remember where to plant value */
|
|
|
d8e7ea |
- if (!out_zero(st->st_oakley.ta_prf->prf_output_size,
|
|
|
d8e7ea |
- &hash_pbs, "HASH"))
|
|
|
d8e7ea |
- return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- close_output_pbs(&hash_pbs);
|
|
|
d8e7ea |
- r_hash_start = rbody->cur; /* hash from after HASH payload */
|
|
|
d8e7ea |
+ struct v1_hash_fixup hash_fixup;
|
|
|
d8e7ea |
+ if (!emit_xauth_hash("XAUTH: mode config response",
|
|
|
d8e7ea |
+ st, &hash_fixup, rbody)) {
|
|
|
d8e7ea |
+ return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* ATTR out */
|
|
|
d8e7ea |
@@ -497,7 +480,7 @@
|
|
|
d8e7ea |
return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
- xauth_mode_cfg_hash(r_hashval, r_hash_start, rbody->cur, st);
|
|
|
d8e7ea |
+ fixup_xauth_hash(st, &hash_fixup, rbody->cur);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
if (!ikev1_close_message(rbody, st) ||
|
|
|
d8e7ea |
!ikev1_encrypt_message(rbody, st))
|
|
|
d8e7ea |
@@ -523,7 +506,6 @@
|
|
|
d8e7ea |
/* HDR out */
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
struct isakmp_hdr hdr = {
|
|
|
d8e7ea |
- .isa_np = ISAKMP_NEXT_HASH,
|
|
|
d8e7ea |
.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT |
|
|
|
d8e7ea |
ISAKMP_MINOR_VERSION,
|
|
|
d8e7ea |
.isa_xchg = ISAKMP_XCHG_MODE_CFG,
|
|
|
d8e7ea |
@@ -604,7 +586,6 @@
|
|
|
d8e7ea |
pb_stream reply;
|
|
|
d8e7ea |
pb_stream rbody;
|
|
|
d8e7ea |
unsigned char buf[256];
|
|
|
d8e7ea |
- u_char *r_hash_start, *r_hashval;
|
|
|
d8e7ea |
const enum state_kind p_state = st->st_state;
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* set up reply */
|
|
|
d8e7ea |
@@ -620,7 +601,6 @@
|
|
|
d8e7ea |
/* HDR out */
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
struct isakmp_hdr hdr = {
|
|
|
d8e7ea |
- .isa_np = ISAKMP_NEXT_HASH,
|
|
|
d8e7ea |
.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT |
|
|
|
d8e7ea |
ISAKMP_MINOR_VERSION,
|
|
|
d8e7ea |
.isa_xchg = ISAKMP_XCHG_MODE_CFG,
|
|
|
d8e7ea |
@@ -638,7 +618,11 @@
|
|
|
d8e7ea |
return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
- START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_MCFG_ATTR);
|
|
|
d8e7ea |
+ struct v1_hash_fixup hash_fixup;
|
|
|
d8e7ea |
+ if (!emit_xauth_hash("XAUTH: send request",
|
|
|
d8e7ea |
+ st, &hash_fixup, &rbody)) {
|
|
|
d8e7ea |
+ return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* ATTR out */
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
@@ -668,7 +652,7 @@
|
|
|
d8e7ea |
return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
- xauth_mode_cfg_hash(r_hashval, r_hash_start, rbody.cur, st);
|
|
|
d8e7ea |
+ fixup_xauth_hash(st, &hash_fixup, rbody.cur);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
if (!ikev1_close_message(&rbody, st))
|
|
|
d8e7ea |
return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
@@ -719,7 +703,6 @@
|
|
|
d8e7ea |
pb_stream reply;
|
|
|
d8e7ea |
pb_stream rbody;
|
|
|
d8e7ea |
unsigned char buf[256];
|
|
|
d8e7ea |
- u_char *r_hash_start, *r_hashval;
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* set up reply */
|
|
|
d8e7ea |
init_out_pbs(&reply, buf, sizeof(buf), "xauth_buf");
|
|
|
d8e7ea |
@@ -733,7 +716,6 @@
|
|
|
d8e7ea |
/* HDR out */
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
struct isakmp_hdr hdr = {
|
|
|
d8e7ea |
- .isa_np = ISAKMP_NEXT_HASH,
|
|
|
d8e7ea |
.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT |
|
|
|
d8e7ea |
ISAKMP_MINOR_VERSION,
|
|
|
d8e7ea |
.isa_xchg = ISAKMP_XCHG_MODE_CFG,
|
|
|
d8e7ea |
@@ -752,7 +734,11 @@
|
|
|
d8e7ea |
return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
- START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_MCFG_ATTR);
|
|
|
d8e7ea |
+ struct v1_hash_fixup hash_fixup;
|
|
|
d8e7ea |
+ if (!emit_xauth_hash("XAUTH: mode config request",
|
|
|
d8e7ea |
+ st, &hash_fixup, &rbody)) {
|
|
|
d8e7ea |
+ return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* ATTR out */
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
@@ -785,7 +771,7 @@
|
|
|
d8e7ea |
return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
- xauth_mode_cfg_hash(r_hashval, r_hash_start, rbody.cur, st);
|
|
|
d8e7ea |
+ fixup_xauth_hash(st, &hash_fixup, rbody.cur);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
if (!ikev1_close_message(&rbody, st))
|
|
|
d8e7ea |
return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
@@ -821,7 +807,6 @@
|
|
|
d8e7ea |
pb_stream reply;
|
|
|
d8e7ea |
pb_stream rbody;
|
|
|
d8e7ea |
unsigned char buf[256];
|
|
|
d8e7ea |
- u_char *r_hash_start, *r_hashval;
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* set up reply */
|
|
|
d8e7ea |
init_out_pbs(&reply, buf, sizeof(buf), "xauth_buf");
|
|
|
d8e7ea |
@@ -832,7 +817,6 @@
|
|
|
d8e7ea |
/* HDR out */
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
struct isakmp_hdr hdr = {
|
|
|
d8e7ea |
- .isa_np = ISAKMP_NEXT_HASH,
|
|
|
d8e7ea |
.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT |
|
|
|
d8e7ea |
ISAKMP_MINOR_VERSION,
|
|
|
d8e7ea |
.isa_xchg = ISAKMP_XCHG_MODE_CFG,
|
|
|
d8e7ea |
@@ -850,7 +834,10 @@
|
|
|
d8e7ea |
return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
- START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_MCFG_ATTR);
|
|
|
d8e7ea |
+ struct v1_hash_fixup hash_fixup;
|
|
|
d8e7ea |
+ if (!emit_xauth_hash("XAUTH: status", st, &hash_fixup, &rbody)) {
|
|
|
d8e7ea |
+ return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
+ }
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* ATTR out */
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
@@ -873,7 +860,7 @@
|
|
|
d8e7ea |
return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
- xauth_mode_cfg_hash(r_hashval, r_hash_start, rbody.cur, st);
|
|
|
d8e7ea |
+ fixup_xauth_hash(st, &hash_fixup, rbody.cur);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
if (!ikev1_close_message(&rbody, st))
|
|
|
d8e7ea |
return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
@@ -1280,12 +1267,6 @@
|
|
|
d8e7ea |
bool gotname = FALSE,
|
|
|
d8e7ea |
gotpassword = FALSE;
|
|
|
d8e7ea |
|
|
|
d8e7ea |
- CHECK_QUICK_HASH(md,
|
|
|
d8e7ea |
- xauth_mode_cfg_hash(hash_val, hash_pbs->roof,
|
|
|
d8e7ea |
- md->message_pbs.roof,
|
|
|
d8e7ea |
- st),
|
|
|
d8e7ea |
- "XAUTH-HASH", "XAUTH R0");
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
setchunk(name, unknown, sizeof(unknown) - 1); /* to make diagnostics easier */
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* XXX This needs checking with the proper RFC's - ISAKMP_CFG_ACK got added for Cisco interop */
|
|
|
d8e7ea |
@@ -1469,11 +1450,6 @@
|
|
|
d8e7ea |
DBG(DBG_CONTROLMORE, DBG_log("arrived in modecfg_inR0"));
|
|
|
d8e7ea |
|
|
|
d8e7ea |
st->st_msgid_phase15 = md->hdr.isa_msgid;
|
|
|
d8e7ea |
- CHECK_QUICK_HASH(md,
|
|
|
d8e7ea |
- xauth_mode_cfg_hash(hash_val,
|
|
|
d8e7ea |
- hash_pbs->roof,
|
|
|
d8e7ea |
- md->message_pbs.roof, st),
|
|
|
d8e7ea |
- "MODECFG-HASH", "MODE R0");
|
|
|
d8e7ea |
|
|
|
d8e7ea |
switch (ma->isama_type) {
|
|
|
d8e7ea |
default:
|
|
|
d8e7ea |
@@ -1559,12 +1535,6 @@
|
|
|
d8e7ea |
DBG(DBG_CONTROL, DBG_log("modecfg_inI2"));
|
|
|
d8e7ea |
|
|
|
d8e7ea |
st->st_msgid_phase15 = md->hdr.isa_msgid;
|
|
|
d8e7ea |
- CHECK_QUICK_HASH(md,
|
|
|
d8e7ea |
- xauth_mode_cfg_hash(hash_val,
|
|
|
d8e7ea |
- hash_pbs->roof,
|
|
|
d8e7ea |
- md->message_pbs.roof,
|
|
|
d8e7ea |
- st),
|
|
|
d8e7ea |
- "MODECFG-HASH", "MODE R1");
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* CHECK that SET has been received. */
|
|
|
d8e7ea |
|
|
|
d8e7ea |
@@ -1690,11 +1660,6 @@
|
|
|
d8e7ea |
DBG(DBG_CONTROL, DBG_log("modecfg_inR1: received mode cfg reply"));
|
|
|
d8e7ea |
|
|
|
d8e7ea |
st->st_msgid_phase15 = md->hdr.isa_msgid;
|
|
|
d8e7ea |
- CHECK_QUICK_HASH(md,
|
|
|
d8e7ea |
- xauth_mode_cfg_hash(hash_val, hash_pbs->roof,
|
|
|
d8e7ea |
- md->message_pbs.roof,
|
|
|
d8e7ea |
- st),
|
|
|
d8e7ea |
- "MODECFG-HASH", "MODE R1");
|
|
|
d8e7ea |
|
|
|
d8e7ea |
switch (ma->isama_type) {
|
|
|
d8e7ea |
default:
|
|
|
d8e7ea |
@@ -1978,26 +1943,12 @@
|
|
|
d8e7ea |
pb_stream *rbody,
|
|
|
d8e7ea |
uint16_t ap_id)
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
- unsigned char *r_hash_start, *r_hashval;
|
|
|
d8e7ea |
char xauth_username[MAX_XAUTH_USERNAME_LEN];
|
|
|
d8e7ea |
struct connection *c = st->st_connection;
|
|
|
d8e7ea |
|
|
|
d8e7ea |
- /* START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_MCFG_ATTR); */
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- {
|
|
|
d8e7ea |
- pb_stream hash_pbs;
|
|
|
d8e7ea |
- int np = ISAKMP_NEXT_MCFG_ATTR;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- if (!ikev1_out_generic(np, &isakmp_hash_desc, rbody, &hash_pbs))
|
|
|
d8e7ea |
- return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- r_hashval = hash_pbs.cur; /* remember where to plant value */
|
|
|
d8e7ea |
- if (!out_zero(st->st_oakley.ta_prf->prf_output_size,
|
|
|
d8e7ea |
- &hash_pbs, "HASH"))
|
|
|
d8e7ea |
- return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- close_output_pbs(&hash_pbs);
|
|
|
d8e7ea |
- r_hash_start = (rbody)->cur; /* hash from after HASH payload */
|
|
|
d8e7ea |
+ struct v1_hash_fixup hash_fixup;
|
|
|
d8e7ea |
+ if (!emit_xauth_hash("XAUTH: client response", st, &hash_fixup, rbody)) {
|
|
|
d8e7ea |
+ return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* MCFG_ATTR out */
|
|
|
d8e7ea |
@@ -2201,7 +2152,7 @@
|
|
|
d8e7ea |
libreswan_log("XAUTH: Answering XAUTH challenge with user='%s'",
|
|
|
d8e7ea |
st->st_xauth_username);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
- xauth_mode_cfg_hash(r_hashval, r_hash_start, rbody->cur, st);
|
|
|
d8e7ea |
+ fixup_xauth_hash(st, &hash_fixup, rbody->cur);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
if (!ikev1_close_message(rbody, st) ||
|
|
|
d8e7ea |
!ikev1_encrypt_message(rbody, st))
|
|
|
d8e7ea |
@@ -2252,10 +2203,6 @@
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
st->st_msgid_phase15 = md->hdr.isa_msgid;
|
|
|
d8e7ea |
- CHECK_QUICK_HASH(md, xauth_mode_cfg_hash(hash_val,
|
|
|
d8e7ea |
- hash_pbs->roof,
|
|
|
d8e7ea |
- md->message_pbs.roof, st),
|
|
|
d8e7ea |
- "MODECFG-HASH", "XAUTH I0");
|
|
|
d8e7ea |
|
|
|
d8e7ea |
switch (ma->isama_type) {
|
|
|
d8e7ea |
default:
|
|
|
d8e7ea |
@@ -2446,24 +2393,9 @@
|
|
|
d8e7ea |
pb_stream *rbody,
|
|
|
d8e7ea |
uint16_t ap_id)
|
|
|
d8e7ea |
{
|
|
|
d8e7ea |
- unsigned char *r_hash_start, *r_hashval;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- /* START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_MCFG_ATTR); */
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- {
|
|
|
d8e7ea |
- pb_stream hash_pbs;
|
|
|
d8e7ea |
- int np = ISAKMP_NEXT_MCFG_ATTR;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- if (!ikev1_out_generic(np, &isakmp_hash_desc, rbody, &hash_pbs))
|
|
|
d8e7ea |
- return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- r_hashval = hash_pbs.cur; /* remember where to plant value */
|
|
|
d8e7ea |
- if (!out_zero(st->st_oakley.ta_prf->prf_output_size,
|
|
|
d8e7ea |
- &hash_pbs, "HASH"))
|
|
|
d8e7ea |
- return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
- close_output_pbs(&hash_pbs);
|
|
|
d8e7ea |
- r_hash_start = (rbody)->cur; /* hash from after HASH payload */
|
|
|
d8e7ea |
+ struct v1_hash_fixup hash_fixup;
|
|
|
d8e7ea |
+ if (!emit_xauth_hash("XAUTH: ack status", st, &hash_fixup, rbody)) {
|
|
|
d8e7ea |
+ return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
/* ATTR out */
|
|
|
d8e7ea |
@@ -2486,7 +2418,7 @@
|
|
|
d8e7ea |
return STF_INTERNAL_ERROR;
|
|
|
d8e7ea |
}
|
|
|
d8e7ea |
|
|
|
d8e7ea |
- xauth_mode_cfg_hash(r_hashval, r_hash_start, rbody->cur, st);
|
|
|
d8e7ea |
+ fixup_xauth_hash(st, &hash_fixup, rbody->cur);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
if (!ikev1_close_message(rbody, st) ||
|
|
|
d8e7ea |
!ikev1_encrypt_message(rbody, st))
|
|
|
d8e7ea |
@@ -2525,11 +2457,6 @@
|
|
|
d8e7ea |
DBG(DBG_CONTROLMORE, DBG_log("Continuing with xauth_inI1"));
|
|
|
d8e7ea |
|
|
|
d8e7ea |
st->st_msgid_phase15 = md->hdr.isa_msgid;
|
|
|
d8e7ea |
- CHECK_QUICK_HASH(md,
|
|
|
d8e7ea |
- xauth_mode_cfg_hash(hash_val,
|
|
|
d8e7ea |
- hash_pbs->roof,
|
|
|
d8e7ea |
- md->message_pbs.roof, st),
|
|
|
d8e7ea |
- "MODECFG-HASH", "XAUTH I1");
|
|
|
d8e7ea |
|
|
|
d8e7ea |
switch (ma->isama_type) {
|
|
|
d8e7ea |
default:
|
|
|
d8e7ea |
diff -Naur libreswan-3.29-orig/programs/pluto/ipsec_doi.h libreswan-3.29/programs/pluto/ipsec_doi.h
|
|
|
d8e7ea |
--- libreswan-3.29-orig/programs/pluto/ipsec_doi.h 2019-06-10 10:22:04.000000000 -0400
|
|
|
d8e7ea |
+++ libreswan-3.29/programs/pluto/ipsec_doi.h 2019-06-11 19:28:00.688844889 -0400
|
|
|
d8e7ea |
@@ -65,67 +65,6 @@
|
|
|
d8e7ea |
const struct oakley_group_desc *gr,
|
|
|
d8e7ea |
struct payload_digest *ke_pd);
|
|
|
d8e7ea |
|
|
|
d8e7ea |
-/* START_HASH_PAYLOAD_NO_HASH_START
|
|
|
d8e7ea |
- *
|
|
|
d8e7ea |
- * Emit a to-be-filled-in hash payload, noting the field start (r_hashval)
|
|
|
d8e7ea |
- * and the start of the part of the message to be hashed (r_hash_start).
|
|
|
d8e7ea |
- * This macro is magic.
|
|
|
d8e7ea |
- * - it can cause the caller to return
|
|
|
d8e7ea |
- * - it references variables local to the caller (r_hashval, st)
|
|
|
d8e7ea |
- */
|
|
|
d8e7ea |
-#define START_HASH_PAYLOAD_NO_R_HASH_START(rbody, np) { \
|
|
|
d8e7ea |
- pb_stream hash_pbs; \
|
|
|
d8e7ea |
- if (!ikev1_out_generic(np, &isakmp_hash_desc, &(rbody), &hash_pbs)) \
|
|
|
d8e7ea |
- return STF_INTERNAL_ERROR; \
|
|
|
d8e7ea |
- r_hashval = hash_pbs.cur; /* remember where to plant value */ \
|
|
|
d8e7ea |
- if (!out_zero(st->st_oakley.ta_prf->prf_output_size, \
|
|
|
d8e7ea |
- &hash_pbs, "HASH")) \
|
|
|
d8e7ea |
- return STF_INTERNAL_ERROR; \
|
|
|
d8e7ea |
- close_output_pbs(&hash_pbs); \
|
|
|
d8e7ea |
-}
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
-/* START_HASH_PAYLOAD
|
|
|
d8e7ea |
- *
|
|
|
d8e7ea |
- * Emit a to-be-filled-in hash payload, noting the field start (r_hashval)
|
|
|
d8e7ea |
- * and the start of the part of the message to be hashed (r_hash_start).
|
|
|
d8e7ea |
- * This macro is magic.
|
|
|
d8e7ea |
- * - it can cause the caller to return
|
|
|
d8e7ea |
- * - it references variables local to the caller (r_hashval, r_hash_start, st)
|
|
|
d8e7ea |
- */
|
|
|
d8e7ea |
-#define START_HASH_PAYLOAD(rbody, np) { \
|
|
|
d8e7ea |
- START_HASH_PAYLOAD_NO_R_HASH_START(rbody, np); \
|
|
|
d8e7ea |
- r_hash_start = (rbody).cur; /* hash from after HASH payload */ \
|
|
|
d8e7ea |
-}
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
-/* CHECK_QUICK_HASH
|
|
|
d8e7ea |
- *
|
|
|
d8e7ea |
- * This macro is magic -- it cannot be expressed as a function.
|
|
|
d8e7ea |
- * - it causes the caller to return!
|
|
|
d8e7ea |
- * - it declares local variables and expects the "do_hash" argument
|
|
|
d8e7ea |
- * expression to reference them (hash_val, hash_pbs)
|
|
|
d8e7ea |
- */
|
|
|
d8e7ea |
-#define CHECK_QUICK_HASH(md, do_hash, hash_name, msg_name) { \
|
|
|
d8e7ea |
- pb_stream *const hash_pbs = &(md)->chain[ISAKMP_NEXT_HASH]->pbs; \
|
|
|
d8e7ea |
- u_char hash_val[MAX_DIGEST_LEN]; \
|
|
|
d8e7ea |
- size_t hash_len = (do_hash); \
|
|
|
d8e7ea |
- if (pbs_left(hash_pbs) != hash_len || \
|
|
|
d8e7ea |
- !memeq(hash_pbs->cur, hash_val, hash_len)) { \
|
|
|
d8e7ea |
- if (DBGP(DBG_CRYPT)) { \
|
|
|
d8e7ea |
- DBG_dump("received " hash_name ":", \
|
|
|
d8e7ea |
- hash_pbs->cur, pbs_left(hash_pbs)); \
|
|
|
d8e7ea |
- } \
|
|
|
d8e7ea |
- loglog(RC_LOG_SERIOUS, \
|
|
|
d8e7ea |
- "received " hash_name " does not match computed value in " msg_name); \
|
|
|
d8e7ea |
- /* XXX Could send notification back */ \
|
|
|
d8e7ea |
- return STF_FAIL + INVALID_HASH_INFORMATION; \
|
|
|
d8e7ea |
- } \
|
|
|
d8e7ea |
- }
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
-size_t quick_mode_hash12(u_char *dest, const u_char *start,
|
|
|
d8e7ea |
- const u_char *roof,
|
|
|
d8e7ea |
- const struct state *st, const msgid_t *msgid,
|
|
|
d8e7ea |
- bool hash2);
|
|
|
d8e7ea |
-
|
|
|
d8e7ea |
extern stf_status send_isakmp_notification(struct state *st,
|
|
|
d8e7ea |
uint16_t type, const void *data,
|
|
|
d8e7ea |
size_t len);
|
|
|
d8e7ea |
diff -Naur libreswan-3.29-orig/programs/pluto/Makefile libreswan-3.29/programs/pluto/Makefile
|
|
|
d8e7ea |
--- libreswan-3.29-orig/programs/pluto/Makefile 2019-06-10 10:22:04.000000000 -0400
|
|
|
d8e7ea |
+++ libreswan-3.29/programs/pluto/Makefile 2019-06-11 19:23:19.841729230 -0400
|
|
|
d8e7ea |
@@ -215,6 +215,7 @@
|
|
|
d8e7ea |
OBJS += ikev2_ipseckey.o
|
|
|
d8e7ea |
endif
|
|
|
d8e7ea |
OBJS += ikev1.o ikev1_main.o ikev1_quick.o ikev1_dpd.o ikev1_spdb_struct.o ikev1_msgid.o
|
|
|
d8e7ea |
+OBJS += ikev1_hash.o
|
|
|
d8e7ea |
OBJS += ikev2.o ikev2_parent.o ikev2_child.o ikev2_spdb_struct.o
|
|
|
d8e7ea |
OBJS += ikev2_ecdsa.o ikev2_rsa.o ikev2_psk.o ikev2_ppk.o ikev2_crypto.o
|
|
|
d8e7ea |
OBJS += ikev2_redirect.o
|