Annotation of embedaddon/strongswan/src/libtls/tls_aead.c, revision 1.1.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>