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

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: 
1.1.1.2 ! misho      81: /**
        !            82:  * Resets the state with the given key, or only resets the internal state
        !            83:  * if key is chunk_empty.
        !            84:  */
        !            85: static bool reset(private_mac_t *this, chunk_t key)
1.1       misho      86: {
                     87: #if OPENSSL_VERSION_NUMBER >= 0x10000000L
                     88:        if (HMAC_Init_ex(this->hmac, key.ptr, key.len, this->hasher, NULL))
                     89:        {
                     90:                return TRUE;
                     91:        }
                     92:        return FALSE;
                     93: #else /* OPENSSL_VERSION_NUMBER < 1.0 */
                     94:        HMAC_Init_ex(this->hmac, key.ptr, key.len, this->hasher, NULL);
                     95:        return TRUE;
                     96: #endif
                     97: }
                     98: 
1.1.1.2 ! misho      99: METHOD(mac_t, set_key, bool,
        !           100:        private_mac_t *this, chunk_t key)
        !           101: {
        !           102:        if (!key.ptr)
        !           103:        {       /* HMAC_Init_ex() won't reset the key if a NULL pointer is passed */
        !           104:                key = chunk_from_str("");
        !           105:        }
        !           106:        return reset(this, key);
        !           107: }
        !           108: 
1.1       misho     109: METHOD(mac_t, get_mac, bool,
                    110:        private_mac_t *this, chunk_t data, uint8_t *out)
                    111: {
                    112: #if OPENSSL_VERSION_NUMBER >= 0x10000000L
                    113:        if (!HMAC_Update(this->hmac, data.ptr, data.len))
                    114:        {
                    115:                return FALSE;
                    116:        }
                    117:        if (out == NULL)
                    118:        {
                    119:                return TRUE;
                    120:        }
                    121:        if (!HMAC_Final(this->hmac, out, NULL))
                    122:        {
                    123:                return FALSE;
                    124:        }
                    125: #else /* OPENSSL_VERSION_NUMBER < 1.0 */
                    126:        HMAC_Update(this->hmac, data.ptr, data.len);
                    127:        if (out == NULL)
                    128:        {
                    129:                return TRUE;
                    130:        }
                    131:        HMAC_Final(this->hmac, out, NULL);
                    132: #endif
1.1.1.2 ! misho     133:        return reset(this, chunk_empty);
1.1       misho     134: }
                    135: 
                    136: METHOD(mac_t, get_mac_size, size_t,
                    137:        private_mac_t *this)
                    138: {
                    139:        return EVP_MD_size(this->hasher);
                    140: }
                    141: 
                    142: METHOD(mac_t, destroy, void,
                    143:        private_mac_t *this)
                    144: {
                    145: #if OPENSSL_VERSION_NUMBER >= 0x10100000L
                    146:        HMAC_CTX_free(this->hmac);
                    147: #else
                    148:        HMAC_CTX_cleanup(&this->hmac_ctx);
                    149: #endif
                    150:        free(this);
                    151: }
                    152: 
                    153: /*
                    154:  * Create an OpenSSL-backed implementation of the mac_t interface
                    155:  */
                    156: static mac_t *hmac_create(hash_algorithm_t algo)
                    157: {
                    158:        private_mac_t *this;
                    159:        char *name;
                    160: 
                    161:        name = enum_to_name(hash_algorithm_short_names, algo);
                    162:        if (!name)
                    163:        {
                    164:                return NULL;
                    165:        }
                    166: 
                    167:        INIT(this,
                    168:                .public = {
                    169:                        .get_mac = _get_mac,
                    170:                        .get_mac_size = _get_mac_size,
                    171:                        .set_key = _set_key,
                    172:                        .destroy = _destroy,
                    173:                },
                    174:                .hasher = EVP_get_digestbyname(name),
                    175:        );
                    176: 
                    177:        if (!this->hasher)
                    178:        {
                    179:                free(this);
                    180:                return NULL;
                    181:        }
                    182: 
                    183: #if OPENSSL_VERSION_NUMBER >= 0x10100000L
                    184:        this->hmac = HMAC_CTX_new();
                    185: #else
                    186:        HMAC_CTX_init(&this->hmac_ctx);
                    187:        this->hmac = &this->hmac_ctx;
                    188: #endif
                    189: 
                    190:        /* make sure the underlying hash algorithm is supported */
                    191:        if (!set_key(this, chunk_from_str("")))
                    192:        {
                    193:                destroy(this);
                    194:                return NULL;
                    195:        }
                    196:        return &this->public;
                    197: }
                    198: 
                    199: /*
                    200:  * Described in header
                    201:  */
                    202: prf_t *openssl_hmac_prf_create(pseudo_random_function_t algo)
                    203: {
                    204:        mac_t *hmac;
                    205: 
                    206:        hmac = hmac_create(hasher_algorithm_from_prf(algo));
                    207:        if (hmac)
                    208:        {
                    209:                return mac_prf_create(hmac);
                    210:        }
                    211:        return NULL;
                    212: }
                    213: 
                    214: /*
                    215:  * Described in header
                    216:  */
                    217: signer_t *openssl_hmac_signer_create(integrity_algorithm_t algo)
                    218: {
                    219:        mac_t *hmac;
                    220:        size_t trunc;
                    221: 
                    222:        hmac = hmac_create(hasher_algorithm_from_integrity(algo, &trunc));
                    223:        if (hmac)
                    224:        {
                    225:                return mac_signer_create(hmac, trunc);
                    226:        }
                    227:        return NULL;
                    228: }
                    229: 
                    230: #endif /* OPENSSL_NO_HMAC */

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