1 /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms,
5 * with or without modification, are permitted provided
6 * that the following conditions are met:
7 *
8 * Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the
10 * following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
16 *
17 * Neither the name of the copyright holder nor the names
18 * of any other contributors may be used to endorse or
19 * promote products derived from this software without
20 * specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
34 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
35 * OF SUCH DAMAGE.
36 */
37
38 #include "libssh2_priv.h"
39 #include "mac.h"
40
41 #ifdef LIBSSH2_MAC_NONE
42 /* mac_none_MAC
43 * Minimalist MAC: No MAC
44 */
45 static int
mac_none_MAC(LIBSSH2_SESSION * session,unsigned char * buf,uint32_t seqno,const unsigned char * packet,uint32_t packet_len,const unsigned char * addtl,uint32_t addtl_len,void ** abstract)46 mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf,
47 uint32_t seqno, const unsigned char *packet,
48 uint32_t packet_len, const unsigned char *addtl,
49 uint32_t addtl_len, void **abstract)
50 {
51 return 0;
52 }
53
54
55
56
57 static LIBSSH2_MAC_METHOD mac_method_none = {
58 "none",
59 0,
60 0,
61 NULL,
62 mac_none_MAC,
63 NULL
64 };
65 #endif /* LIBSSH2_MAC_NONE */
66
67 /* mac_method_common_init
68 * Initialize simple mac methods
69 */
70 static int
mac_method_common_init(LIBSSH2_SESSION * session,unsigned char * key,int * free_key,void ** abstract)71 mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key,
72 int *free_key, void **abstract)
73 {
74 *abstract = key;
75 *free_key = 0;
76 (void) session;
77
78 return 0;
79 }
80
81
82
83 /* mac_method_common_dtor
84 * Cleanup simple mac methods
85 */
86 static int
mac_method_common_dtor(LIBSSH2_SESSION * session,void ** abstract)87 mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract)
88 {
89 if (*abstract) {
90 LIBSSH2_FREE(session, *abstract);
91 }
92 *abstract = NULL;
93
94 return 0;
95 }
96
97
98
99 #if LIBSSH2_HMAC_SHA512
100 /* mac_method_hmac_sha512_hash
101 * Calculate hash using full sha512 value
102 */
103 static int
mac_method_hmac_sha2_512_hash(LIBSSH2_SESSION * session,unsigned char * buf,uint32_t seqno,const unsigned char * packet,uint32_t packet_len,const unsigned char * addtl,uint32_t addtl_len,void ** abstract)104 mac_method_hmac_sha2_512_hash(LIBSSH2_SESSION * session,
105 unsigned char *buf, uint32_t seqno,
106 const unsigned char *packet,
107 uint32_t packet_len,
108 const unsigned char *addtl,
109 uint32_t addtl_len, void **abstract)
110 {
111 libssh2_hmac_ctx ctx;
112 unsigned char seqno_buf[4];
113 (void) session;
114
115 _libssh2_htonu32(seqno_buf, seqno);
116
117 libssh2_hmac_ctx_init(ctx);
118 libssh2_hmac_sha512_init(&ctx, *abstract, 64);
119 libssh2_hmac_update(ctx, seqno_buf, 4);
120 libssh2_hmac_update(ctx, packet, packet_len);
121 if (addtl && addtl_len) {
122 libssh2_hmac_update(ctx, addtl, addtl_len);
123 }
124 libssh2_hmac_final(ctx, buf);
125 libssh2_hmac_cleanup(&ctx);
126
127 return 0;
128 }
129
130
131
132 static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512 = {
133 "hmac-sha2-512",
134 64,
135 64,
136 mac_method_common_init,
137 mac_method_hmac_sha2_512_hash,
138 mac_method_common_dtor,
139 };
140 #endif
141
142
143
144 #if LIBSSH2_HMAC_SHA256
145 /* mac_method_hmac_sha256_hash
146 * Calculate hash using full sha256 value
147 */
148 static int
mac_method_hmac_sha2_256_hash(LIBSSH2_SESSION * session,unsigned char * buf,uint32_t seqno,const unsigned char * packet,uint32_t packet_len,const unsigned char * addtl,uint32_t addtl_len,void ** abstract)149 mac_method_hmac_sha2_256_hash(LIBSSH2_SESSION * session,
150 unsigned char *buf, uint32_t seqno,
151 const unsigned char *packet,
152 uint32_t packet_len,
153 const unsigned char *addtl,
154 uint32_t addtl_len, void **abstract)
155 {
156 libssh2_hmac_ctx ctx;
157 unsigned char seqno_buf[4];
158 (void) session;
159
160 _libssh2_htonu32(seqno_buf, seqno);
161
162 libssh2_hmac_ctx_init(ctx);
163 libssh2_hmac_sha256_init(&ctx, *abstract, 32);
164 libssh2_hmac_update(ctx, seqno_buf, 4);
165 libssh2_hmac_update(ctx, packet, packet_len);
166 if (addtl && addtl_len) {
167 libssh2_hmac_update(ctx, addtl, addtl_len);
168 }
169 libssh2_hmac_final(ctx, buf);
170 libssh2_hmac_cleanup(&ctx);
171
172 return 0;
173 }
174
175
176
177 static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_256 = {
178 "hmac-sha2-256",
179 32,
180 32,
181 mac_method_common_init,
182 mac_method_hmac_sha2_256_hash,
183 mac_method_common_dtor,
184 };
185 #endif
186
187
188
189
190 /* mac_method_hmac_sha1_hash
191 * Calculate hash using full sha1 value
192 */
193 static int
mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,unsigned char * buf,uint32_t seqno,const unsigned char * packet,uint32_t packet_len,const unsigned char * addtl,uint32_t addtl_len,void ** abstract)194 mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
195 unsigned char *buf, uint32_t seqno,
196 const unsigned char *packet,
197 uint32_t packet_len,
198 const unsigned char *addtl,
199 uint32_t addtl_len, void **abstract)
200 {
201 libssh2_hmac_ctx ctx;
202 unsigned char seqno_buf[4];
203 (void) session;
204
205 _libssh2_htonu32(seqno_buf, seqno);
206
207 libssh2_hmac_ctx_init(ctx);
208 libssh2_hmac_sha1_init(&ctx, *abstract, 20);
209 libssh2_hmac_update(ctx, seqno_buf, 4);
210 libssh2_hmac_update(ctx, packet, packet_len);
211 if (addtl && addtl_len) {
212 libssh2_hmac_update(ctx, addtl, addtl_len);
213 }
214 libssh2_hmac_final(ctx, buf);
215 libssh2_hmac_cleanup(&ctx);
216
217 return 0;
218 }
219
220
221
222 static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1 = {
223 "hmac-sha1",
224 20,
225 20,
226 mac_method_common_init,
227 mac_method_hmac_sha1_hash,
228 mac_method_common_dtor,
229 };
230
231 /* mac_method_hmac_sha1_96_hash
232 * Calculate hash using first 96 bits of sha1 value
233 */
234 static int
mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session,unsigned char * buf,uint32_t seqno,const unsigned char * packet,uint32_t packet_len,const unsigned char * addtl,uint32_t addtl_len,void ** abstract)235 mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session,
236 unsigned char *buf, uint32_t seqno,
237 const unsigned char *packet,
238 uint32_t packet_len,
239 const unsigned char *addtl,
240 uint32_t addtl_len, void **abstract)
241 {
242 unsigned char temp[SHA_DIGEST_LENGTH];
243
244 mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len,
245 addtl, addtl_len, abstract);
246 memcpy(buf, (char *) temp, 96 / 8);
247
248 return 0;
249 }
250
251
252
253 static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_96 = {
254 "hmac-sha1-96",
255 12,
256 20,
257 mac_method_common_init,
258 mac_method_hmac_sha1_96_hash,
259 mac_method_common_dtor,
260 };
261
262 #if LIBSSH2_MD5
263 /* mac_method_hmac_md5_hash
264 * Calculate hash using full md5 value
265 */
266 static int
mac_method_hmac_md5_hash(LIBSSH2_SESSION * session,unsigned char * buf,uint32_t seqno,const unsigned char * packet,uint32_t packet_len,const unsigned char * addtl,uint32_t addtl_len,void ** abstract)267 mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
268 uint32_t seqno,
269 const unsigned char *packet,
270 uint32_t packet_len,
271 const unsigned char *addtl,
272 uint32_t addtl_len, void **abstract)
273 {
274 libssh2_hmac_ctx ctx;
275 unsigned char seqno_buf[4];
276 (void) session;
277
278 _libssh2_htonu32(seqno_buf, seqno);
279
280 libssh2_hmac_ctx_init(ctx);
281 libssh2_hmac_md5_init(&ctx, *abstract, 16);
282 libssh2_hmac_update(ctx, seqno_buf, 4);
283 libssh2_hmac_update(ctx, packet, packet_len);
284 if (addtl && addtl_len) {
285 libssh2_hmac_update(ctx, addtl, addtl_len);
286 }
287 libssh2_hmac_final(ctx, buf);
288 libssh2_hmac_cleanup(&ctx);
289
290 return 0;
291 }
292
293
294
295 static const LIBSSH2_MAC_METHOD mac_method_hmac_md5 = {
296 "hmac-md5",
297 16,
298 16,
299 mac_method_common_init,
300 mac_method_hmac_md5_hash,
301 mac_method_common_dtor,
302 };
303
304 /* mac_method_hmac_md5_96_hash
305 * Calculate hash using first 96 bits of md5 value
306 */
307 static int
mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session,unsigned char * buf,uint32_t seqno,const unsigned char * packet,uint32_t packet_len,const unsigned char * addtl,uint32_t addtl_len,void ** abstract)308 mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session,
309 unsigned char *buf, uint32_t seqno,
310 const unsigned char *packet,
311 uint32_t packet_len,
312 const unsigned char *addtl,
313 uint32_t addtl_len, void **abstract)
314 {
315 unsigned char temp[MD5_DIGEST_LENGTH];
316 mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len,
317 addtl, addtl_len, abstract);
318 memcpy(buf, (char *) temp, 96 / 8);
319 return 0;
320 }
321
322
323
324 static const LIBSSH2_MAC_METHOD mac_method_hmac_md5_96 = {
325 "hmac-md5-96",
326 12,
327 16,
328 mac_method_common_init,
329 mac_method_hmac_md5_96_hash,
330 mac_method_common_dtor,
331 };
332 #endif /* LIBSSH2_MD5 */
333
334 #if LIBSSH2_HMAC_RIPEMD
335 /* mac_method_hmac_ripemd160_hash
336 * Calculate hash using ripemd160 value
337 */
338 static int
mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,unsigned char * buf,uint32_t seqno,const unsigned char * packet,uint32_t packet_len,const unsigned char * addtl,uint32_t addtl_len,void ** abstract)339 mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
340 unsigned char *buf, uint32_t seqno,
341 const unsigned char *packet,
342 uint32_t packet_len,
343 const unsigned char *addtl,
344 uint32_t addtl_len,
345 void **abstract)
346 {
347 libssh2_hmac_ctx ctx;
348 unsigned char seqno_buf[4];
349 (void) session;
350
351 _libssh2_htonu32(seqno_buf, seqno);
352
353 libssh2_hmac_ctx_init(ctx);
354 libssh2_hmac_ripemd160_init(&ctx, *abstract, 20);
355 libssh2_hmac_update(ctx, seqno_buf, 4);
356 libssh2_hmac_update(ctx, packet, packet_len);
357 if (addtl && addtl_len) {
358 libssh2_hmac_update(ctx, addtl, addtl_len);
359 }
360 libssh2_hmac_final(ctx, buf);
361 libssh2_hmac_cleanup(&ctx);
362
363 return 0;
364 }
365
366
367
368 static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160 = {
369 "hmac-ripemd160",
370 20,
371 20,
372 mac_method_common_init,
373 mac_method_hmac_ripemd160_hash,
374 mac_method_common_dtor,
375 };
376
377 static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160_openssh_com = {
378 "hmac-ripemd160@openssh.com",
379 20,
380 20,
381 mac_method_common_init,
382 mac_method_hmac_ripemd160_hash,
383 mac_method_common_dtor,
384 };
385 #endif /* LIBSSH2_HMAC_RIPEMD */
386
387 static const LIBSSH2_MAC_METHOD *mac_methods[] = {
388 #if LIBSSH2_HMAC_SHA256
389 &mac_method_hmac_sha2_256,
390 #endif
391 #if LIBSSH2_HMAC_SHA512
392 &mac_method_hmac_sha2_512,
393 #endif
394 &mac_method_hmac_sha1,
395 &mac_method_hmac_sha1_96,
396 #if LIBSSH2_MD5
397 &mac_method_hmac_md5,
398 &mac_method_hmac_md5_96,
399 #endif
400 #if LIBSSH2_HMAC_RIPEMD
401 &mac_method_hmac_ripemd160,
402 &mac_method_hmac_ripemd160_openssh_com,
403 #endif /* LIBSSH2_HMAC_RIPEMD */
404 #ifdef LIBSSH2_MAC_NONE
405 &mac_method_none,
406 #endif /* LIBSSH2_MAC_NONE */
407 NULL
408 };
409
410 const LIBSSH2_MAC_METHOD **
_libssh2_mac_methods(void)411 _libssh2_mac_methods(void)
412 {
413 return mac_methods;
414 }
415