1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
|
/* IKEv1 message contents, for libreswan
*
* Copyright (C) 2019 Andrew Cagney
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "shunk.h"
#include "id.h"
#include "connections.h"
#include "packet.h"
#include "ikev1_message.h"
#include "diag.h"
#include "lswlog.h"
#include "unpack.h"
#include "demux.h"
#include "crypt_ke.h"
#include "crypt_cipher.h"
#include "crypt_hash.h"
struct isakmp_ipsec_id build_v1_id_payload(const struct host_end *end, shunk_t *body)
{
struct isakmp_ipsec_id id_hd = {
.isaiid_idtype = id_to_payload(&end->id, &end->addr, body),
};
return id_hd;
}
bool out_raw(const void *bytes, size_t len, struct pbs_out *outs, const char *name)
{
if (!pbs_out_raw(outs, bytes, len, name)) {
/* already logged */
return false;
}
return true;
}
bool ikev1_justship_nonce(chunk_t *n, struct pbs_out *outs,
const char *name)
{
return ikev1_out_generic_chunk(&isakmp_nonce_desc, outs, *n, name);
}
bool ikev1_ship_nonce(chunk_t *n, chunk_t *nonce,
struct pbs_out *outs, const char *name)
{
unpack_nonce(n, nonce);
return ikev1_justship_nonce(n, outs, name);
}
v1_notification_t accept_v1_nonce(struct logger *logger,
struct msg_digest *md, chunk_t *dest,
const char *name)
{
struct pbs_in *nonce_pbs = &md->chain[ISAKMP_NEXT_NONCE]->pbs;
size_t len = pbs_left(nonce_pbs);
if (len < IKEv1_MINIMUM_NONCE_SIZE || IKEv1_MAXIMUM_NONCE_SIZE < len) {
llog(RC_LOG, logger, "%s length not between %d and %d",
name, IKEv1_MINIMUM_NONCE_SIZE, IKEv1_MAXIMUM_NONCE_SIZE);
return v1N_PAYLOAD_MALFORMED; /* ??? */
}
replace_chunk(dest, pbs_in_left(nonce_pbs), "nonce");
passert(len == dest->len);
return v1N_NOTHING_WRONG;
}
/*
* package up the calculate KE value, and emit it as a KE payload.
* used by IKEv1: main, aggressive, and quick (in PFS mode).
*/
bool ikev1_justship_KE(struct logger *logger, chunk_t *g, struct pbs_out *outs)
{
switch (impair.ke_payload) {
case IMPAIR_EMIT_NO:
return ikev1_out_generic_chunk(&isakmp_keyex_desc, outs, *g,
"keyex value");
case IMPAIR_EMIT_OMIT:
llog(RC_LOG, logger, "IMPAIR: sending no KE (g^x) payload");
return true;
case IMPAIR_EMIT_EMPTY:
llog(RC_LOG, logger, "IMPAIR: sending empty KE (g^x)");
return ikev1_out_generic_chunk(&isakmp_keyex_desc, outs,
EMPTY_CHUNK, "empty KE");
default:
{
struct pbs_out z;
uint8_t byte = impair.ke_payload - IMPAIR_EMIT_ROOF;
llog(RC_LOG, logger, "IMPAIR: sending bogus KE (g^x) == %u value to break DH calculations", byte);
/* Only used to test sending/receiving bogus g^x */
return ikev1_out_generic(&isakmp_keyex_desc, outs, &z) &&
pbs_out_repeated_byte(&z, byte, g->len, "fake g^x") &&
(close_output_pbs(&z), true);
}
}
}
bool ikev1_ship_KE(struct state *st, struct dh_local_secret *local_secret,
chunk_t *g, struct pbs_out *outs)
{
unpack_KE_from_helper(st, local_secret, g);
return ikev1_justship_KE(st->logger, g, outs);
}
/*
* In IKEv1, some implementations (including
* freeswan/openswan/libreswan) interpreted the RFC that the whole IKE
* message must padded to a multiple of 4 octets, but other
* implementations (i.e. Checkpoint in Aggressive Mode) drop padded
* IKE packets.
*
* It's not clear this came from as:
*
* IKEv1 RFC 2409, describes how block cipher's always need to be
* padded (with the last byte the pad length) (Libreswan instead
* zero pads).
*
* IKEv1 RFC 2408, section 3.6 Transform Payload, just states that
* the payload isn't padded so the message may need to be 4-byte
* padded (suspect there's an underlying assumption that all packets
* are 4-byte aligned).
*
* Also note that MODECFG (which includes XAUTH) code was calling
* close_v1_message() and that caused MODECFG attributes to be padded.
* This is really broken. The only thing saving us is implementations
* seeing a truncated attribute with a zero length (if it had been
* non-zero, hmm...).
* The ikepad= option can be set to yes or no on a per-connection basis,
* and defaults to yes.
*/
bool emit_v1_zero_padding(struct pbs_out *pbs)
{
size_t padding = pad_up(pbs_out_all(pbs).len, 4);
if (padding == 0) {
ldbg(pbs->logger, "no IKEv1 message padding required");
} else {
ldbg(pbs->logger, "padding IKEv1 message with %zu bytes", padding);
if (!pbs_out_zero(pbs, padding, "message padding")) {
/* already logged */
return false; /*fatal*/
}
}
return true;
}
bool close_v1_message(struct pbs_out *pbs, const struct ike_sa *ike)
{
if (pbad(ike == NULL)) {
return false;
}
if (ike->sa.st_connection->config->v1_ikepad.message) {
if (!emit_v1_zero_padding(pbs)) {
/* already logged */
return false; /*fatal*/
}
}
close_output_pbs(pbs);
return true;
}
/*
* encrypt message, sans fixed part of header
* IV is fetched from st->st_new_iv and stored into st->st_iv.
* The theory is that there will be no "backing out", so we commit to IV.
* We also close the pbs.
*/
bool close_and_encrypt_v1_message(struct ike_sa *ike,
struct pbs_out *pbs,
struct crypt_mac *iv)
{
struct logger *logger = pbs->logger;
const struct encrypt_desc *e = ike->sa.st_oakley.ta_encrypt;
/*
* Pad the message (header and body) to message alignment
* which is normally 4-bytes.
*/
if (ike->sa.st_connection->config->v1_ikepad.message) {
if (!emit_v1_zero_padding(pbs)) {
/* already logged */
return false; /*fatal*/
}
}
/*
* Next pad the encrypted part of the payload so it is
* alligned with the encryption's blocksize.
*
* Since the header is isn't encrypted, this doesn't include
* the header. See the description associated with the
* definition of struct isakmp_hdr in packet.h.
*
* For a block cipher the alignment is probably 16-bytes, but
* for other ciphers it can be 1-byte!
*
* XXX: The RFC says that the final pad byte should be the
* length (see IKEv2) which means that there is never zero
* bytes of padding, but this code doesn't do this.
* Fortunately, everything ignores that byte.
*/
shunk_t message = pbs_out_all(pbs);
shunk_t unpadded_encrypt = hunk_slice(message, sizeof(struct isakmp_hdr), message.len);
size_t encrypt_padding = pad_up(unpadded_encrypt.len, e->enc_blocksize);
if (encrypt_padding != 0) {
if (!pbs_out_zero(pbs, encrypt_padding, "encryption padding")) {
/* already logged */
return false; /*fatal*/
}
}
/*
* Now mark out the block that will be encrypted.
*
* Hack to get at writeable buffer! IKEv2 does something
* vaguely similar.
*/
chunk_t padded_message = chunk2(pbs->start, pbs_out_all(pbs).len);
chunk_t padded_encrypt = hunk_slice(padded_message,
sizeof(struct isakmp_hdr),
padded_message.len);
/*
* Finally, re-pad the entire message (header and body) to
* message alignment.
*
* This should be a no-op?
*
* XXX: note the double padding (triple if you count the code
* paths that call close_v1_message(), instead of
* pbs_out_close(), when closing an XAUTH / MODECFG payload.
*/
if (ike->sa.st_connection->config->v1_ikepad.message) {
if (!emit_v1_zero_padding(pbs)) {
/* already logged */
return false; /*fatal*/
}
}
close_output_pbs(pbs);
/* XXX: not ldbg(pbs->logger) as can be NULL */
dbg("encrypt unpadded %zu padding %zu padded %zu bytes",
unpadded_encrypt.len, encrypt_padding, padded_encrypt.len);
if (LDBGP(DBG_CRYPT, logger)) {
LDBG_log(logger, "encrypting:");
LDBG_hunk(logger, padded_encrypt);
LDBG_log(logger, "IV:");
LDBG_hunk(logger, *iv);
}
/*
* The IV is always truncated down to .enc_blocksize.
*/
PASSERT(logger, iv->len == e->enc_blocksize);
cipher_ikev1(e, ENCRYPT, padded_encrypt,
iv, ike->sa.st_enc_key_nss,
logger);
if (LDBGP(DBG_CRYPT, logger)) {
LDBG_log(logger, "next IV:");
LDBG_hunk(logger, *iv);
}
return true;
}
/*
* Compute Phase 2 IV.
*
* Uses Phase 1 IV from st_iv; puts result in st_new_iv.
*/
struct crypt_mac new_phase2_iv(const struct ike_sa *ike,
const msgid_t msgid,
const char *why, where_t where)
{
struct logger *logger = ike->sa.logger;
const struct encrypt_desc *e = ike->sa.st_oakley.ta_encrypt;
pdbg(logger, "phase2_iv: %s "PRI_WHERE, why, pri_where(where));
const struct hash_desc *h = ike->sa.st_oakley.ta_prf->hasher;
PASSERT_WHERE(logger, where, h != NULL);
struct crypt_hash *ctx = crypt_hash_init("Phase 2 IV", h, logger);
/*
* Start with the Phase 1 IV.
*
* This is the output block from the last encrypt/decrypt
* operation. Hence, it is .enc_blocksize long.
*/
PASSERT_WHERE(logger, where, ike->sa.st_v1_phase_1_iv.len == e->enc_blocksize);
crypt_hash_digest_hunk(ctx, "Phase 1 IV", ike->sa.st_v1_phase_1_iv);
/* plus the MSGID in network order */
PASSERT_WHERE(logger, where, sizeof(msgid_t) == sizeof(uint32_t));
PASSERT_WHERE(logger, where, msgid > 0); /* i.e., not Phase 1! */
msgid_t raw_msgid = htonl(msgid);
crypt_hash_digest_thing(ctx, "Message ID", raw_msgid);
/* save in new */
struct crypt_mac iv = crypt_hash_final_mac(&ctx);
/*
* The Phase 2 IV.
*
* Again, this is the size of an encryption block, ready for
* feeding into the encryption algorithm.
*/
PASSERT_WHERE(ike->sa.logger, where, iv.len >= e->enc_blocksize);
iv.len = e->enc_blocksize; /* truncate */
return iv;
}
void update_v1_phase_1_iv(struct ike_sa *ike, struct crypt_mac iv, where_t where)
{
LDBGP_JAMBUF(DBG_BASE, ike->sa.logger, buf) {
jam_string(buf, "updating Phase 1 IV .st_v1_phase_1_iv from ");
jam_hex_hunk(buf, ike->sa.st_v1_phase_1_iv);
jam_string(buf, " to ");
jam_hex_hunk(buf, iv);
jam_string(buf, " ");
jam_where(buf, where);
}
/*
* The Phase 1 IV, is always truncated down to the
* .enc_blocksize.
*/
const struct encrypt_desc *e = ike->sa.st_oakley.ta_encrypt;
PASSERT_WHERE(ike->sa.logger, where, iv.len == e->enc_blocksize);
ike->sa.st_v1_phase_1_iv = iv;
}
|