Annotation of embedaddon/strongswan/src/libtls/tls_prf.c, revision 1.1.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>