File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / freevrrpd / vrrp_ah.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 14 12:01:54 2017 UTC (6 years, 11 months ago) by misho
Branches: freevrrpd, MAIN
CVS tags: v1_1, HEAD
freevrrpd 1.1

    1: /*
    2:  * Copyright (c) 2003 BurnesOnLine <bol@b0l.org>
    3:  *
    4:  * Redistribution and use in source forms, with and without modification,
    5:  * are permitted provided that the following conditions are met:
    6:  * 1. Redistributions of source code must retain the above copyright notice,
    7:  *    this list of conditions and the following disclaimer.
    8:  * 2. Redistributions in binary form must reproduce the above copyright notice,
    9:  *    this list of conditions and the following disclaimer in the documentation
   10:  *    and/or other materials provided with the distribution. Obviously, it
   11:  *    would be nice if you gave credit where credit is due but requiring it
   12:  *    would be too onerous.
   13:  * 3. All advertising materials mentioning features or use of this software
   14:  *    must display the following acknowledgement:
   15:  *      This product includes software developed by Sebastien Petit.
   16:  * 4. Neither the name of its contributors may be used to endorse or promote
   17:  *    products derived from this software without specific prior written
   18:  *    permission.
   19:  *
   20:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   21:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   24:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30:  * SUCH DAMAGE.
   31:  *
   32:  * $Id: vrrp_ah.c,v 1.1.1.1 2017/06/14 12:01:54 misho Exp $  
   33:  *
   34:  * MISC COMMENTS :
   35:  * FreeVRRPd project AH implementation using KAME based ipsec stack.
   36:  * tested on :
   37:  *    FreeBSD
   38:  *    NetBSD
   39:  * should work on :
   40:  *    Linux 2.6 or KAME based linux ipsec stack
   41:  *
   42:  * this code use KAME not fully implemented :
   43:  * RFC 2367 - PF_KEY Key Management API, Version 2
   44:  *
   45:  * AUTHORS:
   46:  * this is a working and almost clean "HACK"  :)
   47:  * problem is, we cant set socket wide SPD and SAD
   48:  * need to work out with KAME project to know exactly 
   49:  * the procedure to make process wide changes and NOT
   50:  * host wide changes.
   51:  *
   52:  * b0l.
   53:  * 
   54:  */
   55: #include "vrrp_proto.h"
   56: #include "vrrp_ah.h"
   57: #include "md5.h"
   58: 
   59: #ifdef ENABLE_VRRP_AH
   60: #ifdef KAME_BASED
   61: /* special struct */
   62: typedef enum {
   63:     HMAC_MD5 = 2,	      /* 128 bits */
   64:     HMAC_SHA1 = 3,	      /* 160 bits */
   65:     HMAC_NULL,
   66:     HMAC_SHA2_256,	      /* 256 bits */
   67:     HMAC_SHA2_384,	      /* 384 bits */
   68:     HMAC_SHA2_512,	      /* 512 bits */
   69:     HMAC_RIPEMD160,	      /* 160 bits */
   70:     AES_XCBC_MAC	      /* 128 bits */
   71: } alg_t;
   72: 
   73: typedef struct algorithm {
   74:     alg_t type;
   75:     size_t keysize;
   76: } algorithm_t;
   77: 
   78: algorithm_t algos[] = {
   79:     { HMAC_MD5, 128 },
   80:     { HMAC_SHA1, 160 },
   81:     { HMAC_NULL, 0 },
   82:     { HMAC_SHA2_256, 256 },
   83:     { HMAC_SHA2_384, 384 },
   84:     { HMAC_SHA2_512, 512 },
   85:     { HMAC_RIPEMD160, 160 },
   86:     { AES_XCBC_MAC, 128 }
   87: };
   88: 
   89: /* what we need 
   90:    ipsec (4)
   91:    setsockopt(2)  * per socket behavior *
   92:    sysctl(3) * host wide *
   93:    ipsec_set_policy(3) * IPsec Policy Control Library (libipsec, -lipsec) *
   94:    */
   95: 
   96: /* STOLEN FROM FreeBSD setkey.c :) */
   97: struct addrinfo * parse_addr(char *host, char *port) {
   98: 	struct addrinfo hints, *res = NULL;
   99: 	int error;
  100: 
  101: 	memset(&hints, 0, sizeof(hints));
  102: 	hints.ai_family = PF_UNSPEC;
  103: 	hints.ai_socktype = SOCK_DGRAM;		/*dummy*/
  104: 	hints.ai_protocol = IPPROTO_UDP;	/*dummy*/
  105: 	hints.ai_flags = 0;
  106: 	error = getaddrinfo(host, port, &hints, &res);
  107: 	if (error != 0) {
  108: 		perror(gai_strerror(error));
  109: 		return NULL;
  110: 	}
  111: 	return res;
  112: }
  113: 
  114: int setkeymsg(struct sadb_msg *msg, unsigned int type, unsigned int satype, size_t l) {
  115: 
  116: 	msg->sadb_msg_version = PF_KEY_V2;
  117: 	msg->sadb_msg_type = type;
  118: 	msg->sadb_msg_errno = 0;
  119: 	msg->sadb_msg_satype = satype;
  120: 	msg->sadb_msg_reserved = 0;
  121: 	msg->sadb_msg_seq = 0;
  122: 	msg->sadb_msg_pid = getpid();
  123: 	msg->sadb_msg_len = PFKEY_UNIT64(l);
  124: 	return 0;
  125: }
  126: 
  127: int setvarbuf(char *buf, int *off, struct sadb_ext *ebuf, int elen, caddr_t vbuf, int vlen) {
  128: 	memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
  129: 	memcpy(buf + *off, (caddr_t)ebuf, elen);
  130: 	memcpy(buf + *off + elen, vbuf, vlen);
  131: 	(*off) += PFKEY_ALIGN8(elen + vlen);
  132: 	return 0;
  133: }
  134: 
  135: /* WE NEED :
  136: setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen)
  137: */
  138: 
  139: /* open the PF_KEY socket */
  140: int vrrp_pfkey_open(void) {
  141:     int key_fd;
  142: 
  143:     /* opening PF_KEY API */
  144:     key_fd = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
  145:     if (key_fd < 0) {
  146: 	perror("socket(PF_KEY)");
  147: 	return key_fd;
  148:     }
  149: 
  150:     return key_fd;
  151: }
  152: 
  153: /* close PF_KEY socket */
  154: int vrrp_pfkey_close(int fd) {
  155:     int rc = 0;
  156:     rc = close(fd);
  157:     return rc;
  158: }
  159: 
  160: /* return -1 on failure, 0 on success */
  161: int vrrp_ah_set_outpolicy(int fd, char *src) {
  162:     int rc = 0;
  163: 
  164:     rc = vrrp_ah_spd(fd, src, VRRP_OUT_POLICY, SADB_X_SPDADD);
  165:     if (rc < 0) {
  166: 	perror("VRRP_OUT_POLICY setup failed!\n");
  167: 	rc = -1;
  168:     }
  169:     return rc;
  170: }
  171: 
  172: /* return -1 on failure, 0 on success */
  173: int vrrp_ah_rm_outpolicy(int fd, char *src) {
  174:     int rc = 0;
  175: 
  176:     rc = vrrp_ah_spd(fd, src, VRRP_OUT_POLICY, SADB_X_SPDDELETE);
  177:     if (rc < 0) {
  178: 	perror("VRRP_OUT_POLICY removal failed\n");
  179: 	rc = -1;
  180:     }
  181:     return rc;
  182: }
  183: 
  184: /* return -1 on failure, 0 on success */
  185: int vrrp_ah_set_inpolicy(int fd, char *src) {
  186:     int rc = 0;
  187: 
  188:     rc = vrrp_ah_spd(fd, src, VRRP_IN_POLICY, SADB_X_SPDADD);
  189:     if (rc < 0) {
  190: 	perror("VRRP_IN_POLICY setup failed\n");
  191: 	rc = -1;
  192:     }
  193:     return rc;
  194: }
  195: 
  196: /* return -1 on failure, 0 on success */
  197: int vrrp_ah_rm_inpolicy(int fd, char *src) {
  198:     int rc = 0;
  199: 
  200:     rc = vrrp_ah_spd(fd, src, VRRP_IN_POLICY, SADB_X_SPDDELETE);
  201:     if (rc < 0) {
  202: 	perror("VRRP_IN_POLICY setup failed\n");
  203: 	rc = -1;
  204:     }
  205:     return rc;
  206: }
  207: 
  208: /* return number of bytes sent to PF_KEY socket/in-kernel */
  209: int vrrp_ah_spd(int fd, char *src_addr, char *ah_policy, unsigned int cmd) {
  210:     /* lets see if it works */
  211:     char *policy;
  212:     int policy_len;
  213:     const int bufsiz = 128 * 1024;
  214:     char * buf = (char *) malloc (bufsiz * sizeof(char));
  215:     struct sadb_msg *msg;
  216:     struct sadb_address m_addr;
  217:     struct sockaddr *sa; 
  218:     struct addrinfo *src, *dst;
  219:     int m_size;
  220:     int salen;
  221:     int rc;
  222: 
  223:     /* sanity checks */
  224:     if (!buf) {
  225: 	fprintf(stderr,"could not allocate memory\n");
  226: 	return -1;
  227:     }
  228: 
  229:     /* prepare the policy */
  230:     policy = ipsec_set_policy(VRRP_OUT_POLICY, strlen(VRRP_OUT_POLICY));
  231:     if (!policy) {
  232: 	perror("ipsec_set_policy()");
  233: 	return -1;
  234:     }
  235: 
  236:     policy_len = ipsec_get_policylen(policy);
  237:     if (policy_len < 0) {
  238: 	perror("ipsec_get_policylen()");
  239: 	return -1;
  240:     }
  241: 
  242:     /* clearing everything, don't want this bugs to happen again */
  243:     memset(buf,0,bufsiz);
  244:     memset(&m_addr, 0, sizeof(m_addr));
  245: 
  246:     /* building PF_KEY msg */
  247:     msg = (struct sadb_msg *) buf;
  248:     setkeymsg(msg,(unsigned int)cmd,SADB_SATYPE_UNSPEC, 0);
  249:     m_size = sizeof(struct sadb_msg);
  250: 
  251:     /* copying the policy */
  252:     memcpy(buf+m_size, policy, policy_len);
  253:     m_size += policy_len;
  254: 
  255:     /* parsing from / to */
  256:     src = parse_addr(src_addr, 0);
  257:     if (!src) {
  258: 	free(policy);
  259: 	free(buf);
  260: 	return -1;
  261:     }
  262: 
  263:     dst = parse_addr(VRRP_ADDRESS, 0);
  264:     if (!dst) {
  265: 	free(policy);
  266: 	freeaddrinfo(src);
  267: 	free(buf);
  268: 	return -1;
  269:     }
  270: 
  271:     /* SOURCE SETUP */
  272:     sa = src->ai_addr;
  273:     salen = src->ai_addr->sa_len;
  274:     m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr)+PFKEY_ALIGN8(salen));
  275:     m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
  276:     m_addr.sadb_address_proto = (unsigned int)IPSEC_IPPROTO_ANY;
  277:     m_addr.sadb_address_prefixlen = HOST_MASK; 
  278:     m_addr.sadb_address_reserved = 0;
  279: 
  280:     setvarbuf(buf, &m_size, (struct sadb_ext *)&m_addr,sizeof(m_addr),(caddr_t)sa, salen);
  281: 
  282:     /* DESTINATION SETUP */
  283:     sa = dst->ai_addr;
  284:     salen = src->ai_addr->sa_len;
  285:     m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr)+PFKEY_ALIGN8(salen));
  286:     m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
  287:     m_addr.sadb_address_proto = (unsigned int)IPSEC_IPPROTO_ANY;
  288:     m_addr.sadb_address_prefixlen = HOST_MASK; /* (splen >= 0 ? -1 : plen ); */
  289:     m_addr.sadb_address_reserved = 0;
  290: 
  291:     setvarbuf(buf, &m_size, (struct sadb_ext *)&m_addr,sizeof(m_addr),(caddr_t)sa, salen);
  292: 
  293:     msg->sadb_msg_len = PFKEY_UNIT64(m_size);
  294: 
  295:     (void)setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz));
  296:     (void)setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz));
  297: 
  298:     rc = send(fd, buf, m_size, 0);
  299:     if (rc < 0)
  300: 	perror("could not add entry to SPD: send()");
  301: 
  302:     free(policy);
  303:     free(buf);
  304:     freeaddrinfo(src);
  305:     freeaddrinfo(dst);
  306:     return rc;
  307: }
  308: 
  309: 
  310: 
  311: /* status = setkeymsg_add(SADB_ADD, $5, $3, $4); */
  312: /* DO NOT FORGET TO CLEAN THOSE FUKING LOCAL STRUCTURE 2 DAYS LOST $#@$!@#$#@!
  313:  * */
  314: int vrrp_ah_sad(int fd, char *src_addr, alg_t algo, char *key) {
  315:     const int bufsiz = 128 * 1024;
  316:     char * buf = (char *) malloc (bufsiz * sizeof(char));
  317:     struct sadb_msg *msg;
  318:     struct sadb_address m_addr;
  319:     struct sockaddr *sa; 
  320:     struct addrinfo *src, *dst, *s;
  321:     int m_size;
  322:     int salen;
  323:     int rc;
  324:     /* ADDED */
  325:     int len;
  326:     char * p_alg_auth = "hmac-sha1";
  327:     char * p_key_auth = "12345678901234567890";
  328:     int p_key_auth_len = strlen(p_key_auth);
  329:     struct sadb_key m_key;
  330:     struct sadb_sa m_sa;
  331:     struct sadb_x_sa2 m_sa2;
  332:     struct sadb_lifetime m_lt;
  333: 
  334:     msg = (struct sadb_msg *) buf;
  335: 
  336:     /* clearing the allocated data */
  337:     memset(buf,0,bufsiz);
  338: 
  339:     setkeymsg(msg, SADB_ADD, SADB_SATYPE_AH, 0);
  340:     /* setkeymsg(msg, SADB_DELETE, SADB_SATYPE_AH, 0); */
  341: 
  342:     m_size = sizeof(struct sadb_msg);
  343:     /* HACK HACK */
  344:     /* hexdump(msg,m_size); */
  345: 
  346:     m_key.sadb_key_len = PFKEY_UNIT64(sizeof(m_key) + PFKEY_ALIGN8(p_key_auth_len));
  347:     m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
  348:     m_key.sadb_key_bits = p_key_auth_len * 8;
  349:     m_key.sadb_key_reserved = 0;
  350:     
  351:     setvarbuf(buf, &m_size, (struct sadb_ext *)&m_key,sizeof(m_key),(caddr_t)p_key_auth, p_key_auth_len);
  352: 
  353:     /*
  354:     u_int slen = sizeof(struct sadb_lifetime);
  355:     m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
  356:     m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
  357:     m_lt.sadb_lifetime_allocations = 0;
  358:     m_lt.sadb_lifetime_bytes = 0;
  359:     m_lt.sadb_lifetime_addtime = 0;
  360:     m_lt.sadb_lifetime_usetime = 0;
  361: 
  362:     memcpy(buf + m_size, &m_lt, slen);
  363:     m_size += slen; 
  364:     */
  365: 
  366:     /*
  367:     m_key.sadb_key_len = PFKEY_UNIT64(sizeof(m_key) + PFKEY_ALIGN8(p_key_auth_len));
  368:     m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
  369:     m_key.sadb_key_bits = p_key_auth_len * 8;
  370:     m_key.sadb_key_reserved = 0;
  371: 
  372:     setvarbuf(buf, &m_size, (struct sadb_ext *)&m_key, sizeof(m_key), (caddr_t)p_key_auth, p_key_auth_len);
  373:     */
  374: 
  375:     len = sizeof(struct sadb_sa);
  376:     m_sa.sadb_sa_len = PFKEY_UNIT64(len);
  377:     m_sa.sadb_sa_exttype = SADB_EXT_SA;
  378:     m_sa.sadb_sa_spi = htonl(0x2710);
  379:     m_sa.sadb_sa_replay = 0;
  380:     m_sa.sadb_sa_state = 0;
  381:     m_sa.sadb_sa_auth = 3; /* hmac-sha1 */
  382:     m_sa.sadb_sa_encrypt = 0; /* no encryption yet */
  383:     m_sa.sadb_sa_flags = 64; /* BUG HERE */
  384: 
  385:     memcpy(buf + m_size, &m_sa, len);
  386:     m_size += len;
  387: 
  388:     bzero(&m_sa2, sizeof(struct sadb_x_sa2));
  389: 
  390:     len = sizeof(struct sadb_x_sa2);
  391:     printf("len: %x  exttype: %x\n",PFKEY_UNIT64(len), SADB_X_EXT_SA2);
  392:     m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
  393:     m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
  394:     m_sa2.sadb_x_sa2_mode = IPSEC_MODE_ANY; 
  395:     m_sa2.sadb_x_sa2_reqid = 0;
  396: 
  397:     memcpy(buf + m_size, &m_sa2, len);
  398:     m_size += len; 
  399: 
  400:     /* parsing from / to */
  401:     src = parse_addr(src_addr, 0);
  402:     if (!src) {
  403: 	free(buf);
  404: 	return -1;
  405:     }
  406: 
  407:     dst = parse_addr(VRRP_ADDRESS, 0);
  408:     if (!dst) {
  409: 	freeaddrinfo(src);
  410: 	free(buf);
  411: 	return -1;
  412:     }
  413: 
  414:     /* SOURCE SETUP */
  415:     for (s = src; s; s = s->ai_next) {
  416: 	sa = s->ai_addr;
  417: 	salen = s->ai_addr->sa_len; /* POSSIBLE BUG */
  418: 	m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr)+PFKEY_ALIGN8(salen));
  419: 	m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
  420: 	m_addr.sadb_address_proto = (unsigned int)IPSEC_ULPROTO_ANY;
  421: 	m_addr.sadb_address_prefixlen = HOST_MASK; /* (splen >= 0 ? -1 : plen ); */
  422: 	m_addr.sadb_address_reserved = 0; 
  423: 	setvarbuf(buf, &m_size, (struct sadb_ext *)&m_addr,sizeof(m_addr),(caddr_t)sa, salen);
  424:     }
  425: 
  426:     /* DESTINATION SETUP */
  427:     sa = dst->ai_addr;
  428:     salen = dst->ai_addr->sa_len;
  429:     m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr)+PFKEY_ALIGN8(salen));
  430:     m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
  431:     m_addr.sadb_address_proto = (unsigned int)IPSEC_ULPROTO_ANY;
  432:     m_addr.sadb_address_prefixlen = HOST_MASK; /* (splen >= 0 ? -1 : plen ); */
  433:     m_addr.sadb_address_reserved = 0;
  434: 
  435:     setvarbuf(buf, &m_size, (struct sadb_ext *)&m_addr,sizeof(m_addr),(caddr_t)sa, salen);
  436: 
  437:     msg->sadb_msg_len = PFKEY_UNIT64(m_size);
  438: 
  439:     (void)setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz));
  440:     (void)setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz));
  441: 
  442:     rc = send(fd, buf, m_size, 0);
  443:     if (rc < 0)
  444: 	perror("could not add entry to SAD: send()");
  445: 
  446:     free(buf);
  447:     freeaddrinfo(src);
  448:     freeaddrinfo(dst);
  449:     return rc;
  450: }
  451: 
  452: #else
  453: /* The simple implementation based on keepalived draft */
  454: void vrrp_ah_init_ahhdr(unsigned char *buffer, struct vrrp_vr *vr) {
  455:     struct ip *ip;
  456:     struct ah_header *ah;
  457: 
  458:     ip = (struct ip *) buffer;
  459:     ah = (struct ah_header *) (buffer+sizeof(struct ip));
  460:     ah->next = IPPROTO_VRRP;
  461:     ah->length = 0x04;
  462:     ah->zero = 0x0000;
  463:     ah->spi = htonl(vr->vr_if->ip_addrs[0].s_addr);
  464:     ah->seq = htonl(1);
  465:     /* clean first */
  466:     memset(ah->auth,0,sizeof(ah->auth));
  467: 
  468:     return;
  469: }
  470: 
  471: void vrrp_ah_hmacmd5(unsigned char *buffer, struct vrrp_vr *vr) {
  472:     struct ip *ip;
  473:     struct ah_header *ah;
  474:     unsigned char md5[16];
  475: 
  476:     ip = (struct ip *) buffer;
  477:     ah = (struct ah_header *) (buffer+sizeof(struct ip));
  478: 
  479:     /* clear md5 */
  480:     memset(md5,0,sizeof(md5));
  481: 
  482:     /* hexdump(md5,sizeof(md5)); */
  483:     /* lets compute digest */
  484:     hmac_md5(buffer, (sizeof(struct ip)+sizeof(struct ah_header)+sizeof(struct vrrp_hdr)), (unsigned char *)vr->password, strlen(vr->password), md5);
  485:     /* hexdump(md5,sizeof(md5)); */
  486: 
  487:     /* copy it */
  488:     memcpy(ah->auth, md5, 12);
  489: 
  490:     return;
  491: }
  492: 
  493: /* return 0 if packet is valid, -1 else */
  494: int vrrp_ah_check_ahhdr(char *buffer, struct vrrp_vr *vr) {
  495:     struct ah_header *ah;
  496:     unsigned char recv_authdata[HMAC_MD596_SIZE], comp_authdata[HMAC_MD596_SIZE+4];
  497: 
  498:     ah = (struct ah_header *) buffer;
  499:     if (ah->next != IPPROTO_VRRP)
  500: 	return -1;
  501:     if (ah->length != 0x04)
  502: 	return -1;
  503:     /*
  504:     if (ah->seq < vr->ahctx->seq) 
  505: 	return -1;
  506:     else 
  507: 	vr->ahctx->seq = ah->seq;
  508: 	*/
  509: 
  510:     /* save auth data and rebuild hmac to see if it match */
  511:     memcpy(recv_authdata,(caddr_t)ah->auth,HMAC_MD596_SIZE);
  512:     memset(ah->auth,0, HMAC_MD596_SIZE);
  513:     hmac_md5((unsigned char *)buffer, sizeof(struct ip)+sizeof(struct ah_header)+sizeof(struct vrrp_hdr), vr->password, strlen(vr->password), comp_authdata);
  514: 
  515:     if (memcmp(recv_authdata, comp_authdata, HMAC_MD596_SIZE) == 0)
  516: 	return 0;
  517: 
  518:     printf("packet invalid!!!\n");
  519:     return -1;
  520: }
  521: #endif /* end of ifdef KAME_BASED */
  522: #endif /* endof ENABLE_VRRP_AH */
  523: 
  524: 
  525: int vrrp_ah_ahhdr_len(struct vrrp_vr *vr) {
  526: #ifdef ENABLE_VRRP_AH
  527:     if (vr->AHencryption == 1)
  528: 	return (sizeof(struct ah_header));
  529: #endif
  530:     return 0;
  531: }
  532: 
  533: 
  534: /*
  535: RFC 2104 define this.
  536: unsigned char*  text;                * pointer to data stream *
  537: int             text_len;            * length of data stream *
  538: unsigned char*  key;                 * pointer to authentication key *
  539: int             key_len;             * length of authentication key *
  540: caddr_t         digest;              * caller digest to be filled in *
  541: */
  542: void hmac_md5(unsigned char *text, int text_len, unsigned char *key, int key_len, caddr_t digest) {
  543:         MD5_CTX context,tctx;
  544:         unsigned char k_ipad[65];    /* inner padding - key XORd with ipad */
  545:         unsigned char k_opad[65];    /* outer padding - key XORd with opad */
  546:         unsigned char tk[16];
  547:         int i;
  548: 
  549:         /* if key is longer than 64 bytes reset it to key=MD5(key) */
  550:         if (key_len > 64) {
  551: 
  552:                 MD5Init(&tctx);
  553:                 MD5Update(&tctx, key, key_len);
  554:                 MD5Final(tk, &tctx);
  555: 
  556:                 key = tk;
  557:                 key_len = 16;
  558:         }
  559: 
  560:         /*
  561:          * the HMAC_MD5 transform looks like:
  562:          *
  563:          * MD5(K XOR opad, MD5(K XOR ipad, text))
  564:          *
  565:          * where K is an n byte key
  566:          * ipad is the byte 0x36 repeated 64 times
  567:          * opad is the byte 0x5c repeated 64 times
  568:          * and text is the data being protected
  569:          */
  570: 
  571:         /* start out by storing key in pads */
  572:         bzero( k_ipad, sizeof k_ipad);
  573:         bzero( k_opad, sizeof k_opad);
  574:         bcopy( key, k_ipad, key_len);
  575:         bcopy( key, k_opad, key_len);
  576: 
  577:         /* XOR key with ipad and opad values */
  578:         for (i=0; i<64; i++) {
  579:                 k_ipad[i] ^= 0x36;
  580:                 k_opad[i] ^= 0x5c;
  581:         }
  582:         /* perform inner MD5 */
  583:         MD5Init(&context);                   /* init context for 1st pass */
  584:         MD5Update(&context, k_ipad, 64);      /* start with inner pad */
  585:         MD5Update(&context, text, text_len); /* then text of datagram */
  586:         MD5Final(digest, &context);          /* finish up 1st pass */
  587: 
  588:         /* perform outer MD5 */
  589: 	
  590:         MD5Init(&context);                   /* init context for 2nd */
  591: 
  592:         MD5Update(&context, k_opad, 64);     /* start with outer pad */
  593:         MD5Update(&context, digest, 16);     /* then results of 1st hash */
  594:         MD5Final(digest, &context);          /* finish up 2nd pass */
  595: }
  596: 
  597: /* Hexdumping on screen in a fancy format for debuging purposes */
  598: int hexdump(unsigned char *zone, int len) {
  599:     int rc=0,i;
  600:     unsigned char *ptr;
  601: 
  602:     ptr = zone;
  603:     fprintf(stderr,"-- hexdump at %p (%d bytes long) --",zone,len);
  604:     for( i = 0 ;i < len;i++) {
  605: 	if((i%16)==0)
  606: 	    fprintf(stderr,"\n%p ",ptr+i);
  607: 	if((i%8)==0)
  608: 	    fprintf(stderr," ");
  609: 	fprintf(stderr,"0x%.2x ",*(ptr+i));
  610:     }
  611:     fprintf(stderr,"\n");
  612:     return rc;
  613: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>