Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/encrypted_payload.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2011-2018 Tobias Brunner
                      3:  * Copyright (C) 2005-2010 Martin Willi
                      4:  * Copyright (C) 2010 revosec AG
                      5:  * Copyright (C) 2005 Jan Hutter
                      6:  * HSR Hochschule fuer Technik Rapperswil
                      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 <stddef.h>
                     20: #include <string.h>
                     21: 
                     22: #include "encrypted_payload.h"
                     23: #include "encrypted_fragment_payload.h"
                     24: 
                     25: #include <daemon.h>
                     26: #include <encoding/payloads/encodings.h>
                     27: #include <collections/linked_list.h>
                     28: #include <encoding/parser.h>
                     29: 
                     30: typedef struct private_encrypted_payload_t private_encrypted_payload_t;
                     31: typedef struct private_encrypted_fragment_payload_t private_encrypted_fragment_payload_t;
                     32: 
                     33: struct private_encrypted_payload_t {
                     34: 
                     35:        /**
                     36:         * Public encrypted_payload_t interface.
                     37:         */
                     38:        encrypted_payload_t public;
                     39: 
                     40:        /**
                     41:         * There is no next payload for an encrypted payload,
                     42:         * since encrypted payload MUST be the last one.
                     43:         * next_payload means here the first payload of the
                     44:         * contained, encrypted payload.
                     45:         */
                     46:        uint8_t next_payload;
                     47: 
                     48:        /**
                     49:         * Flags, including reserved bits
                     50:         */
                     51:        uint8_t flags;
                     52: 
                     53:        /**
                     54:         * Length of this payload
                     55:         */
                     56:        uint16_t payload_length;
                     57: 
                     58:        /**
                     59:         * Chunk containing the IV, plain, padding and ICV.
                     60:         */
                     61:        chunk_t encrypted;
                     62: 
                     63:        /**
                     64:         * AEAD transform to use
                     65:         */
                     66:        aead_t *aead;
                     67: 
                     68:        /**
                     69:         * Contained payloads
                     70:         */
                     71:        linked_list_t *payloads;
                     72: 
                     73:        /**
                     74:         * Type of payload, PLV2_ENCRYPTED or PLV1_ENCRYPTED
                     75:         */
                     76:        payload_type_t type;
                     77: };
                     78: 
                     79: struct private_encrypted_fragment_payload_t {
                     80: 
                     81:        /**
                     82:         * Public interface.
                     83:         */
                     84:        encrypted_fragment_payload_t public;
                     85: 
                     86:        /**
                     87:         * The first fragment contains the type of the first payload contained in
                     88:         * the original encrypted payload, for all other fragments it MUST be set
                     89:         * to zero.
                     90:         */
                     91:        uint8_t next_payload;
                     92: 
                     93:        /**
                     94:         * Flags, including reserved bits
                     95:         */
                     96:        uint8_t flags;
                     97: 
                     98:        /**
                     99:         * Length of this payload
                    100:         */
                    101:        uint16_t payload_length;
                    102: 
                    103:        /**
                    104:         * Chunk containing the IV, plain, padding and ICV.
                    105:         */
                    106:        chunk_t encrypted;
                    107: 
                    108:        /**
                    109:         * Fragment number
                    110:         */
                    111:        uint16_t fragment_number;
                    112: 
                    113:        /**
                    114:         * Total fragments
                    115:         */
                    116:        uint16_t total_fragments;
                    117: 
                    118:        /**
                    119:         * AEAD transform to use
                    120:         */
                    121:        aead_t *aead;
                    122: 
                    123:        /**
                    124:         * Chunk containing the plain packet data.
                    125:         */
                    126:        chunk_t plain;
                    127: };
                    128: 
                    129: /**
                    130:  * Encoding rules to parse or generate a IKEv2-Encrypted Payload.
                    131:  *
                    132:  * The defined offsets are the positions in a object of type
                    133:  * private_encrypted_payload_t.
                    134:  */
                    135: static encoding_rule_t encodings_v2[] = {
                    136:        /* 1 Byte next payload type, stored in the field next_payload */
                    137:        { U_INT_8,                      offsetof(private_encrypted_payload_t, next_payload)     },
                    138:        /* Critical and 7 reserved bits, all stored for reconstruction */
                    139:        { U_INT_8,                      offsetof(private_encrypted_payload_t, flags)                    },
                    140:        /* Length of the whole encrypted payload*/
                    141:        { PAYLOAD_LENGTH,       offsetof(private_encrypted_payload_t, payload_length)   },
                    142:        /* encrypted data, stored in a chunk. contains iv, data, padding */
                    143:        { CHUNK_DATA,           offsetof(private_encrypted_payload_t, encrypted)                },
                    144: };
                    145: 
                    146: /*
                    147:                            1                   2                   3
                    148:        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                    149:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    150:       ! Next Payload  !C!  RESERVED   !         Payload Length        !
                    151:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    152:       !                     Initialization Vector                     !
                    153:       !         (length is block size for encryption algorithm)       !
                    154:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    155:       !                    Encrypted IKE Payloads                     !
                    156:       +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    157:       !               !             Padding (0-255 octets)            !
                    158:       +-+-+-+-+-+-+-+-+                               +-+-+-+-+-+-+-+-+
                    159:       !                                               !  Pad Length   !
                    160:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    161:       ~                    Integrity Checksum Data                    ~
                    162:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    163: */
                    164: 
                    165: /**
                    166:  * Encoding rules to parse or generate a complete encrypted IKEv1 message.
                    167:  *
                    168:  * The defined offsets are the positions in a object of type
                    169:  * private_encrypted_payload_t.
                    170:  */
                    171: static encoding_rule_t encodings_v1[] = {
                    172:        /* encrypted data, stored in a chunk */
                    173:        { ENCRYPTED_DATA,       offsetof(private_encrypted_payload_t, encrypted)                },
                    174: };
                    175: 
                    176: /*
                    177:                            1                   2                   3
                    178:        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                    179:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    180:       !                    Encrypted IKE Payloads                     !
                    181:       +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    182:       !               !             Padding (0-255 octets)            !
                    183:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    184: */
                    185: 
                    186: /**
                    187:  * Encoding rules to parse or generate an IKEv2-Encrypted Fragment Payload.
                    188:  *
                    189:  * The defined offsets are the positions in a object of type
                    190:  * private_encrypted_payload_t.
                    191:  */
                    192: static encoding_rule_t encodings_fragment[] = {
                    193:        /* 1 Byte next payload type, stored in the field next_payload */
                    194:        { U_INT_8,                      offsetof(private_encrypted_fragment_payload_t, next_payload)    },
                    195:        /* Critical and 7 reserved bits, all stored for reconstruction */
                    196:        { U_INT_8,                      offsetof(private_encrypted_fragment_payload_t, flags)                   },
                    197:        /* Length of the whole encryption payload*/
                    198:        { PAYLOAD_LENGTH,       offsetof(private_encrypted_fragment_payload_t, payload_length)  },
                    199:        /* Fragment number */
                    200:        { U_INT_16,                     offsetof(private_encrypted_fragment_payload_t, fragment_number) },
                    201:        /* Total number of fragments */
                    202:        { U_INT_16,                     offsetof(private_encrypted_fragment_payload_t, total_fragments) },
                    203:        /* encrypted data, stored in a chunk. contains iv, data, padding */
                    204:        { CHUNK_DATA,           offsetof(private_encrypted_fragment_payload_t, encrypted)               },
                    205: };
                    206: 
                    207: /*
                    208:                            1                   2                   3
                    209:        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                    210:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    211:       ! Next Payload  !C!  RESERVED   !         Payload Length        !
                    212:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    213:       !        Fragment Number        |        Total Fragments        !
                    214:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    215:       !                     Initialization Vector                     !
                    216:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    217:       !                    Encrypted IKE Payloads                     !
                    218:       +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    219:       !               !             Padding (0-255 octets)            !
                    220:       +-+-+-+-+-+-+-+-+                               +-+-+-+-+-+-+-+-+
                    221:       !                                               !  Pad Length   !
                    222:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    223:       ~                    Integrity Checksum Data                    ~
                    224:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    225: */
                    226: 
                    227: METHOD(payload_t, verify, status_t,
                    228:        private_encrypted_payload_t *this)
                    229: {
                    230:        return SUCCESS;
                    231: }
                    232: 
                    233: METHOD(payload_t, get_encoding_rules, int,
                    234:        private_encrypted_payload_t *this, encoding_rule_t **rules)
                    235: {
                    236:        if (this->type == PLV2_ENCRYPTED)
                    237:        {
                    238:                *rules = encodings_v2;
                    239:                return countof(encodings_v2);
                    240:        }
                    241:        *rules = encodings_v1;
                    242:        return countof(encodings_v1);
                    243: }
                    244: 
                    245: METHOD(payload_t, get_header_length, int,
                    246:        private_encrypted_payload_t *this)
                    247: {
                    248:        if (this->type == PLV2_ENCRYPTED)
                    249:        {
                    250:                return 4;
                    251:        }
                    252:        return 0;
                    253: }
                    254: 
                    255: METHOD(payload_t, get_type, payload_type_t,
                    256:        private_encrypted_payload_t *this)
                    257: {
                    258:        return this->type;
                    259: }
                    260: 
                    261: METHOD(payload_t, get_next_type, payload_type_t,
                    262:        private_encrypted_payload_t *this)
                    263: {
                    264:        return this->next_payload;
                    265: }
                    266: 
                    267: METHOD(payload_t, set_next_type, void,
                    268:        private_encrypted_payload_t *this, payload_type_t type)
                    269: {
                    270:        /* the next payload is set during add, still allow this for IKEv1 */
                    271:        this->next_payload = type;
                    272: }
                    273: 
                    274: /**
                    275:  * Get length of encryption/integrity overhead for the given plaintext length
                    276:  */
                    277: static size_t compute_overhead(aead_t *aead, size_t len)
                    278: {
                    279:        size_t bs, overhead;
                    280: 
                    281:        /* padding */
                    282:        bs = aead->get_block_size(aead);
                    283:        overhead = bs - (len % bs);
                    284:        /* add iv */
                    285:        overhead += aead->get_iv_size(aead);
                    286:        /* add icv */
                    287:        overhead += aead->get_icv_size(aead);
                    288:        return overhead;
                    289: }
                    290: 
                    291: /**
                    292:  * Compute the length of the whole payload
                    293:  */
                    294: static void compute_length(private_encrypted_payload_t *this)
                    295: {
                    296:        enumerator_t *enumerator;
                    297:        payload_t *payload;
                    298:        size_t length = 0;
                    299: 
                    300:        if (this->encrypted.len)
                    301:        {
                    302:                length = this->encrypted.len;
                    303:        }
                    304:        else
                    305:        {
                    306:                enumerator = this->payloads->create_enumerator(this->payloads);
                    307:                while (enumerator->enumerate(enumerator, &payload))
                    308:                {
                    309:                        length += payload->get_length(payload);
                    310:                }
                    311:                enumerator->destroy(enumerator);
                    312: 
                    313:                if (this->aead)
                    314:                {
                    315:                        length += compute_overhead(this->aead, length);
                    316:                }
                    317:        }
                    318:        length += get_header_length(this);
                    319:        this->payload_length = length;
                    320: }
                    321: 
                    322: METHOD2(payload_t, encrypted_payload_t, get_length, size_t,
                    323:        private_encrypted_payload_t *this)
                    324: {
                    325:        compute_length(this);
                    326:        return this->payload_length;
                    327: }
                    328: 
                    329: METHOD2(payload_t, encrypted_payload_t, get_length_plain, size_t,
                    330:        private_encrypted_payload_t *this)
                    331: {
                    332:        /* contains only the decrypted payload data, no IV, padding or ICV */
                    333:        this->payload_length = this->encrypted.len;
                    334: 
                    335:        if (this->aead)
                    336:        {
                    337:                this->payload_length += compute_overhead(this->aead,
                    338:                                                                                                 this->payload_length);
                    339:        }
                    340:        this->payload_length += get_header_length(this);
                    341:        return this->payload_length;
                    342: }
                    343: 
                    344: METHOD(encrypted_payload_t, add_payload, void,
                    345:        private_encrypted_payload_t *this, payload_t *payload)
                    346: {
                    347:        payload_t *last_payload;
                    348: 
                    349:        if (this->payloads->get_count(this->payloads) > 0)
                    350:        {
                    351:                this->payloads->get_last(this->payloads, (void **)&last_payload);
                    352:                last_payload->set_next_type(last_payload, payload->get_type(payload));
                    353:        }
                    354:        else
                    355:        {
                    356:                this->next_payload = payload->get_type(payload);
                    357:        }
                    358:        payload->set_next_type(payload, PL_NONE);
                    359:        this->payloads->insert_last(this->payloads, payload);
                    360:        compute_length(this);
                    361: }
                    362: 
                    363: METHOD(encrypted_payload_t, remove_payload, payload_t *,
                    364:        private_encrypted_payload_t *this)
                    365: {
                    366:        payload_t *payload;
                    367: 
                    368:        if (this->payloads->remove_first(this->payloads,
                    369:                                                                         (void**)&payload) == SUCCESS)
                    370:        {
                    371:                return payload;
                    372:        }
                    373:        return NULL;
                    374: }
                    375: 
                    376: /**
                    377:  * Generate payload before encryption
                    378:  */
                    379: static chunk_t generate(private_encrypted_payload_t *this,
                    380:                                                generator_t *generator)
                    381: {
                    382:        payload_t *current, *next;
                    383:        enumerator_t *enumerator;
                    384:        uint32_t *lenpos;
                    385:        chunk_t chunk = chunk_empty;
                    386: 
                    387:        enumerator = this->payloads->create_enumerator(this->payloads);
                    388:        if (enumerator->enumerate(enumerator, &current))
                    389:        {
                    390:                this->next_payload = current->get_type(current);
                    391: 
                    392:                while (enumerator->enumerate(enumerator, &next))
                    393:                {
                    394:                        current->set_next_type(current, next->get_type(next));
                    395:                        generator->generate_payload(generator, current);
                    396:                        current = next;
                    397:                }
                    398:                current->set_next_type(current, PL_NONE);
                    399:                generator->generate_payload(generator, current);
                    400: 
                    401:                chunk = generator->get_chunk(generator, &lenpos);
                    402:                DBG2(DBG_ENC, "generated content in encrypted payload");
                    403:        }
                    404:        enumerator->destroy(enumerator);
                    405:        return chunk;
                    406: }
                    407: 
                    408: METHOD(encrypted_payload_t, generate_payloads, void,
                    409:        private_encrypted_payload_t *this, generator_t *generator)
                    410: {
                    411:        generate(this, generator);
                    412: }
                    413: 
                    414: /**
                    415:  * Append the encrypted payload header to the associated data
                    416:  */
                    417: static chunk_t append_header(private_encrypted_payload_t *this, chunk_t assoc)
                    418: {
                    419:        struct {
                    420:                uint8_t next_payload;
                    421:                uint8_t flags;
                    422:                uint16_t length;
                    423:        } __attribute__((packed)) header = {
                    424:                .next_payload = this->next_payload,
                    425:                .flags = this->flags,
                    426:                .length = htons(get_length(this)),
                    427:        };
                    428:        return chunk_cat("cc", assoc, chunk_from_thing(header));
                    429: }
                    430: 
                    431: /**
                    432:  * Encrypts the data in plain and returns it in an allocated chunk.
                    433:  */
                    434: static status_t encrypt_content(char *label, aead_t *aead, uint64_t mid,
                    435:                                                        chunk_t plain, chunk_t assoc, chunk_t *encrypted)
                    436: {
                    437:        chunk_t iv, padding, icv, crypt;
                    438:        iv_gen_t *iv_gen;
                    439:        rng_t *rng;
                    440:        size_t bs;
                    441: 
                    442:        rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
                    443:        if (!rng)
                    444:        {
                    445:                DBG1(DBG_ENC, "encrypting %s failed, no RNG found", label);
                    446:                return NOT_SUPPORTED;
                    447:        }
                    448: 
                    449:        iv_gen = aead->get_iv_gen(aead);
                    450:        if (!iv_gen)
                    451:        {
                    452:                DBG1(DBG_ENC, "encrypting %s failed, no IV generator", label);
                    453:                return NOT_SUPPORTED;
                    454:        }
                    455: 
                    456:        bs = aead->get_block_size(aead);
                    457:        /* we need at least one byte padding to store the padding length */
                    458:        padding.len = bs - (plain.len % bs);
                    459:        iv.len = aead->get_iv_size(aead);
                    460:        icv.len = aead->get_icv_size(aead);
                    461: 
                    462:        /* prepare data to authenticate-encrypt:
                    463:         * | IV | plain | padding | ICV |
                    464:         *       \____crypt______/   ^
                    465:         *              |           /
                    466:         *              v          /
                    467:         *     assoc -> + ------->/
                    468:         */
                    469:        *encrypted = chunk_alloc(iv.len + plain.len + padding.len + icv.len);
                    470:        iv.ptr = encrypted->ptr;
                    471:        memcpy(iv.ptr + iv.len, plain.ptr, plain.len);
                    472:        plain.ptr = iv.ptr + iv.len;
                    473:        padding.ptr = plain.ptr + plain.len;
                    474:        icv.ptr = padding.ptr + padding.len;
                    475:        crypt = chunk_create(plain.ptr, plain.len + padding.len);
                    476: 
                    477:        if (!iv_gen->get_iv(iv_gen, mid, iv.len, iv.ptr) ||
                    478:                !rng->get_bytes(rng, padding.len - 1, padding.ptr))
                    479:        {
                    480:                DBG1(DBG_ENC, "encrypting %s failed, no IV or padding", label);
                    481:                rng->destroy(rng);
                    482: 
                    483:                return FAILED;
                    484:        }
                    485:        padding.ptr[padding.len - 1] = padding.len - 1;
                    486:        rng->destroy(rng);
                    487: 
                    488:        DBG3(DBG_ENC, "%s encryption:", label);
                    489:        DBG3(DBG_ENC, "IV %B", &iv);
                    490:        DBG3(DBG_ENC, "plain %B", &plain);
                    491:        DBG3(DBG_ENC, "padding %B", &padding);
                    492:        DBG3(DBG_ENC, "assoc %B", &assoc);
                    493: 
                    494:        if (!aead->encrypt(aead, crypt, assoc, iv, NULL))
                    495:        {
                    496:                return FAILED;
                    497:        }
                    498:        DBG3(DBG_ENC, "encrypted %B", &crypt);
                    499:        DBG3(DBG_ENC, "ICV %B", &icv);
                    500:        return SUCCESS;
                    501: }
                    502: 
                    503: METHOD(encrypted_payload_t, encrypt, status_t,
                    504:        private_encrypted_payload_t *this, uint64_t mid, chunk_t assoc)
                    505: {
                    506:        generator_t *generator;
                    507:        chunk_t plain;
                    508:        status_t status;
                    509: 
                    510:        if (this->aead == NULL)
                    511:        {
                    512:                DBG1(DBG_ENC, "encrypting encrypted payload failed, transform missing");
                    513:                return INVALID_STATE;
                    514:        }
                    515: 
                    516:        free(this->encrypted.ptr);
                    517:        generator = generator_create();
                    518:        plain = generate(this, generator);
                    519:        assoc = append_header(this, assoc);
                    520:        /* lower 32-bits are for fragment number, if used */
                    521:        mid <<= 32;
                    522:        status = encrypt_content("encrypted payload", this->aead, mid, plain, assoc,
                    523:                                                         &this->encrypted);
                    524:        generator->destroy(generator);
                    525:        free(assoc.ptr);
                    526:        return status;
                    527: }
                    528: 
                    529: METHOD(encrypted_payload_t, encrypt_v1, status_t,
                    530:        private_encrypted_payload_t *this, uint64_t mid, chunk_t iv)
                    531: {
                    532:        generator_t *generator;
                    533:        chunk_t plain, padding;
                    534:        size_t bs;
                    535: 
                    536:        if (this->aead == NULL)
                    537:        {
                    538:                DBG1(DBG_ENC, "encryption failed, transform missing");
                    539:                return INVALID_STATE;
                    540:        }
                    541: 
                    542:        generator = generator_create();
                    543:        plain = generate(this, generator);
                    544:        bs = this->aead->get_block_size(this->aead);
                    545:        padding.len = bs - (plain.len % bs);
                    546: 
                    547:        /* prepare data to encrypt:
                    548:         * | plain | padding | */
                    549:        free(this->encrypted.ptr);
                    550:        this->encrypted = chunk_alloc(plain.len + padding.len);
                    551:        memcpy(this->encrypted.ptr, plain.ptr, plain.len);
                    552:        plain.ptr = this->encrypted.ptr;
                    553:        padding.ptr = plain.ptr + plain.len;
                    554:        memset(padding.ptr, 0, padding.len);
                    555:        generator->destroy(generator);
                    556: 
                    557:        DBG3(DBG_ENC, "encrypting payloads:");
                    558:        DBG3(DBG_ENC, "IV %B", &iv);
                    559:        DBG3(DBG_ENC, "plain %B", &plain);
                    560:        DBG3(DBG_ENC, "padding %B", &padding);
                    561: 
                    562:        if (!this->aead->encrypt(this->aead, this->encrypted, chunk_empty, iv, NULL))
                    563:        {
                    564:                return FAILED;
                    565:        }
                    566: 
                    567:        DBG3(DBG_ENC, "encrypted %B", &this->encrypted);
                    568: 
                    569:        return SUCCESS;
                    570: }
                    571: 
                    572: /**
                    573:  * Parse the payloads after decryption.
                    574:  */
                    575: static status_t parse(private_encrypted_payload_t *this, chunk_t plain)
                    576: {
                    577:        parser_t *parser;
                    578:        payload_type_t type;
                    579: 
                    580:        parser = parser_create(plain);
                    581:        parser->set_major_version(parser, this->type == PLV1_ENCRYPTED ? 1 : 2);
                    582:        type = this->next_payload;
                    583:        while (type != PL_NONE)
                    584:        {
                    585:                payload_t *payload;
                    586: 
                    587:                if (plain.len < 4 || untoh16(plain.ptr + 2) > plain.len)
                    588:                {
                    589:                        DBG1(DBG_ENC, "invalid %N payload length, decryption failed?",
                    590:                                 payload_type_names, type);
                    591:                        parser->destroy(parser);
                    592:                        return PARSE_ERROR;
                    593:                }
                    594:                if (parser->parse_payload(parser, type, &payload) != SUCCESS)
                    595:                {
                    596:                        parser->destroy(parser);
                    597:                        return PARSE_ERROR;
                    598:                }
                    599:                if (payload->verify(payload) != SUCCESS)
                    600:                {
                    601:                        DBG1(DBG_ENC, "%N verification failed",
                    602:                                 payload_type_names, payload->get_type(payload));
                    603:                        payload->destroy(payload);
                    604:                        parser->destroy(parser);
                    605:                        return VERIFY_ERROR;
                    606:                }
                    607:                type = payload->get_next_type(payload);
                    608:                this->payloads->insert_last(this->payloads, payload);
                    609:        }
                    610:        parser->destroy(parser);
                    611:        DBG2(DBG_ENC, "parsed content of encrypted payload");
                    612:        return SUCCESS;
                    613: }
                    614: 
                    615: /**
                    616:  * Decrypts the given data in-place and returns a chunk pointing to the
                    617:  * resulting plaintext.
                    618:  */
                    619: static status_t decrypt_content(char *label, aead_t *aead, chunk_t encrypted,
                    620:                                                                chunk_t assoc, chunk_t *plain)
                    621: {
                    622:        chunk_t iv, padding, icv, crypt;
                    623:        size_t bs;
                    624: 
                    625:        /* prepare data to authenticate-decrypt:
                    626:         * | IV | plain | padding | ICV |
                    627:         *       \____crypt______/   ^
                    628:         *              |           /
                    629:         *              v          /
                    630:         *     assoc -> + ------->/
                    631:         */
                    632:        bs = aead->get_block_size(aead);
                    633:        iv.len = aead->get_iv_size(aead);
                    634:        iv.ptr = encrypted.ptr;
                    635:        icv.len = aead->get_icv_size(aead);
                    636:        icv.ptr = encrypted.ptr + encrypted.len - icv.len;
                    637:        crypt.ptr = iv.ptr + iv.len;
                    638:        crypt.len = encrypted.len - iv.len;
                    639: 
                    640:        if (iv.len + icv.len > encrypted.len ||
                    641:                (crypt.len - icv.len) % bs)
                    642:        {
                    643:                DBG1(DBG_ENC, "decrypting %s payload failed, invalid length", label);
                    644:                return FAILED;
                    645:        }
                    646: 
                    647:        DBG3(DBG_ENC, "%s decryption:", label);
                    648:        DBG3(DBG_ENC, "IV %B", &iv);
                    649:        DBG3(DBG_ENC, "encrypted %B", &crypt);
                    650:        DBG3(DBG_ENC, "ICV %B", &icv);
                    651:        DBG3(DBG_ENC, "assoc %B", &assoc);
                    652: 
                    653:        if (!aead->decrypt(aead, crypt, assoc, iv, NULL))
                    654:        {
                    655:                DBG1(DBG_ENC, "verifying %s integrity failed", label);
                    656:                return FAILED;
                    657:        }
                    658: 
                    659:        *plain = chunk_create(crypt.ptr, crypt.len - icv.len);
                    660:        padding.len = plain->ptr[plain->len - 1] + 1;
                    661:        if (padding.len > plain->len)
                    662:        {
                    663:                DBG1(DBG_ENC, "decrypting %s failed, padding invalid %B", label,
                    664:                         &crypt);
                    665:                return PARSE_ERROR;
                    666:        }
                    667:        plain->len -= padding.len;
                    668:        padding.ptr = plain->ptr + plain->len;
                    669: 
                    670:        DBG3(DBG_ENC, "plain %B", plain);
                    671:        DBG3(DBG_ENC, "padding %B", &padding);
                    672:        return SUCCESS;
                    673: }
                    674: 
                    675: METHOD(encrypted_payload_t, decrypt, status_t,
                    676:        private_encrypted_payload_t *this, chunk_t assoc)
                    677: {
                    678:        chunk_t plain;
                    679:        status_t status;
                    680: 
                    681:        if (this->aead == NULL)
                    682:        {
                    683:                DBG1(DBG_ENC, "decrypting encrypted payload failed, transform missing");
                    684:                return INVALID_STATE;
                    685:        }
                    686: 
                    687:        assoc = append_header(this, assoc);
                    688:        status = decrypt_content("encrypted payload", this->aead, this->encrypted,
                    689:                                                         assoc, &plain);
                    690:        free(assoc.ptr);
                    691: 
                    692:        if (status != SUCCESS)
                    693:        {
                    694:                return status;
                    695:        }
                    696:        return parse(this, plain);
                    697: }
                    698: 
                    699: METHOD(encrypted_payload_t, decrypt_plain, status_t,
                    700:        private_encrypted_payload_t *this, chunk_t assoc)
                    701: {
                    702:        if (!this->encrypted.ptr)
                    703:        {
                    704:                return FAILED;
                    705:        }
                    706:        return parse(this, this->encrypted);
                    707: }
                    708: 
                    709: METHOD(encrypted_payload_t, decrypt_v1, status_t,
                    710:        private_encrypted_payload_t *this, chunk_t iv)
                    711: {
                    712:        if (this->aead == NULL)
                    713:        {
                    714:                DBG1(DBG_ENC, "decryption failed, transform missing");
                    715:                return INVALID_STATE;
                    716:        }
                    717: 
                    718:        /* data must be a multiple of block size */
                    719:        if (iv.len != this->aead->get_block_size(this->aead) ||
                    720:                this->encrypted.len < iv.len || this->encrypted.len % iv.len)
                    721:        {
                    722:                DBG1(DBG_ENC, "decryption failed, invalid length");
                    723:                return FAILED;
                    724:        }
                    725: 
                    726:        DBG3(DBG_ENC, "decrypting payloads:");
                    727:        DBG3(DBG_ENC, "encrypted %B", &this->encrypted);
                    728: 
                    729:        if (!this->aead->decrypt(this->aead, this->encrypted, chunk_empty, iv, NULL))
                    730:        {
                    731:                return FAILED;
                    732:        }
                    733: 
                    734:        DBG3(DBG_ENC, "plain %B", &this->encrypted);
                    735: 
                    736:        return parse(this, this->encrypted);
                    737: }
                    738: 
                    739: METHOD(encrypted_payload_t, set_transform, void,
                    740:        private_encrypted_payload_t *this, aead_t* aead)
                    741: {
                    742:        this->aead = aead;
                    743: }
                    744: 
                    745: METHOD(encrypted_payload_t, get_transform, aead_t*,
                    746:        private_encrypted_payload_t *this)
                    747: {
                    748:        return this->aead;
                    749: }
                    750: 
                    751: METHOD2(payload_t, encrypted_payload_t, destroy, void,
                    752:        private_encrypted_payload_t *this)
                    753: {
                    754:        this->payloads->destroy_offset(this->payloads, offsetof(payload_t, destroy));
                    755:        free(this->encrypted.ptr);
                    756:        free(this);
                    757: }
                    758: 
                    759: /*
                    760:  * Described in header
                    761:  */
                    762: encrypted_payload_t *encrypted_payload_create(payload_type_t type)
                    763: {
                    764:        private_encrypted_payload_t *this;
                    765: 
                    766:        INIT(this,
                    767:                .public = {
                    768:                        .payload_interface = {
                    769:                                .verify = _verify,
                    770:                                .get_encoding_rules = _get_encoding_rules,
                    771:                                .get_header_length = _get_header_length,
                    772:                                .get_length = _get_length,
                    773:                                .get_next_type = _get_next_type,
                    774:                                .set_next_type = _set_next_type,
                    775:                                .get_type = _get_type,
                    776:                                .destroy = _destroy,
                    777:                        },
                    778:                        .get_length = _get_length,
                    779:                        .add_payload = _add_payload,
                    780:                        .remove_payload = _remove_payload,
                    781:                        .generate_payloads = _generate_payloads,
                    782:                        .set_transform = _set_transform,
                    783:                        .get_transform = _get_transform,
                    784:                        .encrypt = _encrypt,
                    785:                        .decrypt = _decrypt,
                    786:                        .destroy = _destroy,
                    787:                },
                    788:                .next_payload = PL_NONE,
                    789:                .payloads = linked_list_create(),
                    790:                .type = type,
                    791:        );
                    792:        this->payload_length = get_header_length(this);
                    793: 
                    794:        if (type == PLV1_ENCRYPTED)
                    795:        {
                    796:                this->public.encrypt = _encrypt_v1;
                    797:                this->public.decrypt = _decrypt_v1;
                    798:        }
                    799: 
                    800:        return &this->public;
                    801: }
                    802: 
                    803: /*
                    804:  * Described in header
                    805:  */
                    806: encrypted_payload_t *encrypted_payload_create_from_plain(payload_type_t next,
                    807:                                                                                                                 chunk_t plain)
                    808: {
                    809:        private_encrypted_payload_t *this;
                    810: 
                    811:        this = (private_encrypted_payload_t*)encrypted_payload_create(PLV2_ENCRYPTED);
                    812:        this->public.payload_interface.get_length = _get_length_plain;
                    813:        this->public.get_length = _get_length_plain;
                    814:        this->public.decrypt = _decrypt_plain;
                    815:        this->next_payload = next;
                    816:        this->encrypted = plain;
                    817: 
                    818:        return &this->public;
                    819: }
                    820: 
                    821: METHOD(payload_t, frag_verify, status_t,
                    822:        private_encrypted_fragment_payload_t *this)
                    823: {
                    824:        if (!this->fragment_number || !this->total_fragments ||
                    825:                this->fragment_number > this->total_fragments)
                    826:        {
                    827:                DBG1(DBG_ENC, "invalid fragment number (%u) or total fragments (%u)",
                    828:                         this->fragment_number, this->total_fragments);
                    829:                return FAILED;
                    830:        }
                    831:        if (this->fragment_number > 1 && this->next_payload != 0)
                    832:        {
                    833:                DBG1(DBG_ENC, "invalid next payload (%u) for fragment %u, ignored",
                    834:                         this->next_payload, this->fragment_number);
                    835:                this->next_payload = 0;
                    836:        }
                    837:        return SUCCESS;
                    838: }
                    839: 
                    840: METHOD(payload_t, frag_get_encoding_rules, int,
                    841:        private_encrypted_fragment_payload_t *this, encoding_rule_t **rules)
                    842: {
                    843:        *rules = encodings_fragment;
                    844:        return countof(encodings_fragment);
                    845: }
                    846: 
                    847: METHOD(payload_t, frag_get_header_length, int,
                    848:        private_encrypted_fragment_payload_t *this)
                    849: {
                    850:        return 8;
                    851: }
                    852: 
                    853: METHOD(payload_t, frag_get_type, payload_type_t,
                    854:        private_encrypted_fragment_payload_t *this)
                    855: {
                    856:        return PLV2_FRAGMENT;
                    857: }
                    858: 
                    859: METHOD(payload_t, frag_get_next_type, payload_type_t,
                    860:        private_encrypted_fragment_payload_t *this)
                    861: {
                    862:        return this->next_payload;
                    863: }
                    864: 
                    865: METHOD(payload_t, frag_set_next_type, void,
                    866:        private_encrypted_fragment_payload_t *this, payload_type_t type)
                    867: {
                    868:        if (this->fragment_number == 1 && this->next_payload == PL_NONE)
                    869:        {
                    870:                this->next_payload = type;
                    871:        }
                    872: }
                    873: 
                    874: METHOD2(payload_t, encrypted_payload_t, frag_get_length, size_t,
                    875:        private_encrypted_fragment_payload_t *this)
                    876: {
                    877:        if (this->encrypted.len)
                    878:        {
                    879:                this->payload_length = this->encrypted.len;
                    880:        }
                    881:        else
                    882:        {
                    883:                this->payload_length = this->plain.len;
                    884: 
                    885:                if (this->aead)
                    886:                {
                    887:                        this->payload_length += compute_overhead(this->aead,
                    888:                                                                                                         this->payload_length);
                    889:                }
                    890:        }
                    891:        this->payload_length += frag_get_header_length(this);
                    892:        return this->payload_length;
                    893: }
                    894: 
                    895: METHOD(encrypted_fragment_payload_t, get_fragment_number, uint16_t,
                    896:        private_encrypted_fragment_payload_t *this)
                    897: {
                    898:        return this->fragment_number;
                    899: }
                    900: 
                    901: METHOD(encrypted_fragment_payload_t, get_total_fragments, uint16_t,
                    902:        private_encrypted_fragment_payload_t *this)
                    903: {
                    904:        return this->total_fragments;
                    905: }
                    906: 
                    907: METHOD(encrypted_fragment_payload_t, frag_get_content, chunk_t,
                    908:        private_encrypted_fragment_payload_t *this)
                    909: {
                    910:        return this->plain;
                    911: }
                    912: 
                    913: METHOD(encrypted_payload_t, frag_add_payload, void,
                    914:        private_encrypted_fragment_payload_t *this, payload_t* payload)
                    915: {
                    916:        payload->destroy(payload);
                    917: }
                    918: 
                    919: METHOD(encrypted_payload_t, frag_set_transform, void,
                    920:        private_encrypted_fragment_payload_t *this, aead_t* aead)
                    921: {
                    922:        this->aead = aead;
                    923: }
                    924: 
                    925: METHOD(encrypted_payload_t, frag_get_transform, aead_t*,
                    926:        private_encrypted_fragment_payload_t *this)
                    927: {
                    928:        return this->aead;
                    929: }
                    930: 
                    931: /**
                    932:  * Append the encrypted fragment payload header to the associated data
                    933:  */
                    934: static chunk_t append_header_frag(private_encrypted_fragment_payload_t *this,
                    935:                                                                  chunk_t assoc)
                    936: {
                    937:        struct {
                    938:                uint8_t next_payload;
                    939:                uint8_t flags;
                    940:                uint16_t length;
                    941:                uint16_t fragment_number;
                    942:                uint16_t total_fragments;
                    943:        } __attribute__((packed)) header = {
                    944:                .next_payload = this->next_payload,
                    945:                .flags = this->flags,
                    946:                .length = htons(frag_get_length(this)),
                    947:                .fragment_number = htons(this->fragment_number),
                    948:                .total_fragments = htons(this->total_fragments),
                    949:        };
                    950:        return chunk_cat("cc", assoc, chunk_from_thing(header));
                    951: }
                    952: 
                    953: METHOD(encrypted_payload_t, frag_encrypt, status_t,
                    954:        private_encrypted_fragment_payload_t *this, uint64_t mid, chunk_t assoc)
                    955: {
                    956:        status_t status;
                    957: 
                    958:        if (!this->aead)
                    959:        {
                    960:                DBG1(DBG_ENC, "encrypting encrypted fragment payload failed, "
                    961:                         "transform missing");
                    962:                return INVALID_STATE;
                    963:        }
                    964:        free(this->encrypted.ptr);
                    965:        assoc = append_header_frag(this, assoc);
                    966:        /* IKEv2 message IDs are not unique if fragmentation is used, hence include
                    967:         * the fragment number to make it unique */
                    968:        mid = mid << 32 | this->fragment_number;
                    969:        status = encrypt_content("encrypted fragment payload", this->aead, mid,
                    970:                                                         this->plain, assoc, &this->encrypted);
                    971:        free(assoc.ptr);
                    972:        return status;
                    973: }
                    974: 
                    975: METHOD(encrypted_payload_t, frag_decrypt, status_t,
                    976:        private_encrypted_fragment_payload_t *this, chunk_t assoc)
                    977: {
                    978:        status_t status;
                    979: 
                    980:        if (!this->aead)
                    981:        {
                    982:                DBG1(DBG_ENC, "decrypting encrypted fragment payload failed, "
                    983:                         "transform missing");
                    984:                return INVALID_STATE;
                    985:        }
                    986:        free(this->plain.ptr);
                    987:        assoc = append_header_frag(this, assoc);
                    988:        status = decrypt_content("encrypted fragment payload", this->aead,
                    989:                                                         this->encrypted, assoc, &this->plain);
                    990:        this->plain = chunk_clone(this->plain);
                    991:        free(assoc.ptr);
                    992:        return status;
                    993: }
                    994: 
                    995: METHOD2(payload_t, encrypted_payload_t, frag_destroy, void,
                    996:        private_encrypted_fragment_payload_t *this)
                    997: {
                    998:        free(this->encrypted.ptr);
                    999:        free(this->plain.ptr);
                   1000:        free(this);
                   1001: }
                   1002: 
                   1003: /*
                   1004:  * Described in header
                   1005:  */
                   1006: encrypted_fragment_payload_t *encrypted_fragment_payload_create()
                   1007: {
                   1008:        private_encrypted_fragment_payload_t *this;
                   1009: 
                   1010:        INIT(this,
                   1011:                .public = {
                   1012:                        .encrypted = {
                   1013:                                .payload_interface = {
                   1014:                                        .verify = _frag_verify,
                   1015:                                        .get_encoding_rules = _frag_get_encoding_rules,
                   1016:                                        .get_header_length = _frag_get_header_length,
                   1017:                                        .get_length = _frag_get_length,
                   1018:                                        .get_next_type = _frag_get_next_type,
                   1019:                                        .set_next_type = _frag_set_next_type,
                   1020:                                        .get_type = _frag_get_type,
                   1021:                                        .destroy = _frag_destroy,
                   1022:                                },
                   1023:                                .get_length = _frag_get_length,
                   1024:                                .add_payload = _frag_add_payload,
                   1025:                                .remove_payload = (void*)return_null,
                   1026:                                .generate_payloads = nop,
                   1027:                                .set_transform = _frag_set_transform,
                   1028:                                .get_transform = _frag_get_transform,
                   1029:                                .encrypt = _frag_encrypt,
                   1030:                                .decrypt = _frag_decrypt,
                   1031:                                .destroy = _frag_destroy,
                   1032:                        },
                   1033:                        .get_fragment_number = _get_fragment_number,
                   1034:                        .get_total_fragments = _get_total_fragments,
                   1035:                        .get_content = _frag_get_content,
                   1036:                },
                   1037:                .next_payload = PL_NONE,
                   1038:        );
                   1039:        this->payload_length = frag_get_header_length(this);
                   1040: 
                   1041:        return &this->public;
                   1042: }
                   1043: 
                   1044: /*
                   1045:  * Described in header
                   1046:  */
                   1047: encrypted_fragment_payload_t *encrypted_fragment_payload_create_from_data(
                   1048:                                                                uint16_t num, uint16_t total, chunk_t plain)
                   1049: {
                   1050:        private_encrypted_fragment_payload_t *this;
                   1051: 
                   1052:        this = (private_encrypted_fragment_payload_t*)encrypted_fragment_payload_create();
                   1053:        this->fragment_number = num;
                   1054:        this->total_fragments = total;
                   1055:        this->plain = chunk_clone(plain);
                   1056: 
                   1057:        return &this->public;
                   1058: }

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