Return to openssl_hmac.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / openssl |
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 */