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>