File: ipsecah.c

package info (click to toggle)
vrrpd 1.0-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k, lenny, sarge
  • size: 300 kB
  • ctags: 308
  • sloc: ansic: 2,618; makefile: 68; sh: 35
file content (84 lines) | stat: -rw-r--r-- 2,901 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/*
 * Soft:        IPSEC AH implementation according to RFC 2402. Processing
 *              authentication data encryption using HMAC MD5 according to
 *              RFCs 2085 & 2104.
 *
 * Version:     $Id: ipsecah.h,v 0.2.8 2001/05/23 16:25:32 acassen Exp $
 *
 * Author:      Alexandre Cassen, <acassen@linux-vs.org>
 *
 * Changes:
 *              Alexandre Cassen : 2001/04/27      Initial release
 *
 *
 *              This program is distributed in the hope that it will be useful, 
 *              but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 *              See the GNU General Public License for more details.
 *
 *              This program is free software; you can redistribute it and/or
 *              modify it under the terms of the GNU General Public License
 *              as published by the Free Software Foundation; either version
 *              2 of the License, or (at your option) any later version.
 */

#include "ipsecah.h"

/* hmac_md5 computation according to the RFCs 2085 & 2104 */
void hmac_md5(unsigned char *buffer,int buffer_len,
              unsigned char *key,int key_len,unsigned char *digest)
{
  MD5_CTX context;
  unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */
  unsigned char k_opad[65]; /* outer padding - key XORd with opad */
  unsigned char tk[16];
  int i;

  /* Initialize data */
  memset(k_ipad,0,sizeof(k_ipad));
  memset(k_opad,0,sizeof(k_opad));
  memset(tk,0,sizeof(tk));

  /* If the key is longer than 64 bytes => set it to key=MD5(key) */
  if (key_len > 64) {
    MD5_CTX tctx;

    /* Compute the MD5 digest */
    MD5Init(&tctx);
    MD5Update(&tctx,key,key_len);
    MD5Final(tk,&tctx);

    key = tk;
    key_len = 16;
  }

  /* The global HMAC_MD5 algo looks like (rfc2085.2.2) :
     MD5(K XOR opad, MD5(K XOR ipad, buffer))
     K : an n byte key
     ipad : byte 0x36 repeated 64 times
     opad : byte 0x5c repeated 64 times
     buffer : buffer being protected
   */
  memset(k_ipad,0,sizeof(k_ipad));
  memset(k_opad,0,sizeof(k_opad));
  memcpy(k_ipad,key,key_len);
  memcpy(k_opad,key,key_len);

  /* XOR key with ipad and opad values */
  for (i=0;i<64;i++) {
    k_ipad[i] ^=0x36;
    k_opad[i] ^=0x5c;
  }

  /* Compute inner MD5 */
  MD5Init(&context);                     /* Init context for 1st pass */
  MD5Update(&context,k_ipad,64);         /* start with inner pad */
  MD5Update(&context,buffer,buffer_len); /* next with buffer datagram */
  MD5Final(digest,&context);             /* Finish 1st pass */

  /* Compute outer MD5 */
  MD5Init(&context);                     /* Init context for 2nd pass */
  MD5Update(&context,k_opad,64);         /* start with inner pad */
  MD5Update(&context,digest,16);         /* next result of 1st pass */
  MD5Final(digest,&context);             /* Finish 2nd pass */
}