X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/5bae4ab8a3d797f4056d957da982ae91e77cfbec..18fc231cd2e005ccb43cef12d2f3863ed665337e:/deattack.c diff --git a/deattack.c b/deattack.c index 9bdbc3ec..bf4451b8 100644 --- a/deattack.c +++ b/deattack.c @@ -1,5 +1,4 @@ /* - * $Id$ * Cryptographic attack detector for ssh - source code * * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. @@ -15,167 +14,120 @@ * SOFTWARE. * * Ariel Futoransky - * */ + * + */ #include "includes.h" + #include "deattack.h" -#include "ssh.h" +#include "log.h" #include "crc32.h" #include "getput.h" #include "xmalloc.h" /* SSH Constants */ -#define SSH_MAXBLOCKS (32 * 1024) -#define SSH_BLOCKSIZE (8) +#define SSH_MAXBLOCKS (32 * 1024) +#define SSH_BLOCKSIZE (8) /* Hashing constants */ -#define HASH_MINSIZE (8 * 1024) -#define HASH_ENTRYSIZE (2) -#define HASH_FACTOR(x) ((x)*3/2) -#define HASH_UNUSEDCHAR (0xff) -#define HASH_UNUSED (0xffff) -#define HASH_IV (0xfffe) +#define HASH_MINSIZE (8 * 1024) +#define HASH_ENTRYSIZE (2) +#define HASH_FACTOR(x) ((x)*3/2) +#define HASH_UNUSEDCHAR (0xff) +#define HASH_UNUSED (0xffff) +#define HASH_IV (0xfffe) -#define HASH_MINBLOCKS (7*SSH_BLOCKSIZE) +#define HASH_MINBLOCKS (7*SSH_BLOCKSIZE) /* Hash function (Input keys are cipher results) */ -#define HASH(x) GET_32BIT(x) +#define HASH(x) GET_32BIT(x) -#define CMP(a,b) (memcmp(a, b, SSH_BLOCKSIZE)) +#define CMP(a, b) (memcmp(a, b, SSH_BLOCKSIZE)) - -void -crc_update(u_int32_t * a, u_int32_t b) +static void +crc_update(u_int32_t *a, u_int32_t b) { - b ^= *a; - *a = crc32((unsigned char *) &b, sizeof(b)); + b ^= *a; + *a = ssh_crc32((u_char *)&b, sizeof(b)); } -/* - check_crc - detects if a block is used in a particular pattern - */ - -int -check_crc(unsigned char *S, unsigned char *buf, u_int32_t len, unsigned char *IV) +/* detect if a block is used in a particular pattern */ +static int +check_crc(u_char *S, u_char *buf, u_int32_t len) { - u_int32_t crc; - unsigned char *c; - - crc = 0; - if (IV && !CMP(S, IV)) - { - crc_update(&crc, 1); - crc_update(&crc, 0); - } - for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) - { - if (!CMP(S, c)) - { - crc_update(&crc, 1); - crc_update(&crc, 0); - } else - { - crc_update(&crc, 0); - crc_update(&crc, 0); - } - } - - return (crc == 0); + u_int32_t crc; + u_char *c; + + crc = 0; + for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { + if (!CMP(S, c)) { + crc_update(&crc, 1); + crc_update(&crc, 0); + } else { + crc_update(&crc, 0); + crc_update(&crc, 0); + } + } + return (crc == 0); } -/* - detect_attack - Detects a crc32 compensation attack on a packet - */ +/* Detect a crc32 compensation attack on a packet */ int -detect_attack(unsigned char *buf, u_int32_t len, unsigned char *IV) +detect_attack(u_char *buf, u_int32_t len) { - static u_int16_t *h = (u_int16_t *) NULL; - static u_int16_t n = HASH_MINSIZE / HASH_ENTRYSIZE; - register u_int32_t i, j; - u_int32_t l; - register unsigned char *c; - unsigned char *d; - - if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) || - len % SSH_BLOCKSIZE != 0) { - fatal("detect_attack: bad length %d", len); - } - - for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2); - - if (h == NULL) - { - debug("Installing crc compensation attack detector."); - n = l; - h = (u_int16_t *) xmalloc(n * HASH_ENTRYSIZE); - } else - { - if (l > n) - { - n = l; - h = (u_int16_t *) xrealloc(h, n * HASH_ENTRYSIZE); - } - } - - - if (len <= HASH_MINBLOCKS) - { - for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) - { - if (IV && (!CMP(c, IV))) - { - if ((check_crc(c, buf, len, IV))) - return (DEATTACK_DETECTED); - else - break; - } - for (d = buf; d < c; d += SSH_BLOCKSIZE) - { - if (!CMP(c, d)) - { - if ((check_crc(c, buf, len, IV))) - return (DEATTACK_DETECTED); - else - break; + static u_int16_t *h = (u_int16_t *) NULL; + static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE; + u_int32_t i, j; + u_int32_t l; + u_char *c; + u_char *d; + + if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) || + len % SSH_BLOCKSIZE != 0) { + fatal("detect_attack: bad length %d", len); + } + for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2) + ; + + if (h == NULL) { + debug("Installing crc compensation attack detector."); + h = (u_int16_t *) xmalloc(l * HASH_ENTRYSIZE); + n = l; + } else { + if (l > n) { + h = (u_int16_t *) xrealloc(h, l * HASH_ENTRYSIZE); + n = l; + } + } + + if (len <= HASH_MINBLOCKS) { + for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { + for (d = buf; d < c; d += SSH_BLOCKSIZE) { + if (!CMP(c, d)) { + if ((check_crc(c, buf, len))) + return (DEATTACK_DETECTED); + else + break; + } + } + } + return (DEATTACK_OK); } - } - } - return (DEATTACK_OK); - } - memset(h, HASH_UNUSEDCHAR, n * HASH_ENTRYSIZE); - - if (IV) - h[HASH(IV) & (n - 1)] = HASH_IV; - - - for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) - { - for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED; - i = (i + 1) & (n - 1)) - { - if (h[i] == HASH_IV) - { - if (!CMP(c, IV)) - { - if (check_crc(c, buf, len, IV)) - return (DEATTACK_DETECTED); - else - break; + memset(h, HASH_UNUSEDCHAR, n * HASH_ENTRYSIZE); + + for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) { + for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED; + i = (i + 1) & (n - 1)) { + if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) { + if (check_crc(c, buf, len)) + return (DEATTACK_DETECTED); + else + break; + } + } + h[i] = j; } - } else if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) - { - if (check_crc(c, buf, len, IV)) - return (DEATTACK_DETECTED); - else - break; - } - } - h[i] = j; - } - - return (DEATTACK_OK); + return (DEATTACK_OK); }