]> git.ipfire.org Git - people/ms/strongswan.git/blame - src/libstrongswan/plugins/openssl/openssl_hmac.c
Fixed some typos, courtesy of codespell
[people/ms/strongswan.git] / src / libstrongswan / plugins / openssl / openssl_hmac.c
CommitLineData
8391c1d0
TB
1/*
2 * Copyright (C) 2012 Tobias Brunner
1b671669 3 * HSR Hochschule fuer Technik Rapperswil
8391c1d0
TB
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
a3a190b7
TB
38#include <openssl/opensslconf.h>
39
40#ifndef OPENSSL_NO_HMAC
41
8391c1d0
TB
42#include <openssl/evp.h>
43#include <openssl/hmac.h>
44
45#include "openssl_hmac.h"
46
c4a3c967
TB
47#include <crypto/mac.h>
48#include <crypto/prfs/mac_prf.h>
49#include <crypto/signers/mac_signer.h>
73d032e4 50
c4a3c967 51typedef struct private_mac_t private_mac_t;
8391c1d0
TB
52
53/**
c4a3c967 54 * Private data of a mac_t object.
8391c1d0 55 */
c4a3c967 56struct private_mac_t {
8391c1d0
TB
57
58 /**
59 * Public interface
60 */
c4a3c967 61 mac_t public;
8391c1d0
TB
62
63 /**
64 * Hasher to use
65 */
66 const EVP_MD *hasher;
67
68 /**
69 * Current HMAC context
70 */
97b1a27f
TB
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
8391c1d0
TB
79};
80
6a440f83
TB
81/**
82 * Resets the state with the given key, or only resets the internal state
83 * if key is chunk_empty.
84 */
85static bool reset(private_mac_t *this, chunk_t key)
8391c1d0 86{
082b0d72 87#if OPENSSL_VERSION_NUMBER >= 0x10000000L
97b1a27f 88 if (HMAC_Init_ex(this->hmac, key.ptr, key.len, this->hasher, NULL))
c2906c8f 89 {
c2906c8f
MW
90 return TRUE;
91 }
92 return FALSE;
082b0d72 93#else /* OPENSSL_VERSION_NUMBER < 1.0 */
97b1a27f 94 HMAC_Init_ex(this->hmac, key.ptr, key.len, this->hasher, NULL);
082b0d72
MW
95 return TRUE;
96#endif
8391c1d0
TB
97}
98
6a440f83
TB
99METHOD(mac_t, set_key, bool,
100 private_mac_t *this, chunk_t key)
101{
102 if (!key.ptr)
64b28172 103 { /* HMAC_Init_ex() won't reset the key if a NULL pointer is passed,
627eaa22 104 * use a lengthy string in case there is a limit in FIPS-mode */
64b28172 105 key = chunk_from_str("00000000000000000000000000000000");
6a440f83
TB
106 }
107 return reset(this, key);
108}
109
27e1eabb 110METHOD(mac_t, get_mac, bool,
b12c53ce 111 private_mac_t *this, chunk_t data, uint8_t *out)
8391c1d0 112{
082b0d72 113#if OPENSSL_VERSION_NUMBER >= 0x10000000L
97b1a27f 114 if (!HMAC_Update(this->hmac, data.ptr, data.len))
082b0d72
MW
115 {
116 return FALSE;
117 }
8391c1d0
TB
118 if (out == NULL)
119 {
082b0d72 120 return TRUE;
8391c1d0 121 }
97b1a27f 122 if (!HMAC_Final(this->hmac, out, NULL))
082b0d72
MW
123 {
124 return FALSE;
125 }
126#else /* OPENSSL_VERSION_NUMBER < 1.0 */
97b1a27f 127 HMAC_Update(this->hmac, data.ptr, data.len);
082b0d72
MW
128 if (out == NULL)
129 {
130 return TRUE;
131 }
97b1a27f 132 HMAC_Final(this->hmac, out, NULL);
082b0d72 133#endif
6a440f83 134 return reset(this, chunk_empty);
8391c1d0
TB
135}
136
c4a3c967
TB
137METHOD(mac_t, get_mac_size, size_t,
138 private_mac_t *this)
8391c1d0
TB
139{
140 return EVP_MD_size(this->hasher);
141}
142
c4a3c967
TB
143METHOD(mac_t, destroy, void,
144 private_mac_t *this)
8391c1d0 145{
97b1a27f
TB
146#if OPENSSL_VERSION_NUMBER >= 0x10100000L
147 HMAC_CTX_free(this->hmac);
148#else
149 HMAC_CTX_cleanup(&this->hmac_ctx);
150#endif
8391c1d0
TB
151 free(this);
152}
153
154/*
c4a3c967 155 * Create an OpenSSL-backed implementation of the mac_t interface
8391c1d0 156 */
c4a3c967 157static mac_t *hmac_create(hash_algorithm_t algo)
8391c1d0 158{
c4a3c967 159 private_mac_t *this;
610f90a8
MW
160 char *name;
161
162 name = enum_to_name(hash_algorithm_short_names, algo);
163 if (!name)
164 {
165 return NULL;
166 }
8391c1d0
TB
167
168 INIT(this,
169 .public = {
170 .get_mac = _get_mac,
73d032e4 171 .get_mac_size = _get_mac_size,
8391c1d0
TB
172 .set_key = _set_key,
173 .destroy = _destroy,
174 },
610f90a8 175 .hasher = EVP_get_digestbyname(name),
8391c1d0
TB
176 );
177
8391c1d0
TB
178 if (!this->hasher)
179 {
180 free(this);
181 return NULL;
182 }
183
97b1a27f
TB
184#if OPENSSL_VERSION_NUMBER >= 0x10100000L
185 this->hmac = HMAC_CTX_new();
186#else
187 HMAC_CTX_init(&this->hmac_ctx);
188 this->hmac = &this->hmac_ctx;
189#endif
8391c1d0 190
6b347d52 191 /* make sure the underlying hash algorithm is supported */
64b28172 192 if (!set_key(this, chunk_empty))
6b347d52
TB
193 {
194 destroy(this);
195 return NULL;
196 }
8391c1d0
TB
197 return &this->public;
198}
73d032e4
TB
199
200/*
201 * Described in header
202 */
203prf_t *openssl_hmac_prf_create(pseudo_random_function_t algo)
204{
c4a3c967 205 mac_t *hmac;
73d032e4 206
228d096e 207 hmac = hmac_create(hasher_algorithm_from_prf(algo));
73d032e4
TB
208 if (hmac)
209 {
c4a3c967 210 return mac_prf_create(hmac);
73d032e4
TB
211 }
212 return NULL;
213}
214
215/*
216 * Described in header
217 */
218signer_t *openssl_hmac_signer_create(integrity_algorithm_t algo)
219{
c4a3c967 220 mac_t *hmac;
228d096e 221 size_t trunc;
73d032e4 222
228d096e 223 hmac = hmac_create(hasher_algorithm_from_integrity(algo, &trunc));
73d032e4
TB
224 if (hmac)
225 {
c4a3c967 226 return mac_signer_create(hmac, trunc);
73d032e4
TB
227 }
228 return NULL;
229}
230
a3a190b7 231#endif /* OPENSSL_NO_HMAC */