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