4
* MontaVista RMCP+ code for doing HMAC, both SHA1 and MD5
6
* Author: MontaVista Software, Inc.
7
* Corey Minyard <minyard@mvista.com>
10
* Copyright 2004 MontaVista Software Inc.
12
* This program is free software; you can redistribute it and/or
13
* modify it under the terms of the GNU Lesser General Public License
14
* as published by the Free Software Foundation; either version 2 of
15
* the License, or (at your option) any later version.
18
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
26
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
27
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
* You should have received a copy of the GNU Lesser General Public
30
* License along with this program; if not, write to the Free
31
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
38
#include <openssl/hmac.h>
39
#include <OpenIPMI/ipmi_lan.h>
40
#include <OpenIPMI/internal/ipmi_malloc.h>
42
typedef struct hmac_info_s
51
hmac_sha1_init(ipmi_con_t *ipmi,
52
ipmi_rmcpp_auth_t *ainfo,
56
static unsigned char *k;
59
info = ipmi_mem_alloc(sizeof(*info));
63
if (ipmi_rmcpp_auth_get_sik_len(ainfo) < 20)
66
if (ipmi->hacks & IPMI_CONN_HACK_RMCPP_INTEG_SIK)
67
k = ipmi_rmcpp_auth_get_sik(ainfo, &klen);
69
k = ipmi_rmcpp_auth_get_k1(ainfo, &klen);
73
memcpy(info->k, k, 20);
77
info->evp_md = EVP_sha1();
83
hmac_md5_init(ipmi_con_t *ipmi,
84
ipmi_rmcpp_auth_t *ainfo,
88
const unsigned char *k;
91
info = ipmi_mem_alloc(sizeof(*info));
95
k = ipmi_rmcpp_auth_get_password(ainfo, &klen);
99
memcpy(info->k, k, 16);
103
info->evp_md = EVP_md5();
109
hmac_free(ipmi_con_t *ipmi,
112
hmac_info_t *info = integ_data;
114
memset(info->k, 0, sizeof(info->k));
115
ipmi_mem_free(integ_data);
119
hmac_pad(ipmi_con_t *ipmi,
121
unsigned char *payload,
122
unsigned int *payload_len,
123
unsigned int max_payload_len)
125
unsigned char *p = payload;
126
unsigned int l = *payload_len;
127
unsigned int count = 0;
129
/* Pad so that when we add two bytes (the pad length and the next
130
header) the result is on a multiple of 4 boundary. */
131
while (((l+2) % 4) != 0) {
132
if (l == max_payload_len)
139
/* Add the padding length. The next header gets added later. */
140
if (l == max_payload_len)
150
hmac_add(ipmi_con_t *ipmi,
152
unsigned char *payload,
153
unsigned int *payload_len,
154
unsigned int max_payload_len)
156
hmac_info_t *info = integ_data;
157
unsigned char *p = payload;
158
unsigned int l = *payload_len;
160
unsigned char integ[20];
162
if (l+info->ilen+1 > max_payload_len)
168
p[l] = 0x07; /* Add the next header */
171
HMAC(info->evp_md, info->k, info->klen, p+4, l-4, integ, &ilen);
172
memcpy(p+l, integ, ilen);
180
hmac_check(ipmi_con_t *ipmi,
182
unsigned char *payload,
183
unsigned int payload_len,
184
unsigned int total_len)
186
hmac_info_t *info = integ_data;
187
unsigned char *p = payload;
188
unsigned int l = payload_len;
190
unsigned char new_integ[20];
192
/* We don't authenticate this part of the header. */
196
if ((total_len - payload_len) < info->ilen+1)
199
/* We add 1 to the length because we also check the next header
201
HMAC(info->evp_md, info->k, info->klen, p, l+1, new_integ, &ilen);
202
if (memcmp(new_integ, p+l+1, info->ilen) != 0)
208
static ipmi_rmcpp_integrity_t hmac_sha1_integ =
210
.integ_init = hmac_sha1_init,
211
.integ_free = hmac_free,
212
.integ_pad = hmac_pad,
213
.integ_add = hmac_add,
214
.integ_check = hmac_check
217
static ipmi_rmcpp_integrity_t hmac_md5_integ =
219
.integ_init = hmac_md5_init,
220
.integ_free = hmac_free,
221
.integ_pad = hmac_pad,
222
.integ_add = hmac_add,
223
.integ_check = hmac_check
225
#endif /* HAVE_OPENSSL */
228
_ipmi_hmac_init(void)
233
rv = ipmi_rmcpp_register_integrity
234
(IPMI_LANP_INTEGRITY_ALGORITHM_HMAC_SHA1_96, &hmac_sha1_integ);
238
rv = ipmi_rmcpp_register_integrity
239
(IPMI_LANP_INTEGRITY_ALGORITHM_HMAC_MD5_128, &hmac_md5_integ);