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 1475438200 Lines: 574 643 89.3 %
Date: 2016-10-02 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         116 : void ikev2_responder_deinit(struct ikev2_responder_data *data)
      18             : {
      19         116 :         ikev2_free_keys(&data->keys);
      20         116 :         wpabuf_free(data->i_dh_public);
      21         116 :         wpabuf_free(data->r_dh_private);
      22         116 :         os_free(data->IDi);
      23         116 :         os_free(data->IDr);
      24         116 :         os_free(data->shared_secret);
      25         116 :         wpabuf_free(data->i_sign_msg);
      26         116 :         wpabuf_free(data->r_sign_msg);
      27         116 :         os_free(data->key_pad);
      28         116 : }
      29             : 
      30             : 
      31          56 : 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          56 :         integ = ikev2_get_integ(data->proposal.integ);
      46          56 :         prf = ikev2_get_prf(data->proposal.prf);
      47          56 :         encr = ikev2_get_encr(data->proposal.encr);
      48          56 :         if (integ == NULL || prf == NULL || encr == NULL) {
      49           0 :                 wpa_printf(MSG_INFO, "IKEV2: Unsupported proposal");
      50           0 :                 return -1;
      51             :         }
      52             : 
      53          56 :         shared = dh_derive_shared(data->i_dh_public, data->r_dh_private,
      54             :                                   data->dh);
      55          56 :         if (shared == NULL)
      56           2 :                 return -1;
      57             : 
      58             :         /* Construct Ni | Nr | SPIi | SPIr */
      59             : 
      60          54 :         buf_len = data->i_nonce_len + data->r_nonce_len + 2 * IKEV2_SPI_LEN;
      61          54 :         buf = os_malloc(buf_len);
      62          54 :         if (buf == NULL) {
      63           1 :                 wpabuf_free(shared);
      64           1 :                 return -1;
      65             :         }
      66             : 
      67          53 :         pos = buf;
      68          53 :         os_memcpy(pos, data->i_nonce, data->i_nonce_len);
      69          53 :         pos += data->i_nonce_len;
      70          53 :         os_memcpy(pos, data->r_nonce, data->r_nonce_len);
      71          53 :         pos += data->r_nonce_len;
      72          53 :         os_memcpy(pos, data->i_spi, IKEV2_SPI_LEN);
      73          53 :         pos += IKEV2_SPI_LEN;
      74          53 :         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          53 :         pad_len = data->dh->prime_len - wpabuf_len(shared);
      79          53 :         pad = os_zalloc(pad_len ? pad_len : 1);
      80          53 :         if (pad == NULL) {
      81           1 :                 wpabuf_free(shared);
      82           1 :                 os_free(buf);
      83           1 :                 return -1;
      84             :         }
      85             : 
      86          52 :         addr[0] = pad;
      87          52 :         len[0] = pad_len;
      88          52 :         addr[1] = wpabuf_head(shared);
      89          52 :         len[1] = wpabuf_len(shared);
      90          52 :         if (ikev2_prf_hash(prf->id, buf, data->i_nonce_len + data->r_nonce_len,
      91             :                            2, addr, len, skeyseed) < 0) {
      92           1 :                 wpabuf_free(shared);
      93           1 :                 os_free(buf);
      94           1 :                 os_free(pad);
      95           1 :                 return -1;
      96             :         }
      97          51 :         os_free(pad);
      98          51 :         wpabuf_free(shared);
      99             : 
     100             :         /* DH parameters are not needed anymore, so free them */
     101          51 :         wpabuf_free(data->i_dh_public);
     102          51 :         data->i_dh_public = NULL;
     103          51 :         wpabuf_free(data->r_dh_private);
     104          51 :         data->r_dh_private = NULL;
     105             : 
     106          51 :         wpa_hexdump_key(MSG_DEBUG, "IKEV2: SKEYSEED",
     107             :                         skeyseed, prf->hash_len);
     108             : 
     109          51 :         ret = ikev2_derive_sk_keys(prf, integ, encr, skeyseed, buf, buf_len,
     110             :                                    &data->keys);
     111          51 :         os_free(buf);
     112          51 :         return ret;
     113             : }
     114             : 
     115             : 
     116         307 : 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         307 :         if (end - pos < (int) sizeof(*t)) {
     125           1 :                 wpa_printf(MSG_INFO, "IKEV2: Too short transform");
     126           1 :                 return -1;
     127             :         }
     128             : 
     129         306 :         t = (const struct ikev2_transform *) pos;
     130         306 :         transform_len = WPA_GET_BE16(t->transform_length);
     131         306 :         if (transform_len < (int) sizeof(*t) || transform_len > end - pos) {
     132           2 :                 wpa_printf(MSG_INFO, "IKEV2: Invalid transform length %d",
     133             :                            transform_len);
     134           2 :                 return -1;
     135             :         }
     136         304 :         tend = pos + transform_len;
     137             : 
     138         304 :         transform_id = WPA_GET_BE16(t->transform_id);
     139             : 
     140         304 :         wpa_printf(MSG_DEBUG, "IKEV2:   Transform:");
     141         912 :         wpa_printf(MSG_DEBUG, "IKEV2:     Type: %d  Transform Length: %d  "
     142             :                    "Transform Type: %d  Transform ID: %d",
     143         608 :                    t->type, transform_len, t->transform_type, transform_id);
     144             : 
     145         304 :         if (t->type != 0 && t->type != 3) {
     146           1 :                 wpa_printf(MSG_INFO, "IKEV2: Unexpected Transform type");
     147           1 :                 return -1;
     148             :         }
     149             : 
     150         303 :         pos = (const u8 *) (t + 1);
     151         303 :         if (pos < tend) {
     152          64 :                 wpa_hexdump(MSG_DEBUG, "IKEV2:     Transform Attributes",
     153          64 :                             pos, tend - pos);
     154             :         }
     155             : 
     156         303 :         switch (t->transform_type) {
     157             :         case IKEV2_TRANSFORM_ENCR:
     158          75 :                 if (ikev2_get_encr(transform_id)) {
     159          75 :                         if (transform_id == ENCR_AES_CBC) {
     160          64 :                                 if (tend - pos != 4) {
     161           1 :                                         wpa_printf(MSG_DEBUG, "IKEV2: No "
     162             :                                                    "Transform Attr for AES");
     163           1 :                                         break;
     164             :                                 }
     165          63 :                                 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          62 :                                 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          72 :                         prop->encr = transform_id;
     180             :                 }
     181          72 :                 break;
     182             :         case IKEV2_TRANSFORM_PRF:
     183          72 :                 if (ikev2_get_prf(transform_id))
     184          72 :                         prop->prf = transform_id;
     185          72 :                 break;
     186             :         case IKEV2_TRANSFORM_INTEG:
     187          72 :                 if (ikev2_get_integ(transform_id))
     188          72 :                         prop->integ = transform_id;
     189          72 :                 break;
     190             :         case IKEV2_TRANSFORM_DH:
     191          72 :                 if (dh_groups_get(transform_id))
     192          72 :                         prop->dh = transform_id;
     193          72 :                 break;
     194             :         }
     195             : 
     196         303 :         return transform_len;
     197             : }
     198             : 
     199             : 
     200          87 : 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          87 :         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          86 :         p = (const struct ikev2_proposal *) pos;
     215          86 :         proposal_len = WPA_GET_BE16(p->proposal_length);
     216          86 :         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          84 :         wpa_printf(MSG_DEBUG, "IKEV2: SAi1 Proposal # %d",
     222          84 :                    p->proposal_num);
     223         168 :         wpa_printf(MSG_DEBUG, "IKEV2:   Type: %d  Proposal Length: %d "
     224             :                    " Protocol ID: %d",
     225         168 :                    p->type, proposal_len, p->protocol_id);
     226         168 :         wpa_printf(MSG_DEBUG, "IKEV2:   SPI Size: %d  Transforms: %d",
     227         168 :                    p->spi_size, p->num_transforms);
     228             : 
     229          84 :         if (p->type != 0 && p->type != 2) {
     230           1 :                 wpa_printf(MSG_INFO, "IKEV2: Unexpected Proposal type");
     231           1 :                 return -1;
     232             :         }
     233             : 
     234          83 :         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          82 :         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          81 :         ppos = (const u8 *) (p + 1);
     250          81 :         pend = pos + proposal_len;
     251          81 :         if (p->spi_size > pend - ppos) {
     252           1 :                 wpa_printf(MSG_INFO, "IKEV2: Not enough room for SPI "
     253             :                            "in proposal");
     254           1 :                 return -1;
     255             :         }
     256          80 :         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          80 :         if (p->spi_size != 0) {
     268           1 :                 wpa_printf(MSG_INFO, "IKEV2: Unexpected SPI Size");
     269           1 :                 return -1;
     270             :         }
     271             : 
     272          79 :         if (p->num_transforms == 0) {
     273           1 :                 wpa_printf(MSG_INFO, "IKEV2: At least one transform required");
     274           1 :                 return -1;
     275             :         }
     276             : 
     277         381 :         for (i = 0; i < (int) p->num_transforms; i++) {
     278         307 :                 int tlen = ikev2_parse_transform(prop, ppos, pend);
     279         307 :                 if (tlen < 0)
     280           4 :                         return -1;
     281         303 :                 ppos += tlen;
     282             :         }
     283             : 
     284          74 :         if (ppos != pend) {
     285           1 :                 wpa_printf(MSG_INFO, "IKEV2: Unexpected data after "
     286             :                            "transforms");
     287           1 :                 return -1;
     288             :         }
     289             : 
     290          73 :         return proposal_len;
     291             : }
     292             : 
     293             : 
     294          89 : 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          89 :         int found = 0;
     300             : 
     301             :         /* Security Association Payloads: <Proposals> */
     302             : 
     303          89 :         if (sai1 == NULL) {
     304           1 :                 wpa_printf(MSG_INFO, "IKEV2: SAi1 not received");
     305           1 :                 return -1;
     306             :         }
     307             : 
     308          88 :         os_memset(&prop, 0, sizeof(prop));
     309          88 :         prop.proposal_num = 1;
     310             : 
     311          88 :         pos = sai1;
     312          88 :         end = sai1 + sai1_len;
     313             : 
     314         249 :         while (pos < end) {
     315             :                 int plen;
     316             : 
     317          87 :                 prop.integ = -1;
     318          87 :                 prop.prf = -1;
     319          87 :                 prop.encr = -1;
     320          87 :                 prop.dh = -1;
     321          87 :                 plen = ikev2_parse_proposal(&prop, pos, end);
     322          87 :                 if (plen < 0)
     323          14 :                         return -1;
     324             : 
     325         145 :                 if (!found && prop.integ != -1 && prop.prf != -1 &&
     326         144 :                     prop.encr != -1 && prop.dh != -1) {
     327          72 :                         os_memcpy(&data->proposal, &prop, sizeof(prop));
     328          72 :                         data->dh = dh_groups_get(prop.dh);
     329          72 :                         found = 1;
     330             :                 }
     331             : 
     332          73 :                 pos += plen;
     333             :         }
     334             : 
     335          74 :         if (pos != end) {
     336           0 :                 wpa_printf(MSG_INFO, "IKEV2: Unexpected data after proposals");
     337           0 :                 return -1;
     338             :         }
     339             : 
     340          74 :         if (!found) {
     341           2 :                 wpa_printf(MSG_INFO, "IKEV2: No acceptable proposal found");
     342           2 :                 return -1;
     343             :         }
     344             : 
     345         144 :         wpa_printf(MSG_DEBUG, "IKEV2: Accepted proposal #%d: ENCR:%d PRF:%d "
     346          72 :                    "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          72 :         return 0;
     351             : }
     352             : 
     353             : 
     354          72 : 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          72 :         if (kei == NULL) {
     367           1 :                 wpa_printf(MSG_INFO, "IKEV2: KEi not received");
     368           1 :                 return -1;
     369             :         }
     370             : 
     371          71 :         if (kei_len < 4 + 96) {
     372           1 :                 wpa_printf(MSG_INFO, "IKEV2: Too short Key Exchange Payload");
     373           1 :                 return -1;
     374             :         }
     375             : 
     376          70 :         group = WPA_GET_BE16(kei);
     377          70 :         wpa_printf(MSG_DEBUG, "IKEV2: KEi DH Group #%u", group);
     378             : 
     379          70 :         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          69 :         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          69 :         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          68 :         wpabuf_free(data->i_dh_public);
     407          68 :         data->i_dh_public = wpabuf_alloc(kei_len - 4);
     408          68 :         if (data->i_dh_public == NULL)
     409           1 :                 return -1;
     410          67 :         wpabuf_put_data(data->i_dh_public, kei + 4, kei_len - 4);
     411             : 
     412          67 :         wpa_hexdump_buf(MSG_DEBUG, "IKEV2: KEi Diffie-Hellman Public Value",
     413          67 :                         data->i_dh_public);
     414             :         
     415          67 :         return 0;
     416             : }
     417             : 
     418             : 
     419          67 : static int ikev2_process_ni(struct ikev2_responder_data *data,
     420             :                             const u8 *ni, size_t ni_len)
     421             : {
     422          67 :         if (ni == NULL) {
     423           1 :                 wpa_printf(MSG_INFO, "IKEV2: Ni not received");
     424           1 :                 return -1;
     425             :         }
     426             : 
     427          66 :         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          64 :         data->i_nonce_len = ni_len;
     434          64 :         os_memcpy(data->i_nonce, ni, ni_len);
     435         128 :         wpa_hexdump(MSG_MSGDUMP, "IKEV2: Ni",
     436          64 :                     data->i_nonce, data->i_nonce_len);
     437             : 
     438          64 :         return 0;
     439             : }
     440             : 
     441             : 
     442          89 : static int ikev2_process_sa_init(struct ikev2_responder_data *data,
     443             :                                  const struct ikev2_hdr *hdr,
     444             :                                  struct ikev2_payloads *pl)
     445             : {
     446         161 :         if (ikev2_process_sai1(data, pl->sa, pl->sa_len) < 0 ||
     447         139 :             ikev2_process_kei(data, pl->ke, pl->ke_len) < 0 ||
     448          67 :             ikev2_process_ni(data, pl->nonce, pl->nonce_len) < 0)
     449          25 :                 return -1;
     450             : 
     451          64 :         os_memcpy(data->i_spi, hdr->i_spi, IKEV2_SPI_LEN);
     452             : 
     453          64 :         return 0;
     454             : }
     455             : 
     456             : 
     457          26 : 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          26 :         if (idi == NULL) {
     463           0 :                 wpa_printf(MSG_INFO, "IKEV2: No IDi received");
     464           0 :                 return -1;
     465             :         }
     466             : 
     467          26 :         if (idi_len < 4) {
     468           0 :                 wpa_printf(MSG_INFO, "IKEV2: Too short IDi payload");
     469           0 :                 return -1;
     470             :         }
     471             : 
     472          26 :         id_type = idi[0];
     473          26 :         idi += 4;
     474          26 :         idi_len -= 4;
     475             : 
     476          26 :         wpa_printf(MSG_DEBUG, "IKEV2: IDi ID Type %d", id_type);
     477          26 :         wpa_hexdump_ascii(MSG_DEBUG, "IKEV2: IDi", idi, idi_len);
     478          26 :         os_free(data->IDi);
     479          26 :         data->IDi = os_malloc(idi_len);
     480          26 :         if (data->IDi == NULL)
     481           1 :                 return -1;
     482          25 :         os_memcpy(data->IDi, idi, idi_len);
     483          25 :         data->IDi_len = idi_len;
     484          25 :         data->IDi_type = id_type;
     485             : 
     486          25 :         return 0;
     487             : }
     488             : 
     489             : 
     490          25 : 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          25 :         if (cert == NULL) {
     496          25 :                 if (data->peer_auth == PEER_AUTH_CERT) {
     497           0 :                         wpa_printf(MSG_INFO, "IKEV2: No Certificate received");
     498           0 :                         return -1;
     499             :                 }
     500          25 :                 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          25 : 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          25 :         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         150 :         if (ikev2_derive_auth_data(data->proposal.prf, data->i_sign_msg,
     550          50 :                                    data->IDi, data->IDi_len, data->IDi_type,
     551          25 :                                    &data->keys, 1, data->shared_secret,
     552             :                                    data->shared_secret_len,
     553          25 :                                    data->r_nonce, data->r_nonce_len,
     554          25 :                                    data->key_pad, data->key_pad_len,
     555             :                                    auth_data) < 0) {
     556           5 :                 wpa_printf(MSG_INFO, "IKEV2: Could not derive AUTH data");
     557           5 :                 return -1;
     558             :         }
     559             : 
     560          20 :         wpabuf_free(data->i_sign_msg);
     561          20 :         data->i_sign_msg = NULL;
     562             : 
     563          20 :         prf = ikev2_get_prf(data->proposal.prf);
     564          20 :         if (prf == NULL)
     565           0 :                 return -1;
     566             : 
     567          40 :         if (auth_len != prf->hash_len ||
     568          20 :             os_memcmp_const(auth, auth_data, auth_len) != 0) {
     569           4 :                 wpa_printf(MSG_INFO, "IKEV2: Invalid Authentication Data");
     570           4 :                 wpa_hexdump(MSG_DEBUG, "IKEV2: Received Authentication Data",
     571             :                             auth, auth_len);
     572           4 :                 wpa_hexdump(MSG_DEBUG, "IKEV2: Expected Authentication Data",
     573             :                             auth_data, prf->hash_len);
     574           4 :                 data->error_type = AUTHENTICATION_FAILED;
     575           4 :                 data->state = NOTIFY;
     576           4 :                 return -1;
     577             :         }
     578             : 
     579          16 :         wpa_printf(MSG_DEBUG, "IKEV2: Server authenticated successfully "
     580             :                    "using shared keys");
     581             : 
     582          16 :         return 0;
     583             : }
     584             : 
     585             : 
     586          25 : 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          25 :         if (auth == NULL) {
     592           0 :                 wpa_printf(MSG_INFO, "IKEV2: No Authentication Payload");
     593           0 :                 return -1;
     594             :         }
     595             : 
     596          25 :         if (auth_len < 4) {
     597           0 :                 wpa_printf(MSG_INFO, "IKEV2: Too short Authentication "
     598             :                            "Payload");
     599           0 :                 return -1;
     600             :         }
     601             : 
     602          25 :         auth_method = auth[0];
     603          25 :         auth += 4;
     604          25 :         auth_len -= 4;
     605             : 
     606          25 :         wpa_printf(MSG_DEBUG, "IKEV2: Auth Method %d", auth_method);
     607          25 :         wpa_hexdump(MSG_MSGDUMP, "IKEV2: Authentication Data", auth, auth_len);
     608             : 
     609          25 :         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          25 :                 return ikev2_process_auth_secret(data, auth_method, auth,
     615             :                                                  auth_len);
     616             :         }
     617             : 
     618           0 :         return -1;
     619             : }
     620             : 
     621             : 
     622          26 : 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          26 :         wpa_printf(MSG_DEBUG, "IKEV2: Processing decrypted payloads");
     629             : 
     630          26 :         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          51 :         if (ikev2_process_idi(data, pl.idi, pl.idi_len) < 0 ||
     638          50 :             ikev2_process_cert(data, pl.cert, pl.cert_len) < 0 ||
     639          25 :             ikev2_process_auth(data, pl.auth, pl.auth_len) < 0)
     640          10 :                 return -1;
     641             : 
     642          16 :         return 0;
     643             : }
     644             : 
     645             : 
     646          30 : 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          30 :         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          30 :         if (decrypted == NULL)
     659           4 :                 return -1;
     660             : 
     661          26 :         ret = ikev2_process_sa_auth_decrypted(data, pl->encr_next_payload,
     662             :                                               decrypted, decrypted_len);
     663          26 :         os_free(decrypted);
     664             : 
     665          26 :         return ret;
     666             : }
     667             : 
     668             : 
     669         128 : static int ikev2_validate_rx_state(struct ikev2_responder_data *data,
     670             :                                    u8 exchange_type, u32 message_id)
     671             : {
     672         128 :         switch (data->state) {
     673             :         case SA_INIT:
     674             :                 /* Expect to receive IKE_SA_INIT: HDR, SAi1, KEi, Ni */
     675          98 :                 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          97 :                 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          96 :                 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          30 :                 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          30 :                 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          30 :                 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         126 :         return 0;
     721             : }
     722             : 
     723             : 
     724         134 : 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         134 :         wpa_printf(MSG_MSGDUMP, "IKEV2: Received message (len %lu)",
     733             :                    (unsigned long) wpabuf_len(buf));
     734             : 
     735         134 :         if (wpabuf_len(buf) < sizeof(*hdr)) {
     736           4 :                 wpa_printf(MSG_INFO, "IKEV2: Too short frame to include HDR");
     737           4 :                 return -1;
     738             :         }
     739             : 
     740         130 :         data->error_type = 0;
     741         130 :         hdr = (const struct ikev2_hdr *) wpabuf_head(buf);
     742         130 :         end = wpabuf_head_u8(buf) + wpabuf_len(buf);
     743         130 :         message_id = WPA_GET_BE32(hdr->message_id);
     744         130 :         length = WPA_GET_BE32(hdr->length);
     745             : 
     746         130 :         wpa_hexdump(MSG_DEBUG, "IKEV2:   IKE_SA Initiator's SPI",
     747         130 :                     hdr->i_spi, IKEV2_SPI_LEN);
     748         130 :         wpa_hexdump(MSG_DEBUG, "IKEV2:   IKE_SA Responder's SPI",
     749         130 :                     hdr->r_spi, IKEV2_SPI_LEN);
     750         390 :         wpa_printf(MSG_DEBUG, "IKEV2:   Next Payload: %u  Version: 0x%x  "
     751             :                    "Exchange Type: %u",
     752         390 :                    hdr->next_payload, hdr->version, hdr->exchange_type);
     753         130 :         wpa_printf(MSG_DEBUG, "IKEV2:   Message ID: %u  Length: %u",
     754             :                    message_id, length);
     755             : 
     756         130 :         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         129 :         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         128 :         if (ikev2_validate_rx_state(data, hdr->exchange_type, message_id) < 0)
     770           2 :                 return -1;
     771             : 
     772         126 :         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         124 :         if (data->state != SA_INIT) {
     780          30 :                 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          30 :                 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         124 :         pos = (const u8 *) (hdr + 1);
     793         124 :         if (ikev2_parse_payloads(&pl, hdr->next_payload, pos, end) < 0)
     794           5 :                 return -1;
     795             : 
     796         119 :         if (data->state == SA_INIT) {
     797          89 :                 data->last_msg = LAST_MSG_SA_INIT;
     798          89 :                 if (ikev2_process_sa_init(data, hdr, &pl) < 0) {
     799          25 :                         if (data->state == NOTIFY)
     800           1 :                                 return 0;
     801          24 :                         return -1;
     802             :                 }
     803          64 :                 wpabuf_free(data->i_sign_msg);
     804          64 :                 data->i_sign_msg = wpabuf_dup(buf);
     805             :         }
     806             : 
     807          94 :         if (data->state == SA_AUTH) {
     808          30 :                 data->last_msg = LAST_MSG_SA_AUTH;
     809          30 :                 if (ikev2_process_sa_auth(data, hdr, &pl) < 0) {
     810          14 :                         if (data->state == NOTIFY)
     811           4 :                                 return 0;
     812          10 :                         return -1;
     813             :                 }
     814             :         }
     815             : 
     816          80 :         return 0;
     817             : }
     818             : 
     819             : 
     820          79 : 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          79 :         wpa_printf(MSG_DEBUG, "IKEV2: Adding HDR");
     827             : 
     828             :         /* HDR - RFC 4306, Sect. 3.1 */
     829          79 :         hdr = wpabuf_put(msg, sizeof(*hdr));
     830          79 :         os_memcpy(hdr->i_spi, data->i_spi, IKEV2_SPI_LEN);
     831          79 :         os_memcpy(hdr->r_spi, data->r_spi, IKEV2_SPI_LEN);
     832          79 :         hdr->next_payload = next_payload;
     833          79 :         hdr->version = IKEV2_VERSION;
     834          79 :         hdr->exchange_type = exchange_type;
     835          79 :         hdr->flags = IKEV2_HDR_RESPONSE;
     836          79 :         WPA_PUT_BE32(hdr->message_id, message_id);
     837          79 : }
     838             : 
     839             : 
     840          61 : 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          61 :         wpa_printf(MSG_DEBUG, "IKEV2: Adding SAr1 payload");
     849             : 
     850             :         /* SAr1 - RFC 4306, Sect. 2.7 and 3.3 */
     851          61 :         phdr = wpabuf_put(msg, sizeof(*phdr));
     852          61 :         phdr->next_payload = next_payload;
     853          61 :         phdr->flags = 0;
     854             : 
     855          61 :         p = wpabuf_put(msg, sizeof(*p));
     856          61 :         p->proposal_num = data->proposal.proposal_num;
     857          61 :         p->protocol_id = IKEV2_PROTOCOL_IKE;
     858          61 :         p->num_transforms = 4;
     859             : 
     860          61 :         t = wpabuf_put(msg, sizeof(*t));
     861          61 :         t->type = 3;
     862          61 :         t->transform_type = IKEV2_TRANSFORM_ENCR;
     863          61 :         WPA_PUT_BE16(t->transform_id, data->proposal.encr);
     864          61 :         if (data->proposal.encr == ENCR_AES_CBC) {
     865             :                 /* Transform Attribute: Key Len = 128 bits */
     866          57 :                 wpabuf_put_be16(msg, 0x800e); /* AF=1, AttrType=14 */
     867          57 :                 wpabuf_put_be16(msg, 128); /* 128-bit key */
     868             :         }
     869          61 :         plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) t;
     870          61 :         WPA_PUT_BE16(t->transform_length, plen);
     871             : 
     872          61 :         t = wpabuf_put(msg, sizeof(*t));
     873          61 :         t->type = 3;
     874          61 :         WPA_PUT_BE16(t->transform_length, sizeof(*t));
     875          61 :         t->transform_type = IKEV2_TRANSFORM_PRF;
     876          61 :         WPA_PUT_BE16(t->transform_id, data->proposal.prf);
     877             : 
     878          61 :         t = wpabuf_put(msg, sizeof(*t));
     879          61 :         t->type = 3;
     880          61 :         WPA_PUT_BE16(t->transform_length, sizeof(*t));
     881          61 :         t->transform_type = IKEV2_TRANSFORM_INTEG;
     882          61 :         WPA_PUT_BE16(t->transform_id, data->proposal.integ);
     883             : 
     884          61 :         t = wpabuf_put(msg, sizeof(*t));
     885          61 :         WPA_PUT_BE16(t->transform_length, sizeof(*t));
     886          61 :         t->transform_type = IKEV2_TRANSFORM_DH;
     887          61 :         WPA_PUT_BE16(t->transform_id, data->proposal.dh);
     888             : 
     889          61 :         plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) p;
     890          61 :         WPA_PUT_BE16(p->proposal_length, plen);
     891             : 
     892          61 :         plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
     893          61 :         WPA_PUT_BE16(phdr->payload_length, plen);
     894             : 
     895          61 :         return 0;
     896             : }
     897             : 
     898             : 
     899          61 : 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          61 :         wpa_printf(MSG_DEBUG, "IKEV2: Adding KEr payload");
     907             : 
     908          61 :         pv = dh_init(data->dh, &data->r_dh_private);
     909          61 :         if (pv == NULL) {
     910           5 :                 wpa_printf(MSG_DEBUG, "IKEV2: Failed to initialize DH");
     911           5 :                 return -1;
     912             :         }
     913             : 
     914             :         /* KEr - RFC 4306, Sect. 3.4 */
     915          56 :         phdr = wpabuf_put(msg, sizeof(*phdr));
     916          56 :         phdr->next_payload = next_payload;
     917          56 :         phdr->flags = 0;
     918             : 
     919          56 :         wpabuf_put_be16(msg, data->proposal.dh); /* DH Group # */
     920          56 :         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          56 :         wpabuf_put(msg, data->dh->prime_len - wpabuf_len(pv));
     926          56 :         wpabuf_put_buf(msg, pv);
     927          56 :         wpabuf_free(pv);
     928             : 
     929          56 :         plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
     930          56 :         WPA_PUT_BE16(phdr->payload_length, plen);
     931          56 :         return 0;
     932             : }
     933             : 
     934             : 
     935          56 : 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          56 :         wpa_printf(MSG_DEBUG, "IKEV2: Adding Nr payload");
     942             : 
     943             :         /* Nr - RFC 4306, Sect. 3.9 */
     944          56 :         phdr = wpabuf_put(msg, sizeof(*phdr));
     945          56 :         phdr->next_payload = next_payload;
     946          56 :         phdr->flags = 0;
     947          56 :         wpabuf_put_data(msg, data->r_nonce, data->r_nonce_len);
     948          56 :         plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
     949          56 :         WPA_PUT_BE16(phdr->payload_length, plen);
     950          56 :         return 0;
     951             : }
     952             : 
     953             : 
     954          55 : 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          55 :         wpa_printf(MSG_DEBUG, "IKEV2: Adding IDr payload");
     961             : 
     962          55 :         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          55 :         phdr = wpabuf_put(msg, sizeof(*phdr));
     969          55 :         phdr->next_payload = next_payload;
     970          55 :         phdr->flags = 0;
     971          55 :         wpabuf_put_u8(msg, ID_KEY_ID);
     972          55 :         wpabuf_put(msg, 3); /* RESERVED */
     973          55 :         wpabuf_put_data(msg, data->IDr, data->IDr_len);
     974          55 :         plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
     975          55 :         WPA_PUT_BE16(phdr->payload_length, plen);
     976          55 :         return 0;
     977             : }
     978             : 
     979             : 
     980          14 : 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          14 :         wpa_printf(MSG_DEBUG, "IKEV2: Adding AUTH payload");
     988             : 
     989          14 :         prf = ikev2_get_prf(data->proposal.prf);
     990          14 :         if (prf == NULL)
     991           0 :                 return -1;
     992             : 
     993             :         /* Authentication - RFC 4306, Sect. 3.8 */
     994          14 :         phdr = wpabuf_put(msg, sizeof(*phdr));
     995          14 :         phdr->next_payload = next_payload;
     996          14 :         phdr->flags = 0;
     997          14 :         wpabuf_put_u8(msg, AUTH_SHARED_KEY_MIC);
     998          14 :         wpabuf_put(msg, 3); /* RESERVED */
     999             : 
    1000             :         /* msg | Ni | prf(SK_pr,IDr') */
    1001          70 :         if (ikev2_derive_auth_data(data->proposal.prf, data->r_sign_msg,
    1002          14 :                                    data->IDr, data->IDr_len, ID_KEY_ID,
    1003          14 :                                    &data->keys, 0, data->shared_secret,
    1004             :                                    data->shared_secret_len,
    1005          14 :                                    data->i_nonce, data->i_nonce_len,
    1006          14 :                                    data->key_pad, data->key_pad_len,
    1007          14 :                                    wpabuf_put(msg, prf->hash_len)) < 0) {
    1008           2 :                 wpa_printf(MSG_INFO, "IKEV2: Could not derive AUTH data");
    1009           2 :                 return -1;
    1010             :         }
    1011          12 :         wpabuf_free(data->r_sign_msg);
    1012          12 :         data->r_sign_msg = NULL;
    1013             : 
    1014          12 :         plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
    1015          12 :         WPA_PUT_BE16(phdr->payload_length, plen);
    1016          12 :         return 0;
    1017             : }
    1018             : 
    1019             : 
    1020           3 : 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           3 :         wpa_printf(MSG_DEBUG, "IKEV2: Adding Notification payload");
    1027             : 
    1028           3 :         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           3 :         phdr = wpabuf_put(msg, sizeof(*phdr));
    1036           3 :         phdr->next_payload = next_payload;
    1037           3 :         phdr->flags = 0;
    1038           3 :         wpabuf_put_u8(msg, 0); /* Protocol ID: no existing SA */
    1039           3 :         wpabuf_put_u8(msg, 0); /* SPI Size */
    1040           3 :         wpabuf_put_be16(msg, data->error_type);
    1041             : 
    1042           3 :         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           2 :                 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           3 :         plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
    1063           3 :         WPA_PUT_BE16(phdr->payload_length, plen);
    1064           3 :         return 0;
    1065             : }
    1066             : 
    1067             : 
    1068          64 : 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          64 :         if (os_get_random(data->r_spi, IKEV2_SPI_LEN))
    1075           1 :                 return NULL;
    1076          63 :         wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Responder's SPI",
    1077          63 :                     data->r_spi, IKEV2_SPI_LEN);
    1078             : 
    1079          63 :         data->r_nonce_len = IKEV2_NONCE_MIN_LEN;
    1080          63 :         if (random_get_bytes(data->r_nonce, data->r_nonce_len))
    1081           1 :                 return NULL;
    1082          62 :         wpa_hexdump(MSG_DEBUG, "IKEV2: Nr", data->r_nonce, data->r_nonce_len);
    1083             : 
    1084          62 :         msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + data->IDr_len + 1500);
    1085          62 :         if (msg == NULL)
    1086           1 :                 return NULL;
    1087             : 
    1088          61 :         ikev2_build_hdr(data, msg, IKE_SA_INIT, IKEV2_PAYLOAD_SA, 0);
    1089         122 :         if (ikev2_build_sar1(data, msg, IKEV2_PAYLOAD_KEY_EXCHANGE) ||
    1090         117 :             ikev2_build_ker(data, msg, IKEV2_PAYLOAD_NONCE) ||
    1091          56 :             ikev2_build_nr(data, msg, data->peer_auth == PEER_AUTH_SECRET ?
    1092             :                            IKEV2_PAYLOAD_ENCRYPTED :
    1093             :                            IKEV2_PAYLOAD_NO_NEXT_PAYLOAD)) {
    1094           5 :                 wpabuf_free(msg);
    1095           5 :                 return NULL;
    1096             :         }
    1097             : 
    1098          56 :         if (ikev2_derive_keys(data)) {
    1099          14 :                 wpabuf_free(msg);
    1100          14 :                 return NULL;
    1101             :         }
    1102             : 
    1103          42 :         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          42 :         if (data->peer_auth == PEER_AUTH_SECRET) {
    1109          42 :                 struct wpabuf *plain = wpabuf_alloc(data->IDr_len + 1000);
    1110          42 :                 if (plain == NULL) {
    1111           1 :                         wpabuf_free(msg);
    1112           1 :                         return NULL;
    1113             :                 }
    1114          41 :                 if (ikev2_build_idr(data, plain,
    1115          41 :                                     IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) ||
    1116          41 :                     ikev2_build_encrypted(data->proposal.encr,
    1117             :                                           data->proposal.integ,
    1118             :                                           &data->keys, 0, msg, plain,
    1119             :                                           IKEV2_PAYLOAD_IDr)) {
    1120           4 :                         wpabuf_free(plain);
    1121           4 :                         wpabuf_free(msg);
    1122           4 :                         return NULL;
    1123             :                 }
    1124          37 :                 wpabuf_free(plain);
    1125             :         }
    1126             : 
    1127          37 :         ikev2_update_hdr(msg);
    1128             : 
    1129          37 :         wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (SA_INIT)", msg);
    1130             : 
    1131          37 :         data->state = SA_AUTH;
    1132             : 
    1133          37 :         wpabuf_free(data->r_sign_msg);
    1134          37 :         data->r_sign_msg = wpabuf_dup(msg);
    1135             : 
    1136          37 :         return msg;
    1137             : }
    1138             : 
    1139             : 
    1140          16 : 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          16 :         msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + data->IDr_len + 1000);
    1147          16 :         if (msg == NULL)
    1148           1 :                 return NULL;
    1149          15 :         ikev2_build_hdr(data, msg, IKE_SA_AUTH, IKEV2_PAYLOAD_ENCRYPTED, 1);
    1150             : 
    1151          15 :         plain = wpabuf_alloc(data->IDr_len + 1000);
    1152          15 :         if (plain == NULL) {
    1153           1 :                 wpabuf_free(msg);
    1154           1 :                 return NULL;
    1155             :         }
    1156             : 
    1157          28 :         if (ikev2_build_idr(data, plain, IKEV2_PAYLOAD_AUTHENTICATION) ||
    1158          26 :             ikev2_build_auth(data, plain, IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) ||
    1159          12 :             ikev2_build_encrypted(data->proposal.encr, data->proposal.integ,
    1160             :                                   &data->keys, 0, msg, plain,
    1161             :                                   IKEV2_PAYLOAD_IDr)) {
    1162           2 :                 wpabuf_free(plain);
    1163           2 :                 wpabuf_free(msg);
    1164           2 :                 return NULL;
    1165             :         }
    1166          12 :         wpabuf_free(plain);
    1167             : 
    1168          12 :         wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (SA_AUTH)", msg);
    1169             : 
    1170          12 :         data->state = IKEV2_DONE;
    1171             : 
    1172          12 :         return msg;
    1173             : }
    1174             : 
    1175             : 
    1176           5 : static struct wpabuf * ikev2_build_notify(struct ikev2_responder_data *data)
    1177             : {
    1178             :         struct wpabuf *msg;
    1179             : 
    1180           5 :         msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + 1000);
    1181           5 :         if (msg == NULL)
    1182           1 :                 return NULL;
    1183           4 :         if (data->last_msg == LAST_MSG_SA_AUTH) {
    1184             :                 /* HDR, SK{N} */
    1185           3 :                 struct wpabuf *plain = wpabuf_alloc(100);
    1186           3 :                 if (plain == NULL) {
    1187           1 :                         wpabuf_free(msg);
    1188           1 :                         return NULL;
    1189             :                 }
    1190           2 :                 ikev2_build_hdr(data, msg, IKE_SA_AUTH,
    1191             :                                 IKEV2_PAYLOAD_ENCRYPTED, 1);
    1192           2 :                 if (ikev2_build_notification(data, plain,
    1193           2 :                                              IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) ||
    1194           2 :                     ikev2_build_encrypted(data->proposal.encr,
    1195             :                                           data->proposal.integ,
    1196             :                                           &data->keys, 0, msg, plain,
    1197             :                                           IKEV2_PAYLOAD_NOTIFICATION)) {
    1198           1 :                         wpabuf_free(plain);
    1199           1 :                         wpabuf_free(msg);
    1200           1 :                         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          85 : struct wpabuf * ikev2_responder_build(struct ikev2_responder_data *data)
    1226             : {
    1227          85 :         switch (data->state) {
    1228             :         case SA_INIT:
    1229          64 :                 return ikev2_build_sa_init(data);
    1230             :         case SA_AUTH:
    1231          16 :                 return ikev2_build_sa_auth(data);
    1232             :         case CHILD_SA:
    1233           0 :                 return NULL;
    1234             :         case NOTIFY:
    1235           5 :                 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