diff options
Diffstat (limited to 'deattack.c')
-rw-r--r-- | deattack.c | 33 |
1 files changed, 6 insertions, 27 deletions
diff --git a/deattack.c b/deattack.c index 3d48afc89..bf4451b88 100644 --- a/deattack.c +++ b/deattack.c | |||
@@ -49,22 +49,17 @@ static void | |||
49 | crc_update(u_int32_t *a, u_int32_t b) | 49 | crc_update(u_int32_t *a, u_int32_t b) |
50 | { | 50 | { |
51 | b ^= *a; | 51 | b ^= *a; |
52 | *a = ssh_crc32((u_char *) &b, sizeof(b)); | 52 | *a = ssh_crc32((u_char *)&b, sizeof(b)); |
53 | } | 53 | } |
54 | 54 | ||
55 | /* detect if a block is used in a particular pattern */ | 55 | /* detect if a block is used in a particular pattern */ |
56 | static int | 56 | static int |
57 | check_crc(u_char *S, u_char *buf, u_int32_t len, | 57 | check_crc(u_char *S, u_char *buf, u_int32_t len) |
58 | u_char *IV) | ||
59 | { | 58 | { |
60 | u_int32_t crc; | 59 | u_int32_t crc; |
61 | u_char *c; | 60 | u_char *c; |
62 | 61 | ||
63 | crc = 0; | 62 | crc = 0; |
64 | if (IV && !CMP(S, IV)) { | ||
65 | crc_update(&crc, 1); | ||
66 | crc_update(&crc, 0); | ||
67 | } | ||
68 | for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { | 63 | for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { |
69 | if (!CMP(S, c)) { | 64 | if (!CMP(S, c)) { |
70 | crc_update(&crc, 1); | 65 | crc_update(&crc, 1); |
@@ -80,7 +75,7 @@ check_crc(u_char *S, u_char *buf, u_int32_t len, | |||
80 | 75 | ||
81 | /* Detect a crc32 compensation attack on a packet */ | 76 | /* Detect a crc32 compensation attack on a packet */ |
82 | int | 77 | int |
83 | detect_attack(u_char *buf, u_int32_t len, u_char *IV) | 78 | detect_attack(u_char *buf, u_int32_t len) |
84 | { | 79 | { |
85 | static u_int16_t *h = (u_int16_t *) NULL; | 80 | static u_int16_t *h = (u_int16_t *) NULL; |
86 | static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE; | 81 | static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE; |
@@ -109,15 +104,9 @@ detect_attack(u_char *buf, u_int32_t len, u_char *IV) | |||
109 | 104 | ||
110 | if (len <= HASH_MINBLOCKS) { | 105 | if (len <= HASH_MINBLOCKS) { |
111 | for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { | 106 | for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { |
112 | if (IV && (!CMP(c, IV))) { | ||
113 | if ((check_crc(c, buf, len, IV))) | ||
114 | return (DEATTACK_DETECTED); | ||
115 | else | ||
116 | break; | ||
117 | } | ||
118 | for (d = buf; d < c; d += SSH_BLOCKSIZE) { | 107 | for (d = buf; d < c; d += SSH_BLOCKSIZE) { |
119 | if (!CMP(c, d)) { | 108 | if (!CMP(c, d)) { |
120 | if ((check_crc(c, buf, len, IV))) | 109 | if ((check_crc(c, buf, len))) |
121 | return (DEATTACK_DETECTED); | 110 | return (DEATTACK_DETECTED); |
122 | else | 111 | else |
123 | break; | 112 | break; |
@@ -128,21 +117,11 @@ detect_attack(u_char *buf, u_int32_t len, u_char *IV) | |||
128 | } | 117 | } |
129 | memset(h, HASH_UNUSEDCHAR, n * HASH_ENTRYSIZE); | 118 | memset(h, HASH_UNUSEDCHAR, n * HASH_ENTRYSIZE); |
130 | 119 | ||
131 | if (IV) | ||
132 | h[HASH(IV) & (n - 1)] = HASH_IV; | ||
133 | |||
134 | for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) { | 120 | for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) { |
135 | for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED; | 121 | for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED; |
136 | i = (i + 1) & (n - 1)) { | 122 | i = (i + 1) & (n - 1)) { |
137 | if (h[i] == HASH_IV) { | 123 | if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) { |
138 | if (!CMP(c, IV)) { | 124 | if (check_crc(c, buf, len)) |
139 | if (check_crc(c, buf, len, IV)) | ||
140 | return (DEATTACK_DETECTED); | ||
141 | else | ||
142 | break; | ||
143 | } | ||
144 | } else if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) { | ||
145 | if (check_crc(c, buf, len, IV)) | ||
146 | return (DEATTACK_DETECTED); | 125 | return (DEATTACK_DETECTED); |
147 | else | 126 | else |
148 | break; | 127 | break; |