summaryrefslogtreecommitdiff
path: root/deattack.c
diff options
context:
space:
mode:
Diffstat (limited to 'deattack.c')
-rw-r--r--deattack.c33
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
49crc_update(u_int32_t *a, u_int32_t b) 49crc_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 */
56static int 56static int
57check_crc(u_char *S, u_char *buf, u_int32_t len, 57check_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 */
82int 77int
83detect_attack(u_char *buf, u_int32_t len, u_char *IV) 78detect_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;