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

1.1       misho       1: /*
                      2:  * Copyright (C) 2013 Tobias Brunner
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * Copyright (C) 2010 Martin Willi
                      6:  * Copyright (C) 2010 revosec AG
                      7:  *
                      8:  * This program is free software; you can redistribute it and/or modify it
                      9:  * under the terms of the GNU General Public License as published by the
                     10:  * Free Software Foundation; either version 2 of the License, or (at your
                     11:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     12:  *
                     13:  * This program is distributed in the hope that it will be useful, but
                     14:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     15:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     16:  * for more details.
                     17:  */
                     18: 
                     19: #include "aead.h"
                     20: 
                     21: #include <utils/debug.h>
                     22: #include <crypto/iv/iv_gen_rand.h>
                     23: 
                     24: typedef struct private_aead_t private_aead_t;
                     25: 
                     26: /**
                     27:  * Private data of an aead_t object.
                     28:  */
                     29: struct private_aead_t {
                     30: 
                     31:        /**
                     32:         * Public aead_t interface.
                     33:         */
                     34:        aead_t public;
                     35: 
                     36:        /**
                     37:         * traditional crypter
                     38:         */
                     39:        crypter_t *crypter;
                     40: 
                     41:        /**
                     42:         * traditional signer
                     43:         */
                     44:        signer_t *signer;
                     45: 
                     46:        /**
                     47:         * IV generator
                     48:         */
                     49:        iv_gen_t *iv_gen;
                     50: };
                     51: 
                     52: METHOD(aead_t, encrypt, bool,
                     53:        private_aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv,
                     54:        chunk_t *encrypted)
                     55: {
                     56:        chunk_t encr, sig;
                     57: 
                     58:        if (!this->signer->get_signature(this->signer, assoc, NULL) ||
                     59:                !this->signer->get_signature(this->signer, iv, NULL))
                     60:        {
                     61:                return FALSE;
                     62:        }
                     63: 
                     64:        if (encrypted)
                     65:        {
                     66:                if (!this->crypter->encrypt(this->crypter, plain, iv, &encr))
                     67:                {
                     68:                        return FALSE;
                     69:                }
                     70:                if (!this->signer->allocate_signature(this->signer, encr, &sig))
                     71:                {
                     72:                        free(encr.ptr);
                     73:                        return FALSE;
                     74:                }
                     75:                *encrypted = chunk_cat("cmm", iv, encr, sig);
                     76:        }
                     77:        else
                     78:        {
                     79:                if (!this->crypter->encrypt(this->crypter, plain, iv, NULL) ||
                     80:                        !this->signer->get_signature(this->signer,
                     81:                                                                                 plain, plain.ptr + plain.len))
                     82:                {
                     83:                        return FALSE;
                     84:                }
                     85:        }
                     86:        return TRUE;
                     87: }
                     88: 
                     89: METHOD(aead_t, decrypt, bool,
                     90:        private_aead_t *this, chunk_t encrypted, chunk_t assoc, chunk_t iv,
                     91:        chunk_t *plain)
                     92: {
                     93:        chunk_t sig;
                     94:        size_t bs;
                     95: 
                     96:        bs = this->crypter->get_block_size(this->crypter);
                     97:        sig.len = this->signer->get_block_size(this->signer);
                     98:        if (sig.len > encrypted.len || (encrypted.len - sig.len) % bs)
                     99:        {
                    100:                DBG1(DBG_LIB, "invalid encrypted data length %d with block size %d",
                    101:                        encrypted.len - sig.len, bs);
                    102:                return FALSE;
                    103:        }
                    104:        chunk_split(encrypted, "mm", encrypted.len - sig.len,
                    105:                                &encrypted, sig.len, &sig);
                    106: 
                    107:        if (!this->signer->get_signature(this->signer, assoc, NULL) ||
                    108:                !this->signer->get_signature(this->signer, iv, NULL))
                    109:        {
                    110:                return FALSE;
                    111:        }
                    112:        if (!this->signer->verify_signature(this->signer, encrypted, sig))
                    113:        {
                    114:                DBG1(DBG_LIB, "MAC verification failed");
                    115:                return FALSE;
                    116:        }
                    117:        return this->crypter->decrypt(this->crypter, encrypted, iv, plain);
                    118: }
                    119: 
                    120: METHOD(aead_t, get_block_size, size_t,
                    121:        private_aead_t *this)
                    122: {
                    123:        return this->crypter->get_block_size(this->crypter);
                    124: }
                    125: 
                    126: METHOD(aead_t, get_icv_size, size_t,
                    127:        private_aead_t *this)
                    128: {
                    129:        return this->signer->get_block_size(this->signer);
                    130: }
                    131: 
                    132: METHOD(aead_t, get_iv_size, size_t,
                    133:        private_aead_t *this)
                    134: {
                    135:        return this->crypter->get_iv_size(this->crypter);
                    136: }
                    137: 
                    138: METHOD(aead_t, get_iv_gen, iv_gen_t*,
                    139:        private_aead_t *this)
                    140: {
                    141:        return this->iv_gen;
                    142: }
                    143: 
                    144: METHOD(aead_t, get_key_size, size_t,
                    145:        private_aead_t *this)
                    146: {
                    147:        return this->crypter->get_key_size(this->crypter) +
                    148:                        this->signer->get_key_size(this->signer);
                    149: }
                    150: 
                    151: METHOD(aead_t, set_key, bool,
                    152:        private_aead_t *this, chunk_t key)
                    153: {
                    154:        chunk_t sig, enc;
                    155: 
                    156:        chunk_split(key, "mm", this->signer->get_key_size(this->signer), &sig,
                    157:                                this->crypter->get_key_size(this->crypter), &enc);
                    158: 
                    159:        return this->signer->set_key(this->signer, sig) &&
                    160:                   this->crypter->set_key(this->crypter, enc);
                    161: }
                    162: 
                    163: METHOD(aead_t, destroy, void,
                    164:        private_aead_t *this)
                    165: {
                    166:        this->iv_gen->destroy(this->iv_gen);
                    167:        this->crypter->destroy(this->crypter);
                    168:        this->signer->destroy(this->signer);
                    169:        free(this);
                    170: }
                    171: 
                    172: /**
                    173:  * See header
                    174:  */
                    175: aead_t *aead_create(crypter_t *crypter, signer_t *signer, iv_gen_t *iv_gen)
                    176: {
                    177:        private_aead_t *this;
                    178: 
                    179:        INIT(this,
                    180:                .public = {
                    181:                        .encrypt = _encrypt,
                    182:                        .decrypt = _decrypt,
                    183:                        .get_block_size = _get_block_size,
                    184:                        .get_icv_size = _get_icv_size,
                    185:                        .get_iv_size = _get_iv_size,
                    186:                        .get_iv_gen = _get_iv_gen,
                    187:                        .get_key_size = _get_key_size,
                    188:                        .set_key = _set_key,
                    189:                        .destroy = _destroy,
                    190:                },
                    191:                .crypter = crypter,
                    192:                .signer = signer,
                    193:                .iv_gen = iv_gen,
                    194:        );
                    195: 
                    196:        return &this->public;
                    197: }

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