summaryrefslogtreecommitdiff
path: root/cipher.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 /cipher.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 'cipher.c')
-rw-r--r--cipher.c409
1 files changed, 207 insertions, 202 deletions
diff --git a/cipher.c b/cipher.c
index a33188e46..92fcd4740 100644
--- a/cipher.c
+++ b/cipher.c
@@ -1,18 +1,18 @@
1/* 1/*
2 2 *
3cipher.c 3 * cipher.c
4 4 *
5Author: Tatu Ylonen <ylo@cs.hut.fi> 5 * Author: Tatu Ylonen <ylo@cs.hut.fi>
6 6 *
7Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 7 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8 All rights reserved 8 * All rights reserved
9 9 *
10Created: Wed Apr 19 17:41:39 1995 ylo 10 * Created: Wed Apr 19 17:41:39 1995 ylo
11 11 *
12*/ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$Id: cipher.c,v 1.6 1999/11/16 02:37:16 damien Exp $"); 15RCSID("$Id: cipher.c,v 1.7 1999/11/24 13:26:22 damien Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "cipher.h" 18#include "cipher.h"
@@ -38,124 +38,124 @@ RCSID("$Id: cipher.c,v 1.6 1999/11/16 02:37:16 damien Exp $");
38 */ 38 */
39void 39void
40SSH_3CBC_ENCRYPT(des_key_schedule ks1, 40SSH_3CBC_ENCRYPT(des_key_schedule ks1,
41 des_key_schedule ks2, des_cblock *iv2, 41 des_key_schedule ks2, des_cblock * iv2,
42 des_key_schedule ks3, des_cblock *iv3, 42 des_key_schedule ks3, des_cblock * iv3,
43 void *dest, void *src, 43 void *dest, void *src,
44 unsigned int len) 44 unsigned int len)
45{ 45{
46 des_cblock iv1; 46 des_cblock iv1;
47 47
48 memcpy(&iv1, iv2, 8); 48 memcpy(&iv1, iv2, 8);
49 49
50 des_cbc_encrypt(src, dest, len, ks1, &iv1, DES_ENCRYPT); 50 des_cbc_encrypt(src, dest, len, ks1, &iv1, DES_ENCRYPT);
51 memcpy(&iv1, dest + len - 8, 8); 51 memcpy(&iv1, dest + len - 8, 8);
52 52
53 des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_DECRYPT); 53 des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_DECRYPT);
54 memcpy(iv2, &iv1, 8); /* Note how iv1 == iv2 on entry and exit. */ 54 memcpy(iv2, &iv1, 8); /* Note how iv1 == iv2 on entry and exit. */
55 55
56 des_cbc_encrypt(dest, dest, len, ks3, iv3, DES_ENCRYPT); 56 des_cbc_encrypt(dest, dest, len, ks3, iv3, DES_ENCRYPT);
57 memcpy(iv3, dest + len - 8, 8); 57 memcpy(iv3, dest + len - 8, 8);
58} 58}
59 59
60void 60void
61SSH_3CBC_DECRYPT(des_key_schedule ks1, 61SSH_3CBC_DECRYPT(des_key_schedule ks1,
62 des_key_schedule ks2, des_cblock *iv2, 62 des_key_schedule ks2, des_cblock * iv2,
63 des_key_schedule ks3, des_cblock *iv3, 63 des_key_schedule ks3, des_cblock * iv3,
64 void *dest, void *src, 64 void *dest, void *src,
65 unsigned int len) 65 unsigned int len)
66{ 66{
67 des_cblock iv1; 67 des_cblock iv1;
68 68
69 memcpy(&iv1, iv2, 8); 69 memcpy(&iv1, iv2, 8);
70 70
71 des_cbc_encrypt(src, dest, len, ks3, iv3, DES_DECRYPT); 71 des_cbc_encrypt(src, dest, len, ks3, iv3, DES_DECRYPT);
72 memcpy(iv3, src + len - 8, 8); 72 memcpy(iv3, src + len - 8, 8);
73 73
74 des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_ENCRYPT); 74 des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_ENCRYPT);
75 memcpy(iv2, dest + len - 8, 8); 75 memcpy(iv2, dest + len - 8, 8);
76 76
77 des_cbc_encrypt(dest, dest, len, ks1, &iv1, DES_DECRYPT); 77 des_cbc_encrypt(dest, dest, len, ks1, &iv1, DES_DECRYPT);
78 /* memcpy(&iv1, iv2, 8); */ /* Note how iv1 == iv2 on entry and exit. */ 78 /* memcpy(&iv1, iv2, 8); */
79 /* Note how iv1 == iv2 on entry and exit. */
79} 80}
80 81
81/* 82/*
82 * SSH uses a variation on Blowfish, all bytes must be swapped before 83 * SSH uses a variation on Blowfish, all bytes must be swapped before
83 * and after encryption/decryption. Thus the swap_bytes stuff (yuk). 84 * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
84 */ 85 */
85static 86static void
86void
87swap_bytes(const unsigned char *src, unsigned char *dst_, int n) 87swap_bytes(const unsigned char *src, unsigned char *dst_, int n)
88{ 88{
89 u_int32_t *dst = (u_int32_t *)dst_; /* dst must be properly aligned. */ 89 /* dst must be properly aligned. */
90 union { 90 u_int32_t *dst = (u_int32_t *) dst_;
91 u_int32_t i; 91 union {
92 char c[4]; 92 u_int32_t i;
93 } t; 93 char c[4];
94 94 } t;
95 /* Process 8 bytes every lap. */ 95
96 for (n = n / 8; n > 0; n--) 96 /* Process 8 bytes every lap. */
97 { 97 for (n = n / 8; n > 0; n--) {
98 t.c[3] = *src++; 98 t.c[3] = *src++;
99 t.c[2] = *src++; 99 t.c[2] = *src++;
100 t.c[1] = *src++; 100 t.c[1] = *src++;
101 t.c[0] = *src++; 101 t.c[0] = *src++;
102 *dst++ = t.i; 102 *dst++ = t.i;
103 103
104 t.c[3] = *src++; 104 t.c[3] = *src++;
105 t.c[2] = *src++; 105 t.c[2] = *src++;
106 t.c[1] = *src++; 106 t.c[1] = *src++;
107 t.c[0] = *src++; 107 t.c[0] = *src++;
108 *dst++ = t.i; 108 *dst++ = t.i;
109 } 109 }
110} 110}
111 111
112void (*cipher_attack_detected)(const char *fmt, ...) = fatal; 112void (*cipher_attack_detected) (const char *fmt,...) = fatal;
113 113
114static inline 114static inline void
115void
116detect_cbc_attack(const unsigned char *src, 115detect_cbc_attack(const unsigned char *src,
117 unsigned int len) 116 unsigned int len)
118{ 117{
119 return; 118 return;
120 119
121 log("CRC-32 CBC insertion attack detected"); 120 log("CRC-32 CBC insertion attack detected");
122 cipher_attack_detected("CRC-32 CBC insertion attack detected"); 121 cipher_attack_detected("CRC-32 CBC insertion attack detected");
123} 122}
124 123
125/* Names of all encryption algorithms. These must match the numbers defined 124/* Names of all encryption algorithms. These must match the numbers defined
126 int cipher.h. */ 125 int cipher.h. */
127static char *cipher_names[] = 126static char *cipher_names[] =
128{ 127{
129 "none", 128 "none",
130 "idea", 129 "idea",
131 "des", 130 "des",
132 "3des", 131 "3des",
133 "tss", 132 "tss",
134 "rc4", 133 "rc4",
135 "blowfish" 134 "blowfish"
136}; 135};
137 136
138/* Returns a bit mask indicating which ciphers are supported by this 137/* Returns a bit mask indicating which ciphers are supported by this
139 implementation. The bit mask has the corresponding bit set of each 138 implementation. The bit mask has the corresponding bit set of each
140 supported cipher. */ 139 supported cipher. */
141 140
142unsigned int cipher_mask() 141unsigned int
142cipher_mask()
143{ 143{
144 unsigned int mask = 0; 144 unsigned int mask = 0;
145 mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ 145 mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */
146 mask |= 1 << SSH_CIPHER_BLOWFISH; 146 mask |= 1 << SSH_CIPHER_BLOWFISH;
147 return mask; 147 return mask;
148} 148}
149 149
150/* Returns the name of the cipher. */ 150/* Returns the name of the cipher. */
151 151
152const 152const char *
153char *cipher_name(int cipher) 153cipher_name(int cipher)
154{ 154{
155 if (cipher < 0 || cipher >= sizeof(cipher_names) / sizeof(cipher_names[0]) || 155 if (cipher < 0 || cipher >= sizeof(cipher_names) / sizeof(cipher_names[0]) ||
156 cipher_names[cipher] == NULL) 156 cipher_names[cipher] == NULL)
157 fatal("cipher_name: bad cipher number: %d", cipher); 157 fatal("cipher_name: bad cipher number: %d", cipher);
158 return cipher_names[cipher]; 158 return cipher_names[cipher];
159} 159}
160 160
161/* Parses the name of the cipher. Returns the number of the corresponding 161/* Parses the name of the cipher. Returns the number of the corresponding
@@ -164,146 +164,151 @@ char *cipher_name(int cipher)
164int 164int
165cipher_number(const char *name) 165cipher_number(const char *name)
166{ 166{
167 int i; 167 int i;
168 for (i = 0; i < sizeof(cipher_names) / sizeof(cipher_names[0]); i++) 168 for (i = 0; i < sizeof(cipher_names) / sizeof(cipher_names[0]); i++)
169 if (strcmp(cipher_names[i], name) == 0 && 169 if (strcmp(cipher_names[i], name) == 0 &&
170 (cipher_mask() & (1 << i))) 170 (cipher_mask() & (1 << i)))
171 return i; 171 return i;
172 return -1; 172 return -1;
173} 173}
174 174
175/* Selects the cipher, and keys if by computing the MD5 checksum of the 175/* Selects the cipher, and keys if by computing the MD5 checksum of the
176 passphrase and using the resulting 16 bytes as the key. */ 176 passphrase and using the resulting 16 bytes as the key. */
177 177
178void cipher_set_key_string(CipherContext *context, int cipher, 178void
179 const char *passphrase, int for_encryption) 179cipher_set_key_string(CipherContext *context, int cipher,
180 const char *passphrase, int for_encryption)
180{ 181{
181 MD5_CTX md; 182 MD5_CTX md;
182 unsigned char digest[16]; 183 unsigned char digest[16];
183 184
184 MD5_Init(&md); 185 MD5_Init(&md);
185 MD5_Update(&md, (const unsigned char *)passphrase, strlen(passphrase)); 186 MD5_Update(&md, (const unsigned char *) passphrase, strlen(passphrase));
186 MD5_Final(digest, &md); 187 MD5_Final(digest, &md);
187 188
188 cipher_set_key(context, cipher, digest, 16, for_encryption); 189 cipher_set_key(context, cipher, digest, 16, for_encryption);
189 190
190 memset(digest, 0, sizeof(digest)); 191 memset(digest, 0, sizeof(digest));
191 memset(&md, 0, sizeof(md)); 192 memset(&md, 0, sizeof(md));
192} 193}
193 194
194/* Selects the cipher to use and sets the key. */ 195/* Selects the cipher to use and sets the key. */
195 196
196void cipher_set_key(CipherContext *context, int cipher, 197void
197 const unsigned char *key, int keylen, int for_encryption) 198cipher_set_key(CipherContext *context, int cipher,
199 const unsigned char *key, int keylen, int for_encryption)
198{ 200{
199 unsigned char padded[32]; 201 unsigned char padded[32];
200 202
201 /* Set cipher type. */ 203 /* Set cipher type. */
202 context->type = cipher; 204 context->type = cipher;
203 205
204 /* Get 32 bytes of key data. Pad if necessary. (So that code below does 206 /* Get 32 bytes of key data. Pad if necessary. (So that code
205 not need to worry about key size). */ 207 below does not need to worry about key size). */
206 memset(padded, 0, sizeof(padded)); 208 memset(padded, 0, sizeof(padded));
207 memcpy(padded, key, keylen < sizeof(padded) ? keylen : sizeof(padded)); 209 memcpy(padded, key, keylen < sizeof(padded) ? keylen : sizeof(padded));
208 210
209 /* Initialize the initialization vector. */ 211 /* Initialize the initialization vector. */
210 switch (cipher) 212 switch (cipher) {
211 { 213 case SSH_CIPHER_NONE:
212 case SSH_CIPHER_NONE: 214 /* Has to stay for authfile saving of private key with
213 /* Has to stay for authfile saving of private key with no passphrase */ 215 no passphrase */
214 break; 216 break;
215 217
216 case SSH_CIPHER_3DES: 218 case SSH_CIPHER_3DES:
217 /* Note: the least significant bit of each byte of key is parity, 219 /* Note: the least significant bit of each byte of key is
218 and must be ignored by the implementation. 16 bytes of key are 220 parity, and must be ignored by the implementation. 16
219 used (first and last keys are the same). */ 221 bytes of key are used (first and last keys are the
220 if (keylen < 16) 222 same). */
221 error("Key length %d is insufficient for 3DES.", keylen); 223 if (keylen < 16)
222 des_set_key((void*)padded, context->u.des3.key1); 224 error("Key length %d is insufficient for 3DES.", keylen);
223 des_set_key((void*)(padded + 8), context->u.des3.key2); 225 des_set_key((void *) padded, context->u.des3.key1);
224 if (keylen <= 16) 226 des_set_key((void *) (padded + 8), context->u.des3.key2);
225 des_set_key((void*)padded, context->u.des3.key3); 227 if (keylen <= 16)
226 else 228 des_set_key((void *) padded, context->u.des3.key3);
227 des_set_key((void*)(padded + 16), context->u.des3.key3); 229 else
228 memset(context->u.des3.iv2, 0, sizeof(context->u.des3.iv2)); 230 des_set_key((void *) (padded + 16), context->u.des3.key3);
229 memset(context->u.des3.iv3, 0, sizeof(context->u.des3.iv3)); 231 memset(context->u.des3.iv2, 0, sizeof(context->u.des3.iv2));
230 break; 232 memset(context->u.des3.iv3, 0, sizeof(context->u.des3.iv3));
231 233 break;
232 case SSH_CIPHER_BLOWFISH: 234
233 BF_set_key(&context->u.bf.key, keylen, padded); 235 case SSH_CIPHER_BLOWFISH:
234 memset(context->u.bf.iv, 0, 8); 236 BF_set_key(&context->u.bf.key, keylen, padded);
235 break; 237 memset(context->u.bf.iv, 0, 8);
236 238 break;
237 default: 239
238 fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher)); 240 default:
239 } 241 fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher));
240 memset(padded, 0, sizeof(padded)); 242 }
243 memset(padded, 0, sizeof(padded));
241} 244}
242 245
243/* Encrypts data using the cipher. */ 246/* Encrypts data using the cipher. */
244 247
245void cipher_encrypt(CipherContext *context, unsigned char *dest, 248void
246 const unsigned char *src, unsigned int len) 249cipher_encrypt(CipherContext *context, unsigned char *dest,
250 const unsigned char *src, unsigned int len)
247{ 251{
248 if ((len & 7) != 0) 252 if ((len & 7) != 0)
249 fatal("cipher_encrypt: bad plaintext length %d", len); 253 fatal("cipher_encrypt: bad plaintext length %d", len);
250 254
251 switch (context->type) 255 switch (context->type) {
252 { 256 case SSH_CIPHER_NONE:
253 case SSH_CIPHER_NONE: 257 memcpy(dest, src, len);
254 memcpy(dest, src, len); 258 break;
255 break; 259
256 260 case SSH_CIPHER_3DES:
257 case SSH_CIPHER_3DES: 261 SSH_3CBC_ENCRYPT(context->u.des3.key1,
258 SSH_3CBC_ENCRYPT(context->u.des3.key1, 262 context->u.des3.key2, &context->u.des3.iv2,
259 context->u.des3.key2, &context->u.des3.iv2, 263 context->u.des3.key3, &context->u.des3.iv3,
260 context->u.des3.key3, &context->u.des3.iv3, 264 dest, (void *) src, len);
261 dest, (void*)src, len); 265 break;
262 break; 266
263 267 case SSH_CIPHER_BLOWFISH:
264 case SSH_CIPHER_BLOWFISH: 268 swap_bytes(src, dest, len);
265 swap_bytes(src, dest, len); 269 BF_cbc_encrypt(dest, dest, len,
266 BF_cbc_encrypt(dest, dest, len, 270 &context->u.bf.key, context->u.bf.iv,
267 &context->u.bf.key, context->u.bf.iv, BF_ENCRYPT); 271 BF_ENCRYPT);
268 swap_bytes(dest, dest, len); 272 swap_bytes(dest, dest, len);
269 break; 273 break;
270 274
271 default: 275 default:
272 fatal("cipher_encrypt: unknown cipher: %d", context->type); 276 fatal("cipher_encrypt: unknown cipher: %s", cipher_name(context->type));
273 } 277 }
274} 278}
275 279
276/* Decrypts data using the cipher. */ 280/* Decrypts data using the cipher. */
277 281
278void cipher_decrypt(CipherContext *context, unsigned char *dest, 282void
279 const unsigned char *src, unsigned int len) 283cipher_decrypt(CipherContext *context, unsigned char *dest,
284 const unsigned char *src, unsigned int len)
280{ 285{
281 if ((len & 7) != 0) 286 if ((len & 7) != 0)
282 fatal("cipher_decrypt: bad ciphertext length %d", len); 287 fatal("cipher_decrypt: bad ciphertext length %d", len);
283 288
284 switch (context->type) 289 switch (context->type) {
285 { 290 case SSH_CIPHER_NONE:
286 case SSH_CIPHER_NONE: 291 memcpy(dest, src, len);
287 memcpy(dest, src, len); 292 break;
288 break; 293
289 294 case SSH_CIPHER_3DES:
290 case SSH_CIPHER_3DES: 295 /* CRC-32 attack? */
291 /* CRC-32 attack? */ 296 SSH_3CBC_DECRYPT(context->u.des3.key1,
292 SSH_3CBC_DECRYPT(context->u.des3.key1, 297 context->u.des3.key2, &context->u.des3.iv2,
293 context->u.des3.key2, &context->u.des3.iv2, 298 context->u.des3.key3, &context->u.des3.iv3,
294 context->u.des3.key3, &context->u.des3.iv3, 299 dest, (void *) src, len);
295 dest, (void*)src, len); 300 break;
296 break; 301
297 302 case SSH_CIPHER_BLOWFISH:
298 case SSH_CIPHER_BLOWFISH: 303 detect_cbc_attack(src, len);
299 detect_cbc_attack(src, len); 304 swap_bytes(src, dest, len);
300 swap_bytes(src, dest, len); 305 BF_cbc_encrypt((void *) dest, dest, len,
301 BF_cbc_encrypt((void*)dest, dest, len, 306 &context->u.bf.key, context->u.bf.iv,
302 &context->u.bf.key, context->u.bf.iv, BF_DECRYPT); 307 BF_DECRYPT);
303 swap_bytes(dest, dest, len); 308 swap_bytes(dest, dest, len);
304 break; 309 break;
305 310
306 default: 311 default:
307 fatal("cipher_decrypt: unknown cipher: %d", context->type); 312 fatal("cipher_decrypt: unknown cipher: %s", cipher_name(context->type));
308 } 313 }
309} 314}