Annotation of embedaddon/strongswan/src/libcharon/sa/ikev2/keymat_v2.c, revision 1.1.1.1

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: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>