LCOV - code coverage report
Current view: top level - src/eap_common - ikev2_common.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1443382998 Lines: 303 374 81.0 %
Date: 2015-09-27 Functions: 16 16 100.0 %

          Line data    Source code
       1             : /*
       2             :  * IKEv2 common routines for initiator and responder
       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/crypto.h"
      13             : #include "crypto/md5.h"
      14             : #include "crypto/sha1.h"
      15             : #include "crypto/random.h"
      16             : #include "ikev2_common.h"
      17             : 
      18             : 
      19             : static const struct ikev2_integ_alg ikev2_integ_algs[] = {
      20             :         { AUTH_HMAC_SHA1_96, 20, 12 },
      21             :         { AUTH_HMAC_MD5_96, 16, 12 }
      22             : };
      23             : 
      24             : #define NUM_INTEG_ALGS ARRAY_SIZE(ikev2_integ_algs)
      25             : 
      26             : 
      27             : static const struct ikev2_prf_alg ikev2_prf_algs[] = {
      28             :         { PRF_HMAC_SHA1, 20, 20 },
      29             :         { PRF_HMAC_MD5, 16, 16 }
      30             : };
      31             : 
      32             : #define NUM_PRF_ALGS ARRAY_SIZE(ikev2_prf_algs)
      33             : 
      34             : 
      35             : static const struct ikev2_encr_alg ikev2_encr_algs[] = {
      36             :         { ENCR_AES_CBC, 16, 16 }, /* only 128-bit keys supported for now */
      37             :         { ENCR_3DES, 24, 8 }
      38             : };
      39             : 
      40             : #define NUM_ENCR_ALGS ARRAY_SIZE(ikev2_encr_algs)
      41             : 
      42             : 
      43         137 : const struct ikev2_integ_alg * ikev2_get_integ(int id)
      44             : {
      45             :         size_t i;
      46             : 
      47         160 :         for (i = 0; i < NUM_INTEG_ALGS; i++) {
      48         159 :                 if (ikev2_integ_algs[i].id == id)
      49         136 :                         return &ikev2_integ_algs[i];
      50             :         }
      51             : 
      52           1 :         return NULL;
      53             : }
      54             : 
      55             : 
      56          87 : int ikev2_integ_hash(int alg, const u8 *key, size_t key_len, const u8 *data,
      57             :                      size_t data_len, u8 *hash)
      58             : {
      59             :         u8 tmphash[IKEV2_MAX_HASH_LEN];
      60             : 
      61          87 :         switch (alg) {
      62             :         case AUTH_HMAC_SHA1_96:
      63          82 :                 if (key_len != 20)
      64           0 :                         return -1;
      65          82 :                 hmac_sha1(key, key_len, data, data_len, tmphash);
      66          82 :                 os_memcpy(hash, tmphash, 12);
      67          82 :                 break;
      68             :         case AUTH_HMAC_MD5_96:
      69           5 :                 if (key_len != 16)
      70           0 :                         return -1;
      71           5 :                 hmac_md5(key, key_len, data, data_len, tmphash);
      72           5 :                 os_memcpy(hash, tmphash, 12);
      73           5 :                 break;
      74             :         default:
      75           0 :                 return -1;
      76             :         }
      77             : 
      78          87 :         return 0;
      79             : }
      80             : 
      81             : 
      82         130 : const struct ikev2_prf_alg * ikev2_get_prf(int id)
      83             : {
      84             :         size_t i;
      85             : 
      86         149 :         for (i = 0; i < NUM_PRF_ALGS; i++) {
      87         149 :                 if (ikev2_prf_algs[i].id == id)
      88         130 :                         return &ikev2_prf_algs[i];
      89             :         }
      90             : 
      91           0 :         return NULL;
      92             : }
      93             : 
      94             : 
      95         310 : int ikev2_prf_hash(int alg, const u8 *key, size_t key_len,
      96             :                    size_t num_elem, const u8 *addr[], const size_t *len,
      97             :                    u8 *hash)
      98             : {
      99         310 :         switch (alg) {
     100             :         case PRF_HMAC_SHA1:
     101         274 :                 hmac_sha1_vector(key, key_len, num_elem, addr, len, hash);
     102         274 :                 break;
     103             :         case PRF_HMAC_MD5:
     104          36 :                 hmac_md5_vector(key, key_len, num_elem, addr, len, hash);
     105          36 :                 break;
     106             :         default:
     107           0 :                 return -1;
     108             :         }
     109             : 
     110         310 :         return 0;
     111             : }
     112             : 
     113             : 
     114          30 : int ikev2_prf_plus(int alg, const u8 *key, size_t key_len,
     115             :                    const u8 *data, size_t data_len,
     116             :                    u8 *out, size_t out_len)
     117             : {
     118             :         u8 hash[IKEV2_MAX_HASH_LEN];
     119             :         size_t hash_len;
     120             :         u8 iter, *pos, *end;
     121             :         const u8 *addr[3];
     122             :         size_t len[3];
     123             :         const struct ikev2_prf_alg *prf;
     124             :         int res;
     125             : 
     126          30 :         prf = ikev2_get_prf(alg);
     127          30 :         if (prf == NULL)
     128           0 :                 return -1;
     129          30 :         hash_len = prf->hash_len;
     130             : 
     131          30 :         addr[0] = hash;
     132          30 :         len[0] = hash_len;
     133          30 :         addr[1] = data;
     134          30 :         len[1] = data_len;
     135          30 :         addr[2] = &iter;
     136          30 :         len[2] = 1;
     137             : 
     138          30 :         pos = out;
     139          30 :         end = out + out_len;
     140          30 :         iter = 1;
     141         274 :         while (pos < end) {
     142             :                 size_t clen;
     143         214 :                 if (iter == 1)
     144          30 :                         res = ikev2_prf_hash(alg, key, key_len, 2, &addr[1],
     145             :                                              &len[1], hash);
     146             :                 else
     147         184 :                         res = ikev2_prf_hash(alg, key, key_len, 3, addr, len,
     148             :                                              hash);
     149         214 :                 if (res < 0)
     150           0 :                         return -1;
     151         214 :                 clen = hash_len;
     152         214 :                 if ((int) clen > end - pos)
     153          26 :                         clen = end - pos;
     154         214 :                 os_memcpy(pos, hash, clen);
     155         214 :                 pos += clen;
     156         214 :                 iter++;
     157             :         }
     158             : 
     159          30 :         return 0;
     160             : }
     161             : 
     162             : 
     163          97 : const struct ikev2_encr_alg * ikev2_get_encr(int id)
     164             : {
     165             :         size_t i;
     166             : 
     167         116 :         for (i = 0; i < NUM_ENCR_ALGS; i++) {
     168         116 :                 if (ikev2_encr_algs[i].id == id)
     169          97 :                         return &ikev2_encr_algs[i];
     170             :         }
     171             : 
     172           0 :         return NULL;
     173             : }
     174             : 
     175             : 
     176          25 : int ikev2_encr_encrypt(int alg, const u8 *key, size_t key_len, const u8 *iv,
     177             :                        const u8 *plain, u8 *crypt, size_t len)
     178             : {
     179             :         struct crypto_cipher *cipher;
     180             :         int encr_alg;
     181             : 
     182          25 :         switch (alg) {
     183             :         case ENCR_3DES:
     184           4 :                 encr_alg = CRYPTO_CIPHER_ALG_3DES;
     185           4 :                 break;
     186             :         case ENCR_AES_CBC:
     187          21 :                 encr_alg = CRYPTO_CIPHER_ALG_AES;
     188          21 :                 break;
     189             :         default:
     190           0 :                 wpa_printf(MSG_DEBUG, "IKEV2: Unsupported encr alg %d", alg);
     191           0 :                 return -1;
     192             :         }
     193             : 
     194          25 :         cipher = crypto_cipher_init(encr_alg, iv, key, key_len);
     195          25 :         if (cipher == NULL) {
     196           0 :                 wpa_printf(MSG_INFO, "IKEV2: Failed to initialize cipher");
     197           0 :                 return -1;
     198             :         }
     199             : 
     200          25 :         if (crypto_cipher_encrypt(cipher, plain, crypt, len) < 0) {
     201           0 :                 wpa_printf(MSG_INFO, "IKEV2: Encryption failed");
     202           0 :                 crypto_cipher_deinit(cipher);
     203           0 :                 return -1;
     204             :         }
     205          25 :         crypto_cipher_deinit(cipher);
     206             : 
     207          25 :         return 0;
     208             : }
     209             : 
     210             : 
     211          21 : int ikev2_encr_decrypt(int alg, const u8 *key, size_t key_len, const u8 *iv,
     212             :                        const u8 *crypt, u8 *plain, size_t len)
     213             : {
     214             :         struct crypto_cipher *cipher;
     215             :         int encr_alg;
     216             : 
     217          21 :         switch (alg) {
     218             :         case ENCR_3DES:
     219           0 :                 encr_alg = CRYPTO_CIPHER_ALG_3DES;
     220           0 :                 break;
     221             :         case ENCR_AES_CBC:
     222          21 :                 encr_alg = CRYPTO_CIPHER_ALG_AES;
     223          21 :                 break;
     224             :         default:
     225           0 :                 wpa_printf(MSG_DEBUG, "IKEV2: Unsupported encr alg %d", alg);
     226           0 :                 return -1;
     227             :         }
     228             : 
     229          21 :         cipher = crypto_cipher_init(encr_alg, iv, key, key_len);
     230          21 :         if (cipher == NULL) {
     231           0 :                 wpa_printf(MSG_INFO, "IKEV2: Failed to initialize cipher");
     232           0 :                 return -1;
     233             :         }
     234             : 
     235          21 :         if (crypto_cipher_decrypt(cipher, crypt, plain, len) < 0) {
     236           0 :                 wpa_printf(MSG_INFO, "IKEV2: Decryption failed");
     237           0 :                 crypto_cipher_deinit(cipher);
     238           0 :                 return -1;
     239             :         }
     240          21 :         crypto_cipher_deinit(cipher);
     241             : 
     242          21 :         return 0;
     243             : }
     244             : 
     245             : 
     246          86 : int ikev2_parse_payloads(struct ikev2_payloads *payloads,
     247             :                          u8 next_payload, const u8 *pos, const u8 *end)
     248             : {
     249             :         const struct ikev2_payload_hdr *phdr;
     250             : 
     251          86 :         os_memset(payloads, 0, sizeof(*payloads));
     252             : 
     253         326 :         while (next_payload != IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) {
     254             :                 unsigned int plen, pdatalen, left;
     255             :                 const u8 *pdata;
     256         158 :                 wpa_printf(MSG_DEBUG, "IKEV2: Processing payload %u",
     257             :                            next_payload);
     258         158 :                 if (end < pos)
     259           0 :                         return -1;
     260         158 :                 left = end - pos;
     261         158 :                 if (left < sizeof(*phdr)) {
     262           1 :                         wpa_printf(MSG_INFO, "IKEV2:   Too short message for "
     263             :                                    "payload header (left=%ld)",
     264             :                                    (long) (end - pos));
     265           1 :                         return -1;
     266             :                 }
     267         157 :                 phdr = (const struct ikev2_payload_hdr *) pos;
     268         157 :                 plen = WPA_GET_BE16(phdr->payload_length);
     269         157 :                 if (plen < sizeof(*phdr) || plen > left) {
     270           2 :                         wpa_printf(MSG_INFO, "IKEV2:   Invalid payload header "
     271             :                                    "length %d", plen);
     272           2 :                         return -1;
     273             :                 }
     274             : 
     275         310 :                 wpa_printf(MSG_DEBUG, "IKEV2:   Next Payload: %u  Flags: 0x%x"
     276             :                            "  Payload Length: %u",
     277         310 :                            phdr->next_payload, phdr->flags, plen);
     278             : 
     279         155 :                 pdata = (const u8 *) (phdr + 1);
     280         155 :                 pdatalen = plen - sizeof(*phdr);
     281             : 
     282         155 :                 switch (next_payload) {
     283             :                 case IKEV2_PAYLOAD_SA:
     284          45 :                         wpa_printf(MSG_DEBUG, "IKEV2:   Payload: Security "
     285             :                                    "Association");
     286          45 :                         payloads->sa = pdata;
     287          45 :                         payloads->sa_len = pdatalen;
     288          45 :                         break;
     289             :                 case IKEV2_PAYLOAD_KEY_EXCHANGE:
     290          28 :                         wpa_printf(MSG_DEBUG, "IKEV2:   Payload: Key "
     291             :                                    "Exchange");
     292          28 :                         payloads->ke = pdata;
     293          28 :                         payloads->ke_len = pdatalen;
     294          28 :                         break;
     295             :                 case IKEV2_PAYLOAD_IDi:
     296           7 :                         wpa_printf(MSG_DEBUG, "IKEV2:   Payload: IDi");
     297           7 :                         payloads->idi = pdata;
     298           7 :                         payloads->idi_len = pdatalen;
     299           7 :                         break;
     300             :                 case IKEV2_PAYLOAD_IDr:
     301          13 :                         wpa_printf(MSG_DEBUG, "IKEV2:   Payload: IDr");
     302          13 :                         payloads->idr = pdata;
     303          13 :                         payloads->idr_len = pdatalen;
     304          13 :                         break;
     305             :                 case IKEV2_PAYLOAD_CERTIFICATE:
     306           1 :                         wpa_printf(MSG_DEBUG, "IKEV2:   Payload: Certificate");
     307           1 :                         payloads->cert = pdata;
     308           1 :                         payloads->cert_len = pdatalen;
     309           1 :                         break;
     310             :                 case IKEV2_PAYLOAD_AUTHENTICATION:
     311          13 :                         wpa_printf(MSG_DEBUG, "IKEV2:   Payload: "
     312             :                                    "Authentication");
     313          13 :                         payloads->auth = pdata;
     314          13 :                         payloads->auth_len = pdatalen;
     315          13 :                         break;
     316             :                 case IKEV2_PAYLOAD_NONCE:
     317          24 :                         wpa_printf(MSG_DEBUG, "IKEV2:   Payload: Nonce");
     318          24 :                         payloads->nonce = pdata;
     319          24 :                         payloads->nonce_len = pdatalen;
     320          24 :                         break;
     321             :                 case IKEV2_PAYLOAD_ENCRYPTED:
     322          21 :                         wpa_printf(MSG_DEBUG, "IKEV2:   Payload: Encrypted");
     323          21 :                         payloads->encrypted = pdata;
     324          21 :                         payloads->encrypted_len = pdatalen;
     325          21 :                         break;
     326             :                 case IKEV2_PAYLOAD_NOTIFICATION:
     327           1 :                         wpa_printf(MSG_DEBUG, "IKEV2:   Payload: "
     328             :                                    "Notification");
     329           1 :                         payloads->notification = pdata;
     330           1 :                         payloads->notification_len = pdatalen;
     331           1 :                         break;
     332             :                 default:
     333           2 :                         if (phdr->flags & IKEV2_PAYLOAD_FLAGS_CRITICAL) {
     334           1 :                                 wpa_printf(MSG_INFO, "IKEV2:   Unsupported "
     335             :                                            "critical payload %u - reject the "
     336             :                                            "entire message", next_payload);
     337           1 :                                 return -1;
     338             :                         } else {
     339           1 :                                 wpa_printf(MSG_DEBUG, "IKEV2:   Skipped "
     340             :                                            "unsupported payload %u",
     341             :                                            next_payload);
     342             :                         }
     343             :                 }
     344             : 
     345         175 :                 if (next_payload == IKEV2_PAYLOAD_ENCRYPTED &&
     346          21 :                     pos + plen == end) {
     347             :                         /*
     348             :                          * Next Payload in the case of Encrypted Payload is
     349             :                          * actually the payload type for the first embedded
     350             :                          * payload.
     351             :                          */
     352          21 :                         payloads->encr_next_payload = phdr->next_payload;
     353          21 :                         next_payload = IKEV2_PAYLOAD_NO_NEXT_PAYLOAD;
     354             :                 } else
     355         133 :                         next_payload = phdr->next_payload;
     356             : 
     357         154 :                 pos += plen;
     358             :         }
     359             : 
     360          82 :         if (pos != end) {
     361           1 :                 wpa_printf(MSG_INFO, "IKEV2: Unexpected extra data after "
     362             :                            "payloads");
     363           1 :                 return -1;
     364             :         }
     365             : 
     366          81 :         return 0;
     367             : }
     368             : 
     369             : 
     370          26 : int ikev2_derive_auth_data(int prf_alg, const struct wpabuf *sign_msg,
     371             :                            const u8 *ID, size_t ID_len, u8 ID_type,
     372             :                            struct ikev2_keys *keys, int initiator,
     373             :                            const u8 *shared_secret, size_t shared_secret_len,
     374             :                            const u8 *nonce, size_t nonce_len,
     375             :                            const u8 *key_pad, size_t key_pad_len,
     376             :                            u8 *auth_data)
     377             : {
     378             :         size_t sign_len, buf_len;
     379             :         u8 *sign_data, *pos, *buf, hash[IKEV2_MAX_HASH_LEN];
     380             :         const struct ikev2_prf_alg *prf;
     381          26 :         const u8 *SK_p = initiator ? keys->SK_pi : keys->SK_pr;
     382             : 
     383          26 :         prf = ikev2_get_prf(prf_alg);
     384          26 :         if (sign_msg == NULL || ID == NULL || SK_p == NULL ||
     385          26 :             shared_secret == NULL || nonce == NULL || prf == NULL)
     386           0 :                 return -1;
     387             : 
     388             :         /* prf(SK_pi/r,IDi/r') */
     389          26 :         buf_len = 4 + ID_len;
     390          26 :         buf = os_zalloc(buf_len);
     391          26 :         if (buf == NULL)
     392           0 :                 return -1;
     393          26 :         buf[0] = ID_type;
     394          26 :         os_memcpy(buf + 4, ID, ID_len);
     395          26 :         if (ikev2_prf_hash(prf->id, SK_p, keys->SK_prf_len,
     396             :                            1, (const u8 **) &buf, &buf_len, hash) < 0) {
     397           0 :                 os_free(buf);
     398           0 :                 return -1;
     399             :         }
     400          26 :         os_free(buf);
     401             : 
     402             :         /* sign_data = msg | Nr/i | prf(SK_pi/r,IDi/r') */
     403          26 :         sign_len = wpabuf_len(sign_msg) + nonce_len + prf->hash_len;
     404          26 :         sign_data = os_malloc(sign_len);
     405          26 :         if (sign_data == NULL)
     406           0 :                 return -1;
     407          26 :         pos = sign_data;
     408          26 :         os_memcpy(pos, wpabuf_head(sign_msg), wpabuf_len(sign_msg));
     409          26 :         pos += wpabuf_len(sign_msg);
     410          26 :         os_memcpy(pos, nonce, nonce_len);
     411          26 :         pos += nonce_len;
     412          26 :         os_memcpy(pos, hash, prf->hash_len);
     413             : 
     414             :         /* AUTH = prf(prf(Shared Secret, key pad, sign_data) */
     415          26 :         if (ikev2_prf_hash(prf->id, shared_secret, shared_secret_len, 1,
     416          26 :                            &key_pad, &key_pad_len, hash) < 0 ||
     417          26 :             ikev2_prf_hash(prf->id, hash, prf->hash_len, 1,
     418             :                            (const u8 **) &sign_data, &sign_len, auth_data) < 0)
     419             :         {
     420           0 :                 os_free(sign_data);
     421           0 :                 return -1;
     422             :         }
     423          26 :         os_free(sign_data);
     424             : 
     425          26 :         return 0;
     426             : }
     427             : 
     428             : 
     429          21 : u8 * ikev2_decrypt_payload(int encr_id, int integ_id,
     430             :                            struct ikev2_keys *keys, int initiator,
     431             :                            const struct ikev2_hdr *hdr,
     432             :                            const u8 *encrypted, size_t encrypted_len,
     433             :                            size_t *res_len)
     434             : {
     435             :         size_t iv_len;
     436             :         const u8 *pos, *end, *iv, *integ;
     437             :         u8 hash[IKEV2_MAX_HASH_LEN], *decrypted;
     438             :         size_t decrypted_len, pad_len;
     439             :         const struct ikev2_integ_alg *integ_alg;
     440             :         const struct ikev2_encr_alg *encr_alg;
     441          21 :         const u8 *SK_e = initiator ? keys->SK_ei : keys->SK_er;
     442          21 :         const u8 *SK_a = initiator ? keys->SK_ai : keys->SK_ar;
     443             : 
     444          21 :         if (encrypted == NULL) {
     445           0 :                 wpa_printf(MSG_INFO, "IKEV2: No Encrypted payload in SA_AUTH");
     446           0 :                 return NULL;
     447             :         }
     448             : 
     449          21 :         encr_alg = ikev2_get_encr(encr_id);
     450          21 :         if (encr_alg == NULL) {
     451           0 :                 wpa_printf(MSG_INFO, "IKEV2: Unsupported encryption type");
     452           0 :                 return NULL;
     453             :         }
     454          21 :         iv_len = encr_alg->block_size;
     455             : 
     456          21 :         integ_alg = ikev2_get_integ(integ_id);
     457          21 :         if (integ_alg == NULL) {
     458           0 :                 wpa_printf(MSG_INFO, "IKEV2: Unsupported intergrity type");
     459           0 :                 return NULL;
     460             :         }
     461             : 
     462          21 :         if (encrypted_len < iv_len + 1 + integ_alg->hash_len) {
     463           0 :                 wpa_printf(MSG_INFO, "IKEV2: No room for IV or Integrity "
     464             :                           "Checksum");
     465           0 :                 return NULL;
     466             :         }
     467             : 
     468          21 :         iv = encrypted;
     469          21 :         pos = iv + iv_len;
     470          21 :         end = encrypted + encrypted_len;
     471          21 :         integ = end - integ_alg->hash_len;
     472             : 
     473          21 :         if (SK_a == NULL) {
     474           0 :                 wpa_printf(MSG_INFO, "IKEV2: No SK_a available");
     475           0 :                 return NULL;
     476             :         }
     477          21 :         if (ikev2_integ_hash(integ_id, SK_a, keys->SK_integ_len,
     478             :                              (const u8 *) hdr,
     479          21 :                              integ - (const u8 *) hdr, hash) < 0) {
     480           0 :                 wpa_printf(MSG_INFO, "IKEV2: Failed to calculate integrity "
     481             :                            "hash");
     482           0 :                 return NULL;
     483             :         }
     484          21 :         if (os_memcmp_const(integ, hash, integ_alg->hash_len) != 0) {
     485           0 :                 wpa_printf(MSG_INFO, "IKEV2: Incorrect Integrity Checksum "
     486             :                            "Data");
     487           0 :                 return NULL;
     488             :         }
     489             : 
     490          21 :         if (SK_e == NULL) {
     491           0 :                 wpa_printf(MSG_INFO, "IKEV2: No SK_e available");
     492           0 :                 return NULL;
     493             :         }
     494             : 
     495          21 :         decrypted_len = integ - pos;
     496          21 :         decrypted = os_malloc(decrypted_len);
     497          21 :         if (decrypted == NULL)
     498           0 :                 return NULL;
     499             : 
     500          21 :         if (ikev2_encr_decrypt(encr_alg->id, SK_e, keys->SK_encr_len, iv, pos,
     501             :                                decrypted, decrypted_len) < 0) {
     502           0 :                 os_free(decrypted);
     503           0 :                 return NULL;
     504             :         }
     505             : 
     506          21 :         pad_len = decrypted[decrypted_len - 1];
     507          21 :         if (decrypted_len < pad_len + 1) {
     508           0 :                 wpa_printf(MSG_INFO, "IKEV2: Invalid padding in encrypted "
     509             :                            "payload");
     510           0 :                 os_free(decrypted);
     511           0 :                 return NULL;
     512             :         }
     513             : 
     514          21 :         decrypted_len -= pad_len + 1;
     515             : 
     516          21 :         *res_len = decrypted_len;
     517          21 :         return decrypted;
     518             : }
     519             : 
     520             : 
     521          49 : void ikev2_update_hdr(struct wpabuf *msg)
     522             : {
     523             :         struct ikev2_hdr *hdr;
     524             : 
     525             :         /* Update lenth field in HDR */
     526          49 :         hdr = wpabuf_mhead(msg);
     527          49 :         WPA_PUT_BE32(hdr->length, wpabuf_len(msg));
     528          49 : }
     529             : 
     530             : 
     531          25 : int ikev2_build_encrypted(int encr_id, int integ_id, struct ikev2_keys *keys,
     532             :                           int initiator, struct wpabuf *msg,
     533             :                           struct wpabuf *plain, u8 next_payload)
     534             : {
     535             :         struct ikev2_payload_hdr *phdr;
     536             :         size_t plen;
     537             :         size_t iv_len, pad_len;
     538             :         u8 *icv, *iv;
     539             :         const struct ikev2_integ_alg *integ_alg;
     540             :         const struct ikev2_encr_alg *encr_alg;
     541          25 :         const u8 *SK_e = initiator ? keys->SK_ei : keys->SK_er;
     542          25 :         const u8 *SK_a = initiator ? keys->SK_ai : keys->SK_ar;
     543             : 
     544          25 :         wpa_printf(MSG_DEBUG, "IKEV2: Adding Encrypted payload");
     545             : 
     546             :         /* Encr - RFC 4306, Sect. 3.14 */
     547             : 
     548          25 :         encr_alg = ikev2_get_encr(encr_id);
     549          25 :         if (encr_alg == NULL) {
     550           0 :                 wpa_printf(MSG_INFO, "IKEV2: Unsupported encryption type");
     551           0 :                 return -1;
     552             :         }
     553          25 :         iv_len = encr_alg->block_size;
     554             : 
     555          25 :         integ_alg = ikev2_get_integ(integ_id);
     556          25 :         if (integ_alg == NULL) {
     557           0 :                 wpa_printf(MSG_INFO, "IKEV2: Unsupported intergrity type");
     558           0 :                 return -1;
     559             :         }
     560             : 
     561          25 :         if (SK_e == NULL) {
     562           0 :                 wpa_printf(MSG_INFO, "IKEV2: No SK_e available");
     563           0 :                 return -1;
     564             :         }
     565             : 
     566          25 :         if (SK_a == NULL) {
     567           0 :                 wpa_printf(MSG_INFO, "IKEV2: No SK_a available");
     568           0 :                 return -1;
     569             :         }
     570             : 
     571          25 :         phdr = wpabuf_put(msg, sizeof(*phdr));
     572          25 :         phdr->next_payload = next_payload;
     573          25 :         phdr->flags = 0;
     574             : 
     575          25 :         iv = wpabuf_put(msg, iv_len);
     576          25 :         if (random_get_bytes(iv, iv_len)) {
     577           0 :                 wpa_printf(MSG_INFO, "IKEV2: Could not generate IV");
     578           0 :                 return -1;
     579             :         }
     580             : 
     581          25 :         pad_len = iv_len - (wpabuf_len(plain) + 1) % iv_len;
     582          25 :         if (pad_len == iv_len)
     583           0 :                 pad_len = 0;
     584          25 :         wpabuf_put(plain, pad_len);
     585          25 :         wpabuf_put_u8(plain, pad_len);
     586             : 
     587          50 :         if (ikev2_encr_encrypt(encr_alg->id, SK_e, keys->SK_encr_len, iv,
     588          25 :                                wpabuf_head(plain), wpabuf_mhead(plain),
     589             :                                wpabuf_len(plain)) < 0)
     590           0 :                 return -1;
     591             : 
     592          25 :         wpabuf_put_buf(msg, plain);
     593             : 
     594             :         /* Need to update all headers (Length fields) prior to hash func */
     595          25 :         icv = wpabuf_put(msg, integ_alg->hash_len);
     596          25 :         plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
     597          25 :         WPA_PUT_BE16(phdr->payload_length, plen);
     598             : 
     599          25 :         ikev2_update_hdr(msg);
     600             : 
     601          50 :         return ikev2_integ_hash(integ_id, SK_a, keys->SK_integ_len,
     602          25 :                                 wpabuf_head(msg),
     603          25 :                                 wpabuf_len(msg) - integ_alg->hash_len, icv);
     604             : 
     605             :         return 0;
     606             : }
     607             : 
     608             : 
     609          18 : int ikev2_keys_set(struct ikev2_keys *keys)
     610             : {
     611          72 :         return keys->SK_d && keys->SK_ai && keys->SK_ar && keys->SK_ei &&
     612          54 :                 keys->SK_er && keys->SK_pi && keys->SK_pr;
     613             : }
     614             : 
     615             : 
     616          89 : void ikev2_free_keys(struct ikev2_keys *keys)
     617             : {
     618          89 :         os_free(keys->SK_d);
     619          89 :         os_free(keys->SK_ai);
     620          89 :         os_free(keys->SK_ar);
     621          89 :         os_free(keys->SK_ei);
     622          89 :         os_free(keys->SK_er);
     623          89 :         os_free(keys->SK_pi);
     624          89 :         os_free(keys->SK_pr);
     625          89 :         keys->SK_d = keys->SK_ai = keys->SK_ar = keys->SK_ei = keys->SK_er =
     626          89 :                 keys->SK_pi = keys->SK_pr = NULL;
     627          89 : }
     628             : 
     629             : 
     630          18 : int ikev2_derive_sk_keys(const struct ikev2_prf_alg *prf,
     631             :                          const struct ikev2_integ_alg *integ,
     632             :                          const struct ikev2_encr_alg *encr,
     633             :                          const u8 *skeyseed, const u8 *data, size_t data_len,
     634             :                          struct ikev2_keys *keys)
     635             : {
     636             :         u8 *keybuf, *pos;
     637             :         size_t keybuf_len;
     638             : 
     639             :         /*
     640             :          * {SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr } =
     641             :          *      prf+(SKEYSEED, Ni | Nr | SPIi | SPIr )
     642             :          */
     643          18 :         ikev2_free_keys(keys);
     644          18 :         keys->SK_d_len = prf->key_len;
     645          18 :         keys->SK_integ_len = integ->key_len;
     646          18 :         keys->SK_encr_len = encr->key_len;
     647          18 :         keys->SK_prf_len = prf->key_len;
     648             : 
     649          54 :         keybuf_len = keys->SK_d_len + 2 * keys->SK_integ_len +
     650          36 :                 2 * keys->SK_encr_len + 2 * keys->SK_prf_len;
     651          18 :         keybuf = os_malloc(keybuf_len);
     652          18 :         if (keybuf == NULL)
     653           0 :                 return -1;
     654             : 
     655          18 :         if (ikev2_prf_plus(prf->id, skeyseed, prf->hash_len,
     656             :                            data, data_len, keybuf, keybuf_len)) {
     657           0 :                 os_free(keybuf);
     658           0 :                 return -1;
     659             :         }
     660             : 
     661          18 :         pos = keybuf;
     662             : 
     663          18 :         keys->SK_d = os_malloc(keys->SK_d_len);
     664          18 :         if (keys->SK_d) {
     665          18 :                 os_memcpy(keys->SK_d, pos, keys->SK_d_len);
     666          36 :                 wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_d",
     667          18 :                                 keys->SK_d, keys->SK_d_len);
     668             :         }
     669          18 :         pos += keys->SK_d_len;
     670             : 
     671          18 :         keys->SK_ai = os_malloc(keys->SK_integ_len);
     672          18 :         if (keys->SK_ai) {
     673          18 :                 os_memcpy(keys->SK_ai, pos, keys->SK_integ_len);
     674          36 :                 wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_ai",
     675          18 :                                 keys->SK_ai, keys->SK_integ_len);
     676             :         }
     677          18 :         pos += keys->SK_integ_len;
     678             : 
     679          18 :         keys->SK_ar = os_malloc(keys->SK_integ_len);
     680          18 :         if (keys->SK_ar) {
     681          18 :                 os_memcpy(keys->SK_ar, pos, keys->SK_integ_len);
     682          36 :                 wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_ar",
     683          18 :                                 keys->SK_ar, keys->SK_integ_len);
     684             :         }
     685          18 :         pos += keys->SK_integ_len;
     686             : 
     687          18 :         keys->SK_ei = os_malloc(keys->SK_encr_len);
     688          18 :         if (keys->SK_ei) {
     689          18 :                 os_memcpy(keys->SK_ei, pos, keys->SK_encr_len);
     690          36 :                 wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_ei",
     691          18 :                                 keys->SK_ei, keys->SK_encr_len);
     692             :         }
     693          18 :         pos += keys->SK_encr_len;
     694             : 
     695          18 :         keys->SK_er = os_malloc(keys->SK_encr_len);
     696          18 :         if (keys->SK_er) {
     697          18 :                 os_memcpy(keys->SK_er, pos, keys->SK_encr_len);
     698          36 :                 wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_er",
     699          18 :                                 keys->SK_er, keys->SK_encr_len);
     700             :         }
     701          18 :         pos += keys->SK_encr_len;
     702             : 
     703          18 :         keys->SK_pi = os_malloc(keys->SK_prf_len);
     704          18 :         if (keys->SK_pi) {
     705          18 :                 os_memcpy(keys->SK_pi, pos, keys->SK_prf_len);
     706          36 :                 wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_pi",
     707          18 :                                 keys->SK_pi, keys->SK_prf_len);
     708             :         }
     709          18 :         pos += keys->SK_prf_len;
     710             : 
     711          18 :         keys->SK_pr = os_malloc(keys->SK_prf_len);
     712          18 :         if (keys->SK_pr) {
     713          18 :                 os_memcpy(keys->SK_pr, pos, keys->SK_prf_len);
     714          36 :                 wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_pr",
     715          18 :                                 keys->SK_pr, keys->SK_prf_len);
     716             :         }
     717             : 
     718          18 :         os_free(keybuf);
     719             : 
     720          18 :         if (!ikev2_keys_set(keys)) {
     721           0 :                 ikev2_free_keys(keys);
     722           0 :                 return -1;
     723             :         }
     724             : 
     725          18 :         return 0;
     726             : }

Generated by: LCOV version 1.10