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