diff options
author | Damien Miller <djm@mindrot.org> | 1999-11-25 00:26:21 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 1999-11-25 00:26:21 +1100 |
commit | 95def09838fc61b37b6ea7cd5c234a465b4b129b (patch) | |
tree | 042744f76f40a326b873cb1c3690a6d7d966bc3e /deattack.c | |
parent | 4d2f15f895f4c795afc008aeff3fd2ceffbc44f4 (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.c | 238 |
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 | ||
48 | void | 49 | void |
49 | crc_update(u_int32_t * a, u_int32_t b) | 50 | crc_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 | |||
60 | int | 57 | int |
61 | check_crc(unsigned char *S, unsigned char *buf, u_int32_t len, unsigned char *IV) | 58 | check_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 | */ | ||
93 | int | 83 | int |
94 | detect_attack(unsigned char *buf, u_int32_t len, unsigned char *IV) | 84 | detect_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 | } |