Annotation of embedaddon/strongswan/src/libtls/tls_prf.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2010 Martin Willi
        !             3:  * Copyright (C) 2010 revosec AG
        !             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: #include "tls_prf.h"
        !            17: 
        !            18: typedef struct private_tls_prf12_t private_tls_prf12_t;
        !            19: 
        !            20: #include <library.h>
        !            21: 
        !            22: /**
        !            23:  * Private data of an tls_prf_t object.
        !            24:  */
        !            25: struct private_tls_prf12_t {
        !            26: 
        !            27:        /**
        !            28:         * Public tls_prf_t interface.
        !            29:         */
        !            30:        tls_prf_t public;
        !            31: 
        !            32:        /**
        !            33:         * Underlying primitive PRF
        !            34:         */
        !            35:        prf_t *prf;
        !            36: };
        !            37: 
        !            38: METHOD(tls_prf_t, set_key12, bool,
        !            39:        private_tls_prf12_t *this, chunk_t key)
        !            40: {
        !            41:        return this->prf->set_key(this->prf, key);
        !            42: }
        !            43: 
        !            44: /**
        !            45:  * The P_hash function as in TLS 1.0/1.2
        !            46:  */
        !            47: static bool p_hash(prf_t *prf, char *label, chunk_t seed, size_t block_size,
        !            48:                                   size_t bytes, char *out)
        !            49: {
        !            50:        char buf[block_size], abuf[block_size];
        !            51:        chunk_t a;
        !            52: 
        !            53:        /* seed = label + seed */
        !            54:        seed = chunk_cata("cc", chunk_create(label, strlen(label)), seed);
        !            55:        /* A(0) = seed */
        !            56:        a = seed;
        !            57: 
        !            58:        while (TRUE)
        !            59:        {
        !            60:                /* A(i) = HMAC_hash(secret, A(i-1)) */
        !            61:                if (!prf->get_bytes(prf, a, abuf))
        !            62:                {
        !            63:                        return FALSE;
        !            64:                }
        !            65:                a = chunk_from_thing(abuf);
        !            66:                /* HMAC_hash(secret, A(i) + seed) */
        !            67:                if (!prf->get_bytes(prf, a, NULL) ||
        !            68:                        !prf->get_bytes(prf, seed, buf))
        !            69:                {
        !            70:                        return FALSE;
        !            71:                }
        !            72: 
        !            73:                if (bytes <= block_size)
        !            74:                {
        !            75:                        memcpy(out, buf, bytes);
        !            76:                        break;
        !            77:                }
        !            78:                memcpy(out, buf, block_size);
        !            79:                out += block_size;
        !            80:                bytes -= block_size;
        !            81:        }
        !            82:        return TRUE;
        !            83: }
        !            84: 
        !            85: METHOD(tls_prf_t, get_bytes12, bool,
        !            86:        private_tls_prf12_t *this, char *label, chunk_t seed,
        !            87:        size_t bytes, char *out)
        !            88: {
        !            89:        return p_hash(this->prf, label, seed, this->prf->get_block_size(this->prf),
        !            90:                                  bytes, out);
        !            91: }
        !            92: 
        !            93: METHOD(tls_prf_t, destroy12, void,
        !            94:        private_tls_prf12_t *this)
        !            95: {
        !            96:        this->prf->destroy(this->prf);
        !            97:        free(this);
        !            98: }
        !            99: 
        !           100: /**
        !           101:  * See header
        !           102:  */
        !           103: tls_prf_t *tls_prf_create_12(pseudo_random_function_t prf)
        !           104: {
        !           105:        private_tls_prf12_t *this;
        !           106: 
        !           107:        INIT(this,
        !           108:                .public = {
        !           109:                        .set_key = _set_key12,
        !           110:                        .get_bytes = _get_bytes12,
        !           111:                        .destroy = _destroy12,
        !           112:                },
        !           113:                .prf = lib->crypto->create_prf(lib->crypto, prf),
        !           114:        );
        !           115:        if (!this->prf)
        !           116:        {
        !           117:                free(this);
        !           118:                return NULL;
        !           119:        }
        !           120:        return &this->public;
        !           121: }
        !           122: 
        !           123: 
        !           124: typedef struct private_tls_prf10_t private_tls_prf10_t;
        !           125: 
        !           126: /**
        !           127:  * Private data of an tls_prf_t object.
        !           128:  */
        !           129: struct private_tls_prf10_t {
        !           130: 
        !           131:        /**
        !           132:         * Public tls_prf_t interface.
        !           133:         */
        !           134:        tls_prf_t public;
        !           135: 
        !           136:        /**
        !           137:         * Underlying MD5 PRF
        !           138:         */
        !           139:        prf_t *md5;
        !           140: 
        !           141:        /**
        !           142:         * Underlying SHA1 PRF
        !           143:         */
        !           144:        prf_t *sha1;
        !           145: };
        !           146: 
        !           147: METHOD(tls_prf_t, set_key10, bool,
        !           148:        private_tls_prf10_t *this, chunk_t key)
        !           149: {
        !           150:        size_t len = key.len / 2 + key.len % 2;
        !           151: 
        !           152:        return this->md5->set_key(this->md5, chunk_create(key.ptr, len)) &&
        !           153:                   this->sha1->set_key(this->sha1, chunk_create(key.ptr + key.len - len,
        !           154:                                                                                                                len));
        !           155: }
        !           156: 
        !           157: METHOD(tls_prf_t, get_bytes10, bool,
        !           158:        private_tls_prf10_t *this, char *label, chunk_t seed,
        !           159:        size_t bytes, char *out)
        !           160: {
        !           161:        char buf[bytes];
        !           162: 
        !           163:        if (!p_hash(this->md5, label, seed, this->md5->get_block_size(this->md5),
        !           164:                                bytes, out) ||
        !           165:                !p_hash(this->sha1, label, seed, this->sha1->get_block_size(this->sha1),
        !           166:                                bytes, buf))
        !           167:        {
        !           168:                return FALSE;
        !           169:        }
        !           170:        memxor(out, buf, bytes);
        !           171:        return TRUE;
        !           172: }
        !           173: 
        !           174: METHOD(tls_prf_t, destroy10, void,
        !           175:        private_tls_prf10_t *this)
        !           176: {
        !           177:        DESTROY_IF(this->md5);
        !           178:        DESTROY_IF(this->sha1);
        !           179:        free(this);
        !           180: }
        !           181: 
        !           182: /**
        !           183:  * See header
        !           184:  */
        !           185: tls_prf_t *tls_prf_create_10()
        !           186: {
        !           187:        private_tls_prf10_t *this;
        !           188: 
        !           189:        INIT(this,
        !           190:                .public = {
        !           191:                        .set_key = _set_key10,
        !           192:                        .get_bytes = _get_bytes10,
        !           193:                        .destroy = _destroy10,
        !           194:                },
        !           195:                .md5 = lib->crypto->create_prf(lib->crypto, PRF_HMAC_MD5),
        !           196:                .sha1 = lib->crypto->create_prf(lib->crypto, PRF_HMAC_SHA1),
        !           197:        );
        !           198:        if (!this->md5 || !this->sha1)
        !           199:        {
        !           200:                destroy10(this);
        !           201:                return NULL;
        !           202:        }
        !           203:        return &this->public;
        !           204: }

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