summaryrefslogtreecommitdiff
path: root/deattack.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
committerDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
commit95def09838fc61b37b6ea7cd5c234a465b4b129b (patch)
tree042744f76f40a326b873cb1c3690a6d7d966bc3e /deattack.c
parent4d2f15f895f4c795afc008aeff3fd2ceffbc44f4 (diff)
- Merged very large OpenBSD source code reformat
- OpenBSD CVS updates - [channels.c cipher.c compat.c log-client.c scp.c serverloop.c] [ssh.h sshd.8 sshd.c] syslog changes: * Unified Logmessage for all auth-types, for success and for failed * Standard connections get only ONE line in the LOG when level==LOG: Auth-attempts are logged only, if authentication is: a) successfull or b) with passwd or c) we had more than AUTH_FAIL_LOG failues * many log() became verbose() * old behaviour with level=VERBOSE - [readconf.c readconf.h ssh.1 ssh.h sshconnect.c sshd.c] tranfer s/key challenge/response data in SSH_SMSG_AUTH_TIS_CHALLENGE messages. allows use of s/key in windows (ttssh, securecrt) and ssh-1.2.27 clients without 'ssh -v', ok: niels@ - [sshd.8] -V, for fallback to openssh in SSH2 compatibility mode - [sshd.c] fix sigchld race; cjc5@po.cwru.edu
Diffstat (limited to 'deattack.c')
-rw-r--r--deattack.c238
1 files changed, 106 insertions, 132 deletions
diff --git a/deattack.c b/deattack.c
index afd96e4e4..81b1c8efb 100644
--- a/deattack.c
+++ b/deattack.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: deattack.c,v 1.2 1999/11/08 05:15:55 damien Exp $ 2 * $Id: deattack.c,v 1.3 1999/11/24 13:26:22 damien Exp $
3 * Cryptographic attack detector for ssh - source code 3 * Cryptographic attack detector for ssh - source code
4 * 4 *
5 * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. 5 * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina.
@@ -15,7 +15,8 @@
15 * SOFTWARE. 15 * SOFTWARE.
16 * 16 *
17 * Ariel Futoransky <futo@core-sdi.com> 17 * Ariel Futoransky <futo@core-sdi.com>
18 * <http://www.core-sdi.com> */ 18 * <http://www.core-sdi.com>
19 */
19 20
20#include "includes.h" 21#include "includes.h"
21#include "deattack.h" 22#include "deattack.h"
@@ -25,157 +26,130 @@
25#include "xmalloc.h" 26#include "xmalloc.h"
26 27
27/* SSH Constants */ 28/* SSH Constants */
28#define SSH_MAXBLOCKS (32 * 1024) 29#define SSH_MAXBLOCKS (32 * 1024)
29#define SSH_BLOCKSIZE (8) 30#define SSH_BLOCKSIZE (8)
30 31
31/* Hashing constants */ 32/* Hashing constants */
32#define HASH_MINSIZE (8 * 1024) 33#define HASH_MINSIZE (8 * 1024)
33#define HASH_ENTRYSIZE (2) 34#define HASH_ENTRYSIZE (2)
34#define HASH_FACTOR(x) ((x)*3/2) 35#define HASH_FACTOR(x) ((x)*3/2)
35#define HASH_UNUSEDCHAR (0xff) 36#define HASH_UNUSEDCHAR (0xff)
36#define HASH_UNUSED (0xffff) 37#define HASH_UNUSED (0xffff)
37#define HASH_IV (0xfffe) 38#define HASH_IV (0xfffe)
38 39
39#define HASH_MINBLOCKS (7*SSH_BLOCKSIZE) 40#define HASH_MINBLOCKS (7*SSH_BLOCKSIZE)
40 41
41 42
42/* Hash function (Input keys are cipher results) */ 43/* Hash function (Input keys are cipher results) */
43#define HASH(x) GET_32BIT(x) 44#define HASH(x) GET_32BIT(x)
44 45
45#define CMP(a,b) (memcmp(a, b, SSH_BLOCKSIZE)) 46#define CMP(a,b) (memcmp(a, b, SSH_BLOCKSIZE))
46 47
47 48
48void 49void
49crc_update(u_int32_t * a, u_int32_t b) 50crc_update(u_int32_t *a, u_int32_t b)
50{ 51{
51 b ^= *a; 52 b ^= *a;
52 *a = crc32((unsigned char *) &b, sizeof(b)); 53 *a = crc32((unsigned char *) &b, sizeof(b));
53} 54}
54 55
55/* 56/* detect if a block is used in a particular pattern */
56 check_crc
57 detects if a block is used in a particular pattern
58 */
59
60int 57int
61check_crc(unsigned char *S, unsigned char *buf, u_int32_t len, unsigned char *IV) 58check_crc(unsigned char *S, unsigned char *buf, u_int32_t len,
59 unsigned char *IV)
62{ 60{
63 u_int32_t crc; 61 u_int32_t crc;
64 unsigned char *c; 62 unsigned char *c;
65 63
66 crc = 0; 64 crc = 0;
67 if (IV && !CMP(S, IV)) 65 if (IV && !CMP(S, IV)) {
68 { 66 crc_update(&crc, 1);
69 crc_update(&crc, 1); 67 crc_update(&crc, 0);
70 crc_update(&crc, 0); 68 }
71 } 69 for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) {
72 for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) 70 if (!CMP(S, c)) {
73 { 71 crc_update(&crc, 1);
74 if (!CMP(S, c)) 72 crc_update(&crc, 0);
75 { 73 } else {
76 crc_update(&crc, 1); 74 crc_update(&crc, 0);
77 crc_update(&crc, 0); 75 crc_update(&crc, 0);
78 } else 76 }
79 { 77 }
80 crc_update(&crc, 0); 78 return (crc == 0);
81 crc_update(&crc, 0);
82 }
83 }
84
85 return (crc == 0);
86} 79}
87 80
88 81
89/* 82/* Detect a crc32 compensation attack on a packet */
90 detect_attack
91 Detects a crc32 compensation attack on a packet
92 */
93int 83int
94detect_attack(unsigned char *buf, u_int32_t len, unsigned char *IV) 84detect_attack(unsigned char *buf, u_int32_t len, unsigned char *IV)
95{ 85{
96 static u_int16_t *h = (u_int16_t *) NULL; 86 static u_int16_t *h = (u_int16_t *) NULL;
97 static u_int16_t n = HASH_MINSIZE / HASH_ENTRYSIZE; 87 static u_int16_t n = HASH_MINSIZE / HASH_ENTRYSIZE;
98 register u_int32_t i, j; 88 register u_int32_t i, j;
99 u_int32_t l; 89 u_int32_t l;
100 register unsigned char *c; 90 register unsigned char *c;
101 unsigned char *d; 91 unsigned char *d;
102 92
103 if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) || 93 if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) ||
104 len % SSH_BLOCKSIZE != 0) { 94 len % SSH_BLOCKSIZE != 0) {
105 fatal("detect_attack: bad length %d", len); 95 fatal("detect_attack: bad length %d", len);
106 } 96 }
107 97 for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2)
108 for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2); 98 ;
109 99
110 if (h == NULL) 100 if (h == NULL) {
111 { 101 debug("Installing crc compensation attack detector.");
112 debug("Installing crc compensation attack detector."); 102 n = l;
113 n = l; 103 h = (u_int16_t *) xmalloc(n * HASH_ENTRYSIZE);
114 h = (u_int16_t *) xmalloc(n * HASH_ENTRYSIZE); 104 } else {
115 } else 105 if (l > n) {
116 { 106 n = l;
117 if (l > n) 107 h = (u_int16_t *) xrealloc(h, n * HASH_ENTRYSIZE);
118 { 108 }
119 n = l; 109 }
120 h = (u_int16_t *) xrealloc(h, n * HASH_ENTRYSIZE); 110
121 } 111 if (len <= HASH_MINBLOCKS) {
122 } 112 for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) {
123 113 if (IV && (!CMP(c, IV))) {
124 114 if ((check_crc(c, buf, len, IV)))
125 if (len <= HASH_MINBLOCKS) 115 return (DEATTACK_DETECTED);
126 { 116 else
127 for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) 117 break;
128 { 118 }
129 if (IV && (!CMP(c, IV))) 119 for (d = buf; d < c; d += SSH_BLOCKSIZE) {
130 { 120 if (!CMP(c, d)) {
131 if ((check_crc(c, buf, len, IV))) 121 if ((check_crc(c, buf, len, IV)))
132 return (DEATTACK_DETECTED); 122 return (DEATTACK_DETECTED);
133 else 123 else
134 break; 124 break;
135 } 125 }
136 for (d = buf; d < c; d += SSH_BLOCKSIZE) 126 }
137 { 127 }
138 if (!CMP(c, d)) 128 return (DEATTACK_OK);
139 {
140 if ((check_crc(c, buf, len, IV)))
141 return (DEATTACK_DETECTED);
142 else
143 break;
144 } 129 }
145 } 130 memset(h, HASH_UNUSEDCHAR, n * HASH_ENTRYSIZE);
146 } 131
147 return (DEATTACK_OK); 132 if (IV)
148 } 133 h[HASH(IV) & (n - 1)] = HASH_IV;
149 memset(h, HASH_UNUSEDCHAR, n * HASH_ENTRYSIZE); 134
150 135 for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) {
151 if (IV) 136 for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED;
152 h[HASH(IV) & (n - 1)] = HASH_IV; 137 i = (i + 1) & (n - 1)) {
153 138 if (h[i] == HASH_IV) {
154 139 if (!CMP(c, IV)) {
155 for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) 140 if (check_crc(c, buf, len, IV))
156 { 141 return (DEATTACK_DETECTED);
157 for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED; 142 else
158 i = (i + 1) & (n - 1)) 143 break;
159 { 144 }
160 if (h[i] == HASH_IV) 145 } else if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) {
161 { 146 if (check_crc(c, buf, len, IV))
162 if (!CMP(c, IV)) 147 return (DEATTACK_DETECTED);
163 { 148 else
164 if (check_crc(c, buf, len, IV)) 149 break;
165 return (DEATTACK_DETECTED); 150 }
166 else 151 }
167 break; 152 h[i] = j;
168 } 153 }
169 } else if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) 154 return (DEATTACK_OK);
170 {
171 if (check_crc(c, buf, len, IV))
172 return (DEATTACK_DETECTED);
173 else
174 break;
175 }
176 }
177 h[i] = j;
178 }
179
180 return (DEATTACK_OK);
181} 155}