Use simple wrappers for HMAC based PRF and signer in openssl plugin
[strongswan.git] / src / libstrongswan / plugins / openssl / openssl_hmac.c
1 /*
2 * Copyright (C) 2012 Tobias Brunner
3 * 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/evp.h>
39 #include <openssl/hmac.h>
40
41 #include "openssl_hmac.h"
42
43 #include <crypto/hmacs/hmac.h>
44 #include <crypto/hmacs/hmac_prf.h>
45 #include <crypto/hmacs/hmac_signer.h>
46
47 typedef struct private_hmac_t private_hmac_t;
48
49 /**
50 * Private data of a hmac_t object.
51 */
52 struct private_hmac_t {
53
54 /**
55 * Public interface
56 */
57 hmac_t public;
58
59 /**
60 * Hasher to use
61 */
62 const EVP_MD *hasher;
63
64 /**
65 * Current HMAC context
66 */
67 HMAC_CTX hmac;
68
69 /**
70 * Key
71 */
72 chunk_t key;
73 };
74
75 /**
76 * Resets HMAC context
77 */
78 static void reset(private_hmac_t *this)
79 {
80 HMAC_Init_ex(&this->hmac, this->key.ptr, this->key.len, this->hasher, NULL);
81 }
82
83 METHOD(hmac_t, get_mac, void,
84 private_hmac_t *this, chunk_t data, u_int8_t *out)
85 {
86 if (out == NULL)
87 {
88 HMAC_Update(&this->hmac, data.ptr, data.len);
89 }
90 else
91 {
92 HMAC_Update(&this->hmac, data.ptr, data.len);
93 HMAC_Final(&this->hmac, out, NULL);
94 reset(this);
95 }
96 }
97
98 METHOD(hmac_t, get_mac_size, size_t,
99 private_hmac_t *this)
100 {
101 return EVP_MD_size(this->hasher);
102 }
103
104 METHOD(hmac_t, set_key, void,
105 private_hmac_t *this, chunk_t key)
106 {
107 chunk_clear(&this->key);
108 this->key = chunk_clone(key);
109 reset(this);
110 }
111
112 METHOD(hmac_t, destroy, void,
113 private_hmac_t *this)
114 {
115 HMAC_CTX_cleanup(&this->hmac);
116 chunk_clear(&this->key);
117 free(this);
118 }
119
120 /*
121 * Create an OpenSSL-backed implementation of the hmac_t interface
122 */
123 static hmac_t *hmac_create(hash_algorithm_t algo)
124 {
125 private_hmac_t *this;
126
127 INIT(this,
128 .public = {
129 .get_mac = _get_mac,
130 .get_mac_size = _get_mac_size,
131 .set_key = _set_key,
132 .destroy = _destroy,
133 },
134 );
135
136 switch (algo)
137 {
138 case HASH_MD5:
139 this->hasher = EVP_get_digestbyname("md5");
140 break;
141 case HASH_SHA1:
142 this->hasher = EVP_get_digestbyname("sha1");
143 break;
144 case HASH_SHA256:
145 this->hasher = EVP_get_digestbyname("sha256");
146 break;
147 case HASH_SHA384:
148 this->hasher = EVP_get_digestbyname("sha384");
149 break;
150 case HASH_SHA512:
151 this->hasher = EVP_get_digestbyname("sha512");
152 break;
153 default:
154 break;
155 }
156
157 if (!this->hasher)
158 {
159 free(this);
160 return NULL;
161 }
162
163 HMAC_CTX_init(&this->hmac);
164
165 return &this->public;
166 }
167
168 /*
169 * Described in header
170 */
171 prf_t *openssl_hmac_prf_create(pseudo_random_function_t algo)
172 {
173 hmac_t *hmac = NULL;
174
175 switch (algo)
176 {
177 case PRF_HMAC_SHA1:
178 hmac = hmac_create(HASH_SHA1);
179 break;
180 case PRF_HMAC_MD5:
181 hmac = hmac_create(HASH_MD5);
182 break;
183 case PRF_HMAC_SHA2_256:
184 hmac = hmac_create(HASH_SHA256);
185 break;
186 case PRF_HMAC_SHA2_384:
187 hmac = hmac_create(HASH_SHA384);
188 break;
189 case PRF_HMAC_SHA2_512:
190 hmac = hmac_create(HASH_SHA512);
191 break;
192 default:
193 break;
194 }
195 if (hmac)
196 {
197 return hmac_prf_create(hmac);
198 }
199 return NULL;
200 }
201
202 /*
203 * Described in header
204 */
205 signer_t *openssl_hmac_signer_create(integrity_algorithm_t algo)
206 {
207 hmac_t *hmac = NULL;
208 size_t trunc = 0;
209
210 switch (algo)
211 {
212 case AUTH_HMAC_MD5_96:
213 hmac = hmac_create(HASH_MD5);
214 trunc = 12;
215 break;
216 case AUTH_HMAC_MD5_128:
217 hmac = hmac_create(HASH_MD5);
218 trunc = 16;
219 break;
220 case AUTH_HMAC_SHA1_96:
221 hmac = hmac_create(HASH_SHA1);
222 trunc = 12;
223 break;
224 case AUTH_HMAC_SHA1_128:
225 hmac = hmac_create(HASH_SHA1);
226 trunc = 16;
227 break;
228 case AUTH_HMAC_SHA1_160:
229 hmac = hmac_create(HASH_SHA1);
230 trunc = 20;
231 break;
232 case AUTH_HMAC_SHA2_256_128:
233 hmac = hmac_create(HASH_SHA256);
234 trunc = 16;
235 break;
236 case AUTH_HMAC_SHA2_256_256:
237 hmac = hmac_create(HASH_SHA256);
238 trunc = 32;
239 break;
240 case AUTH_HMAC_SHA2_384_192:
241 hmac = hmac_create(HASH_SHA384);
242 trunc = 24;
243 break;
244 case AUTH_HMAC_SHA2_384_384:
245 hmac = hmac_create(HASH_SHA384);
246 trunc = 48;
247 break;
248 case AUTH_HMAC_SHA2_512_256:
249 hmac = hmac_create(HASH_SHA512);
250 trunc = 32;
251 break;
252 default:
253 break;
254 }
255 if (hmac)
256 {
257 return hmac_signer_create(hmac, trunc);
258 }
259 return NULL;
260 }
261
262