Return to keymat_v2.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / sa / ikev2 |
1.1 misho 1: /* 2: * Copyright (C) 2015 Tobias Brunner 3: * Copyright (C) 2008 Martin Willi 4: * HSR Hochschule fuer Technik Rapperswil 5: * 6: * This program is free software; you can redistribute it and/or modify it 7: * under the terms of the GNU General Public License as published by the 8: * Free Software Foundation; either version 2 of the License, or (at your 9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 10: * 11: * This program is distributed in the hope that it will be useful, but 12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14: * for more details. 15: */ 16: 17: #include "keymat_v2.h" 18: 19: #include <daemon.h> 20: #include <crypto/prf_plus.h> 21: #include <crypto/hashers/hash_algorithm_set.h> 22: 23: typedef struct private_keymat_v2_t private_keymat_v2_t; 24: 25: /** 26: * Private data of an keymat_t object. 27: */ 28: struct private_keymat_v2_t { 29: 30: /** 31: * Public keymat_v2_t interface. 32: */ 33: keymat_v2_t public; 34: 35: /** 36: * IKE_SA Role, initiator or responder 37: */ 38: bool initiator; 39: 40: /** 41: * inbound AEAD 42: */ 43: aead_t *aead_in; 44: 45: /** 46: * outbound AEAD 47: */ 48: aead_t *aead_out; 49: 50: /** 51: * General purpose PRF 52: */ 53: prf_t *prf; 54: 55: /** 56: * Negotiated PRF algorithm 57: */ 58: pseudo_random_function_t prf_alg; 59: 60: /** 61: * Key to derive key material from for CHILD_SAs, rekeying 62: */ 63: chunk_t skd; 64: 65: /** 66: * Key to build outgoing authentication data (SKp) 67: */ 68: chunk_t skp_build; 69: 70: /** 71: * Key to verify incoming authentication data (SKp) 72: */ 73: chunk_t skp_verify; 74: 75: /** 76: * Set of hash algorithms supported by peer for signature authentication 77: */ 78: hash_algorithm_set_t *hash_algorithms; 79: }; 80: 81: METHOD(keymat_t, get_version, ike_version_t, 82: private_keymat_v2_t *this) 83: { 84: return IKEV2; 85: } 86: 87: METHOD(keymat_t, create_dh, diffie_hellman_t*, 88: private_keymat_v2_t *this, diffie_hellman_group_t group) 89: { 90: return lib->crypto->create_dh(lib->crypto, group); 91: } 92: 93: METHOD(keymat_t, create_nonce_gen, nonce_gen_t*, 94: private_keymat_v2_t *this) 95: { 96: return lib->crypto->create_nonce_gen(lib->crypto); 97: } 98: 99: /** 100: * Derive IKE keys for a combined AEAD algorithm 101: */ 102: static bool derive_ike_aead(private_keymat_v2_t *this, uint16_t alg, 103: uint16_t key_size, prf_plus_t *prf_plus) 104: { 105: aead_t *aead_i, *aead_r; 106: chunk_t sk_ei = chunk_empty, sk_er = chunk_empty; 107: u_int salt_size; 108: 109: switch (alg) 110: { 111: case ENCR_AES_GCM_ICV8: 112: case ENCR_AES_GCM_ICV12: 113: case ENCR_AES_GCM_ICV16: 114: /* RFC 4106 */ 115: case ENCR_CHACHA20_POLY1305: 116: salt_size = 4; 117: break; 118: case ENCR_AES_CCM_ICV8: 119: case ENCR_AES_CCM_ICV12: 120: case ENCR_AES_CCM_ICV16: 121: /* RFC 4309 */ 122: case ENCR_CAMELLIA_CCM_ICV8: 123: case ENCR_CAMELLIA_CCM_ICV12: 124: case ENCR_CAMELLIA_CCM_ICV16: 125: /* RFC 5529 */ 126: salt_size = 3; 127: break; 128: default: 129: DBG1(DBG_IKE, "nonce size for %N unknown!", 130: encryption_algorithm_names, alg); 131: return FALSE; 132: } 133: 134: /* SK_ei/SK_er used for encryption */ 135: aead_i = lib->crypto->create_aead(lib->crypto, alg, key_size / 8, salt_size); 136: aead_r = lib->crypto->create_aead(lib->crypto, alg, key_size / 8, salt_size); 137: if (aead_i == NULL || aead_r == NULL) 138: { 139: DBG1(DBG_IKE, "%N %N (key size %d) not supported!", 140: transform_type_names, ENCRYPTION_ALGORITHM, 141: encryption_algorithm_names, alg, key_size); 142: goto failure; 143: } 144: key_size = aead_i->get_key_size(aead_i); 145: if (key_size != aead_r->get_key_size(aead_r)) 146: { 147: goto failure; 148: } 149: if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_ei)) 150: { 151: goto failure; 152: } 153: DBG4(DBG_IKE, "Sk_ei secret %B", &sk_ei); 154: if (!aead_i->set_key(aead_i, sk_ei)) 155: { 156: goto failure; 157: } 158: 159: if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_er)) 160: { 161: goto failure; 162: } 163: DBG4(DBG_IKE, "Sk_er secret %B", &sk_er); 164: if (!aead_r->set_key(aead_r, sk_er)) 165: { 166: goto failure; 167: } 168: 169: if (this->initiator) 170: { 171: this->aead_in = aead_r; 172: this->aead_out = aead_i; 173: } 174: else 175: { 176: this->aead_in = aead_i; 177: this->aead_out = aead_r; 178: } 179: aead_i = aead_r = NULL; 180: charon->bus->ike_derived_keys(charon->bus, sk_ei, sk_er, chunk_empty, 181: chunk_empty); 182: 183: failure: 184: DESTROY_IF(aead_i); 185: DESTROY_IF(aead_r); 186: chunk_clear(&sk_ei); 187: chunk_clear(&sk_er); 188: return this->aead_in && this->aead_out; 189: } 190: 191: /** 192: * Derive IKE keys for traditional encryption and MAC algorithms 193: */ 194: static bool derive_ike_traditional(private_keymat_v2_t *this, uint16_t enc_alg, 195: uint16_t enc_size, uint16_t int_alg, prf_plus_t *prf_plus) 196: { 197: crypter_t *crypter_i = NULL, *crypter_r = NULL; 198: signer_t *signer_i, *signer_r; 199: iv_gen_t *ivg_i, *ivg_r; 200: size_t key_size; 201: chunk_t sk_ei = chunk_empty, sk_er = chunk_empty, 202: sk_ai = chunk_empty, sk_ar = chunk_empty; 203: 204: signer_i = lib->crypto->create_signer(lib->crypto, int_alg); 205: signer_r = lib->crypto->create_signer(lib->crypto, int_alg); 206: crypter_i = lib->crypto->create_crypter(lib->crypto, enc_alg, enc_size / 8); 207: crypter_r = lib->crypto->create_crypter(lib->crypto, enc_alg, enc_size / 8); 208: if (signer_i == NULL || signer_r == NULL) 209: { 210: DBG1(DBG_IKE, "%N %N not supported!", 211: transform_type_names, INTEGRITY_ALGORITHM, 212: integrity_algorithm_names, int_alg); 213: goto failure; 214: } 215: if (crypter_i == NULL || crypter_r == NULL) 216: { 217: DBG1(DBG_IKE, "%N %N (key size %d) not supported!", 218: transform_type_names, ENCRYPTION_ALGORITHM, 219: encryption_algorithm_names, enc_alg, enc_size); 220: goto failure; 221: } 222: 223: /* SK_ai/SK_ar used for integrity protection */ 224: key_size = signer_i->get_key_size(signer_i); 225: 226: if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_ai)) 227: { 228: goto failure; 229: } 230: DBG4(DBG_IKE, "Sk_ai secret %B", &sk_ai); 231: if (!signer_i->set_key(signer_i, sk_ai)) 232: { 233: goto failure; 234: } 235: 236: if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_ar)) 237: { 238: goto failure; 239: } 240: DBG4(DBG_IKE, "Sk_ar secret %B", &sk_ar); 241: if (!signer_r->set_key(signer_r, sk_ar)) 242: { 243: goto failure; 244: } 245: 246: /* SK_ei/SK_er used for encryption */ 247: key_size = crypter_i->get_key_size(crypter_i); 248: 249: if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_ei)) 250: { 251: goto failure; 252: } 253: DBG4(DBG_IKE, "Sk_ei secret %B", &sk_ei); 254: if (!crypter_i->set_key(crypter_i, sk_ei)) 255: { 256: goto failure; 257: } 258: 259: if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_er)) 260: { 261: goto failure; 262: } 263: DBG4(DBG_IKE, "Sk_er secret %B", &sk_er); 264: if (!crypter_r->set_key(crypter_r, sk_er)) 265: { 266: goto failure; 267: } 268: 269: ivg_i = iv_gen_create_for_alg(enc_alg); 270: ivg_r = iv_gen_create_for_alg(enc_alg); 271: if (!ivg_i || !ivg_r) 272: { 273: goto failure; 274: } 275: if (this->initiator) 276: { 277: this->aead_in = aead_create(crypter_r, signer_r, ivg_r); 278: this->aead_out = aead_create(crypter_i, signer_i, ivg_i); 279: } 280: else 281: { 282: this->aead_in = aead_create(crypter_i, signer_i, ivg_i); 283: this->aead_out = aead_create(crypter_r, signer_r, ivg_r); 284: } 285: signer_i = signer_r = NULL; 286: crypter_i = crypter_r = NULL; 287: charon->bus->ike_derived_keys(charon->bus, sk_ei, sk_er, sk_ai, sk_ar); 288: 289: failure: 290: chunk_clear(&sk_ai); 291: chunk_clear(&sk_ar); 292: chunk_clear(&sk_ei); 293: chunk_clear(&sk_er); 294: DESTROY_IF(signer_i); 295: DESTROY_IF(signer_r); 296: DESTROY_IF(crypter_i); 297: DESTROY_IF(crypter_r); 298: return this->aead_in && this->aead_out; 299: } 300: 301: METHOD(keymat_v2_t, derive_ike_keys, bool, 302: private_keymat_v2_t *this, proposal_t *proposal, diffie_hellman_t *dh, 303: chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id, 304: pseudo_random_function_t rekey_function, chunk_t rekey_skd) 305: { 306: chunk_t skeyseed = chunk_empty, key, secret, full_nonce, fixed_nonce; 307: chunk_t prf_plus_seed, spi_i, spi_r; 308: prf_plus_t *prf_plus = NULL; 309: uint16_t alg, key_size, int_alg; 310: prf_t *rekey_prf = NULL; 311: 312: spi_i = chunk_alloca(sizeof(uint64_t)); 313: spi_r = chunk_alloca(sizeof(uint64_t)); 314: 315: if (!dh->get_shared_secret(dh, &secret)) 316: { 317: return FALSE; 318: } 319: 320: /* Create SAs general purpose PRF first, we may use it here */ 321: if (!proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &alg, NULL)) 322: { 323: DBG1(DBG_IKE, "no %N selected", 324: transform_type_names, PSEUDO_RANDOM_FUNCTION); 325: chunk_clear(&secret); 326: return FALSE; 327: } 328: this->prf_alg = alg; 329: this->prf = lib->crypto->create_prf(lib->crypto, alg); 330: if (this->prf == NULL) 331: { 332: DBG1(DBG_IKE, "%N %N not supported!", 333: transform_type_names, PSEUDO_RANDOM_FUNCTION, 334: pseudo_random_function_names, alg); 335: chunk_clear(&secret); 336: return FALSE; 337: } 338: DBG4(DBG_IKE, "shared Diffie Hellman secret %B", &secret); 339: /* full nonce is used as seed for PRF+ ... */ 340: full_nonce = chunk_cat("cc", nonce_i, nonce_r); 341: /* but the PRF may need a fixed key which only uses the first bytes of 342: * the nonces. */ 343: switch (alg) 344: { 345: case PRF_AES128_CMAC: 346: /* while variable keys may be used according to RFC 4615, RFC 7296 347: * explicitly limits the key size to 128 bit for this application */ 348: case PRF_AES128_XCBC: 349: /* while RFC 4434 defines variable keys for AES-XCBC, RFC 3664 does 350: * not and therefore fixed key semantics apply to XCBC for key 351: * derivation, which is also reinforced by RFC 7296 */ 352: case PRF_CAMELLIA128_XCBC: 353: /* draft-kanno-ipsecme-camellia-xcbc refers to rfc 4434, we 354: * assume fixed key length. */ 355: key_size = this->prf->get_key_size(this->prf)/2; 356: nonce_i.len = min(nonce_i.len, key_size); 357: nonce_r.len = min(nonce_r.len, key_size); 358: break; 359: default: 360: /* all other algorithms use variable key length, full nonce */ 361: break; 362: } 363: fixed_nonce = chunk_cat("cc", nonce_i, nonce_r); 364: *((uint64_t*)spi_i.ptr) = id->get_initiator_spi(id); 365: *((uint64_t*)spi_r.ptr) = id->get_responder_spi(id); 366: prf_plus_seed = chunk_cat("ccc", full_nonce, spi_i, spi_r); 367: 368: /* KEYMAT = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr) 369: * 370: * if we are rekeying, SKEYSEED is built on another way 371: */ 372: if (rekey_function == PRF_UNDEFINED) /* not rekeying */ 373: { 374: /* SKEYSEED = prf(Ni | Nr, g^ir) */ 375: if (this->prf->set_key(this->prf, fixed_nonce) && 376: this->prf->allocate_bytes(this->prf, secret, &skeyseed) && 377: this->prf->set_key(this->prf, skeyseed)) 378: { 379: prf_plus = prf_plus_create(this->prf, TRUE, prf_plus_seed); 380: } 381: } 382: else 383: { 384: /* SKEYSEED = prf(SK_d (old), [g^ir (new)] | Ni | Nr) 385: * use OLD SAs PRF functions for both prf_plus and prf */ 386: rekey_prf = lib->crypto->create_prf(lib->crypto, rekey_function); 387: if (!rekey_prf) 388: { 389: DBG1(DBG_IKE, "PRF of old SA %N not supported!", 390: pseudo_random_function_names, rekey_function); 391: chunk_clear(&secret); 392: chunk_free(&full_nonce); 393: chunk_free(&fixed_nonce); 394: chunk_clear(&prf_plus_seed); 395: return FALSE; 396: } 397: secret = chunk_cat("mc", secret, full_nonce); 398: if (rekey_prf->set_key(rekey_prf, rekey_skd) && 399: rekey_prf->allocate_bytes(rekey_prf, secret, &skeyseed) && 400: rekey_prf->set_key(rekey_prf, skeyseed)) 401: { 402: prf_plus = prf_plus_create(rekey_prf, TRUE, prf_plus_seed); 403: } 404: } 405: DBG4(DBG_IKE, "SKEYSEED %B", &skeyseed); 406: 407: chunk_clear(&skeyseed); 408: chunk_clear(&secret); 409: chunk_free(&full_nonce); 410: chunk_free(&fixed_nonce); 411: chunk_clear(&prf_plus_seed); 412: 413: if (!prf_plus) 414: { 415: goto failure; 416: } 417: 418: /* KEYMAT = SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr */ 419: 420: /* SK_d is used for generating CHILD_SA key mat => store for later use */ 421: key_size = this->prf->get_key_size(this->prf); 422: if (!prf_plus->allocate_bytes(prf_plus, key_size, &this->skd)) 423: { 424: goto failure; 425: } 426: DBG4(DBG_IKE, "Sk_d secret %B", &this->skd); 427: 428: if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg, &key_size)) 429: { 430: DBG1(DBG_IKE, "no %N selected", 431: transform_type_names, ENCRYPTION_ALGORITHM); 432: goto failure; 433: } 434: 435: if (encryption_algorithm_is_aead(alg)) 436: { 437: if (!derive_ike_aead(this, alg, key_size, prf_plus)) 438: { 439: goto failure; 440: } 441: } 442: else 443: { 444: if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, 445: &int_alg, NULL)) 446: { 447: DBG1(DBG_IKE, "no %N selected", 448: transform_type_names, INTEGRITY_ALGORITHM); 449: goto failure; 450: } 451: if (!derive_ike_traditional(this, alg, key_size, int_alg, prf_plus)) 452: { 453: goto failure; 454: } 455: } 456: 457: /* SK_pi/SK_pr used for authentication => stored for later */ 458: key_size = this->prf->get_key_size(this->prf); 459: if (!prf_plus->allocate_bytes(prf_plus, key_size, &key)) 460: { 461: goto failure; 462: } 463: DBG4(DBG_IKE, "Sk_pi secret %B", &key); 464: if (this->initiator) 465: { 466: this->skp_build = key; 467: } 468: else 469: { 470: this->skp_verify = key; 471: } 472: if (!prf_plus->allocate_bytes(prf_plus, key_size, &key)) 473: { 474: goto failure; 475: } 476: DBG4(DBG_IKE, "Sk_pr secret %B", &key); 477: if (this->initiator) 478: { 479: this->skp_verify = key; 480: } 481: else 482: { 483: this->skp_build = key; 484: } 485: 486: /* all done, prf_plus not needed anymore */ 487: failure: 488: DESTROY_IF(prf_plus); 489: DESTROY_IF(rekey_prf); 490: 491: return this->skp_build.len && this->skp_verify.len; 492: } 493: 494: /** 495: * Derives a key from the given key and a PRF that was initialized with a PPK 496: */ 497: static bool derive_ppk_key(prf_t *prf, char *name, chunk_t key, 498: chunk_t *new_key) 499: { 500: prf_plus_t *prf_plus; 501: 502: prf_plus = prf_plus_create(prf, TRUE, key); 503: if (!prf_plus || 504: !prf_plus->allocate_bytes(prf_plus, key.len, new_key)) 505: { 506: DBG1(DBG_IKE, "unable to derive %s with PPK", name); 507: DESTROY_IF(prf_plus); 508: return FALSE; 509: } 510: prf_plus->destroy(prf_plus); 511: return TRUE; 512: } 513: 514: /** 515: * Use the given PPK to derive a new SK_pi/r 516: */ 517: static bool derive_skp_ppk(private_keymat_v2_t *this, chunk_t ppk, chunk_t skp, 518: chunk_t *new_skp) 519: { 520: if (!this->prf->set_key(this->prf, ppk)) 521: { 522: DBG1(DBG_IKE, "unable to set PPK in PRF"); 523: return FALSE; 524: } 525: return derive_ppk_key(this->prf, "SK_p", skp, new_skp); 526: } 527: 528: METHOD(keymat_v2_t, derive_ike_keys_ppk, bool, 529: private_keymat_v2_t *this, chunk_t ppk) 530: { 531: chunk_t skd = chunk_empty, new_skpi = chunk_empty, new_skpr = chunk_empty; 532: chunk_t *skpi, *skpr; 533: 534: if (!this->skd.ptr) 535: { 536: return FALSE; 537: } 538: 539: if (this->initiator) 540: { 541: skpi = &this->skp_build; 542: skpr = &this->skp_verify; 543: } 544: else 545: { 546: skpi = &this->skp_verify; 547: skpr = &this->skp_build; 548: } 549: 550: DBG4(DBG_IKE, "derive keys using PPK %B", &ppk); 551: 552: if (!this->prf->set_key(this->prf, ppk)) 553: { 554: DBG1(DBG_IKE, "unable to set PPK in PRF"); 555: return FALSE; 556: } 557: if (!derive_ppk_key(this->prf, "Sk_d", this->skd, &skd) || 558: !derive_ppk_key(this->prf, "Sk_pi", *skpi, &new_skpi) || 559: !derive_ppk_key(this->prf, "Sk_pr", *skpr, &new_skpr)) 560: { 561: chunk_clear(&skd); 562: chunk_clear(&new_skpi); 563: chunk_clear(&new_skpr); 564: return FALSE; 565: } 566: 567: DBG4(DBG_IKE, "Sk_d secret %B", &skd); 568: chunk_clear(&this->skd); 569: this->skd = skd; 570: 571: DBG4(DBG_IKE, "Sk_pi secret %B", &new_skpi); 572: chunk_clear(skpi); 573: *skpi = new_skpi; 574: 575: DBG4(DBG_IKE, "Sk_pr secret %B", &new_skpr); 576: chunk_clear(skpr); 577: *skpr = new_skpr; 578: return TRUE; 579: } 580: 581: METHOD(keymat_v2_t, derive_child_keys, bool, 582: private_keymat_v2_t *this, proposal_t *proposal, diffie_hellman_t *dh, 583: chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i, chunk_t *integ_i, 584: chunk_t *encr_r, chunk_t *integ_r) 585: { 586: uint16_t enc_alg, int_alg, enc_size = 0, int_size = 0; 587: chunk_t seed, secret = chunk_empty; 588: prf_plus_t *prf_plus; 589: 590: if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, 591: &enc_alg, &enc_size)) 592: { 593: DBG2(DBG_CHD, " using %N for encryption", 594: encryption_algorithm_names, enc_alg); 595: 596: if (!enc_size) 597: { 598: enc_size = keymat_get_keylen_encr(enc_alg); 599: } 600: if (enc_alg != ENCR_NULL && !enc_size) 601: { 602: DBG1(DBG_CHD, "no keylength defined for %N", 603: encryption_algorithm_names, enc_alg); 604: return FALSE; 605: } 606: /* to bytes */ 607: enc_size /= 8; 608: 609: /* CCM/GCM/CTR/GMAC needs additional bytes */ 610: switch (enc_alg) 611: { 612: case ENCR_AES_CCM_ICV8: 613: case ENCR_AES_CCM_ICV12: 614: case ENCR_AES_CCM_ICV16: 615: case ENCR_CAMELLIA_CCM_ICV8: 616: case ENCR_CAMELLIA_CCM_ICV12: 617: case ENCR_CAMELLIA_CCM_ICV16: 618: enc_size += 3; 619: break; 620: case ENCR_AES_GCM_ICV8: 621: case ENCR_AES_GCM_ICV12: 622: case ENCR_AES_GCM_ICV16: 623: case ENCR_AES_CTR: 624: case ENCR_CAMELLIA_CTR: 625: case ENCR_NULL_AUTH_AES_GMAC: 626: case ENCR_CHACHA20_POLY1305: 627: enc_size += 4; 628: break; 629: default: 630: break; 631: } 632: } 633: 634: if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, 635: &int_alg, &int_size)) 636: { 637: DBG2(DBG_CHD, " using %N for integrity", 638: integrity_algorithm_names, int_alg); 639: 640: if (!int_size) 641: { 642: int_size = keymat_get_keylen_integ(int_alg); 643: } 644: if (!int_size) 645: { 646: DBG1(DBG_CHD, "no keylength defined for %N", 647: integrity_algorithm_names, int_alg); 648: return FALSE; 649: } 650: /* to bytes */ 651: int_size /= 8; 652: } 653: 654: if (!this->prf->set_key(this->prf, this->skd)) 655: { 656: return FALSE; 657: } 658: 659: if (dh) 660: { 661: if (!dh->get_shared_secret(dh, &secret)) 662: { 663: return FALSE; 664: } 665: DBG4(DBG_CHD, "DH secret %B", &secret); 666: } 667: seed = chunk_cata("scc", secret, nonce_i, nonce_r); 668: DBG4(DBG_CHD, "seed %B", &seed); 669: 670: prf_plus = prf_plus_create(this->prf, TRUE, seed); 671: memwipe(seed.ptr, seed.len); 672: 673: if (!prf_plus) 674: { 675: return FALSE; 676: } 677: 678: *encr_i = *integ_i = *encr_r = *integ_r = chunk_empty; 679: if (!prf_plus->allocate_bytes(prf_plus, enc_size, encr_i) || 680: !prf_plus->allocate_bytes(prf_plus, int_size, integ_i) || 681: !prf_plus->allocate_bytes(prf_plus, enc_size, encr_r) || 682: !prf_plus->allocate_bytes(prf_plus, int_size, integ_r)) 683: { 684: chunk_free(encr_i); 685: chunk_free(integ_i); 686: chunk_free(encr_r); 687: chunk_free(integ_r); 688: prf_plus->destroy(prf_plus); 689: return FALSE; 690: } 691: 692: prf_plus->destroy(prf_plus); 693: 694: if (enc_size) 695: { 696: DBG4(DBG_CHD, "encryption initiator key %B", encr_i); 697: DBG4(DBG_CHD, "encryption responder key %B", encr_r); 698: } 699: if (int_size) 700: { 701: DBG4(DBG_CHD, "integrity initiator key %B", integ_i); 702: DBG4(DBG_CHD, "integrity responder key %B", integ_r); 703: } 704: return TRUE; 705: } 706: 707: METHOD(keymat_v2_t, get_skd, pseudo_random_function_t, 708: private_keymat_v2_t *this, chunk_t *skd) 709: { 710: *skd = this->skd; 711: return this->prf_alg; 712: } 713: 714: METHOD(keymat_t, get_aead, aead_t*, 715: private_keymat_v2_t *this, bool in) 716: { 717: return in ? this->aead_in : this->aead_out; 718: } 719: 720: METHOD(keymat_v2_t, get_auth_octets, bool, 721: private_keymat_v2_t *this, bool verify, chunk_t ike_sa_init, 722: chunk_t nonce, chunk_t ppk, identification_t *id, char reserved[3], 723: chunk_t *octets, array_t *schemes) 724: { 725: chunk_t chunk, idx; 726: chunk_t skp_ppk = chunk_empty; 727: chunk_t skp; 728: 729: skp = verify ? this->skp_verify : this->skp_build; 730: if (ppk.ptr) 731: { 732: DBG4(DBG_IKE, "PPK %B", &ppk); 733: if (!derive_skp_ppk(this, ppk, skp, &skp_ppk)) 734: { 735: return FALSE; 736: } 737: skp = skp_ppk; 738: } 739: 740: chunk = chunk_alloca(4); 741: chunk.ptr[0] = id->get_type(id); 742: memcpy(chunk.ptr + 1, reserved, 3); 743: idx = chunk_cata("cc", chunk, id->get_encoding(id)); 744: 745: DBG3(DBG_IKE, "IDx' %B", &idx); 746: DBG4(DBG_IKE, "SK_p %B", &skp); 747: if (!this->prf->set_key(this->prf, skp) || 748: !this->prf->allocate_bytes(this->prf, idx, &chunk)) 749: { 750: chunk_clear(&skp_ppk); 751: return FALSE; 752: } 753: chunk_clear(&skp_ppk); 754: *octets = chunk_cat("ccm", ike_sa_init, nonce, chunk); 755: DBG3(DBG_IKE, "octets = message + nonce + prf(Sk_px, IDx') %B", octets); 756: return TRUE; 757: } 758: 759: /** 760: * Key pad for the AUTH method SHARED_KEY_MESSAGE_INTEGRITY_CODE. 761: */ 762: #define IKEV2_KEY_PAD "Key Pad for IKEv2" 763: #define IKEV2_KEY_PAD_LENGTH 17 764: 765: METHOD(keymat_v2_t, get_psk_sig, bool, 766: private_keymat_v2_t *this, bool verify, chunk_t ike_sa_init, chunk_t nonce, 767: chunk_t secret, chunk_t ppk, identification_t *id, char reserved[3], 768: chunk_t *sig) 769: { 770: chunk_t skp_ppk = chunk_empty, key = chunk_empty, octets = chunk_empty; 771: chunk_t key_pad; 772: bool success = FALSE; 773: 774: if (!secret.len) 775: { /* EAP uses SK_p if no MSK has been established */ 776: secret = verify ? this->skp_verify : this->skp_build; 777: if (ppk.ptr) 778: { 779: if (!derive_skp_ppk(this, ppk, secret, &skp_ppk)) 780: { 781: return FALSE; 782: } 783: secret = skp_ppk; 784: } 785: } 786: if (!get_auth_octets(this, verify, ike_sa_init, nonce, ppk, id, reserved, 787: &octets, NULL)) 788: { 789: goto failure; 790: } 791: /* AUTH = prf(prf(Shared Secret,"Key Pad for IKEv2"), <msg octets>) */ 792: key_pad = chunk_create(IKEV2_KEY_PAD, IKEV2_KEY_PAD_LENGTH); 793: if (!this->prf->set_key(this->prf, secret) || 794: !this->prf->allocate_bytes(this->prf, key_pad, &key)) 795: { 796: goto failure; 797: } 798: if (!this->prf->set_key(this->prf, key) || 799: !this->prf->allocate_bytes(this->prf, octets, sig)) 800: { 801: goto failure; 802: } 803: DBG4(DBG_IKE, "secret %B", &secret); 804: DBG4(DBG_IKE, "prf(secret, keypad) %B", &key); 805: DBG3(DBG_IKE, "AUTH = prf(prf(secret, keypad), octets) %B", sig); 806: success = TRUE; 807: 808: failure: 809: chunk_clear(&skp_ppk); 810: chunk_free(&octets); 811: chunk_free(&key); 812: return success; 813: 814: } 815: 816: METHOD(keymat_v2_t, hash_algorithm_supported, bool, 817: private_keymat_v2_t *this, hash_algorithm_t hash) 818: { 819: if (!this->hash_algorithms) 820: { 821: return FALSE; 822: } 823: return this->hash_algorithms->contains(this->hash_algorithms, hash); 824: } 825: 826: METHOD(keymat_v2_t, add_hash_algorithm, void, 827: private_keymat_v2_t *this, hash_algorithm_t hash) 828: { 829: if (!this->hash_algorithms) 830: { 831: this->hash_algorithms = hash_algorithm_set_create(); 832: } 833: this->hash_algorithms->add(this->hash_algorithms, hash); 834: } 835: 836: METHOD(keymat_t, destroy, void, 837: private_keymat_v2_t *this) 838: { 839: DESTROY_IF(this->aead_in); 840: DESTROY_IF(this->aead_out); 841: DESTROY_IF(this->prf); 842: chunk_clear(&this->skd); 843: chunk_clear(&this->skp_verify); 844: chunk_clear(&this->skp_build); 845: DESTROY_IF(this->hash_algorithms); 846: free(this); 847: } 848: 849: /** 850: * See header 851: */ 852: keymat_v2_t *keymat_v2_create(bool initiator) 853: { 854: private_keymat_v2_t *this; 855: 856: INIT(this, 857: .public = { 858: .keymat = { 859: .get_version = _get_version, 860: .create_dh = _create_dh, 861: .create_nonce_gen = _create_nonce_gen, 862: .get_aead = _get_aead, 863: .destroy = _destroy, 864: }, 865: .derive_ike_keys = _derive_ike_keys, 866: .derive_ike_keys_ppk = _derive_ike_keys_ppk, 867: .derive_child_keys = _derive_child_keys, 868: .get_skd = _get_skd, 869: .get_auth_octets = _get_auth_octets, 870: .get_psk_sig = _get_psk_sig, 871: .add_hash_algorithm = _add_hash_algorithm, 872: .hash_algorithm_supported = _hash_algorithm_supported, 873: 874: }, 875: .initiator = initiator, 876: .prf_alg = PRF_UNDEFINED, 877: ); 878: 879: return &this->public; 880: }