| /* Copyright (c) 2004-2007, Sara Golemon <[email protected]> |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, |
| * with or without modification, are permitted provided |
| * that the following conditions are met: |
| * |
| * Redistributions of source code must retain the above |
| * copyright notice, this list of conditions and the |
| * following disclaimer. |
| * |
| * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following |
| * disclaimer in the documentation and/or other materials |
| * provided with the distribution. |
| * |
| * Neither the name of the copyright holder nor the names |
| * of any other contributors may be used to endorse or |
| * promote products derived from this software without |
| * specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
| * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
| * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE |
| * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
| * OF SUCH DAMAGE. |
| */ |
| |
| #include "libssh2_priv.h" |
| #include "mac.h" |
| |
| #ifdef LIBSSH2_MAC_NONE |
| /* mac_none_MAC |
| * Minimalist MAC: No MAC |
| */ |
| 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) |
| { |
| return 0; |
| } |
| |
| |
| |
| |
| static LIBSSH2_MAC_METHOD mac_method_none = { |
| "none", |
| 0, |
| 0, |
| NULL, |
| mac_none_MAC, |
| NULL |
| }; |
| #endif /* LIBSSH2_MAC_NONE */ |
| |
| /* mac_method_common_init |
| * Initialize simple mac methods |
| */ |
| static int |
| mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key, |
| int *free_key, void **abstract) |
| { |
| *abstract = key; |
| *free_key = 0; |
| (void) session; |
| |
| return 0; |
| } |
| |
| |
| |
| /* mac_method_common_dtor |
| * Cleanup simple mac methods |
| */ |
| static int |
| mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract) |
| { |
| if(*abstract) { |
| LIBSSH2_FREE(session, *abstract); |
| } |
| *abstract = NULL; |
| |
| return 0; |
| } |
| |
| |
| |
| #if LIBSSH2_HMAC_SHA512 |
| /* mac_method_hmac_sha512_hash |
| * Calculate hash using full sha512 value |
| */ |
| 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) |
| { |
| libssh2_hmac_ctx ctx; |
| unsigned char seqno_buf[4]; |
| (void) session; |
| |
| _libssh2_htonu32(seqno_buf, seqno); |
| |
| libssh2_hmac_ctx_init(ctx); |
| libssh2_hmac_sha512_init(&ctx, *abstract, 64); |
| libssh2_hmac_update(ctx, seqno_buf, 4); |
| libssh2_hmac_update(ctx, packet, packet_len); |
| if(addtl && addtl_len) { |
| libssh2_hmac_update(ctx, addtl, addtl_len); |
| } |
| libssh2_hmac_final(ctx, buf); |
| libssh2_hmac_cleanup(&ctx); |
| |
| return 0; |
| } |
| |
| |
| |
| static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512 = { |
| "hmac-sha2-512", |
| 64, |
| 64, |
| mac_method_common_init, |
| mac_method_hmac_sha2_512_hash, |
| mac_method_common_dtor, |
| }; |
| #endif |
| |
| |
| |
| #if LIBSSH2_HMAC_SHA256 |
| /* mac_method_hmac_sha256_hash |
| * Calculate hash using full sha256 value |
| */ |
| 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) |
| { |
| libssh2_hmac_ctx ctx; |
| unsigned char seqno_buf[4]; |
| (void) session; |
| |
| _libssh2_htonu32(seqno_buf, seqno); |
| |
| libssh2_hmac_ctx_init(ctx); |
| libssh2_hmac_sha256_init(&ctx, *abstract, 32); |
| libssh2_hmac_update(ctx, seqno_buf, 4); |
| libssh2_hmac_update(ctx, packet, packet_len); |
| if(addtl && addtl_len) { |
| libssh2_hmac_update(ctx, addtl, addtl_len); |
| } |
| libssh2_hmac_final(ctx, buf); |
| libssh2_hmac_cleanup(&ctx); |
| |
| return 0; |
| } |
| |
| |
| |
| static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_256 = { |
| "hmac-sha2-256", |
| 32, |
| 32, |
| mac_method_common_init, |
| mac_method_hmac_sha2_256_hash, |
| mac_method_common_dtor, |
| }; |
| #endif |
| |
| |
| |
| |
| /* mac_method_hmac_sha1_hash |
| * Calculate hash using full sha1 value |
| */ |
| 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) |
| { |
| libssh2_hmac_ctx ctx; |
| unsigned char seqno_buf[4]; |
| (void) session; |
| |
| _libssh2_htonu32(seqno_buf, seqno); |
| |
| libssh2_hmac_ctx_init(ctx); |
| libssh2_hmac_sha1_init(&ctx, *abstract, 20); |
| libssh2_hmac_update(ctx, seqno_buf, 4); |
| libssh2_hmac_update(ctx, packet, packet_len); |
| if(addtl && addtl_len) { |
| libssh2_hmac_update(ctx, addtl, addtl_len); |
| } |
| libssh2_hmac_final(ctx, buf); |
| libssh2_hmac_cleanup(&ctx); |
| |
| return 0; |
| } |
| |
| |
| |
| static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1 = { |
| "hmac-sha1", |
| 20, |
| 20, |
| mac_method_common_init, |
| mac_method_hmac_sha1_hash, |
| mac_method_common_dtor, |
| }; |
| |
| /* mac_method_hmac_sha1_96_hash |
| * Calculate hash using first 96 bits of sha1 value |
| */ |
| 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) |
| { |
| unsigned char temp[SHA_DIGEST_LENGTH]; |
| |
| mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len, |
| addtl, addtl_len, abstract); |
| memcpy(buf, (char *) temp, 96 / 8); |
| |
| return 0; |
| } |
| |
| |
| |
| static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_96 = { |
| "hmac-sha1-96", |
| 12, |
| 20, |
| mac_method_common_init, |
| mac_method_hmac_sha1_96_hash, |
| mac_method_common_dtor, |
| }; |
| |
| #if LIBSSH2_MD5 |
| /* mac_method_hmac_md5_hash |
| * Calculate hash using full md5 value |
| */ |
| 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) |
| { |
| libssh2_hmac_ctx ctx; |
| unsigned char seqno_buf[4]; |
| (void) session; |
| |
| _libssh2_htonu32(seqno_buf, seqno); |
| |
| libssh2_hmac_ctx_init(ctx); |
| libssh2_hmac_md5_init(&ctx, *abstract, 16); |
| libssh2_hmac_update(ctx, seqno_buf, 4); |
| libssh2_hmac_update(ctx, packet, packet_len); |
| if(addtl && addtl_len) { |
| libssh2_hmac_update(ctx, addtl, addtl_len); |
| } |
| libssh2_hmac_final(ctx, buf); |
| libssh2_hmac_cleanup(&ctx); |
| |
| return 0; |
| } |
| |
| |
| |
| static const LIBSSH2_MAC_METHOD mac_method_hmac_md5 = { |
| "hmac-md5", |
| 16, |
| 16, |
| mac_method_common_init, |
| mac_method_hmac_md5_hash, |
| mac_method_common_dtor, |
| }; |
| |
| /* mac_method_hmac_md5_96_hash |
| * Calculate hash using first 96 bits of md5 value |
| */ |
| 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) |
| { |
| unsigned char temp[MD5_DIGEST_LENGTH]; |
| mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len, |
| addtl, addtl_len, abstract); |
| memcpy(buf, (char *) temp, 96 / 8); |
| return 0; |
| } |
| |
| |
| |
| static const LIBSSH2_MAC_METHOD mac_method_hmac_md5_96 = { |
| "hmac-md5-96", |
| 12, |
| 16, |
| mac_method_common_init, |
| mac_method_hmac_md5_96_hash, |
| mac_method_common_dtor, |
| }; |
| #endif /* LIBSSH2_MD5 */ |
| |
| #if LIBSSH2_HMAC_RIPEMD |
| /* mac_method_hmac_ripemd160_hash |
| * Calculate hash using ripemd160 value |
| */ |
| 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) |
| { |
| libssh2_hmac_ctx ctx; |
| unsigned char seqno_buf[4]; |
| (void) session; |
| |
| _libssh2_htonu32(seqno_buf, seqno); |
| |
| libssh2_hmac_ctx_init(ctx); |
| libssh2_hmac_ripemd160_init(&ctx, *abstract, 20); |
| libssh2_hmac_update(ctx, seqno_buf, 4); |
| libssh2_hmac_update(ctx, packet, packet_len); |
| if(addtl && addtl_len) { |
| libssh2_hmac_update(ctx, addtl, addtl_len); |
| } |
| libssh2_hmac_final(ctx, buf); |
| libssh2_hmac_cleanup(&ctx); |
| |
| return 0; |
| } |
| |
| |
| |
| static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160 = { |
| "hmac-ripemd160", |
| 20, |
| 20, |
| mac_method_common_init, |
| mac_method_hmac_ripemd160_hash, |
| mac_method_common_dtor, |
| }; |
| |
| static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160_openssh_com = { |
| "[email protected]", |
| 20, |
| 20, |
| mac_method_common_init, |
| mac_method_hmac_ripemd160_hash, |
| mac_method_common_dtor, |
| }; |
| #endif /* LIBSSH2_HMAC_RIPEMD */ |
| |
| static const LIBSSH2_MAC_METHOD *mac_methods[] = { |
| #if LIBSSH2_HMAC_SHA256 |
| &mac_method_hmac_sha2_256, |
| #endif |
| #if LIBSSH2_HMAC_SHA512 |
| &mac_method_hmac_sha2_512, |
| #endif |
| &mac_method_hmac_sha1, |
| &mac_method_hmac_sha1_96, |
| #if LIBSSH2_MD5 |
| &mac_method_hmac_md5, |
| &mac_method_hmac_md5_96, |
| #endif |
| #if LIBSSH2_HMAC_RIPEMD |
| &mac_method_hmac_ripemd160, |
| &mac_method_hmac_ripemd160_openssh_com, |
| #endif /* LIBSSH2_HMAC_RIPEMD */ |
| #ifdef LIBSSH2_MAC_NONE |
| &mac_method_none, |
| #endif /* LIBSSH2_MAC_NONE */ |
| NULL |
| }; |
| |
| const LIBSSH2_MAC_METHOD ** |
| _libssh2_mac_methods(void) |
| { |
| return mac_methods; |
| } |