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>