1 /* 2 * Redistribution and use in source and binary forms, with or without 3 * modification, are permitted provided that: (1) source code 4 * distributions retain the above copyright notice and this paragraph 5 * in its entirety, and (2) distributions including binary code include 6 * the above copyright notice and this paragraph in its entirety in 7 * the documentation or other materials provided with the distribution. 8 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND 9 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 10 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 11 * FOR A PARTICULAR PURPOSE. 12 * 13 * Functions for signature and digest verification. 14 * 15 * Original code by Hannes Gredler (hannes@juniper.net) 16 */ 17 18 #include <sys/cdefs.h> 19 #ifndef lint 20 #if 0 21 static const char rcsid[] _U_ = 22 "@(#) Header: /tcpdump/master/tcpdump/signature.c,v 1.2 2008-09-22 20:22:10 guy Exp (LBL)"; 23 #else 24 __RCSID("$NetBSD: signature.c,v 1.4 2013/12/31 17:33:31 christos Exp $"); 25 #endif 26 #endif 27 28 #ifdef HAVE_CONFIG_H 29 #include "config.h" 30 #endif 31 32 #include <tcpdump-stdinc.h> 33 34 #include <string.h> 35 36 #include "interface.h" 37 #include "signature.h" 38 39 #ifdef HAVE_LIBCRYPTO 40 #include <openssl/md5.h> 41 #endif 42 43 const struct tok signature_check_values[] = { 44 { SIGNATURE_VALID, "valid"}, 45 { SIGNATURE_INVALID, "invalid"}, 46 { CANT_CHECK_SIGNATURE, "unchecked"}, 47 { 0, NULL } 48 }; 49 50 51 #ifdef HAVE_LIBCRYPTO 52 /* 53 * Compute a HMAC MD5 sum. 54 * Taken from rfc2104, Appendix. 55 */ 56 USES_APPLE_DEPRECATED_API 57 static void 58 signature_compute_hmac_md5(const u_int8_t *text, int text_len, unsigned char *key, 59 unsigned int key_len, u_int8_t *digest) 60 { 61 MD5_CTX context; 62 unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */ 63 unsigned char k_opad[65]; /* outer padding - key XORd with opad */ 64 unsigned char tk[16]; 65 int i; 66 67 /* if key is longer than 64 bytes reset it to key=MD5(key) */ 68 if (key_len > 64) { 69 70 MD5_CTX tctx; 71 72 MD5_Init(&tctx); 73 MD5_Update(&tctx, key, key_len); 74 MD5_Final(tk, &tctx); 75 76 key = tk; 77 key_len = 16; 78 } 79 80 /* 81 * the HMAC_MD5 transform looks like: 82 * 83 * MD5(K XOR opad, MD5(K XOR ipad, text)) 84 * 85 * where K is an n byte key 86 * ipad is the byte 0x36 repeated 64 times 87 * opad is the byte 0x5c repeated 64 times 88 * and text is the data being protected 89 */ 90 91 /* start out by storing key in pads */ 92 memset(k_ipad, 0, sizeof k_ipad); 93 memset(k_opad, 0, sizeof k_opad); 94 memcpy(k_ipad, key, key_len); 95 memcpy(k_opad, key, key_len); 96 97 /* XOR key with ipad and opad values */ 98 for (i=0; i<64; i++) { 99 k_ipad[i] ^= 0x36; 100 k_opad[i] ^= 0x5c; 101 } 102 103 /* 104 * perform inner MD5 105 */ 106 MD5_Init(&context); /* init context for 1st pass */ 107 MD5_Update(&context, k_ipad, 64); /* start with inner pad */ 108 MD5_Update(&context, text, text_len); /* then text of datagram */ 109 MD5_Final(digest, &context); /* finish up 1st pass */ 110 111 /* 112 * perform outer MD5 113 */ 114 MD5_Init(&context); /* init context for 2nd pass */ 115 MD5_Update(&context, k_opad, 64); /* start with outer pad */ 116 MD5_Update(&context, digest, 16); /* then results of 1st hash */ 117 MD5_Final(digest, &context); /* finish up 2nd pass */ 118 } 119 USES_APPLE_RST 120 #endif 121 122 #ifdef HAVE_LIBCRYPTO 123 /* 124 * Verify a cryptographic signature of the packet. 125 * Currently only MD5 is supported. 126 */ 127 int 128 signature_verify (const u_char *pptr, u_int plen, u_char *sig_ptr) 129 { 130 u_int8_t rcvsig[16]; 131 u_int8_t sig[16]; 132 unsigned int i; 133 134 /* 135 * Save the signature before clearing it. 136 */ 137 memcpy(rcvsig, sig_ptr, sizeof(rcvsig)); 138 memset(sig_ptr, 0, sizeof(rcvsig)); 139 140 if (!sigsecret) { 141 return (CANT_CHECK_SIGNATURE); 142 } 143 144 signature_compute_hmac_md5(pptr, plen, (unsigned char *)sigsecret, 145 strlen(sigsecret), sig); 146 147 if (memcmp(rcvsig, sig, sizeof(sig)) == 0) { 148 return (SIGNATURE_VALID); 149 150 } else { 151 152 for (i = 0; i < sizeof(sig); ++i) { 153 (void)printf("%02x", sig[i]); 154 } 155 156 return (SIGNATURE_INVALID); 157 } 158 } 159 #endif 160 161 /* 162 * Local Variables: 163 * c-style: whitesmith 164 * c-basic-offset: 4 165 * End: 166 */ 167