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