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

1.1       misho       1: /*
                      2:  * Copyright (C) 2013 Tobias Brunner
                      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: #include "iv_gen_seq.h"
                     17: 
                     18: /**
                     19:  * Magic value for the initial IV state
                     20:  */
                     21: #define SEQ_IV_INIT_STATE (~(uint64_t)0)
                     22: #define SEQ_IV_HIGH_MASK (1ULL << 63)
                     23: 
                     24: typedef struct private_iv_gen_t private_iv_gen_t;
                     25: 
                     26: /**
                     27:  * Private data of an iv_gen_t object.
                     28:  */
                     29: struct private_iv_gen_t {
                     30: 
                     31:        /**
                     32:         * Public iv_gen_t interface.
                     33:         */
                     34:        iv_gen_t public;
                     35: 
                     36:        /**
                     37:         * Previously passed sequence number in lower space to enforce uniqueness
                     38:         */
                     39:        uint64_t prevl;
                     40: 
                     41:        /**
                     42:         * Previously passed sequence number in upper space to enforce uniqueness
                     43:         */
                     44:        uint64_t prevh;
                     45: 
                     46:        /**
                     47:         * Salt to mask counter
                     48:         */
                     49:        uint8_t *salt;
                     50: };
                     51: 
                     52: METHOD(iv_gen_t, get_iv, bool,
                     53:        private_iv_gen_t *this, uint64_t seq, size_t size, uint8_t *buffer)
                     54: {
                     55:        uint8_t iv[sizeof(uint64_t)];
                     56:        size_t len = size;
                     57: 
                     58:        if (!this->salt)
                     59:        {
                     60:                return FALSE;
                     61:        }
                     62:        if (size < sizeof(uint64_t))
                     63:        {
                     64:                return FALSE;
                     65:        }
                     66:        if (this->prevl != SEQ_IV_INIT_STATE && seq <= this->prevl)
                     67:        {
                     68:                seq |= SEQ_IV_HIGH_MASK;
                     69:                if (this->prevh != SEQ_IV_INIT_STATE && seq <= this->prevh)
                     70:                {
                     71:                        return FALSE;
                     72:                }
                     73:        }
                     74:        if ((seq | SEQ_IV_HIGH_MASK) == SEQ_IV_INIT_STATE)
                     75:        {
                     76:                return FALSE;
                     77:        }
                     78:        if (seq & SEQ_IV_HIGH_MASK)
                     79:        {
                     80:                this->prevh = seq;
                     81:        }
                     82:        else
                     83:        {
                     84:                this->prevl = seq;
                     85:        }
                     86:        if (len > sizeof(uint64_t))
                     87:        {
                     88:                len = sizeof(uint64_t);
                     89:                memset(buffer, 0, size - len);
                     90:        }
                     91:        htoun64(iv, seq);
                     92:        memxor(iv, this->salt, sizeof(uint64_t));
                     93:        memcpy(buffer + size - len, iv + sizeof(uint64_t) - len, len);
                     94:        return TRUE;
                     95: }
                     96: 
                     97: METHOD(iv_gen_t, allocate_iv, bool,
                     98:        private_iv_gen_t *this, uint64_t seq, size_t size, chunk_t *chunk)
                     99: {
                    100:        *chunk = chunk_alloc(size);
                    101:        if (!get_iv(this, seq, chunk->len, chunk->ptr))
                    102:        {
                    103:                chunk_free(chunk);
                    104:                return FALSE;
                    105:        }
                    106:        return TRUE;
                    107: }
                    108: 
                    109: METHOD(iv_gen_t, destroy, void,
                    110:        private_iv_gen_t *this)
                    111: {
                    112:        free(this->salt);
                    113:        free(this);
                    114: }
                    115: 
                    116: iv_gen_t *iv_gen_seq_create()
                    117: {
                    118:        private_iv_gen_t *this;
                    119:        rng_t *rng;
                    120: 
                    121:        INIT(this,
                    122:                .public = {
                    123:                        .get_iv = _get_iv,
                    124:                        .allocate_iv = _allocate_iv,
                    125:                        .destroy = _destroy,
                    126:                },
                    127:                .prevl = SEQ_IV_INIT_STATE,
                    128:                .prevh = SEQ_IV_INIT_STATE,
                    129:        );
                    130: 
                    131:        rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
                    132:        if (rng)
                    133:        {
                    134:                this->salt = malloc(sizeof(uint64_t));
                    135:                if (!rng->get_bytes(rng, sizeof(uint64_t), this->salt))
                    136:                {
                    137:                        free(this->salt);
                    138:                        this->salt = NULL;
                    139:                }
                    140:                rng->destroy(rng);
                    141:        }
                    142: 
                    143:        return &this->public;
                    144: }

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