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