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

1.1       misho       1: /*
                      2:  * Copyright (C) 2012 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: /*
                     17:  * Copyright (C) 2012 Aleksandr Grinberg
                     18:  *
                     19:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                     20:  * of this software and associated documentation files (the "Software"), to deal
                     21:  * in the Software without restriction, including without limitation the rights
                     22:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     23:  * copies of the Software, and to permit persons to whom the Software is
                     24:  * furnished to do so, subject to the following conditions:
                     25:  *
                     26:  * The above copyright notice and this permission notice shall be included in
                     27:  * all copies or substantial portions of the Software.
                     28:  *
                     29:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     30:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     31:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
                     32:  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     33:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     34:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     35:  * THE SOFTWARE.
                     36:  */
                     37: 
                     38: #include <openssl/opensslconf.h>
                     39: 
                     40: #ifndef OPENSSL_NO_HMAC
                     41: 
                     42: #include <openssl/evp.h>
                     43: #include <openssl/hmac.h>
                     44: 
                     45: #include "openssl_hmac.h"
                     46: 
                     47: #include <crypto/mac.h>
                     48: #include <crypto/prfs/mac_prf.h>
                     49: #include <crypto/signers/mac_signer.h>
                     50: 
                     51: typedef struct private_mac_t private_mac_t;
                     52: 
                     53: /**
                     54:  * Private data of a mac_t object.
                     55:  */
                     56: struct private_mac_t {
                     57: 
                     58:        /**
                     59:         * Public interface
                     60:         */
                     61:        mac_t public;
                     62: 
                     63:        /**
                     64:         * Hasher to use
                     65:         */
                     66:        const EVP_MD *hasher;
                     67: 
                     68:        /**
                     69:         * Current HMAC context
                     70:         */
                     71:        HMAC_CTX *hmac;
                     72: 
                     73: #if OPENSSL_VERSION_NUMBER < 0x10100000L
                     74:        /**
                     75:         * Static context for OpenSSL < 1.1.0
                     76:         */
                     77:        HMAC_CTX hmac_ctx;
                     78: #endif
                     79: 
                     80:        /**
                     81:         * Key set on HMAC_CTX?
                     82:         */
                     83:        bool key_set;
                     84: };
                     85: 
                     86: METHOD(mac_t, set_key, bool,
                     87:        private_mac_t *this, chunk_t key)
                     88: {
                     89: #if OPENSSL_VERSION_NUMBER >= 0x10000000L
                     90:        if (HMAC_Init_ex(this->hmac, key.ptr, key.len, this->hasher, NULL))
                     91:        {
                     92:                this->key_set = TRUE;
                     93:                return TRUE;
                     94:        }
                     95:        return FALSE;
                     96: #else /* OPENSSL_VERSION_NUMBER < 1.0 */
                     97:        HMAC_Init_ex(this->hmac, key.ptr, key.len, this->hasher, NULL);
                     98:        this->key_set = TRUE;
                     99:        return TRUE;
                    100: #endif
                    101: }
                    102: 
                    103: METHOD(mac_t, get_mac, bool,
                    104:        private_mac_t *this, chunk_t data, uint8_t *out)
                    105: {
                    106:        if (!this->key_set)
                    107:        {
                    108:                return FALSE;
                    109:        }
                    110: #if OPENSSL_VERSION_NUMBER >= 0x10000000L
                    111:        if (!HMAC_Update(this->hmac, data.ptr, data.len))
                    112:        {
                    113:                return FALSE;
                    114:        }
                    115:        if (out == NULL)
                    116:        {
                    117:                return TRUE;
                    118:        }
                    119:        if (!HMAC_Final(this->hmac, out, NULL))
                    120:        {
                    121:                return FALSE;
                    122:        }
                    123: #else /* OPENSSL_VERSION_NUMBER < 1.0 */
                    124:        HMAC_Update(this->hmac, data.ptr, data.len);
                    125:        if (out == NULL)
                    126:        {
                    127:                return TRUE;
                    128:        }
                    129:        HMAC_Final(this->hmac, out, NULL);
                    130: #endif
                    131:        return set_key(this, chunk_empty);
                    132: }
                    133: 
                    134: METHOD(mac_t, get_mac_size, size_t,
                    135:        private_mac_t *this)
                    136: {
                    137:        return EVP_MD_size(this->hasher);
                    138: }
                    139: 
                    140: METHOD(mac_t, destroy, void,
                    141:        private_mac_t *this)
                    142: {
                    143: #if OPENSSL_VERSION_NUMBER >= 0x10100000L
                    144:        HMAC_CTX_free(this->hmac);
                    145: #else
                    146:        HMAC_CTX_cleanup(&this->hmac_ctx);
                    147: #endif
                    148:        free(this);
                    149: }
                    150: 
                    151: /*
                    152:  * Create an OpenSSL-backed implementation of the mac_t interface
                    153:  */
                    154: static mac_t *hmac_create(hash_algorithm_t algo)
                    155: {
                    156:        private_mac_t *this;
                    157:        char *name;
                    158: 
                    159:        name = enum_to_name(hash_algorithm_short_names, algo);
                    160:        if (!name)
                    161:        {
                    162:                return NULL;
                    163:        }
                    164: 
                    165:        INIT(this,
                    166:                .public = {
                    167:                        .get_mac = _get_mac,
                    168:                        .get_mac_size = _get_mac_size,
                    169:                        .set_key = _set_key,
                    170:                        .destroy = _destroy,
                    171:                },
                    172:                .hasher = EVP_get_digestbyname(name),
                    173:        );
                    174: 
                    175:        if (!this->hasher)
                    176:        {
                    177:                free(this);
                    178:                return NULL;
                    179:        }
                    180: 
                    181: #if OPENSSL_VERSION_NUMBER >= 0x10100000L
                    182:        this->hmac = HMAC_CTX_new();
                    183: #else
                    184:        HMAC_CTX_init(&this->hmac_ctx);
                    185:        this->hmac = &this->hmac_ctx;
                    186: #endif
                    187: 
                    188:        /* make sure the underlying hash algorithm is supported */
                    189:        if (!set_key(this, chunk_from_str("")))
                    190:        {
                    191:                destroy(this);
                    192:                return NULL;
                    193:        }
                    194:        return &this->public;
                    195: }
                    196: 
                    197: /*
                    198:  * Described in header
                    199:  */
                    200: prf_t *openssl_hmac_prf_create(pseudo_random_function_t algo)
                    201: {
                    202:        mac_t *hmac;
                    203: 
                    204:        hmac = hmac_create(hasher_algorithm_from_prf(algo));
                    205:        if (hmac)
                    206:        {
                    207:                return mac_prf_create(hmac);
                    208:        }
                    209:        return NULL;
                    210: }
                    211: 
                    212: /*
                    213:  * Described in header
                    214:  */
                    215: signer_t *openssl_hmac_signer_create(integrity_algorithm_t algo)
                    216: {
                    217:        mac_t *hmac;
                    218:        size_t trunc;
                    219: 
                    220:        hmac = hmac_create(hasher_algorithm_from_integrity(algo, &trunc));
                    221:        if (hmac)
                    222:        {
                    223:                return mac_signer_create(hmac, trunc);
                    224:        }
                    225:        return NULL;
                    226: }
                    227: 
                    228: #endif /* OPENSSL_NO_HMAC */

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