$search
00001 /* 00002 * IKEv2 common routines for initiator and responder 00003 * Copyright (c) 2007, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "includes.h" 00016 00017 #include "common.h" 00018 #include "crypto/crypto.h" 00019 #include "crypto/md5.h" 00020 #include "crypto/sha1.h" 00021 #include "ikev2_common.h" 00022 00023 00024 static struct ikev2_integ_alg ikev2_integ_algs[] = { 00025 { AUTH_HMAC_SHA1_96, 20, 12 }, 00026 { AUTH_HMAC_MD5_96, 16, 12 } 00027 }; 00028 00029 #define NUM_INTEG_ALGS (sizeof(ikev2_integ_algs) / sizeof(ikev2_integ_algs[0])) 00030 00031 00032 static struct ikev2_prf_alg ikev2_prf_algs[] = { 00033 { PRF_HMAC_SHA1, 20, 20 }, 00034 { PRF_HMAC_MD5, 16, 16 } 00035 }; 00036 00037 #define NUM_PRF_ALGS (sizeof(ikev2_prf_algs) / sizeof(ikev2_prf_algs[0])) 00038 00039 00040 static struct ikev2_encr_alg ikev2_encr_algs[] = { 00041 { ENCR_AES_CBC, 16, 16 }, /* only 128-bit keys supported for now */ 00042 { ENCR_3DES, 24, 8 } 00043 }; 00044 00045 #define NUM_ENCR_ALGS (sizeof(ikev2_encr_algs) / sizeof(ikev2_encr_algs[0])) 00046 00047 00048 const struct ikev2_integ_alg * ikev2_get_integ(int id) 00049 { 00050 size_t i; 00051 00052 for (i = 0; i < NUM_INTEG_ALGS; i++) { 00053 if (ikev2_integ_algs[i].id == id) 00054 return &ikev2_integ_algs[i]; 00055 } 00056 00057 return NULL; 00058 } 00059 00060 00061 int ikev2_integ_hash(int alg, const u8 *key, size_t key_len, const u8 *data, 00062 size_t data_len, u8 *hash) 00063 { 00064 u8 tmphash[IKEV2_MAX_HASH_LEN]; 00065 00066 switch (alg) { 00067 case AUTH_HMAC_SHA1_96: 00068 if (key_len != 20) 00069 return -1; 00070 hmac_sha1(key, key_len, data, data_len, tmphash); 00071 os_memcpy(hash, tmphash, 12); 00072 break; 00073 case AUTH_HMAC_MD5_96: 00074 if (key_len != 16) 00075 return -1; 00076 hmac_md5(key, key_len, data, data_len, tmphash); 00077 os_memcpy(hash, tmphash, 12); 00078 break; 00079 default: 00080 return -1; 00081 } 00082 00083 return 0; 00084 } 00085 00086 00087 const struct ikev2_prf_alg * ikev2_get_prf(int id) 00088 { 00089 size_t i; 00090 00091 for (i = 0; i < NUM_PRF_ALGS; i++) { 00092 if (ikev2_prf_algs[i].id == id) 00093 return &ikev2_prf_algs[i]; 00094 } 00095 00096 return NULL; 00097 } 00098 00099 00100 int ikev2_prf_hash(int alg, const u8 *key, size_t key_len, 00101 size_t num_elem, const u8 *addr[], const size_t *len, 00102 u8 *hash) 00103 { 00104 switch (alg) { 00105 case PRF_HMAC_SHA1: 00106 hmac_sha1_vector(key, key_len, num_elem, addr, len, hash); 00107 break; 00108 case PRF_HMAC_MD5: 00109 hmac_md5_vector(key, key_len, num_elem, addr, len, hash); 00110 break; 00111 default: 00112 return -1; 00113 } 00114 00115 return 0; 00116 } 00117 00118 00119 int ikev2_prf_plus(int alg, const u8 *key, size_t key_len, 00120 const u8 *data, size_t data_len, 00121 u8 *out, size_t out_len) 00122 { 00123 u8 hash[IKEV2_MAX_HASH_LEN]; 00124 size_t hash_len; 00125 u8 iter, *pos, *end; 00126 const u8 *addr[3]; 00127 size_t len[3]; 00128 const struct ikev2_prf_alg *prf; 00129 int res; 00130 00131 prf = ikev2_get_prf(alg); 00132 if (prf == NULL) 00133 return -1; 00134 hash_len = prf->hash_len; 00135 00136 addr[0] = hash; 00137 len[0] = hash_len; 00138 addr[1] = data; 00139 len[1] = data_len; 00140 addr[2] = &iter; 00141 len[2] = 1; 00142 00143 pos = out; 00144 end = out + out_len; 00145 iter = 1; 00146 while (pos < end) { 00147 size_t clen; 00148 if (iter == 1) 00149 res = ikev2_prf_hash(alg, key, key_len, 2, &addr[1], 00150 &len[1], hash); 00151 else 00152 res = ikev2_prf_hash(alg, key, key_len, 3, addr, len, 00153 hash); 00154 if (res < 0) 00155 return -1; 00156 clen = hash_len; 00157 if ((int) clen > end - pos) 00158 clen = end - pos; 00159 os_memcpy(pos, hash, clen); 00160 pos += clen; 00161 iter++; 00162 } 00163 00164 return 0; 00165 } 00166 00167 00168 const struct ikev2_encr_alg * ikev2_get_encr(int id) 00169 { 00170 size_t i; 00171 00172 for (i = 0; i < NUM_ENCR_ALGS; i++) { 00173 if (ikev2_encr_algs[i].id == id) 00174 return &ikev2_encr_algs[i]; 00175 } 00176 00177 return NULL; 00178 } 00179 00180 00181 #ifdef CCNS_PL 00182 /* from des.c */ 00183 struct des3_key_s { 00184 u32 ek[3][32]; 00185 u32 dk[3][32]; 00186 }; 00187 00188 void des3_key_setup(const u8 *key, struct des3_key_s *dkey); 00189 void des3_encrypt(const u8 *plain, const struct des3_key_s *key, u8 *crypt); 00190 void des3_decrypt(const u8 *crypt, const struct des3_key_s *key, u8 *plain); 00191 #endif /* CCNS_PL */ 00192 00193 00194 int ikev2_encr_encrypt(int alg, const u8 *key, size_t key_len, const u8 *iv, 00195 const u8 *plain, u8 *crypt, size_t len) 00196 { 00197 struct crypto_cipher *cipher; 00198 int encr_alg; 00199 00200 #ifdef CCNS_PL 00201 if (alg == ENCR_3DES) { 00202 struct des3_key_s des3key; 00203 size_t i, blocks; 00204 u8 *pos; 00205 00206 /* ECB mode is used incorrectly for 3DES!? */ 00207 if (key_len != 24) { 00208 wpa_printf(MSG_INFO, "IKEV2: Invalid encr key length"); 00209 return -1; 00210 } 00211 des3_key_setup(key, &des3key); 00212 00213 blocks = len / 8; 00214 pos = crypt; 00215 for (i = 0; i < blocks; i++) { 00216 des3_encrypt(pos, &des3key, pos); 00217 pos += 8; 00218 } 00219 } else { 00220 #endif /* CCNS_PL */ 00221 switch (alg) { 00222 case ENCR_3DES: 00223 encr_alg = CRYPTO_CIPHER_ALG_3DES; 00224 break; 00225 case ENCR_AES_CBC: 00226 encr_alg = CRYPTO_CIPHER_ALG_AES; 00227 break; 00228 default: 00229 wpa_printf(MSG_DEBUG, "IKEV2: Unsupported encr alg %d", alg); 00230 return -1; 00231 } 00232 00233 cipher = crypto_cipher_init(encr_alg, iv, key, key_len); 00234 if (cipher == NULL) { 00235 wpa_printf(MSG_INFO, "IKEV2: Failed to initialize cipher"); 00236 return -1; 00237 } 00238 00239 if (crypto_cipher_encrypt(cipher, plain, crypt, len) < 0) { 00240 wpa_printf(MSG_INFO, "IKEV2: Encryption failed"); 00241 crypto_cipher_deinit(cipher); 00242 return -1; 00243 } 00244 crypto_cipher_deinit(cipher); 00245 #ifdef CCNS_PL 00246 } 00247 #endif /* CCNS_PL */ 00248 00249 return 0; 00250 } 00251 00252 00253 int ikev2_encr_decrypt(int alg, const u8 *key, size_t key_len, const u8 *iv, 00254 const u8 *crypt, u8 *plain, size_t len) 00255 { 00256 struct crypto_cipher *cipher; 00257 int encr_alg; 00258 00259 #ifdef CCNS_PL 00260 if (alg == ENCR_3DES) { 00261 struct des3_key_s des3key; 00262 size_t i, blocks; 00263 00264 /* ECB mode is used incorrectly for 3DES!? */ 00265 if (key_len != 24) { 00266 wpa_printf(MSG_INFO, "IKEV2: Invalid encr key length"); 00267 return -1; 00268 } 00269 des3_key_setup(key, &des3key); 00270 00271 if (len % 8) { 00272 wpa_printf(MSG_INFO, "IKEV2: Invalid encrypted " 00273 "length"); 00274 return -1; 00275 } 00276 blocks = len / 8; 00277 for (i = 0; i < blocks; i++) { 00278 des3_decrypt(crypt, &des3key, plain); 00279 plain += 8; 00280 crypt += 8; 00281 } 00282 } else { 00283 #endif /* CCNS_PL */ 00284 switch (alg) { 00285 case ENCR_3DES: 00286 encr_alg = CRYPTO_CIPHER_ALG_3DES; 00287 break; 00288 case ENCR_AES_CBC: 00289 encr_alg = CRYPTO_CIPHER_ALG_AES; 00290 break; 00291 default: 00292 wpa_printf(MSG_DEBUG, "IKEV2: Unsupported encr alg %d", alg); 00293 return -1; 00294 } 00295 00296 cipher = crypto_cipher_init(encr_alg, iv, key, key_len); 00297 if (cipher == NULL) { 00298 wpa_printf(MSG_INFO, "IKEV2: Failed to initialize cipher"); 00299 return -1; 00300 } 00301 00302 if (crypto_cipher_decrypt(cipher, crypt, plain, len) < 0) { 00303 wpa_printf(MSG_INFO, "IKEV2: Decryption failed"); 00304 crypto_cipher_deinit(cipher); 00305 return -1; 00306 } 00307 crypto_cipher_deinit(cipher); 00308 #ifdef CCNS_PL 00309 } 00310 #endif /* CCNS_PL */ 00311 00312 return 0; 00313 } 00314 00315 00316 int ikev2_parse_payloads(struct ikev2_payloads *payloads, 00317 u8 next_payload, const u8 *pos, const u8 *end) 00318 { 00319 const struct ikev2_payload_hdr *phdr; 00320 00321 os_memset(payloads, 0, sizeof(*payloads)); 00322 00323 while (next_payload != IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) { 00324 int plen, pdatalen; 00325 const u8 *pdata; 00326 wpa_printf(MSG_DEBUG, "IKEV2: Processing payload %u", 00327 next_payload); 00328 if (end - pos < (int) sizeof(*phdr)) { 00329 wpa_printf(MSG_INFO, "IKEV2: Too short message for " 00330 "payload header (left=%ld)", 00331 (long) (end - pos)); 00332 } 00333 phdr = (const struct ikev2_payload_hdr *) pos; 00334 plen = WPA_GET_BE16(phdr->payload_length); 00335 if (plen < (int) sizeof(*phdr) || pos + plen > end) { 00336 wpa_printf(MSG_INFO, "IKEV2: Invalid payload header " 00337 "length %d", plen); 00338 return -1; 00339 } 00340 00341 wpa_printf(MSG_DEBUG, "IKEV2: Next Payload: %u Flags: 0x%x" 00342 " Payload Length: %d", 00343 phdr->next_payload, phdr->flags, plen); 00344 00345 pdata = (const u8 *) (phdr + 1); 00346 pdatalen = plen - sizeof(*phdr); 00347 00348 switch (next_payload) { 00349 case IKEV2_PAYLOAD_SA: 00350 wpa_printf(MSG_DEBUG, "IKEV2: Payload: Security " 00351 "Association"); 00352 payloads->sa = pdata; 00353 payloads->sa_len = pdatalen; 00354 break; 00355 case IKEV2_PAYLOAD_KEY_EXCHANGE: 00356 wpa_printf(MSG_DEBUG, "IKEV2: Payload: Key " 00357 "Exchange"); 00358 payloads->ke = pdata; 00359 payloads->ke_len = pdatalen; 00360 break; 00361 case IKEV2_PAYLOAD_IDi: 00362 wpa_printf(MSG_DEBUG, "IKEV2: Payload: IDi"); 00363 payloads->idi = pdata; 00364 payloads->idi_len = pdatalen; 00365 break; 00366 case IKEV2_PAYLOAD_IDr: 00367 wpa_printf(MSG_DEBUG, "IKEV2: Payload: IDr"); 00368 payloads->idr = pdata; 00369 payloads->idr_len = pdatalen; 00370 break; 00371 case IKEV2_PAYLOAD_CERTIFICATE: 00372 wpa_printf(MSG_DEBUG, "IKEV2: Payload: Certificate"); 00373 payloads->cert = pdata; 00374 payloads->cert_len = pdatalen; 00375 break; 00376 case IKEV2_PAYLOAD_AUTHENTICATION: 00377 wpa_printf(MSG_DEBUG, "IKEV2: Payload: " 00378 "Authentication"); 00379 payloads->auth = pdata; 00380 payloads->auth_len = pdatalen; 00381 break; 00382 case IKEV2_PAYLOAD_NONCE: 00383 wpa_printf(MSG_DEBUG, "IKEV2: Payload: Nonce"); 00384 payloads->nonce = pdata; 00385 payloads->nonce_len = pdatalen; 00386 break; 00387 case IKEV2_PAYLOAD_ENCRYPTED: 00388 wpa_printf(MSG_DEBUG, "IKEV2: Payload: Encrypted"); 00389 payloads->encrypted = pdata; 00390 payloads->encrypted_len = pdatalen; 00391 break; 00392 case IKEV2_PAYLOAD_NOTIFICATION: 00393 wpa_printf(MSG_DEBUG, "IKEV2: Payload: " 00394 "Notification"); 00395 payloads->notification = pdata; 00396 payloads->notification_len = pdatalen; 00397 break; 00398 default: 00399 if (phdr->flags & IKEV2_PAYLOAD_FLAGS_CRITICAL) { 00400 wpa_printf(MSG_INFO, "IKEV2: Unsupported " 00401 "critical payload %u - reject the " 00402 "entire message", next_payload); 00403 return -1; 00404 } else { 00405 wpa_printf(MSG_DEBUG, "IKEV2: Skipped " 00406 "unsupported payload %u", 00407 next_payload); 00408 } 00409 } 00410 00411 if (next_payload == IKEV2_PAYLOAD_ENCRYPTED && 00412 pos + plen == end) { 00413 /* 00414 * Next Payload in the case of Encrypted Payload is 00415 * actually the payload type for the first embedded 00416 * payload. 00417 */ 00418 payloads->encr_next_payload = phdr->next_payload; 00419 next_payload = IKEV2_PAYLOAD_NO_NEXT_PAYLOAD; 00420 } else 00421 next_payload = phdr->next_payload; 00422 00423 pos += plen; 00424 } 00425 00426 if (pos != end) { 00427 wpa_printf(MSG_INFO, "IKEV2: Unexpected extra data after " 00428 "payloads"); 00429 return -1; 00430 } 00431 00432 return 0; 00433 } 00434 00435 00436 int ikev2_derive_auth_data(int prf_alg, const struct wpabuf *sign_msg, 00437 const u8 *ID, size_t ID_len, u8 ID_type, 00438 struct ikev2_keys *keys, int initiator, 00439 const u8 *shared_secret, size_t shared_secret_len, 00440 const u8 *nonce, size_t nonce_len, 00441 const u8 *key_pad, size_t key_pad_len, 00442 u8 *auth_data) 00443 { 00444 size_t sign_len, buf_len; 00445 u8 *sign_data, *pos, *buf, hash[IKEV2_MAX_HASH_LEN]; 00446 const struct ikev2_prf_alg *prf; 00447 const u8 *SK_p = initiator ? keys->SK_pi : keys->SK_pr; 00448 00449 prf = ikev2_get_prf(prf_alg); 00450 if (sign_msg == NULL || ID == NULL || SK_p == NULL || 00451 shared_secret == NULL || nonce == NULL || prf == NULL) 00452 return -1; 00453 00454 /* prf(SK_pi/r,IDi/r') */ 00455 buf_len = 4 + ID_len; 00456 buf = os_zalloc(buf_len); 00457 if (buf == NULL) 00458 return -1; 00459 buf[0] = ID_type; 00460 os_memcpy(buf + 4, ID, ID_len); 00461 if (ikev2_prf_hash(prf->id, SK_p, keys->SK_prf_len, 00462 1, (const u8 **) &buf, &buf_len, hash) < 0) { 00463 os_free(buf); 00464 return -1; 00465 } 00466 os_free(buf); 00467 00468 /* sign_data = msg | Nr/i | prf(SK_pi/r,IDi/r') */ 00469 sign_len = wpabuf_len(sign_msg) + nonce_len + prf->hash_len; 00470 sign_data = os_malloc(sign_len); 00471 if (sign_data == NULL) 00472 return -1; 00473 pos = sign_data; 00474 os_memcpy(pos, wpabuf_head(sign_msg), wpabuf_len(sign_msg)); 00475 pos += wpabuf_len(sign_msg); 00476 os_memcpy(pos, nonce, nonce_len); 00477 pos += nonce_len; 00478 os_memcpy(pos, hash, prf->hash_len); 00479 00480 /* AUTH = prf(prf(Shared Secret, key pad, sign_data) */ 00481 if (ikev2_prf_hash(prf->id, shared_secret, shared_secret_len, 1, 00482 &key_pad, &key_pad_len, hash) < 0 || 00483 ikev2_prf_hash(prf->id, hash, prf->hash_len, 1, 00484 (const u8 **) &sign_data, &sign_len, auth_data) < 0) 00485 { 00486 os_free(sign_data); 00487 return -1; 00488 } 00489 os_free(sign_data); 00490 00491 return 0; 00492 } 00493 00494 00495 u8 * ikev2_decrypt_payload(int encr_id, int integ_id, 00496 struct ikev2_keys *keys, int initiator, 00497 const struct ikev2_hdr *hdr, 00498 const u8 *encrypted, size_t encrypted_len, 00499 size_t *res_len) 00500 { 00501 size_t iv_len; 00502 const u8 *pos, *end, *iv, *integ; 00503 u8 hash[IKEV2_MAX_HASH_LEN], *decrypted; 00504 size_t decrypted_len, pad_len; 00505 const struct ikev2_integ_alg *integ_alg; 00506 const struct ikev2_encr_alg *encr_alg; 00507 const u8 *SK_e = initiator ? keys->SK_ei : keys->SK_er; 00508 const u8 *SK_a = initiator ? keys->SK_ai : keys->SK_ar; 00509 00510 if (encrypted == NULL) { 00511 wpa_printf(MSG_INFO, "IKEV2: No Encrypted payload in SA_AUTH"); 00512 return NULL; 00513 } 00514 00515 encr_alg = ikev2_get_encr(encr_id); 00516 if (encr_alg == NULL) { 00517 wpa_printf(MSG_INFO, "IKEV2: Unsupported encryption type"); 00518 return NULL; 00519 } 00520 iv_len = encr_alg->block_size; 00521 00522 integ_alg = ikev2_get_integ(integ_id); 00523 if (integ_alg == NULL) { 00524 wpa_printf(MSG_INFO, "IKEV2: Unsupported intergrity type"); 00525 return NULL; 00526 } 00527 00528 if (encrypted_len < iv_len + 1 + integ_alg->hash_len) { 00529 wpa_printf(MSG_INFO, "IKEV2: No room for IV or Integrity " 00530 "Checksum"); 00531 return NULL; 00532 } 00533 00534 iv = encrypted; 00535 pos = iv + iv_len; 00536 end = encrypted + encrypted_len; 00537 integ = end - integ_alg->hash_len; 00538 00539 if (SK_a == NULL) { 00540 wpa_printf(MSG_INFO, "IKEV2: No SK_a available"); 00541 return NULL; 00542 } 00543 if (ikev2_integ_hash(integ_id, SK_a, keys->SK_integ_len, 00544 (const u8 *) hdr, 00545 integ - (const u8 *) hdr, hash) < 0) { 00546 wpa_printf(MSG_INFO, "IKEV2: Failed to calculate integrity " 00547 "hash"); 00548 return NULL; 00549 } 00550 if (os_memcmp(integ, hash, integ_alg->hash_len) != 0) { 00551 wpa_printf(MSG_INFO, "IKEV2: Incorrect Integrity Checksum " 00552 "Data"); 00553 return NULL; 00554 } 00555 00556 if (SK_e == NULL) { 00557 wpa_printf(MSG_INFO, "IKEV2: No SK_e available"); 00558 return NULL; 00559 } 00560 00561 decrypted_len = integ - pos; 00562 decrypted = os_malloc(decrypted_len); 00563 if (decrypted == NULL) 00564 return NULL; 00565 00566 if (ikev2_encr_decrypt(encr_alg->id, SK_e, keys->SK_encr_len, iv, pos, 00567 decrypted, decrypted_len) < 0) { 00568 os_free(decrypted); 00569 return NULL; 00570 } 00571 00572 pad_len = decrypted[decrypted_len - 1]; 00573 if (decrypted_len < pad_len + 1) { 00574 wpa_printf(MSG_INFO, "IKEV2: Invalid padding in encrypted " 00575 "payload"); 00576 os_free(decrypted); 00577 return NULL; 00578 } 00579 00580 decrypted_len -= pad_len + 1; 00581 00582 *res_len = decrypted_len; 00583 return decrypted; 00584 } 00585 00586 00587 void ikev2_update_hdr(struct wpabuf *msg) 00588 { 00589 struct ikev2_hdr *hdr; 00590 00591 /* Update lenth field in HDR */ 00592 hdr = wpabuf_mhead(msg); 00593 WPA_PUT_BE32(hdr->length, wpabuf_len(msg)); 00594 } 00595 00596 00597 int ikev2_build_encrypted(int encr_id, int integ_id, struct ikev2_keys *keys, 00598 int initiator, struct wpabuf *msg, 00599 struct wpabuf *plain, u8 next_payload) 00600 { 00601 struct ikev2_payload_hdr *phdr; 00602 size_t plen; 00603 size_t iv_len, pad_len; 00604 u8 *icv, *iv; 00605 const struct ikev2_integ_alg *integ_alg; 00606 const struct ikev2_encr_alg *encr_alg; 00607 const u8 *SK_e = initiator ? keys->SK_ei : keys->SK_er; 00608 const u8 *SK_a = initiator ? keys->SK_ai : keys->SK_ar; 00609 00610 wpa_printf(MSG_DEBUG, "IKEV2: Adding Encrypted payload"); 00611 00612 /* Encr - RFC 4306, Sect. 3.14 */ 00613 00614 encr_alg = ikev2_get_encr(encr_id); 00615 if (encr_alg == NULL) { 00616 wpa_printf(MSG_INFO, "IKEV2: Unsupported encryption type"); 00617 return -1; 00618 } 00619 iv_len = encr_alg->block_size; 00620 00621 integ_alg = ikev2_get_integ(integ_id); 00622 if (integ_alg == NULL) { 00623 wpa_printf(MSG_INFO, "IKEV2: Unsupported intergrity type"); 00624 return -1; 00625 } 00626 00627 if (SK_e == NULL) { 00628 wpa_printf(MSG_INFO, "IKEV2: No SK_e available"); 00629 return -1; 00630 } 00631 00632 if (SK_a == NULL) { 00633 wpa_printf(MSG_INFO, "IKEV2: No SK_a available"); 00634 return -1; 00635 } 00636 00637 phdr = wpabuf_put(msg, sizeof(*phdr)); 00638 phdr->next_payload = next_payload; 00639 phdr->flags = 0; 00640 00641 iv = wpabuf_put(msg, iv_len); 00642 if (os_get_random(iv, iv_len)) { 00643 wpa_printf(MSG_INFO, "IKEV2: Could not generate IV"); 00644 return -1; 00645 } 00646 00647 pad_len = iv_len - (wpabuf_len(plain) + 1) % iv_len; 00648 if (pad_len == iv_len) 00649 pad_len = 0; 00650 wpabuf_put(plain, pad_len); 00651 wpabuf_put_u8(plain, pad_len); 00652 00653 if (ikev2_encr_encrypt(encr_alg->id, SK_e, keys->SK_encr_len, iv, 00654 wpabuf_head(plain), wpabuf_mhead(plain), 00655 wpabuf_len(plain)) < 0) 00656 return -1; 00657 00658 wpabuf_put_buf(msg, plain); 00659 00660 /* Need to update all headers (Length fields) prior to hash func */ 00661 icv = wpabuf_put(msg, integ_alg->hash_len); 00662 plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr; 00663 WPA_PUT_BE16(phdr->payload_length, plen); 00664 00665 ikev2_update_hdr(msg); 00666 00667 return ikev2_integ_hash(integ_id, SK_a, keys->SK_integ_len, 00668 wpabuf_head(msg), 00669 wpabuf_len(msg) - integ_alg->hash_len, icv); 00670 00671 return 0; 00672 } 00673 00674 00675 int ikev2_keys_set(struct ikev2_keys *keys) 00676 { 00677 return keys->SK_d && keys->SK_ai && keys->SK_ar && keys->SK_ei && 00678 keys->SK_er && keys->SK_pi && keys->SK_pr; 00679 } 00680 00681 00682 void ikev2_free_keys(struct ikev2_keys *keys) 00683 { 00684 os_free(keys->SK_d); 00685 os_free(keys->SK_ai); 00686 os_free(keys->SK_ar); 00687 os_free(keys->SK_ei); 00688 os_free(keys->SK_er); 00689 os_free(keys->SK_pi); 00690 os_free(keys->SK_pr); 00691 keys->SK_d = keys->SK_ai = keys->SK_ar = keys->SK_ei = keys->SK_er = 00692 keys->SK_pi = keys->SK_pr = NULL; 00693 } 00694 00695 00696 int ikev2_derive_sk_keys(const struct ikev2_prf_alg *prf, 00697 const struct ikev2_integ_alg *integ, 00698 const struct ikev2_encr_alg *encr, 00699 const u8 *skeyseed, const u8 *data, size_t data_len, 00700 struct ikev2_keys *keys) 00701 { 00702 u8 *keybuf, *pos; 00703 size_t keybuf_len; 00704 00705 /* 00706 * {SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr } = 00707 * prf+(SKEYSEED, Ni | Nr | SPIi | SPIr ) 00708 */ 00709 ikev2_free_keys(keys); 00710 keys->SK_d_len = prf->key_len; 00711 keys->SK_integ_len = integ->key_len; 00712 keys->SK_encr_len = encr->key_len; 00713 keys->SK_prf_len = prf->key_len; 00714 #ifdef CCNS_PL 00715 /* Uses encryption key length for SK_d; should be PRF length */ 00716 keys->SK_d_len = keys->SK_encr_len; 00717 #endif /* CCNS_PL */ 00718 00719 keybuf_len = keys->SK_d_len + 2 * keys->SK_integ_len + 00720 2 * keys->SK_encr_len + 2 * keys->SK_prf_len; 00721 keybuf = os_malloc(keybuf_len); 00722 if (keybuf == NULL) 00723 return -1; 00724 00725 if (ikev2_prf_plus(prf->id, skeyseed, prf->hash_len, 00726 data, data_len, keybuf, keybuf_len)) { 00727 os_free(keybuf); 00728 return -1; 00729 } 00730 00731 pos = keybuf; 00732 00733 keys->SK_d = os_malloc(keys->SK_d_len); 00734 if (keys->SK_d) { 00735 os_memcpy(keys->SK_d, pos, keys->SK_d_len); 00736 wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_d", 00737 keys->SK_d, keys->SK_d_len); 00738 } 00739 pos += keys->SK_d_len; 00740 00741 keys->SK_ai = os_malloc(keys->SK_integ_len); 00742 if (keys->SK_ai) { 00743 os_memcpy(keys->SK_ai, pos, keys->SK_integ_len); 00744 wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_ai", 00745 keys->SK_ai, keys->SK_integ_len); 00746 } 00747 pos += keys->SK_integ_len; 00748 00749 keys->SK_ar = os_malloc(keys->SK_integ_len); 00750 if (keys->SK_ar) { 00751 os_memcpy(keys->SK_ar, pos, keys->SK_integ_len); 00752 wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_ar", 00753 keys->SK_ar, keys->SK_integ_len); 00754 } 00755 pos += keys->SK_integ_len; 00756 00757 keys->SK_ei = os_malloc(keys->SK_encr_len); 00758 if (keys->SK_ei) { 00759 os_memcpy(keys->SK_ei, pos, keys->SK_encr_len); 00760 wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_ei", 00761 keys->SK_ei, keys->SK_encr_len); 00762 } 00763 pos += keys->SK_encr_len; 00764 00765 keys->SK_er = os_malloc(keys->SK_encr_len); 00766 if (keys->SK_er) { 00767 os_memcpy(keys->SK_er, pos, keys->SK_encr_len); 00768 wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_er", 00769 keys->SK_er, keys->SK_encr_len); 00770 } 00771 pos += keys->SK_encr_len; 00772 00773 keys->SK_pi = os_malloc(keys->SK_prf_len); 00774 if (keys->SK_pi) { 00775 os_memcpy(keys->SK_pi, pos, keys->SK_prf_len); 00776 wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_pi", 00777 keys->SK_pi, keys->SK_prf_len); 00778 } 00779 pos += keys->SK_prf_len; 00780 00781 keys->SK_pr = os_malloc(keys->SK_prf_len); 00782 if (keys->SK_pr) { 00783 os_memcpy(keys->SK_pr, pos, keys->SK_prf_len); 00784 wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_pr", 00785 keys->SK_pr, keys->SK_prf_len); 00786 } 00787 00788 os_free(keybuf); 00789 00790 if (!ikev2_keys_set(keys)) { 00791 ikev2_free_keys(keys); 00792 return -1; 00793 } 00794 00795 return 0; 00796 }