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 */
}
|