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