Annotation of embedaddon/strongswan/src/libstrongswan/plugins/ctr/ctr_ipsec_crypter.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 "ctr_ipsec_crypter.h"
                     17: 
                     18: typedef struct private_ctr_ipsec_crypter_t private_ctr_ipsec_crypter_t;
                     19: 
                     20: /**
                     21:  * Private data of an ctr_ipsec_crypter_t object.
                     22:  */
                     23: struct private_ctr_ipsec_crypter_t {
                     24: 
                     25:        /**
                     26:         * Public ctr_ipsec_crypter_t interface.
                     27:         */
                     28:        ctr_ipsec_crypter_t public;
                     29: 
                     30:        /**
                     31:         * Underlying CBC crypter
                     32:         */
                     33:        crypter_t *crypter;
                     34: 
                     35:        /**
                     36:         * counter state
                     37:         */
                     38:        struct {
                     39:                char nonce[4];
                     40:                char iv[8];
                     41:                uint32_t counter;
                     42:        } __attribute__((packed)) state;
                     43: };
                     44: 
                     45: /**
                     46:  * Do the CTR crypto operation
                     47:  */
                     48: static bool crypt_ctr(private_ctr_ipsec_crypter_t *this,
                     49:                                          chunk_t in, chunk_t out)
                     50: {
                     51:        size_t is, bs;
                     52:        chunk_t state;
                     53: 
                     54:        is = this->crypter->get_iv_size(this->crypter);
                     55:        bs = sizeof(this->state);
                     56: 
                     57:        this->state.counter = htonl(1);
                     58:        state = chunk_create((char*)&this->state, bs);
                     59: 
                     60:        while (in.len > 0)
                     61:        {
                     62:                char iv[is], block[bs];
                     63: 
                     64:                memset(iv, 0, is);
                     65:                memcpy(block, state.ptr, bs);
                     66:                if (!this->crypter->encrypt(this->crypter, chunk_create(block, bs),
                     67:                                                                        chunk_create(iv, is), NULL))
                     68:                {
                     69:                        return FALSE;
                     70:                }
                     71:                chunk_increment(state);
                     72: 
                     73:                if (in.ptr != out.ptr)
                     74:                {
                     75:                        memcpy(out.ptr, in.ptr, min(in.len, bs));
                     76:                }
                     77:                memxor(out.ptr, block, min(in.len, bs));
                     78:                in = chunk_skip(in, bs);
                     79:                out = chunk_skip(out, bs);
                     80:        }
                     81:        return TRUE;
                     82: }
                     83: 
                     84: METHOD(crypter_t, crypt, bool,
                     85:        private_ctr_ipsec_crypter_t *this, chunk_t in, chunk_t iv, chunk_t *out)
                     86: {
                     87:        memcpy(this->state.iv, iv.ptr, sizeof(this->state.iv));
                     88: 
                     89:        if (out)
                     90:        {
                     91:                *out = chunk_alloc(in.len);
                     92:                return crypt_ctr(this, in, *out);
                     93:        }
                     94:        return crypt_ctr(this, in, in);
                     95: }
                     96: 
                     97: METHOD(crypter_t, get_block_size, size_t,
                     98:        private_ctr_ipsec_crypter_t *this)
                     99: {
                    100:        return 1;
                    101: }
                    102: 
                    103: METHOD(crypter_t, get_iv_size, size_t,
                    104:        private_ctr_ipsec_crypter_t *this)
                    105: {
                    106:        return sizeof(this->state.iv);
                    107: }
                    108: 
                    109: METHOD(crypter_t, get_key_size, size_t,
                    110:        private_ctr_ipsec_crypter_t *this)
                    111: {
                    112:        return this->crypter->get_key_size(this->crypter)
                    113:                        + sizeof(this->state.nonce);
                    114: }
                    115: 
                    116: METHOD(crypter_t, set_key, bool,
                    117:        private_ctr_ipsec_crypter_t *this, chunk_t key)
                    118: {
                    119:        memcpy(this->state.nonce, key.ptr + key.len - sizeof(this->state.nonce),
                    120:                   sizeof(this->state.nonce));
                    121:        key.len -= sizeof(this->state.nonce);
                    122:        return this->crypter->set_key(this->crypter, key);
                    123: }
                    124: 
                    125: METHOD(crypter_t, destroy, void,
                    126:        private_ctr_ipsec_crypter_t *this)
                    127: {
                    128:        this->crypter->destroy(this->crypter);
                    129:        free(this);
                    130: }
                    131: 
                    132: /**
                    133:  * See header
                    134:  */
                    135: ctr_ipsec_crypter_t *ctr_ipsec_crypter_create(encryption_algorithm_t algo,
                    136:                                                                                          size_t key_size)
                    137: {
                    138:        private_ctr_ipsec_crypter_t *this;
                    139: 
                    140:        switch (algo)
                    141:        {
                    142:                case ENCR_AES_CTR:
                    143:                        algo = ENCR_AES_CBC;
                    144:                        break;
                    145:                case ENCR_CAMELLIA_CTR:
                    146:                        algo = ENCR_CAMELLIA_CBC;
                    147:                        break;
                    148:                default:
                    149:                        return NULL;
                    150:        }
                    151: 
                    152:        INIT(this,
                    153:                .public = {
                    154:                        .crypter = {
                    155:                                .encrypt = _crypt,
                    156:                                .decrypt = _crypt,
                    157:                                .get_block_size = _get_block_size,
                    158:                                .get_iv_size = _get_iv_size,
                    159:                                .get_key_size = _get_key_size,
                    160:                                .set_key = _set_key,
                    161:                                .destroy = _destroy,
                    162:                        },
                    163:                },
                    164:                .crypter = lib->crypto->create_crypter(lib->crypto, algo, key_size),
                    165:        );
                    166: 
                    167:        if (!this->crypter)
                    168:        {
                    169:                free(this);
                    170:                return NULL;
                    171:        }
                    172: 
                    173:        return &this->public;
                    174: }

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