/*
* Copyright 2002 Christopher SEKIYA <wileyc@rezrov.net>
* portions copyright 1997-2000 by Pawel Krawczyk <kravietz@ceti.pl>
*
* crypt.c TACACS+ encryption related functions
*
*/
#include "tacshell.h"
#include "md5.h"
unsigned char *
tac_md5_pad(int len, struct tacacs_header * hdr)
{
int n, i, bufsize;
int bp = 0; /* buffer pointer */
int pp = 0; /* pad pointer */
unsigned char *pad;
unsigned char *buf;
MD5_CTX mdcontext;
/* make pseudo pad */
n = (int) (len / 16) + 1; /* number of MD5 runs */
bufsize = sizeof(hdr->session_id) + strlen(server_secret) + sizeof(hdr->version)
+ sizeof(hdr->seq_no) + MD5_LEN + 10;
buf = (unsigned char *) calloc(1, bufsize);
pad = (unsigned char *) calloc(n, MD5_LEN);
for (i = 0; i < n; i++) {
/*
* MD5_1 = MD5{session_id, secret, version, seq_no} MD5_2 =
* MD5{session_id, secret, version, seq_no, MD5_1}
*/
/* place session_id, key, version and seq_no in buffer */
bp = 0;
bcopy(&hdr->session_id, buf, sizeof(session_id));
bp += sizeof(session_id);
bcopy(server_secret, buf + bp, strlen(server_secret));
bp += strlen(server_secret);
bcopy(&hdr->version, buf + bp, sizeof(hdr->version));
bp += sizeof(hdr->version);
bcopy(&hdr->seq_no, buf + bp, sizeof(hdr->seq_no));
bp += sizeof(hdr->seq_no);
/* append previous pad if this is not the first run */
if (i) {
bcopy(pad + ((i - 1) * MD5_LEN), buf + bp, MD5_LEN);
bp += MD5_LEN;
}
MD5Init(&mdcontext);
MD5Update(&mdcontext, buf, bp);
MD5Final(pad + pp, &mdcontext); /* correct for pppd-2.3.4 */
pp += MD5_LEN;
}
free(buf);
return (pad);
}
/*
* Perform encryption/decryption on buffer. This means simply XORing each
* byte from buffer with according byte from pseudo-random pad.
*/
void
tac_crypt(unsigned char *buf, struct tacacs_header * th, int length)
{
int i;
unsigned char *pad;
/* null operation if no encryption requested */
if (th->encryption == TAC_PLUS_ENCRYPTED) {
pad = tac_md5_pad(length, th);
for (i = 0; i < length; i++) {
*(buf + i) ^= pad[i];
}
free(pad);
} else {
fprintf(stderr, "tacshell: not using TACACS+ encryption\n");
}
}
syntax highlighted by Code2HTML, v. 0.9.1