LCOV - code coverage report
Current view: top level - src/eap_peer - ikev2.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1443382998 Lines: 537 643 83.5 %
Date: 2015-09-27 Functions: 27 28 96.4 %

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

Generated by: LCOV version 1.10