Annotation of embedaddon/strongswan/src/libtls/tls_aead.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2014 Martin Willi
        !             3:  * Copyright (C) 2014 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_aead.h"
        !            17: 
        !            18: #include <crypto/iv/iv_gen_rand.h>
        !            19: 
        !            20: typedef struct private_tls_aead_t private_tls_aead_t;
        !            21: 
        !            22: /**
        !            23:  * Private data of an tls_aead_t object.
        !            24:  */
        !            25: struct private_tls_aead_t {
        !            26: 
        !            27:        /**
        !            28:         * Public tls_aead_t interface.
        !            29:         */
        !            30:        tls_aead_t public;
        !            31: 
        !            32:        /**
        !            33:         * AEAD transform
        !            34:         */
        !            35:        aead_t *aead;
        !            36: 
        !            37:        /**
        !            38:         * Size of salt, the implicit nonce
        !            39:         */
        !            40:        size_t salt;
        !            41: };
        !            42: 
        !            43: /**
        !            44:  * Associated header data to create signature over
        !            45:  */
        !            46: typedef struct __attribute__((__packed__)) {
        !            47:        uint64_t seq;
        !            48:        uint8_t type;
        !            49:        uint16_t version;
        !            50:        uint16_t length;
        !            51: } sigheader_t;
        !            52: 
        !            53: METHOD(tls_aead_t, encrypt, bool,
        !            54:        private_tls_aead_t *this, tls_version_t version, tls_content_type_t type,
        !            55:        uint64_t seq, chunk_t *data)
        !            56: {
        !            57:        chunk_t assoc, encrypted, iv, plain;
        !            58:        uint8_t icvlen;
        !            59:        sigheader_t hdr;
        !            60:        iv_gen_t *gen;
        !            61: 
        !            62:        gen = this->aead->get_iv_gen(this->aead);
        !            63:        iv.len = this->aead->get_iv_size(this->aead);
        !            64:        icvlen = this->aead->get_icv_size(this->aead);
        !            65: 
        !            66:        encrypted = chunk_alloc(iv.len + data->len + icvlen);
        !            67:        iv.ptr = encrypted.ptr;
        !            68:        if (!gen->get_iv(gen, seq, iv.len, iv.ptr))
        !            69:        {
        !            70:                chunk_free(&encrypted);
        !            71:                return FALSE;
        !            72:        }
        !            73:        memcpy(encrypted.ptr + iv.len, data->ptr, data->len);
        !            74:        plain = chunk_skip(encrypted, iv.len);
        !            75:        plain.len -= icvlen;
        !            76: 
        !            77:        hdr.type = type;
        !            78:        htoun64(&hdr.seq, seq);
        !            79:        htoun16(&hdr.version, version);
        !            80:        htoun16(&hdr.length, plain.len);
        !            81: 
        !            82:        assoc = chunk_from_thing(hdr);
        !            83:        if (!this->aead->encrypt(this->aead, plain, assoc, iv, NULL))
        !            84:        {
        !            85:                chunk_free(&encrypted);
        !            86:                return FALSE;
        !            87:        }
        !            88:        chunk_free(data);
        !            89:        *data = encrypted;
        !            90:        return TRUE;
        !            91: }
        !            92: 
        !            93: METHOD(tls_aead_t, decrypt, bool,
        !            94:        private_tls_aead_t *this, tls_version_t version, tls_content_type_t type,
        !            95:        uint64_t seq, chunk_t *data)
        !            96: {
        !            97:        chunk_t assoc, iv;
        !            98:        uint8_t icvlen;
        !            99:        sigheader_t hdr;
        !           100: 
        !           101:        iv.len = this->aead->get_iv_size(this->aead);
        !           102:        if (data->len < iv.len)
        !           103:        {
        !           104:                return FALSE;
        !           105:        }
        !           106:        iv.ptr = data->ptr;
        !           107:        *data = chunk_skip(*data, iv.len);
        !           108:        icvlen = this->aead->get_icv_size(this->aead);
        !           109:        if (data->len < icvlen)
        !           110:        {
        !           111:                return FALSE;
        !           112:        }
        !           113: 
        !           114:        hdr.type = type;
        !           115:        htoun64(&hdr.seq, seq);
        !           116:        htoun16(&hdr.version, version);
        !           117:        htoun16(&hdr.length, data->len - icvlen);
        !           118: 
        !           119:        assoc = chunk_from_thing(hdr);
        !           120:        if (!this->aead->decrypt(this->aead, *data, assoc, iv, NULL))
        !           121:        {
        !           122:                return FALSE;
        !           123:        }
        !           124:        data->len -= icvlen;
        !           125:        return TRUE;
        !           126: }
        !           127: 
        !           128: METHOD(tls_aead_t, get_mac_key_size, size_t,
        !           129:        private_tls_aead_t *this)
        !           130: {
        !           131:        return 0;
        !           132: }
        !           133: 
        !           134: METHOD(tls_aead_t, get_encr_key_size, size_t,
        !           135:        private_tls_aead_t *this)
        !           136: {
        !           137:        return this->aead->get_key_size(this->aead) - this->salt;
        !           138: }
        !           139: 
        !           140: METHOD(tls_aead_t, get_iv_size, size_t,
        !           141:        private_tls_aead_t *this)
        !           142: {
        !           143:        return this->salt;
        !           144: }
        !           145: 
        !           146: METHOD(tls_aead_t, set_keys, bool,
        !           147:        private_tls_aead_t *this, chunk_t mac, chunk_t encr, chunk_t iv)
        !           148: {
        !           149:        chunk_t key;
        !           150: 
        !           151:        if (mac.len)
        !           152:        {
        !           153:                return FALSE;
        !           154:        }
        !           155:        key = chunk_cata("cc", encr, iv);
        !           156:        return this->aead->set_key(this->aead, key);
        !           157: }
        !           158: 
        !           159: METHOD(tls_aead_t, destroy, void,
        !           160:        private_tls_aead_t *this)
        !           161: {
        !           162:        this->aead->destroy(this->aead);
        !           163:        free(this);
        !           164: }
        !           165: 
        !           166: /**
        !           167:  * See header
        !           168:  */
        !           169: tls_aead_t *tls_aead_create_aead(encryption_algorithm_t encr, size_t encr_size)
        !           170: {
        !           171:        private_tls_aead_t *this;
        !           172:        size_t salt;
        !           173: 
        !           174:        switch (encr)
        !           175:        {
        !           176:                case ENCR_AES_GCM_ICV8:
        !           177:                case ENCR_AES_GCM_ICV12:
        !           178:                case ENCR_AES_GCM_ICV16:
        !           179:                case ENCR_AES_CCM_ICV8:
        !           180:                case ENCR_AES_CCM_ICV12:
        !           181:                case ENCR_AES_CCM_ICV16:
        !           182:                case ENCR_CAMELLIA_CCM_ICV8:
        !           183:                case ENCR_CAMELLIA_CCM_ICV12:
        !           184:                case ENCR_CAMELLIA_CCM_ICV16:
        !           185:                        salt = 4;
        !           186:                        break;
        !           187:                default:
        !           188:                        return NULL;
        !           189:        }
        !           190: 
        !           191:        INIT(this,
        !           192:                .public = {
        !           193:                        .encrypt = _encrypt,
        !           194:                        .decrypt = _decrypt,
        !           195:                        .get_mac_key_size = _get_mac_key_size,
        !           196:                        .get_encr_key_size = _get_encr_key_size,
        !           197:                        .get_iv_size = _get_iv_size,
        !           198:                        .set_keys = _set_keys,
        !           199:                        .destroy = _destroy,
        !           200:                },
        !           201:                .aead = lib->crypto->create_aead(lib->crypto, encr, encr_size, salt),
        !           202:                .salt = salt,
        !           203:        );
        !           204: 
        !           205:        if (!this->aead)
        !           206:        {
        !           207:                free(this);
        !           208:                return NULL;
        !           209:        }
        !           210: 
        !           211:        if (this->aead->get_block_size(this->aead) != 1)
        !           212:        {       /* TLS does not define any padding scheme for AEAD */
        !           213:                destroy(this);
        !           214:                return NULL;
        !           215:        }
        !           216: 
        !           217:        return &this->public;
        !           218: }

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