Annotation of embedaddon/strongswan/src/libstrongswan/plugins/openssl/openssl_xof.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2020 Tobias Brunner
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      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 <openssl/evp.h>
                     17: 
                     18: /* SHA3 was added with 1.1.1 */
                     19: #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_SHAKE)
                     20: 
                     21: #include "openssl_xof.h"
                     22: 
                     23: #define KECCAK_STATE_SIZE 200 /* 1600 bits*/
                     24: 
                     25: typedef struct private_xof_t private_xof_t;
                     26: 
                     27: /**
                     28:  * Private data
                     29:  */
                     30: struct private_xof_t {
                     31: 
                     32:        /**
                     33:         * Public interface.
                     34:         */
                     35:        xof_t public;
                     36: 
                     37:        /**
                     38:         * XOF algorithm to be used
                     39:         */
                     40:        ext_out_function_t algorithm;
                     41: 
                     42:        /**
                     43:         * Internal type reference
                     44:         */
                     45:        const EVP_MD *md;
                     46: 
                     47:        /**
                     48:         * Internal context
                     49:         */
                     50:        EVP_MD_CTX *ctx;
                     51: 
                     52:        /**
                     53:         * Current seed
                     54:         */
                     55:        chunk_t seed;
                     56: 
                     57:        /**
                     58:         * Offset into generated data
                     59:         */
                     60:        size_t offset;
                     61: };
                     62: 
                     63: METHOD(xof_t, get_type, ext_out_function_t,
                     64:        private_xof_t *this)
                     65: {
                     66:        return this->algorithm;
                     67: }
                     68: 
                     69: METHOD(xof_t, get_bytes, bool,
                     70:        private_xof_t *this, size_t out_len, uint8_t *buffer)
                     71: {
                     72:        bool success = FALSE;
                     73:        chunk_t data;
                     74: 
                     75:        /* we can call EVP_DigestFinalXOF() only once, so to support an arbitrary
                     76:         * number of calls to get_bytes(), we request all the data we already
                     77:         * requested previously and just ignore what we already handed out */
                     78:        if (EVP_DigestInit_ex(this->ctx, this->md, NULL) == 1 &&
                     79:                EVP_DigestUpdate(this->ctx, this->seed.ptr, this->seed.len) == 1)
                     80:        {
                     81:                data = chunk_alloc(out_len + this->offset);
                     82:                if (EVP_DigestFinalXOF(this->ctx, data.ptr, data.len) == 1)
                     83:                {
                     84:                        memcpy(buffer, data.ptr + this->offset, out_len);
                     85:                        this->offset += out_len;
                     86:                        success = TRUE;
                     87:                }
                     88:                chunk_clear(&data);
                     89:        }
                     90:        return success;
                     91: }
                     92: 
                     93: METHOD(xof_t, allocate_bytes, bool,
                     94:        private_xof_t *this, size_t out_len, chunk_t *chunk)
                     95: {
                     96:        *chunk = chunk_alloc(out_len);
                     97:        return get_bytes(this, out_len, chunk->ptr);
                     98: }
                     99: 
                    100: METHOD(xof_t, get_block_size, size_t,
                    101:        private_xof_t *this)
                    102: {
                    103:        return EVP_MD_block_size(this->md);
                    104: }
                    105: 
                    106: METHOD(xof_t, get_seed_size, size_t,
                    107:        private_xof_t *this)
                    108: {
                    109:        return KECCAK_STATE_SIZE - EVP_MD_block_size(this->md);
                    110: }
                    111: 
                    112: METHOD(xof_t, set_seed, bool,
                    113:        private_xof_t *this, chunk_t seed)
                    114: {
                    115:        chunk_clear(&this->seed);
                    116:        this->seed = chunk_clone(seed);
                    117:        this->offset = 0;
                    118:        return TRUE;
                    119: }
                    120: 
                    121: METHOD(xof_t, destroy, void,
                    122:        private_xof_t *this)
                    123: {
                    124:        EVP_MD_CTX_free(this->ctx);
                    125:        chunk_clear(&this->seed);
                    126:        free(this);
                    127: }
                    128: 
                    129: /*
                    130:  * Described in header
                    131:  */
                    132: xof_t *openssl_xof_create(ext_out_function_t algorithm)
                    133: {
                    134:        private_xof_t *this;
                    135:        const EVP_MD *md;
                    136: 
                    137:        switch (algorithm)
                    138:        {
                    139:                case XOF_SHAKE_128:
                    140:                        md = EVP_shake128();
                    141:                        break;
                    142:                case XOF_SHAKE_256:
                    143:                        md = EVP_shake256();
                    144:                        break;
                    145:                default:
                    146:                        return NULL;
                    147:        }
                    148: 
                    149:        INIT(this,
                    150:                .public = {
                    151:                        .get_type = _get_type,
                    152:                        .get_bytes = _get_bytes,
                    153:                        .allocate_bytes = _allocate_bytes,
                    154:                        .get_block_size = _get_block_size,
                    155:                        .get_seed_size = _get_seed_size,
                    156:                        .set_seed = _set_seed,
                    157:                        .destroy = _destroy,
                    158:                },
                    159:                .algorithm = algorithm,
                    160:                .md = md,
                    161:                .ctx = EVP_MD_CTX_new(),
                    162:        );
                    163:        return &this->public;
                    164: }
                    165: 
                    166: #endif /* OPENSSL_NO_ECDH */

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