~ubuntu-branches/ubuntu/lucid/wpasupplicant/lucid-updates

« back to all changes in this revision

Viewing changes to src/eap_server/ikev2.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2008-12-02 20:52:16 UTC
  • mfrom: (2.1.30 intrepid)
  • Revision ID: james.westby@ubuntu.com-20081202205216-72fqozu84sdt89a8
Tags: 0.6.4-3
Bugfix: "Missing -d in testing for a directory in init script". 
Thanks to Braun Gábor <braung@renyi.hu> for reporting and the patch.
(Closes: #506328)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * IKEv2 initiator (RFC 4306) for EAP-IKEV2
 
3
 * Copyright (c) 2007, Jouni Malinen <j@w1.fi>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License version 2 as
 
7
 * published by the Free Software Foundation.
 
8
 *
 
9
 * Alternatively, this software may be distributed under the terms of BSD
 
10
 * license.
 
11
 *
 
12
 * See README and COPYING for more details.
 
13
 */
 
14
 
 
15
#include "includes.h"
 
16
 
 
17
#include "common.h"
 
18
#include "dh_groups.h"
 
19
#include "ikev2.h"
 
20
 
 
21
 
 
22
static int ikev2_process_idr(struct ikev2_initiator_data *data,
 
23
                             const u8 *idr, size_t idr_len);
 
24
 
 
25
 
 
26
void ikev2_initiator_deinit(struct ikev2_initiator_data *data)
 
27
{
 
28
        ikev2_free_keys(&data->keys);
 
29
        wpabuf_free(data->r_dh_public);
 
30
        wpabuf_free(data->i_dh_private);
 
31
        os_free(data->IDi);
 
32
        os_free(data->IDr);
 
33
        os_free(data->shared_secret);
 
34
        wpabuf_free(data->i_sign_msg);
 
35
        wpabuf_free(data->r_sign_msg);
 
36
        os_free(data->key_pad);
 
37
}
 
38
 
 
39
 
 
40
static int ikev2_derive_keys(struct ikev2_initiator_data *data)
 
41
{
 
42
        u8 *buf, *pos, *pad, skeyseed[IKEV2_MAX_HASH_LEN];
 
43
        size_t buf_len, pad_len;
 
44
        struct wpabuf *shared;
 
45
        const struct ikev2_integ_alg *integ;
 
46
        const struct ikev2_prf_alg *prf;
 
47
        const struct ikev2_encr_alg *encr;
 
48
        int ret;
 
49
        const u8 *addr[2];
 
50
        size_t len[2];
 
51
 
 
52
        /* RFC 4306, Sect. 2.14 */
 
53
 
 
54
        integ = ikev2_get_integ(data->proposal.integ);
 
55
        prf = ikev2_get_prf(data->proposal.prf);
 
56
        encr = ikev2_get_encr(data->proposal.encr);
 
57
        if (integ == NULL || prf == NULL || encr == NULL) {
 
58
                wpa_printf(MSG_INFO, "IKEV2: Unsupported proposal");
 
59
                return -1;
 
60
        }
 
61
 
 
62
        shared = dh_derive_shared(data->r_dh_public, data->i_dh_private,
 
63
                                  data->dh);
 
64
        if (shared == NULL)
 
65
                return -1;
 
66
 
 
67
        /* Construct Ni | Nr | SPIi | SPIr */
 
68
 
 
69
        buf_len = data->i_nonce_len + data->r_nonce_len + 2 * IKEV2_SPI_LEN;
 
70
        buf = os_malloc(buf_len);
 
71
        if (buf == NULL) {
 
72
                wpabuf_free(shared);
 
73
                return -1;
 
74
        }
 
75
 
 
76
        pos = buf;
 
77
        os_memcpy(pos, data->i_nonce, data->i_nonce_len);
 
78
        pos += data->i_nonce_len;
 
79
        os_memcpy(pos, data->r_nonce, data->r_nonce_len);
 
80
        pos += data->r_nonce_len;
 
81
        os_memcpy(pos, data->i_spi, IKEV2_SPI_LEN);
 
82
        pos += IKEV2_SPI_LEN;
 
83
        os_memcpy(pos, data->r_spi, IKEV2_SPI_LEN);
 
84
 
 
85
        /* SKEYSEED = prf(Ni | Nr, g^ir) */
 
86
 
 
87
        /* Use zero-padding per RFC 4306, Sect. 2.14 */
 
88
        pad_len = data->dh->prime_len - wpabuf_len(shared);
 
89
        pad = os_zalloc(pad_len ? pad_len : 1);
 
90
        if (pad == NULL) {
 
91
                wpabuf_free(shared);
 
92
                os_free(buf);
 
93
                return -1;
 
94
        }
 
95
        addr[0] = pad;
 
96
        len[0] = pad_len;
 
97
        addr[1] = wpabuf_head(shared);
 
98
        len[1] = wpabuf_len(shared);
 
99
        if (ikev2_prf_hash(prf->id, buf, data->i_nonce_len + data->r_nonce_len,
 
100
                           2, addr, len, skeyseed) < 0) {
 
101
                wpabuf_free(shared);
 
102
                os_free(buf);
 
103
                os_free(pad);
 
104
                return -1;
 
105
        }
 
106
        os_free(pad);
 
107
        wpabuf_free(shared);
 
108
 
 
109
        /* DH parameters are not needed anymore, so free them */
 
110
        wpabuf_free(data->r_dh_public);
 
111
        data->r_dh_public = NULL;
 
112
        wpabuf_free(data->i_dh_private);
 
113
        data->i_dh_private = NULL;
 
114
 
 
115
        wpa_hexdump_key(MSG_DEBUG, "IKEV2: SKEYSEED",
 
116
                        skeyseed, prf->hash_len);
 
117
 
 
118
        ret = ikev2_derive_sk_keys(prf, integ, encr, skeyseed, buf, buf_len,
 
119
                                   &data->keys);
 
120
        os_free(buf);
 
121
        return ret;
 
122
}
 
123
 
 
124
 
 
125
static int ikev2_parse_transform(struct ikev2_initiator_data *data,
 
126
                                 struct ikev2_proposal_data *prop,
 
127
                                 const u8 *pos, const u8 *end)
 
128
{
 
129
        int transform_len;
 
130
        const struct ikev2_transform *t;
 
131
        u16 transform_id;
 
132
        const u8 *tend;
 
133
 
 
134
        if (end - pos < (int) sizeof(*t)) {
 
135
                wpa_printf(MSG_INFO, "IKEV2: Too short transform");
 
136
                return -1;
 
137
        }
 
138
 
 
139
        t = (const struct ikev2_transform *) pos;
 
140
        transform_len = WPA_GET_BE16(t->transform_length);
 
141
        if (transform_len < (int) sizeof(*t) || pos + transform_len > end) {
 
142
                wpa_printf(MSG_INFO, "IKEV2: Invalid transform length %d",
 
143
                           transform_len);
 
144
                return -1;
 
145
        }
 
146
        tend = pos + transform_len;
 
147
 
 
148
        transform_id = WPA_GET_BE16(t->transform_id);
 
149
 
 
150
        wpa_printf(MSG_DEBUG, "IKEV2:   Transform:");
 
151
        wpa_printf(MSG_DEBUG, "IKEV2:     Type: %d  Transform Length: %d  "
 
152
                   "Transform Type: %d  Transform ID: %d",
 
153
                   t->type, transform_len, t->transform_type, transform_id);
 
154
 
 
155
        if (t->type != 0 && t->type != 3) {
 
156
                wpa_printf(MSG_INFO, "IKEV2: Unexpected Transform type");
 
157
                return -1;
 
158
        }
 
159
 
 
160
        pos = (const u8 *) (t + 1);
 
161
        if (pos < tend) {
 
162
                wpa_hexdump(MSG_DEBUG, "IKEV2:     Transform Attributes",
 
163
                            pos, tend - pos);
 
164
        }
 
165
 
 
166
        switch (t->transform_type) {
 
167
        case IKEV2_TRANSFORM_ENCR:
 
168
                if (ikev2_get_encr(transform_id) &&
 
169
                    transform_id == data->proposal.encr) {
 
170
                        if (transform_id == ENCR_AES_CBC) {
 
171
                                if (tend - pos != 4) {
 
172
                                        wpa_printf(MSG_DEBUG, "IKEV2: No "
 
173
                                                   "Transform Attr for AES");
 
174
                                        break;
 
175
                                }
 
176
                                if (WPA_GET_BE16(pos) != 0x800e) {
 
177
                                        wpa_printf(MSG_DEBUG, "IKEV2: Not a "
 
178
                                                   "Key Size attribute for "
 
179
                                                   "AES");
 
180
                                        break;
 
181
                                }
 
182
                                if (WPA_GET_BE16(pos + 2) != 128) {
 
183
                                        wpa_printf(MSG_DEBUG, "IKEV2: "
 
184
                                                   "Unsupported AES key size "
 
185
                                                   "%d bits",
 
186
                                                   WPA_GET_BE16(pos + 2));
 
187
                                        break;
 
188
                                }
 
189
                        }
 
190
                        prop->encr = transform_id;
 
191
                }
 
192
                break;
 
193
        case IKEV2_TRANSFORM_PRF:
 
194
                if (ikev2_get_prf(transform_id) &&
 
195
                    transform_id == data->proposal.prf)
 
196
                        prop->prf = transform_id;
 
197
                break;
 
198
        case IKEV2_TRANSFORM_INTEG:
 
199
                if (ikev2_get_integ(transform_id) &&
 
200
                    transform_id == data->proposal.integ)
 
201
                        prop->integ = transform_id;
 
202
                break;
 
203
        case IKEV2_TRANSFORM_DH:
 
204
                if (dh_groups_get(transform_id) &&
 
205
                    transform_id == data->proposal.dh)
 
206
                        prop->dh = transform_id;
 
207
                break;
 
208
        }
 
209
 
 
210
        return transform_len;
 
211
}
 
212
 
 
213
 
 
214
static int ikev2_parse_proposal(struct ikev2_initiator_data *data,
 
215
                                struct ikev2_proposal_data *prop,
 
216
                                const u8 *pos, const u8 *end)
 
217
{
 
218
        const u8 *pend, *ppos;
 
219
        int proposal_len, i;
 
220
        const struct ikev2_proposal *p;
 
221
 
 
222
        if (end - pos < (int) sizeof(*p)) {
 
223
                wpa_printf(MSG_INFO, "IKEV2: Too short proposal");
 
224
                return -1;
 
225
        }
 
226
 
 
227
        p = (const struct ikev2_proposal *) pos;
 
228
        proposal_len = WPA_GET_BE16(p->proposal_length);
 
229
        if (proposal_len < (int) sizeof(*p) || pos + proposal_len > end) {
 
230
                wpa_printf(MSG_INFO, "IKEV2: Invalid proposal length %d",
 
231
                           proposal_len);
 
232
                return -1;
 
233
        }
 
234
        wpa_printf(MSG_DEBUG, "IKEV2: SAi1 Proposal # %d",
 
235
                   p->proposal_num);
 
236
        wpa_printf(MSG_DEBUG, "IKEV2:   Type: %d  Proposal Length: %d "
 
237
                   " Protocol ID: %d",
 
238
                   p->type, proposal_len, p->protocol_id);
 
239
        wpa_printf(MSG_DEBUG, "IKEV2:   SPI Size: %d  Transforms: %d",
 
240
                   p->spi_size, p->num_transforms);
 
241
 
 
242
        if (p->type != 0 && p->type != 2) {
 
243
                wpa_printf(MSG_INFO, "IKEV2: Unexpected Proposal type");
 
244
                return -1;
 
245
        }
 
246
 
 
247
        if (p->protocol_id != IKEV2_PROTOCOL_IKE) {
 
248
                wpa_printf(MSG_DEBUG, "IKEV2: Unexpected Protocol ID "
 
249
                           "(only IKE allowed for EAP-IKEv2)");
 
250
                return -1;
 
251
        }
 
252
 
 
253
        if (p->proposal_num != prop->proposal_num) {
 
254
                if (p->proposal_num == prop->proposal_num + 1)
 
255
                        prop->proposal_num = p->proposal_num;
 
256
                else {
 
257
                        wpa_printf(MSG_INFO, "IKEV2: Unexpected Proposal #");
 
258
                        return -1;
 
259
                }
 
260
        }
 
261
 
 
262
        ppos = (const u8 *) (p + 1);
 
263
        pend = pos + proposal_len;
 
264
        if (ppos + p->spi_size > pend) {
 
265
                wpa_printf(MSG_INFO, "IKEV2: Not enough room for SPI "
 
266
                           "in proposal");
 
267
                return -1;
 
268
        }
 
269
        if (p->spi_size) {
 
270
                wpa_hexdump(MSG_DEBUG, "IKEV2:    SPI",
 
271
                            ppos, p->spi_size);
 
272
                ppos += p->spi_size;
 
273
        }
 
274
 
 
275
        /*
 
276
         * For initial IKE_SA negotiation, SPI Size MUST be zero; for
 
277
         * subsequent negotiations, it must be 8 for IKE. We only support
 
278
         * initial case for now.
 
279
         */
 
280
        if (p->spi_size != 0) {
 
281
                wpa_printf(MSG_INFO, "IKEV2: Unexpected SPI Size");
 
282
                return -1;
 
283
        }
 
284
 
 
285
        if (p->num_transforms == 0) {
 
286
                wpa_printf(MSG_INFO, "IKEV2: At least one transform required");
 
287
                return -1;
 
288
        }
 
289
 
 
290
        for (i = 0; i < (int) p->num_transforms; i++) {
 
291
                int tlen = ikev2_parse_transform(data, prop, ppos, pend);
 
292
                if (tlen < 0)
 
293
                        return -1;
 
294
                ppos += tlen;
 
295
        }
 
296
 
 
297
        if (ppos != pend) {
 
298
                wpa_printf(MSG_INFO, "IKEV2: Unexpected data after "
 
299
                           "transforms");
 
300
                return -1;
 
301
        }
 
302
 
 
303
        return proposal_len;
 
304
}
 
305
 
 
306
 
 
307
static int ikev2_process_sar1(struct ikev2_initiator_data *data,
 
308
                              const u8 *sar1, size_t sar1_len)
 
309
{
 
310
        struct ikev2_proposal_data prop;
 
311
        const u8 *pos, *end;
 
312
        int found = 0;
 
313
 
 
314
        /* Security Association Payloads: <Proposals> */
 
315
 
 
316
        if (sar1 == NULL) {
 
317
                wpa_printf(MSG_INFO, "IKEV2: SAr1 not received");
 
318
                return -1;
 
319
        }
 
320
 
 
321
        os_memset(&prop, 0, sizeof(prop));
 
322
        prop.proposal_num = 1;
 
323
 
 
324
        pos = sar1;
 
325
        end = sar1 + sar1_len;
 
326
 
 
327
        while (pos < end) {
 
328
                int plen;
 
329
 
 
330
                prop.integ = -1;
 
331
                prop.prf = -1;
 
332
                prop.encr = -1;
 
333
                prop.dh = -1;
 
334
                plen = ikev2_parse_proposal(data, &prop, pos, end);
 
335
                if (plen < 0)
 
336
                        return -1;
 
337
 
 
338
                if (!found && prop.integ != -1 && prop.prf != -1 &&
 
339
                    prop.encr != -1 && prop.dh != -1) {
 
340
                        found = 1;
 
341
                }
 
342
 
 
343
                pos += plen;
 
344
 
 
345
                /* Only one proposal expected in SAr */
 
346
                break;
 
347
        }
 
348
 
 
349
        if (pos != end) {
 
350
                wpa_printf(MSG_INFO, "IKEV2: Unexpected data after proposal");
 
351
                return -1;
 
352
        }
 
353
 
 
354
        if (!found) {
 
355
                wpa_printf(MSG_INFO, "IKEV2: No acceptable proposal found");
 
356
                return -1;
 
357
        }
 
358
 
 
359
        wpa_printf(MSG_DEBUG, "IKEV2: Accepted proposal #%d: ENCR:%d PRF:%d "
 
360
                   "INTEG:%d D-H:%d", data->proposal.proposal_num,
 
361
                   data->proposal.encr, data->proposal.prf,
 
362
                   data->proposal.integ, data->proposal.dh);
 
363
 
 
364
        return 0;
 
365
}
 
366
 
 
367
 
 
368
static int ikev2_process_ker(struct ikev2_initiator_data *data,
 
369
                             const u8 *ker, size_t ker_len)
 
370
{
 
371
        u16 group;
 
372
 
 
373
        /*
 
374
         * Key Exchange Payload:
 
375
         * DH Group # (16 bits)
 
376
         * RESERVED (16 bits)
 
377
         * Key Exchange Data (Diffie-Hellman public value)
 
378
         */
 
379
 
 
380
        if (ker == NULL) {
 
381
                wpa_printf(MSG_INFO, "IKEV2: KEr not received");
 
382
                return -1;
 
383
        }
 
384
 
 
385
        if (ker_len < 4 + 96) {
 
386
                wpa_printf(MSG_INFO, "IKEV2: Too show Key Exchange Payload");
 
387
                return -1;
 
388
        }
 
389
 
 
390
        group = WPA_GET_BE16(ker);
 
391
        wpa_printf(MSG_DEBUG, "IKEV2: KEr DH Group #%u", group);
 
392
 
 
393
        if (group != data->proposal.dh) {
 
394
                wpa_printf(MSG_DEBUG, "IKEV2: KEr DH Group #%u does not match "
 
395
                           "with the selected proposal (%u)",
 
396
                           group, data->proposal.dh);
 
397
                return -1;
 
398
        }
 
399
 
 
400
        if (data->dh == NULL) {
 
401
                wpa_printf(MSG_INFO, "IKEV2: Unsupported DH group");
 
402
                return -1;
 
403
        }
 
404
 
 
405
        /* RFC 4306, Section 3.4:
 
406
         * The length of DH public value MUST be equal to the lenght of the
 
407
         * prime modulus.
 
408
         */
 
409
        if (ker_len - 4 != data->dh->prime_len) {
 
410
                wpa_printf(MSG_INFO, "IKEV2: Invalid DH public value length "
 
411
                           "%ld (expected %ld)",
 
412
                           (long) (ker_len - 4), (long) data->dh->prime_len);
 
413
                return -1;
 
414
        }
 
415
 
 
416
        wpabuf_free(data->r_dh_public);
 
417
        data->r_dh_public = wpabuf_alloc_copy(ker + 4, ker_len - 4);
 
418
        if (data->r_dh_public == NULL)
 
419
                return -1;
 
420
 
 
421
        wpa_hexdump_buf(MSG_DEBUG, "IKEV2: KEr Diffie-Hellman Public Value",
 
422
                        data->r_dh_public);
 
423
        
 
424
        return 0;
 
425
}
 
426
 
 
427
 
 
428
static int ikev2_process_nr(struct ikev2_initiator_data *data,
 
429
                            const u8 *nr, size_t nr_len)
 
430
{
 
431
        if (nr == NULL) {
 
432
                wpa_printf(MSG_INFO, "IKEV2: Nr not received");
 
433
                return -1;
 
434
        }
 
435
 
 
436
        if (nr_len < IKEV2_NONCE_MIN_LEN || nr_len > IKEV2_NONCE_MAX_LEN) {
 
437
                wpa_printf(MSG_INFO, "IKEV2: Invalid Nr length %ld",
 
438
                           (long) nr_len);
 
439
                return -1;
 
440
        }
 
441
 
 
442
        data->r_nonce_len = nr_len;
 
443
        os_memcpy(data->r_nonce, nr, nr_len);
 
444
        wpa_hexdump(MSG_MSGDUMP, "IKEV2: Nr",
 
445
                    data->r_nonce, data->r_nonce_len);
 
446
 
 
447
        return 0;
 
448
}
 
449
 
 
450
 
 
451
static int ikev2_process_sa_init_encr(struct ikev2_initiator_data *data,
 
452
                                      const struct ikev2_hdr *hdr,
 
453
                                      const u8 *encrypted,
 
454
                                      size_t encrypted_len, u8 next_payload)
 
455
{
 
456
        u8 *decrypted;
 
457
        size_t decrypted_len;
 
458
        struct ikev2_payloads pl;
 
459
        int ret = 0;
 
460
 
 
461
        decrypted = ikev2_decrypt_payload(data->proposal.encr,
 
462
                                          data->proposal.integ, &data->keys, 0,
 
463
                                          hdr, encrypted, encrypted_len,
 
464
                                          &decrypted_len);
 
465
        if (decrypted == NULL)
 
466
                return -1;
 
467
 
 
468
        wpa_printf(MSG_DEBUG, "IKEV2: Processing decrypted payloads");
 
469
 
 
470
        if (ikev2_parse_payloads(&pl, next_payload, decrypted,
 
471
                                 decrypted + decrypted_len) < 0) {
 
472
                wpa_printf(MSG_INFO, "IKEV2: Failed to parse decrypted "
 
473
                           "payloads");
 
474
                return -1;
 
475
        }
 
476
 
 
477
        if (pl.idr)
 
478
                ret = ikev2_process_idr(data, pl.idr, pl.idr_len);
 
479
 
 
480
        os_free(decrypted);
 
481
 
 
482
        return ret;
 
483
}
 
484
 
 
485
 
 
486
static int ikev2_process_sa_init(struct ikev2_initiator_data *data,
 
487
                                 const struct ikev2_hdr *hdr,
 
488
                                 struct ikev2_payloads *pl)
 
489
{
 
490
        if (ikev2_process_sar1(data, pl->sa, pl->sa_len) < 0 ||
 
491
            ikev2_process_ker(data, pl->ke, pl->ke_len) < 0 ||
 
492
            ikev2_process_nr(data, pl->nonce, pl->nonce_len) < 0)
 
493
                return -1;
 
494
 
 
495
        os_memcpy(data->r_spi, hdr->r_spi, IKEV2_SPI_LEN);
 
496
 
 
497
        if (ikev2_derive_keys(data) < 0)
 
498
                return -1;
 
499
 
 
500
        if (pl->encrypted) {
 
501
                wpa_printf(MSG_DEBUG, "IKEV2: Encrypted payload in SA_INIT - "
 
502
                           "try to get IDr from it");
 
503
                if (ikev2_process_sa_init_encr(data, hdr, pl->encrypted,
 
504
                                               pl->encrypted_len,
 
505
                                               pl->encr_next_payload) < 0) {
 
506
                        wpa_printf(MSG_INFO, "IKEV2: Failed to process "
 
507
                                   "encrypted payload");
 
508
                        return -1;
 
509
                }
 
510
        }
 
511
 
 
512
        data->state = SA_AUTH;
 
513
 
 
514
        return 0;
 
515
}
 
516
 
 
517
 
 
518
static int ikev2_process_idr(struct ikev2_initiator_data *data,
 
519
                             const u8 *idr, size_t idr_len)
 
520
{
 
521
        u8 id_type;
 
522
 
 
523
        if (idr == NULL) {
 
524
                wpa_printf(MSG_INFO, "IKEV2: No IDr received");
 
525
                return -1;
 
526
        }
 
527
 
 
528
        if (idr_len < 4) {
 
529
                wpa_printf(MSG_INFO, "IKEV2: Too short IDr payload");
 
530
                return -1;
 
531
        }
 
532
 
 
533
        id_type = idr[0];
 
534
        idr += 4;
 
535
        idr_len -= 4;
 
536
 
 
537
        wpa_printf(MSG_DEBUG, "IKEV2: IDr ID Type %d", id_type);
 
538
        wpa_hexdump_ascii(MSG_DEBUG, "IKEV2: IDr", idr, idr_len);
 
539
        if (data->IDr) {
 
540
                if (id_type != data->IDr_type || idr_len != data->IDr_len ||
 
541
                    os_memcmp(idr, data->IDr, idr_len) != 0) {
 
542
                        wpa_printf(MSG_INFO, "IKEV2: IDr differs from the one "
 
543
                                   "received earlier");
 
544
                        wpa_printf(MSG_DEBUG, "IKEV2: Previous IDr ID Type %d",
 
545
                                   id_type);
 
546
                        wpa_hexdump_ascii(MSG_DEBUG, "Previous IKEV2: IDr",
 
547
                                          data->IDr, data->IDr_len);
 
548
                        return -1;
 
549
                }
 
550
                os_free(data->IDr);
 
551
        }
 
552
        data->IDr = os_malloc(idr_len);
 
553
        if (data->IDr == NULL)
 
554
                return -1;
 
555
        os_memcpy(data->IDr, idr, idr_len);
 
556
        data->IDr_len = idr_len;
 
557
        data->IDr_type = id_type;
 
558
 
 
559
        return 0;
 
560
}
 
561
 
 
562
 
 
563
static int ikev2_process_cert(struct ikev2_initiator_data *data,
 
564
                              const u8 *cert, size_t cert_len)
 
565
{
 
566
        u8 cert_encoding;
 
567
 
 
568
        if (cert == NULL) {
 
569
                if (data->peer_auth == PEER_AUTH_CERT) {
 
570
                        wpa_printf(MSG_INFO, "IKEV2: No Certificate received");
 
571
                        return -1;
 
572
                }
 
573
                return 0;
 
574
        }
 
575
 
 
576
        if (cert_len < 1) {
 
577
                wpa_printf(MSG_INFO, "IKEV2: No Cert Encoding field");
 
578
                return -1;
 
579
        }
 
580
 
 
581
        cert_encoding = cert[0];
 
582
        cert++;
 
583
        cert_len--;
 
584
 
 
585
        wpa_printf(MSG_DEBUG, "IKEV2: Cert Encoding %d", cert_encoding);
 
586
        wpa_hexdump(MSG_MSGDUMP, "IKEV2: Certificate Data", cert, cert_len);
 
587
 
 
588
        /* TODO: validate certificate */
 
589
 
 
590
        return 0;
 
591
}
 
592
 
 
593
 
 
594
static int ikev2_process_auth_cert(struct ikev2_initiator_data *data,
 
595
                                   u8 method, const u8 *auth, size_t auth_len)
 
596
{
 
597
        if (method != AUTH_RSA_SIGN) {
 
598
                wpa_printf(MSG_INFO, "IKEV2: Unsupported authentication "
 
599
                           "method %d", method);
 
600
                return -1;
 
601
        }
 
602
 
 
603
        /* TODO: validate AUTH */
 
604
        return 0;
 
605
}
 
606
 
 
607
 
 
608
static int ikev2_process_auth_secret(struct ikev2_initiator_data *data,
 
609
                                     u8 method, const u8 *auth,
 
610
                                     size_t auth_len)
 
611
{
 
612
        u8 auth_data[IKEV2_MAX_HASH_LEN];
 
613
        const struct ikev2_prf_alg *prf;
 
614
 
 
615
        if (method != AUTH_SHARED_KEY_MIC) {
 
616
                wpa_printf(MSG_INFO, "IKEV2: Unsupported authentication "
 
617
                           "method %d", method);
 
618
                return -1;
 
619
        }
 
620
 
 
621
        /* msg | Ni | prf(SK_pr,IDr') */
 
622
        if (ikev2_derive_auth_data(data->proposal.prf, data->r_sign_msg,
 
623
                                   data->IDr, data->IDr_len, data->IDr_type,
 
624
                                   &data->keys, 0, data->shared_secret,
 
625
                                   data->shared_secret_len,
 
626
                                   data->i_nonce, data->i_nonce_len,
 
627
                                   data->key_pad, data->key_pad_len,
 
628
                                   auth_data) < 0) {
 
629
                wpa_printf(MSG_INFO, "IKEV2: Could not derive AUTH data");
 
630
                return -1;
 
631
        }
 
632
 
 
633
        wpabuf_free(data->r_sign_msg);
 
634
        data->r_sign_msg = NULL;
 
635
 
 
636
        prf = ikev2_get_prf(data->proposal.prf);
 
637
        if (prf == NULL)
 
638
                return -1;
 
639
 
 
640
        if (auth_len != prf->hash_len ||
 
641
            os_memcmp(auth, auth_data, auth_len) != 0) {
 
642
                wpa_printf(MSG_INFO, "IKEV2: Invalid Authentication Data");
 
643
                wpa_hexdump(MSG_DEBUG, "IKEV2: Received Authentication Data",
 
644
                            auth, auth_len);
 
645
                wpa_hexdump(MSG_DEBUG, "IKEV2: Expected Authentication Data",
 
646
                            auth_data, prf->hash_len);
 
647
                return -1;
 
648
        }
 
649
 
 
650
        wpa_printf(MSG_DEBUG, "IKEV2: Peer authenticated successfully "
 
651
                   "using shared keys");
 
652
 
 
653
        return 0;
 
654
}
 
655
 
 
656
 
 
657
static int ikev2_process_auth(struct ikev2_initiator_data *data,
 
658
                              const u8 *auth, size_t auth_len)
 
659
{
 
660
        u8 auth_method;
 
661
 
 
662
        if (auth == NULL) {
 
663
                wpa_printf(MSG_INFO, "IKEV2: No Authentication Payload");
 
664
                return -1;
 
665
        }
 
666
 
 
667
        if (auth_len < 4) {
 
668
                wpa_printf(MSG_INFO, "IKEV2: Too short Authentication "
 
669
                           "Payload");
 
670
                return -1;
 
671
        }
 
672
 
 
673
        auth_method = auth[0];
 
674
        auth += 4;
 
675
        auth_len -= 4;
 
676
 
 
677
        wpa_printf(MSG_DEBUG, "IKEV2: Auth Method %d", auth_method);
 
678
        wpa_hexdump(MSG_MSGDUMP, "IKEV2: Authentication Data", auth, auth_len);
 
679
 
 
680
        switch (data->peer_auth) {
 
681
        case PEER_AUTH_CERT:
 
682
                return ikev2_process_auth_cert(data, auth_method, auth,
 
683
                                               auth_len);
 
684
        case PEER_AUTH_SECRET:
 
685
                return ikev2_process_auth_secret(data, auth_method, auth,
 
686
                                                 auth_len);
 
687
        }
 
688
 
 
689
        return -1;
 
690
}
 
691
 
 
692
 
 
693
static int ikev2_process_sa_auth_decrypted(struct ikev2_initiator_data *data,
 
694
                                           u8 next_payload,
 
695
                                           u8 *payload, size_t payload_len)
 
696
{
 
697
        struct ikev2_payloads pl;
 
698
 
 
699
        wpa_printf(MSG_DEBUG, "IKEV2: Processing decrypted payloads");
 
700
 
 
701
        if (ikev2_parse_payloads(&pl, next_payload, payload, payload +
 
702
                                 payload_len) < 0) {
 
703
                wpa_printf(MSG_INFO, "IKEV2: Failed to parse decrypted "
 
704
                           "payloads");
 
705
                return -1;
 
706
        }
 
707
 
 
708
        if (ikev2_process_idr(data, pl.idr, pl.idr_len) < 0 ||
 
709
            ikev2_process_cert(data, pl.cert, pl.cert_len) < 0 ||
 
710
            ikev2_process_auth(data, pl.auth, pl.auth_len) < 0)
 
711
                return -1;
 
712
 
 
713
        return 0;
 
714
}
 
715
 
 
716
 
 
717
static int ikev2_process_sa_auth(struct ikev2_initiator_data *data,
 
718
                                 const struct ikev2_hdr *hdr,
 
719
                                 struct ikev2_payloads *pl)
 
720
{
 
721
        u8 *decrypted;
 
722
        size_t decrypted_len;
 
723
        int ret;
 
724
 
 
725
        decrypted = ikev2_decrypt_payload(data->proposal.encr,
 
726
                                          data->proposal.integ,
 
727
                                          &data->keys, 0, hdr, pl->encrypted,
 
728
                                          pl->encrypted_len, &decrypted_len);
 
729
        if (decrypted == NULL)
 
730
                return -1;
 
731
 
 
732
        ret = ikev2_process_sa_auth_decrypted(data, pl->encr_next_payload,
 
733
                                              decrypted, decrypted_len);
 
734
        os_free(decrypted);
 
735
 
 
736
        if (ret == 0 && !data->unknown_user) {
 
737
                wpa_printf(MSG_DEBUG, "IKEV2: Authentication completed");
 
738
                data->state = IKEV2_DONE;
 
739
        }
 
740
 
 
741
        return ret;
 
742
}
 
743
 
 
744
 
 
745
static int ikev2_validate_rx_state(struct ikev2_initiator_data *data,
 
746
                                   u8 exchange_type, u32 message_id)
 
747
{
 
748
        switch (data->state) {
 
749
        case SA_INIT:
 
750
                /* Expect to receive IKE_SA_INIT: HDR, SAr, KEr, Nr, [CERTREQ],
 
751
                 * [SK{IDr}] */
 
752
                if (exchange_type != IKE_SA_INIT) {
 
753
                        wpa_printf(MSG_INFO, "IKEV2: Unexpected Exchange Type "
 
754
                                   "%u in SA_INIT state", exchange_type);
 
755
                        return -1;
 
756
                }
 
757
                if (message_id != 0) {
 
758
                        wpa_printf(MSG_INFO, "IKEV2: Unexpected Message ID %u "
 
759
                                   "in SA_INIT state", message_id);
 
760
                        return -1;
 
761
                }
 
762
                break;
 
763
        case SA_AUTH:
 
764
                /* Expect to receive IKE_SA_AUTH:
 
765
                 * HDR, SK {IDr, [CERT,] [CERTREQ,] [NFID,] AUTH}
 
766
                 */
 
767
                if (exchange_type != IKE_SA_AUTH) {
 
768
                        wpa_printf(MSG_INFO, "IKEV2: Unexpected Exchange Type "
 
769
                                   "%u in SA_AUTH state", exchange_type);
 
770
                        return -1;
 
771
                }
 
772
                if (message_id != 1) {
 
773
                        wpa_printf(MSG_INFO, "IKEV2: Unexpected Message ID %u "
 
774
                                   "in SA_AUTH state", message_id);
 
775
                        return -1;
 
776
                }
 
777
                break;
 
778
        case CHILD_SA:
 
779
                if (exchange_type != CREATE_CHILD_SA) {
 
780
                        wpa_printf(MSG_INFO, "IKEV2: Unexpected Exchange Type "
 
781
                                   "%u in CHILD_SA state", exchange_type);
 
782
                        return -1;
 
783
                }
 
784
                if (message_id != 2) {
 
785
                        wpa_printf(MSG_INFO, "IKEV2: Unexpected Message ID %u "
 
786
                                   "in CHILD_SA state", message_id);
 
787
                        return -1;
 
788
                }
 
789
                break;
 
790
        case IKEV2_DONE:
 
791
                return -1;
 
792
        }
 
793
 
 
794
        return 0;
 
795
}
 
796
 
 
797
 
 
798
int ikev2_initiator_process(struct ikev2_initiator_data *data,
 
799
                            const struct wpabuf *buf)
 
800
{
 
801
        const struct ikev2_hdr *hdr;
 
802
        u32 length, message_id;
 
803
        const u8 *pos, *end;
 
804
        struct ikev2_payloads pl;
 
805
 
 
806
        wpa_printf(MSG_MSGDUMP, "IKEV2: Received message (len %lu)",
 
807
                   (unsigned long) wpabuf_len(buf));
 
808
 
 
809
        if (wpabuf_len(buf) < sizeof(*hdr)) {
 
810
                wpa_printf(MSG_INFO, "IKEV2: Too short frame to include HDR");
 
811
                return -1;
 
812
        }
 
813
 
 
814
        hdr = (const struct ikev2_hdr *) wpabuf_head(buf);
 
815
        end = wpabuf_head_u8(buf) + wpabuf_len(buf);
 
816
        message_id = WPA_GET_BE32(hdr->message_id);
 
817
        length = WPA_GET_BE32(hdr->length);
 
818
 
 
819
        wpa_hexdump(MSG_DEBUG, "IKEV2:   IKE_SA Initiator's SPI",
 
820
                    hdr->i_spi, IKEV2_SPI_LEN);
 
821
        wpa_hexdump(MSG_DEBUG, "IKEV2:   IKE_SA Initiator's SPI",
 
822
                    hdr->r_spi, IKEV2_SPI_LEN);
 
823
        wpa_printf(MSG_DEBUG, "IKEV2:   Next Payload: %u  Version: 0x%x  "
 
824
                   "Exchange Type: %u",
 
825
                   hdr->next_payload, hdr->version, hdr->exchange_type);
 
826
        wpa_printf(MSG_DEBUG, "IKEV2:   Message ID: %u  Length: %u",
 
827
                   message_id, length);
 
828
 
 
829
        if (hdr->version != IKEV2_VERSION) {
 
830
                wpa_printf(MSG_INFO, "IKEV2: Unsupported HDR version 0x%x "
 
831
                           "(expected 0x%x)", hdr->version, IKEV2_VERSION);
 
832
                return -1;
 
833
        }
 
834
 
 
835
        if (length != wpabuf_len(buf)) {
 
836
                wpa_printf(MSG_INFO, "IKEV2: Invalid length (HDR: %lu != "
 
837
                           "RX: %lu)", (unsigned long) length,
 
838
                           (unsigned long) wpabuf_len(buf));
 
839
                return -1;
 
840
        }
 
841
 
 
842
        if (ikev2_validate_rx_state(data, hdr->exchange_type, message_id) < 0)
 
843
                return -1;
 
844
 
 
845
        if ((hdr->flags & (IKEV2_HDR_INITIATOR | IKEV2_HDR_RESPONSE)) !=
 
846
            IKEV2_HDR_RESPONSE) {
 
847
                wpa_printf(MSG_INFO, "IKEV2: Unexpected Flags value 0x%x",
 
848
                           hdr->flags);
 
849
                return -1;
 
850
        }
 
851
 
 
852
        if (data->state != SA_INIT) {
 
853
                if (os_memcmp(data->i_spi, hdr->i_spi, IKEV2_SPI_LEN) != 0) {
 
854
                        wpa_printf(MSG_INFO, "IKEV2: Unexpected IKE_SA "
 
855
                                   "Initiator's SPI");
 
856
                        return -1;
 
857
                }
 
858
                if (os_memcmp(data->r_spi, hdr->r_spi, IKEV2_SPI_LEN) != 0) {
 
859
                        wpa_printf(MSG_INFO, "IKEV2: Unexpected IKE_SA "
 
860
                                   "Responder's SPI");
 
861
                        return -1;
 
862
                }
 
863
        }
 
864
 
 
865
        pos = (const u8 *) (hdr + 1);
 
866
        if (ikev2_parse_payloads(&pl, hdr->next_payload, pos, end) < 0)
 
867
                return -1;
 
868
 
 
869
        switch (data->state) {
 
870
        case SA_INIT:
 
871
                if (ikev2_process_sa_init(data, hdr, &pl) < 0)
 
872
                        return -1;
 
873
                wpabuf_free(data->r_sign_msg);
 
874
                data->r_sign_msg = wpabuf_dup(buf);
 
875
                break;
 
876
        case SA_AUTH:
 
877
                if (ikev2_process_sa_auth(data, hdr, &pl) < 0)
 
878
                        return -1;
 
879
                break;
 
880
        case CHILD_SA:
 
881
        case IKEV2_DONE:
 
882
                break;
 
883
        }
 
884
 
 
885
        return 0;
 
886
}
 
887
 
 
888
 
 
889
static void ikev2_build_hdr(struct ikev2_initiator_data *data,
 
890
                            struct wpabuf *msg, u8 exchange_type,
 
891
                            u8 next_payload, u32 message_id)
 
892
{
 
893
        struct ikev2_hdr *hdr;
 
894
 
 
895
        wpa_printf(MSG_DEBUG, "IKEV2: Adding HDR");
 
896
 
 
897
        /* HDR - RFC 4306, Sect. 3.1 */
 
898
        hdr = wpabuf_put(msg, sizeof(*hdr));
 
899
        os_memcpy(hdr->i_spi, data->i_spi, IKEV2_SPI_LEN);
 
900
        os_memcpy(hdr->r_spi, data->r_spi, IKEV2_SPI_LEN);
 
901
        hdr->next_payload = next_payload;
 
902
        hdr->version = IKEV2_VERSION;
 
903
        hdr->exchange_type = exchange_type;
 
904
        hdr->flags = IKEV2_HDR_INITIATOR;
 
905
        WPA_PUT_BE32(hdr->message_id, message_id);
 
906
}
 
907
 
 
908
 
 
909
static int ikev2_build_sai(struct ikev2_initiator_data *data,
 
910
                            struct wpabuf *msg, u8 next_payload)
 
911
{
 
912
        struct ikev2_payload_hdr *phdr;
 
913
        size_t plen;
 
914
        struct ikev2_proposal *p;
 
915
        struct ikev2_transform *t;
 
916
 
 
917
        wpa_printf(MSG_DEBUG, "IKEV2: Adding SAi payload");
 
918
 
 
919
        /* SAi1 - RFC 4306, Sect. 2.7 and 3.3 */
 
920
        phdr = wpabuf_put(msg, sizeof(*phdr));
 
921
        phdr->next_payload = next_payload;
 
922
        phdr->flags = 0;
 
923
 
 
924
        /* TODO: support for multiple proposals */
 
925
        p = wpabuf_put(msg, sizeof(*p));
 
926
        p->proposal_num = data->proposal.proposal_num;
 
927
        p->protocol_id = IKEV2_PROTOCOL_IKE;
 
928
        p->num_transforms = 4;
 
929
 
 
930
        t = wpabuf_put(msg, sizeof(*t));
 
931
        t->type = 3;
 
932
        t->transform_type = IKEV2_TRANSFORM_ENCR;
 
933
        WPA_PUT_BE16(t->transform_id, data->proposal.encr);
 
934
        if (data->proposal.encr == ENCR_AES_CBC) {
 
935
                /* Transform Attribute: Key Len = 128 bits */
 
936
                wpabuf_put_be16(msg, 0x800e); /* AF=1, AttrType=14 */
 
937
                wpabuf_put_be16(msg, 128); /* 128-bit key */
 
938
        }
 
939
        plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) t;
 
940
        WPA_PUT_BE16(t->transform_length, plen);
 
941
 
 
942
        t = wpabuf_put(msg, sizeof(*t));
 
943
        t->type = 3;
 
944
        WPA_PUT_BE16(t->transform_length, sizeof(*t));
 
945
        t->transform_type = IKEV2_TRANSFORM_PRF;
 
946
        WPA_PUT_BE16(t->transform_id, data->proposal.prf);
 
947
 
 
948
        t = wpabuf_put(msg, sizeof(*t));
 
949
        t->type = 3;
 
950
        WPA_PUT_BE16(t->transform_length, sizeof(*t));
 
951
        t->transform_type = IKEV2_TRANSFORM_INTEG;
 
952
        WPA_PUT_BE16(t->transform_id, data->proposal.integ);
 
953
 
 
954
        t = wpabuf_put(msg, sizeof(*t));
 
955
        WPA_PUT_BE16(t->transform_length, sizeof(*t));
 
956
        t->transform_type = IKEV2_TRANSFORM_DH;
 
957
        WPA_PUT_BE16(t->transform_id, data->proposal.dh);
 
958
 
 
959
        plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) p;
 
960
        WPA_PUT_BE16(p->proposal_length, plen);
 
961
 
 
962
        plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
 
963
        WPA_PUT_BE16(phdr->payload_length, plen);
 
964
 
 
965
        return 0;
 
966
}
 
967
 
 
968
 
 
969
static int ikev2_build_kei(struct ikev2_initiator_data *data,
 
970
                           struct wpabuf *msg, u8 next_payload)
 
971
{
 
972
        struct ikev2_payload_hdr *phdr;
 
973
        size_t plen;
 
974
        struct wpabuf *pv;
 
975
 
 
976
        wpa_printf(MSG_DEBUG, "IKEV2: Adding KEi payload");
 
977
 
 
978
        data->dh = dh_groups_get(data->proposal.dh);
 
979
        pv = dh_init(data->dh, &data->i_dh_private);
 
980
        if (pv == NULL) {
 
981
                wpa_printf(MSG_DEBUG, "IKEV2: Failed to initialize DH");
 
982
                return -1;
 
983
        }
 
984
 
 
985
        /* KEi - RFC 4306, Sect. 3.4 */
 
986
        phdr = wpabuf_put(msg, sizeof(*phdr));
 
987
        phdr->next_payload = next_payload;
 
988
        phdr->flags = 0;
 
989
 
 
990
        wpabuf_put_be16(msg, data->proposal.dh); /* DH Group # */
 
991
        wpabuf_put(msg, 2); /* RESERVED */
 
992
        /*
 
993
         * RFC 4306, Sect. 3.4: possible zero padding for public value to
 
994
         * match the length of the prime.
 
995
         */
 
996
        wpabuf_put(msg, data->dh->prime_len - wpabuf_len(pv));
 
997
        wpabuf_put_buf(msg, pv);
 
998
        os_free(pv);
 
999
 
 
1000
        plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
 
1001
        WPA_PUT_BE16(phdr->payload_length, plen);
 
1002
        return 0;
 
1003
}
 
1004
 
 
1005
 
 
1006
static int ikev2_build_ni(struct ikev2_initiator_data *data,
 
1007
                          struct wpabuf *msg, u8 next_payload)
 
1008
{
 
1009
        struct ikev2_payload_hdr *phdr;
 
1010
        size_t plen;
 
1011
 
 
1012
        wpa_printf(MSG_DEBUG, "IKEV2: Adding Ni payload");
 
1013
 
 
1014
        /* Ni - RFC 4306, Sect. 3.9 */
 
1015
        phdr = wpabuf_put(msg, sizeof(*phdr));
 
1016
        phdr->next_payload = next_payload;
 
1017
        phdr->flags = 0;
 
1018
        wpabuf_put_data(msg, data->i_nonce, data->i_nonce_len);
 
1019
        plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
 
1020
        WPA_PUT_BE16(phdr->payload_length, plen);
 
1021
        return 0;
 
1022
}
 
1023
 
 
1024
 
 
1025
static int ikev2_build_idi(struct ikev2_initiator_data *data,
 
1026
                           struct wpabuf *msg, u8 next_payload)
 
1027
{
 
1028
        struct ikev2_payload_hdr *phdr;
 
1029
        size_t plen;
 
1030
 
 
1031
        wpa_printf(MSG_DEBUG, "IKEV2: Adding IDi payload");
 
1032
 
 
1033
        if (data->IDi == NULL) {
 
1034
                wpa_printf(MSG_INFO, "IKEV2: No IDi available");
 
1035
                return -1;
 
1036
        }
 
1037
 
 
1038
        /* IDi - RFC 4306, Sect. 3.5 */
 
1039
        phdr = wpabuf_put(msg, sizeof(*phdr));
 
1040
        phdr->next_payload = next_payload;
 
1041
        phdr->flags = 0;
 
1042
        wpabuf_put_u8(msg, ID_KEY_ID);
 
1043
        wpabuf_put(msg, 3); /* RESERVED */
 
1044
        wpabuf_put_data(msg, data->IDi, data->IDi_len);
 
1045
        plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
 
1046
        WPA_PUT_BE16(phdr->payload_length, plen);
 
1047
        return 0;
 
1048
}
 
1049
 
 
1050
 
 
1051
static int ikev2_build_auth(struct ikev2_initiator_data *data,
 
1052
                            struct wpabuf *msg, u8 next_payload)
 
1053
{
 
1054
        struct ikev2_payload_hdr *phdr;
 
1055
        size_t plen;
 
1056
        const struct ikev2_prf_alg *prf;
 
1057
 
 
1058
        wpa_printf(MSG_DEBUG, "IKEV2: Adding AUTH payload");
 
1059
 
 
1060
        prf = ikev2_get_prf(data->proposal.prf);
 
1061
        if (prf == NULL)
 
1062
                return -1;
 
1063
 
 
1064
        /* Authentication - RFC 4306, Sect. 3.8 */
 
1065
        phdr = wpabuf_put(msg, sizeof(*phdr));
 
1066
        phdr->next_payload = next_payload;
 
1067
        phdr->flags = 0;
 
1068
        wpabuf_put_u8(msg, AUTH_SHARED_KEY_MIC);
 
1069
        wpabuf_put(msg, 3); /* RESERVED */
 
1070
 
 
1071
        /* msg | Nr | prf(SK_pi,IDi') */
 
1072
        if (ikev2_derive_auth_data(data->proposal.prf, data->i_sign_msg,
 
1073
                                   data->IDi, data->IDi_len, ID_KEY_ID,
 
1074
                                   &data->keys, 1, data->shared_secret,
 
1075
                                   data->shared_secret_len,
 
1076
                                   data->r_nonce, data->r_nonce_len,
 
1077
                                   data->key_pad, data->key_pad_len,
 
1078
                                   wpabuf_put(msg, prf->hash_len)) < 0) {
 
1079
                wpa_printf(MSG_INFO, "IKEV2: Could not derive AUTH data");
 
1080
                return -1;
 
1081
        }
 
1082
        wpabuf_free(data->i_sign_msg);
 
1083
        data->i_sign_msg = NULL;
 
1084
 
 
1085
        plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
 
1086
        WPA_PUT_BE16(phdr->payload_length, plen);
 
1087
        return 0;
 
1088
}
 
1089
 
 
1090
 
 
1091
static struct wpabuf * ikev2_build_sa_init(struct ikev2_initiator_data *data)
 
1092
{
 
1093
        struct wpabuf *msg;
 
1094
 
 
1095
        /* build IKE_SA_INIT: HDR, SAi, KEi, Ni */
 
1096
 
 
1097
        if (os_get_random(data->i_spi, IKEV2_SPI_LEN))
 
1098
                return NULL;
 
1099
        wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Initiator's SPI",
 
1100
                    data->i_spi, IKEV2_SPI_LEN);
 
1101
 
 
1102
        data->i_nonce_len = IKEV2_NONCE_MIN_LEN;
 
1103
        if (os_get_random(data->i_nonce, data->i_nonce_len))
 
1104
                return NULL;
 
1105
        wpa_hexdump(MSG_DEBUG, "IKEV2: Ni", data->i_nonce, data->i_nonce_len);
 
1106
 
 
1107
        msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + 1000);
 
1108
        if (msg == NULL)
 
1109
                return NULL;
 
1110
 
 
1111
        ikev2_build_hdr(data, msg, IKE_SA_INIT, IKEV2_PAYLOAD_SA, 0);
 
1112
        if (ikev2_build_sai(data, msg, IKEV2_PAYLOAD_KEY_EXCHANGE) ||
 
1113
            ikev2_build_kei(data, msg, IKEV2_PAYLOAD_NONCE) ||
 
1114
            ikev2_build_ni(data, msg, IKEV2_PAYLOAD_NO_NEXT_PAYLOAD)) {
 
1115
                wpabuf_free(msg);
 
1116
                return NULL;
 
1117
        }
 
1118
 
 
1119
        ikev2_update_hdr(msg);
 
1120
 
 
1121
        wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (SA_INIT)", msg);
 
1122
 
 
1123
        wpabuf_free(data->i_sign_msg);
 
1124
        data->i_sign_msg = wpabuf_dup(msg);
 
1125
 
 
1126
        return msg;
 
1127
}
 
1128
 
 
1129
 
 
1130
static struct wpabuf * ikev2_build_sa_auth(struct ikev2_initiator_data *data)
 
1131
{
 
1132
        struct wpabuf *msg, *plain;
 
1133
        const u8 *secret;
 
1134
        size_t secret_len;
 
1135
 
 
1136
        secret = data->get_shared_secret(data->cb_ctx, data->IDr,
 
1137
                                         data->IDr_len, &secret_len);
 
1138
        if (secret == NULL) {
 
1139
                wpa_printf(MSG_INFO, "IKEV2: Could not get shared secret - "
 
1140
                           "use fake value");
 
1141
                /* RFC 5106, Sect. 7:
 
1142
                 * Use a random key to fake AUTH generation in order to prevent
 
1143
                 * probing of user identities.
 
1144
                 */
 
1145
                data->unknown_user = 1;
 
1146
                os_free(data->shared_secret);
 
1147
                data->shared_secret = os_malloc(16);
 
1148
                if (data->shared_secret == NULL)
 
1149
                        return NULL;
 
1150
                data->shared_secret_len = 16;
 
1151
                if (os_get_random(data->shared_secret, 16))
 
1152
                        return NULL;
 
1153
        } else {
 
1154
                os_free(data->shared_secret);
 
1155
                data->shared_secret = os_malloc(secret_len);
 
1156
                if (data->shared_secret == NULL)
 
1157
                        return NULL;
 
1158
                os_memcpy(data->shared_secret, secret, secret_len);
 
1159
                data->shared_secret_len = secret_len;
 
1160
        }
 
1161
 
 
1162
        /* build IKE_SA_AUTH: HDR, SK {IDi, [CERT,] [CERTREQ,] AUTH} */
 
1163
 
 
1164
        msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + data->IDr_len + 1000);
 
1165
        if (msg == NULL)
 
1166
                return NULL;
 
1167
        ikev2_build_hdr(data, msg, IKE_SA_AUTH, IKEV2_PAYLOAD_ENCRYPTED, 1);
 
1168
 
 
1169
        plain = wpabuf_alloc(data->IDr_len + 1000);
 
1170
        if (plain == NULL) {
 
1171
                wpabuf_free(msg);
 
1172
                return NULL;
 
1173
        }
 
1174
 
 
1175
        if (ikev2_build_idi(data, plain, IKEV2_PAYLOAD_AUTHENTICATION) ||
 
1176
            ikev2_build_auth(data, plain, IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) ||
 
1177
            ikev2_build_encrypted(data->proposal.encr, data->proposal.integ,
 
1178
                                  &data->keys, 1, msg, plain,
 
1179
                                  IKEV2_PAYLOAD_IDi)) {
 
1180
                wpabuf_free(plain);
 
1181
                wpabuf_free(msg);
 
1182
                return NULL;
 
1183
        }
 
1184
        wpabuf_free(plain);
 
1185
 
 
1186
        wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (SA_AUTH)", msg);
 
1187
 
 
1188
        return msg;
 
1189
}
 
1190
 
 
1191
 
 
1192
struct wpabuf * ikev2_initiator_build(struct ikev2_initiator_data *data)
 
1193
{
 
1194
        switch (data->state) {
 
1195
        case SA_INIT:
 
1196
                return ikev2_build_sa_init(data);
 
1197
        case SA_AUTH:
 
1198
                return ikev2_build_sa_auth(data);
 
1199
        case CHILD_SA:
 
1200
                return NULL;
 
1201
        case IKEV2_DONE:
 
1202
                return NULL;
 
1203
        }
 
1204
        return NULL;
 
1205
}