signature.c revision 1.2
11558Srgrimes/* 21558Srgrimes * Redistribution and use in source and binary forms, with or without 31558Srgrimes * modification, are permitted provided that: (1) source code 41558Srgrimes * distributions retain the above copyright notice and this paragraph 51558Srgrimes * in its entirety, and (2) distributions including binary code include 61558Srgrimes * the above copyright notice and this paragraph in its entirety in 71558Srgrimes * the documentation or other materials provided with the distribution. 81558Srgrimes * THIS SOFTWARE IS PROVIDED ``AS IS'' AND 91558Srgrimes * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 101558Srgrimes * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 111558Srgrimes * FOR A PARTICULAR PURPOSE. 121558Srgrimes * 13128085Sbde * Functions for signature and digest verification. 141558Srgrimes * 151558Srgrimes * Original code by Hannes Gredler (hannes@juniper.net) 161558Srgrimes */ 171558Srgrimes 181558Srgrimes#include <sys/cdefs.h> 191558Srgrimes#ifndef lint 201558Srgrimes#if 0 211558Srgrimesstatic const char rcsid[] _U_ = 221558Srgrimes "@(#) Header: /tcpdump/master/tcpdump/signature.c,v 1.2 2008-09-22 20:22:10 guy Exp (LBL)"; 231558Srgrimes#else 241558Srgrimes__RCSID("$NetBSD: signature.c,v 1.2 2010/12/05 05:11:31 christos Exp $"); 251558Srgrimes#endif 261558Srgrimes#endif 271558Srgrimes 281558Srgrimes#ifdef HAVE_CONFIG_H 291558Srgrimes#include "config.h" 301558Srgrimes#endif 3136997Scharnier 3223672Speter#include <tcpdump-stdinc.h> 3336997Scharnier 3436997Scharnier#include <string.h> 3550476Speter 361558Srgrimes#include "interface.h" 371558Srgrimes#include "signature.h" 381558Srgrimes 391558Srgrimes#ifdef HAVE_LIBCRYPTO 401558Srgrimes#include <openssl/md5.h> 411558Srgrimes#endif 421558Srgrimes 431558Srgrimesconst struct tok signature_check_values[] = { 441558Srgrimes { SIGNATURE_VALID, "valid"}, 451558Srgrimes { SIGNATURE_INVALID, "invalid"}, 4619239Sfenner { CANT_CHECK_SIGNATURE, "unchecked"}, 4719239Sfenner { 0, NULL } 4836115Sfenner}; 491558Srgrimes 501558Srgrimes 511558Srgrimes#ifdef HAVE_LIBCRYPTO 521558Srgrimes/* 531558Srgrimes * Compute a HMAC MD5 sum. 541558Srgrimes * Taken from rfc2104, Appendix. 551558Srgrimes */ 56103949Smikestatic void 5759216Simpsignature_compute_hmac_md5(const u_int8_t *text, int text_len, unsigned char *key, 581558Srgrimes unsigned int key_len, u_int8_t *digest) 591558Srgrimes{ 601558Srgrimes MD5_CTX context; 611558Srgrimes unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */ 621558Srgrimes unsigned char k_opad[65]; /* outer padding - key XORd with opad */ 631558Srgrimes unsigned char tk[16]; 641558Srgrimes int i; 651558Srgrimes 661558Srgrimes /* if key is longer than 64 bytes reset it to key=MD5(key) */ 671558Srgrimes if (key_len > 64) { 681558Srgrimes 691558Srgrimes MD5_CTX tctx; 701558Srgrimes 711558Srgrimes MD5_Init(&tctx); 7292837Simp MD5_Update(&tctx, key, key_len); 7392837Simp MD5_Final(tk, &tctx); 7492837Simp 7592837Simp key = tk; 7692837Simp key_len = 16; 7792837Simp } 7892837Simp 791558Srgrimes /* 8019300Sfenner * the HMAC_MD5 transform looks like: 811558Srgrimes * 821558Srgrimes * MD5(K XOR opad, MD5(K XOR ipad, text)) 831558Srgrimes * 8492837Simp * where K is an n byte key 851558Srgrimes * ipad is the byte 0x36 repeated 64 times 861558Srgrimes * opad is the byte 0x5c repeated 64 times 8792837Simp * and text is the data being protected 8892837Simp */ 8992837Simp 901558Srgrimes /* start out by storing key in pads */ 911558Srgrimes memset(k_ipad, 0, sizeof k_ipad); 921558Srgrimes memset(k_opad, 0, sizeof k_opad); 931558Srgrimes memcpy(k_ipad, key, key_len); 941558Srgrimes memcpy(k_opad, key, key_len); 951558Srgrimes 961558Srgrimes /* XOR key with ipad and opad values */ 971558Srgrimes for (i=0; i<64; i++) { 9892837Simp k_ipad[i] ^= 0x36; 991558Srgrimes k_opad[i] ^= 0x5c; 10019300Sfenner } 10119300Sfenner 10219300Sfenner /* 10319300Sfenner * perform inner MD5 1041558Srgrimes */ 10519300Sfenner MD5_Init(&context); /* init context for 1st pass */ 10619300Sfenner MD5_Update(&context, k_ipad, 64); /* start with inner pad */ 10719300Sfenner MD5_Update(&context, text, text_len); /* then text of datagram */ 10819300Sfenner MD5_Final(digest, &context); /* finish up 1st pass */ 10919300Sfenner 11019300Sfenner /* 11119300Sfenner * perform outer MD5 11219300Sfenner */ 11319300Sfenner MD5_Init(&context); /* init context for 2nd pass */ 11419300Sfenner MD5_Update(&context, k_opad, 64); /* start with outer pad */ 11519300Sfenner MD5_Update(&context, digest, 16); /* then results of 1st hash */ 11619300Sfenner MD5_Final(digest, &context); /* finish up 2nd pass */ 11719300Sfenner} 11819300Sfenner#endif 11919300Sfenner 12019300Sfenner#ifdef HAVE_LIBCRYPTO 12119300Sfenner/* 1221558Srgrimes * Verify a cryptographic signature of the packet. 1231558Srgrimes * Currently only MD5 is supported. 1241558Srgrimes */ 12592837Simpint 1261558Srgrimessignature_verify (const u_char *pptr, u_int plen, u_char *sig_ptr) 12786473Siedowse{ 12886473Siedowse u_int8_t rcvsig[16]; 1291558Srgrimes u_int8_t sig[16]; 1301558Srgrimes unsigned int i; 1311558Srgrimes 1321558Srgrimes /* 13319239Sfenner * Save the signature before clearing it. 13436115Sfenner */ 1351558Srgrimes memcpy(rcvsig, sig_ptr, sizeof(rcvsig)); 1361558Srgrimes memset(sig_ptr, 0, sizeof(rcvsig)); 137114452Smarkm 1381558Srgrimes if (!sigsecret) { 139114452Smarkm return (CANT_CHECK_SIGNATURE); 14037635Sjkoshy } 1411558Srgrimes 1421558Srgrimes signature_compute_hmac_md5(pptr, plen, (unsigned char *)sigsecret, 1431558Srgrimes strlen(sigsecret), sig); 14419300Sfenner 14537635Sjkoshy if (memcmp(rcvsig, sig, sizeof(sig)) == 0) { 1461558Srgrimes return (SIGNATURE_VALID); 1471558Srgrimes 14823672Speter } else { 1491558Srgrimes 1501558Srgrimes for (i = 0; i < sizeof(sig); ++i) { 1511558Srgrimes (void)printf("%02x", sig[i]); 15237635Sjkoshy } 1531558Srgrimes 1541558Srgrimes return (SIGNATURE_INVALID); 1551558Srgrimes } 15612377Sjoerg} 15712377Sjoerg#endif 158122669Sjohan 159114452Smarkm/* 160114452Smarkm * Local Variables: 16119300Sfenner * c-style: whitesmith 16219300Sfenner * c-basic-offset: 4 16319239Sfenner * End: 16419300Sfenner */ 16519317Sfenner