Annotation of embedaddon/strongswan/src/libstrongswan/crypto/prf_plus.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2005-2006 Martin Willi
                      3:  * Copyright (C) 2005 Jan Hutter
                      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 <string.h>
                     18: 
                     19: #include "prf_plus.h"
                     20: 
                     21: typedef struct private_prf_plus_t private_prf_plus_t;
                     22: 
                     23: typedef bool (*apply_prf_t)(private_prf_plus_t *this);
                     24: 
                     25: /**
                     26:  * Private data of an prf_plus_t object.
                     27:  *
                     28:  */
                     29: struct private_prf_plus_t {
                     30: 
                     31:        /**
                     32:         * Public interface of prf_plus_t.
                     33:         */
                     34:        prf_plus_t public;
                     35: 
                     36:        /**
                     37:         * PRF to use.
                     38:         */
                     39:        prf_t *prf;
                     40: 
                     41:        /**
                     42:         * Initial seed.
                     43:         */
                     44:        chunk_t seed;
                     45: 
                     46:        /**
                     47:         * Octet which will be appended to the seed if a counter is used.
                     48:         */
                     49:        uint8_t counter;
                     50: 
                     51:        /**
                     52:         * Already given out bytes in current buffer.
                     53:         */
                     54:        size_t used;
                     55: 
                     56:        /**
                     57:         * Buffer to store current PRF result.
                     58:         */
                     59:        chunk_t buffer;
                     60: 
                     61:        /**
                     62:         * The prf application method depending on whether a counter is used.
                     63:         */
                     64:        apply_prf_t apply_prf;
                     65: };
                     66: 
                     67: /**
                     68:  * Apply the PRF using the running counter
                     69:  */
                     70: static bool apply_prf_counter(private_prf_plus_t *this)
                     71: {
                     72:        if (!this->prf->get_bytes(this->prf, this->seed, NULL) ||
                     73:                !this->prf->get_bytes(this->prf, chunk_from_thing(this->counter),
                     74:                                                          this->buffer.ptr))
                     75:        {
                     76:                return FALSE;
                     77:        }
                     78:        this->counter++;
                     79:        if (!this->counter)
                     80:        {       /* according to RFC 7296, section 2.13, prf+ is undefined once the
                     81:                 * counter wrapped, so let's fail for future calls */
                     82:                this->apply_prf = (void*)return_false;
                     83:        }
                     84:        return TRUE;
                     85: }
                     86: 
                     87: /**
                     88:  * Apply the PRF using the running counter
                     89:  */
                     90: static bool apply_prf(private_prf_plus_t *this)
                     91: {
                     92:        return this->prf->get_bytes(this->prf, this->seed, this->buffer.ptr);
                     93: }
                     94: 
                     95: METHOD(prf_plus_t, get_bytes, bool,
                     96:        private_prf_plus_t *this, size_t length, uint8_t *buffer)
                     97: {
                     98:        size_t round, written = 0;
                     99: 
                    100:        while (length > 0)
                    101:        {
                    102:                if (this->buffer.len == this->used)
                    103:                {       /* buffer used, get next round */
                    104:                        if (!this->prf->get_bytes(this->prf, this->buffer, NULL))
                    105:                        {
                    106:                                return FALSE;
                    107:                        }
                    108:                        if (!this->apply_prf(this))
                    109:                        {
                    110:                                return FALSE;
                    111:                        }
                    112:                        this->used = 0;
                    113:                }
                    114:                round = min(length, this->buffer.len - this->used);
                    115:                memcpy(buffer + written, this->buffer.ptr + this->used, round);
                    116: 
                    117:                length -= round;
                    118:                this->used += round;
                    119:                written += round;
                    120:        }
                    121:        return TRUE;
                    122: }
                    123: 
                    124: METHOD(prf_plus_t, allocate_bytes, bool,
                    125:        private_prf_plus_t *this, size_t length, chunk_t *chunk)
                    126: {
                    127:        *chunk = chunk_alloc(length);
                    128:        if (!get_bytes(this, length, chunk->ptr))
                    129:        {
                    130:                chunk_free(chunk);
                    131:                return FALSE;
                    132:        }
                    133:        return TRUE;
                    134: }
                    135: 
                    136: METHOD(prf_plus_t, destroy, void,
                    137:        private_prf_plus_t *this)
                    138: {
                    139:        chunk_clear(&this->buffer);
                    140:        chunk_clear(&this->seed);
                    141:        free(this);
                    142: }
                    143: 
                    144: /*
                    145:  * Description in header.
                    146:  */
                    147: prf_plus_t *prf_plus_create(prf_t *prf, bool counter, chunk_t seed)
                    148: {
                    149:        private_prf_plus_t *this;
                    150: 
                    151:        INIT(this,
                    152:                .public = {
                    153:                        .get_bytes = _get_bytes,
                    154:                        .allocate_bytes = _allocate_bytes,
                    155:                        .destroy = _destroy,
                    156:                },
                    157:                .prf = prf,
                    158:                .seed = chunk_clone(seed),
                    159:                .buffer = chunk_alloc(prf->get_block_size(prf)),
                    160:                .apply_prf = counter ? apply_prf_counter : apply_prf,
                    161:                .counter = 0x01,
                    162:        );
                    163: 
                    164:        if (!this->apply_prf(this))
                    165:        {
                    166:                destroy(this);
                    167:                return NULL;
                    168:        }
                    169:        return &this->public;
                    170: }

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