Annotation of embedaddon/strongswan/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_card.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2008-2009 Martin Willi
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: /*
                     16:  * Copyright (C) 2015 Thomas Strangert
                     17:  * Polystar System AB, Sweden
                     18:  *
                     19:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                     20:  * of this software and associated documentation files (the "Software"), to deal
                     21:  * in the Software without restriction, including without limitation the rights
                     22:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     23:  * copies of the Software, and to permit persons to whom the Software is
                     24:  * furnished to do so, subject to the following conditions:
                     25:  *
                     26:  * The above copyright notice and this permission notice shall be included in
                     27:  * all copies or substantial portions of the Software.
                     28:  *
                     29:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     30:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     31:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
                     32:  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     33:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     34:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     35:  * THE SOFTWARE.
                     36:  */
                     37: 
                     38: #include "eap_aka_3gpp_card.h"
                     39: 
                     40: #include <daemon.h>
                     41: 
                     42: typedef struct private_eap_aka_3gpp_card_t private_eap_aka_3gpp_card_t;
                     43: 
                     44: /**
                     45:  * Private data of an eap_aka_3gpp_card_t object.
                     46:  */
                     47: struct private_eap_aka_3gpp_card_t {
                     48: 
                     49:        /**
                     50:         * Public eap_aka_3gpp_card_t interface.
                     51:         */
                     52:        eap_aka_3gpp_card_t public;
                     53: 
                     54:        /**
                     55:         * AKA functions
                     56:         */
                     57:        eap_aka_3gpp_functions_t *f;
                     58: 
                     59:        /**
                     60:         * do sequence number checking?
                     61:         */
                     62:        bool seq_check;
                     63: 
                     64:        /**
                     65:         * SQN stored in this pseudo-USIM
                     66:         */
                     67:        uint8_t sqn[AKA_SQN_LEN];
                     68: };
                     69: 
                     70: METHOD(simaka_card_t, get_quintuplet, status_t,
                     71:        private_eap_aka_3gpp_card_t *this, identification_t *id,
                     72:        char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN],
                     73:        char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len)
                     74: {
                     75:        uint8_t *amf, *mac;
                     76:        uint8_t k[AKA_K_LEN], opc[AKA_OPC_LEN], ak[AKA_AK_LEN], sqn[AKA_SQN_LEN],
                     77:                        xmac[AKA_MAC_LEN];
                     78: 
                     79:        if (!eap_aka_3gpp_get_k_opc(id, k, opc))
                     80:        {
                     81:                DBG1(DBG_IKE, "no EAP key found for %Y to authenticate with AKA", id);
                     82:                return FAILED;
                     83:        }
                     84:        DBG4(DBG_IKE, "EAP key found for id %Y, using K %b and OPc %b", id, k,
                     85:                 AKA_K_LEN, opc, AKA_OPC_LEN);
                     86: 
                     87:        /* AUTN = SQN xor AK | AMF | MAC */
                     88:        memcpy(sqn, autn, AKA_SQN_LEN);
                     89:        amf = autn + AKA_SQN_LEN;
                     90:        mac = autn + AKA_SQN_LEN + AKA_AMF_LEN;
                     91:        DBG3(DBG_IKE, "received AUTN %b", autn, AKA_AUTN_LEN);
                     92:        DBG3(DBG_IKE, "received AMF %b", amf, AKA_AMF_LEN);
                     93:        DBG3(DBG_IKE, "received MAC %b", mac, AKA_MAC_LEN);
                     94: 
                     95:        /* generate RES, CK, IK, AK from received RAND */
                     96:        DBG3(DBG_IKE, "received RAND %b", rand, AKA_RAND_LEN);
                     97:        if (!this->f->f2345(this->f, k, opc, rand, res, ck, ik, ak))
                     98:        {
                     99:                return FAILED;
                    100:        }
                    101:        *res_len = AKA_RES_LEN;
                    102:        DBG3(DBG_IKE, "using RES %b", res, AKA_RES_LEN);
                    103:        DBG3(DBG_IKE, "using CK %b", ck, AKA_CK_LEN);
                    104:        DBG3(DBG_IKE, "using IK %b", ik, AKA_IK_LEN);
                    105:        DBG3(DBG_IKE, "using AK %b", ak, AKA_AK_LEN);
                    106: 
                    107:        /* XOR anonymity key AK into SQN to decrypt it */
                    108:        memxor(sqn, ak, AKA_SQN_LEN);
                    109:        DBG3(DBG_IKE, "using SQN %b", sqn, AKA_SQN_LEN);
                    110: 
                    111:        /* calculate expected MAC and compare against received one */
                    112:        if (!this->f->f1(this->f, k, opc, rand, sqn, amf, xmac))
                    113:        {
                    114:                return FAILED;
                    115:        }
                    116:        if (!memeq_const(mac, xmac, AKA_MAC_LEN))
                    117:        {
                    118:                DBG1(DBG_IKE, "received MAC does not match XMAC");
                    119:                DBG3(DBG_IKE, "MAC %b\nXMAC %b", mac, AKA_MAC_LEN, xmac, AKA_MAC_LEN);
                    120:                return FAILED;
                    121:        }
                    122:        DBG3(DBG_IKE, "MAC equals XMAC %b", mac, AKA_MAC_LEN);
                    123: 
                    124:        if (this->seq_check && memcmp(this->sqn, sqn, AKA_SQN_LEN) >= 0)
                    125:        {
                    126:                DBG3(DBG_IKE, "received SQN %b\ncurrent SQN %b",
                    127:                         sqn, AKA_SQN_LEN, this->sqn, AKA_SQN_LEN);
                    128:                return INVALID_STATE;
                    129:        }
                    130: 
                    131:        /* update stored SQN to the received one */
                    132:        memcpy(this->sqn, sqn, AKA_SQN_LEN);
                    133: 
                    134:        return SUCCESS;
                    135: }
                    136: 
                    137: METHOD(simaka_card_t, resync, bool,
                    138:        private_eap_aka_3gpp_card_t *this, identification_t *id,
                    139:        char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
                    140: {
                    141:        uint8_t amf[AKA_AMF_LEN], k[AKA_K_LEN], opc[AKA_OPC_LEN], aks[AKA_AK_LEN],
                    142:                        macs[AKA_MAC_LEN];
                    143: 
                    144:        if (!eap_aka_3gpp_get_k_opc(id, k, opc))
                    145:        {
                    146:                DBG1(DBG_IKE, "no EAP key found for %Y to resync AKA", id);
                    147:                return FALSE;
                    148:        }
                    149:        DBG4(DBG_IKE, "EAP key found for id %Y, using K %b and OPc %b to resync AKA",
                    150:                 id, k, AKA_K_LEN, opc, AKA_OPC_LEN);
                    151: 
                    152:        /* AMF is set to zero in resync */
                    153:        memset(amf, 0, AKA_AMF_LEN);
                    154:        if (!this->f->f5star(this->f, k, opc, rand, aks) ||
                    155:            !this->f->f1star(this->f, k, opc, rand, this->sqn, amf, macs))
                    156:        {
                    157:                return FALSE;
                    158:        }
                    159:        /* AUTS = SQN xor AKS | MACS */
                    160:        memcpy(auts, this->sqn, AKA_SQN_LEN);
                    161:        memxor(auts, aks, AKA_AK_LEN);
                    162:        memcpy(auts + AKA_AK_LEN, macs, AKA_MAC_LEN);
                    163:        DBG3(DBG_IKE, "generated AUTS %b", auts, AKA_AUTN_LEN);
                    164: 
                    165:        return TRUE;
                    166: }
                    167: 
                    168: METHOD(eap_aka_3gpp_card_t, destroy, void,
                    169:        private_eap_aka_3gpp_card_t *this)
                    170: {
                    171:        free(this);
                    172: }
                    173: 
                    174: /**
                    175:  * See header
                    176:  */
                    177: eap_aka_3gpp_card_t *eap_aka_3gpp_card_create(eap_aka_3gpp_functions_t *f)
                    178: {
                    179:        private_eap_aka_3gpp_card_t *this;
                    180: 
                    181:        INIT(this,
                    182:                .public = {
                    183:                        .card = {
                    184:                                .get_triplet = (void*)return_false,
                    185:                                .get_quintuplet = _get_quintuplet,
                    186:                                .resync = _resync,
                    187:                                .get_pseudonym = (void*)return_null,
                    188:                                .set_pseudonym = (void*)nop,
                    189:                                .get_reauth = (void*)return_null,
                    190:                                .set_reauth = (void*)nop,
                    191:                        },
                    192:                        .destroy = _destroy,
                    193:                },
                    194:                .f = f,
                    195:                .seq_check = lib->settings->get_bool(lib->settings,
                    196:                                                                        "%s.plugins.eap-aka-3gpp.seq_check",
                    197: #ifdef SEQ_CHECK /* handle legacy compile time configuration as default */
                    198:                                                                        TRUE,
                    199: #else /* !SEQ_CHECK */
                    200:                                                                        FALSE,
                    201: #endif /* SEQ_CHECK */
                    202:                                                                        lib->ns),
                    203:        );
                    204: 
                    205:        eap_aka_3gpp_get_sqn(this->sqn, 0);
                    206: 
                    207:        return &this->public;
                    208: }

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