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.20 2000/03/22 09:55:10 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 /* 109 * Names of all encryption algorithms. 110 * These must match the numbers defined in cipher.h. 111 */ 112 static char *cipher_names[] = 113 { 114 "none", 115 "idea", 116 "des", 117 "3des", 118 "tss", 119 "rc4", 120 "blowfish" 121 }; 122 123 /* 124 * Returns a bit mask indicating which ciphers are supported by this 125 * implementation. The bit mask has the corresponding bit set of each 126 * supported cipher. 127 */ 128 129 unsigned int 130 cipher_mask() 131 { 132 unsigned int mask = 0; 133 mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ 134 mask |= 1 << SSH_CIPHER_BLOWFISH; 135 return mask; 136 } 137 138 /* Returns the name of the cipher. */ 139 140 const char * 141 cipher_name(int cipher) 142 { 143 if (cipher < 0 || cipher >= sizeof(cipher_names) / sizeof(cipher_names[0]) || 144 cipher_names[cipher] == NULL) 145 fatal("cipher_name: bad cipher number: %d", cipher); 146 return cipher_names[cipher]; 147 } 148 149 /* 150 * Parses the name of the cipher. Returns the number of the corresponding 151 * cipher, or -1 on error. 152 */ 153 154 int 155 cipher_number(const char *name) 156 { 157 int i; 158 for (i = 0; i < sizeof(cipher_names) / sizeof(cipher_names[0]); i++) 159 if (strcmp(cipher_names[i], name) == 0 && 160 (cipher_mask() & (1 << i))) 161 return i; 162 return -1; 163 } 164 165 /* 166 * Selects the cipher, and keys if by computing the MD5 checksum of the 167 * passphrase and using the resulting 16 bytes as the key. 168 */ 169 170 void 171 cipher_set_key_string(CipherContext *context, int cipher, 172 const char *passphrase, int for_encryption) 173 { 174 MD5_CTX md; 175 unsigned char digest[16]; 176 177 MD5_Init(&md); 178 MD5_Update(&md, (const unsigned char *) passphrase, strlen(passphrase)); 179 MD5_Final(digest, &md); 180 181 cipher_set_key(context, cipher, digest, 16, for_encryption); 182 183 memset(digest, 0, sizeof(digest)); 184 memset(&md, 0, sizeof(md)); 185 } 186 187 /* Selects the cipher to use and sets the key. */ 188 189 void 190 cipher_set_key(CipherContext *context, int cipher, 191 const unsigned char *key, int keylen, int for_encryption) 192 { 193 unsigned char padded[32]; 194 195 /* Set cipher type. */ 196 context->type = cipher; 197 198 /* Get 32 bytes of key data. Pad if necessary. (So that code 199 below does not need to worry about key size). */ 200 memset(padded, 0, sizeof(padded)); 201 memcpy(padded, key, keylen < sizeof(padded) ? keylen : sizeof(padded)); 202 203 /* Initialize the initialization vector. */ 204 switch (cipher) { 205 case SSH_CIPHER_NONE: 206 /* 207 * Has to stay for authfile saving of private key with no 208 * passphrase 209 */ 210 break; 211 212 case SSH_CIPHER_3DES: 213 /* 214 * Note: the least significant bit of each byte of key is 215 * parity, and must be ignored by the implementation. 16 216 * bytes of key are used (first and last keys are the same). 217 */ 218 if (keylen < 16) 219 error("Key length %d is insufficient for 3DES.", keylen); 220 des_set_key((void *) padded, context->u.des3.key1); 221 des_set_key((void *) (padded + 8), context->u.des3.key2); 222 if (keylen <= 16) 223 des_set_key((void *) padded, context->u.des3.key3); 224 else 225 des_set_key((void *) (padded + 16), context->u.des3.key3); 226 memset(context->u.des3.iv2, 0, sizeof(context->u.des3.iv2)); 227 memset(context->u.des3.iv3, 0, sizeof(context->u.des3.iv3)); 228 break; 229 230 case SSH_CIPHER_BLOWFISH: 231 BF_set_key(&context->u.bf.key, keylen, padded); 232 memset(context->u.bf.iv, 0, 8); 233 break; 234 235 default: 236 fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher)); 237 } 238 memset(padded, 0, sizeof(padded)); 239 } 240 241 /* Encrypts data using the cipher. */ 242 243 void 244 cipher_encrypt(CipherContext *context, unsigned char *dest, 245 const unsigned char *src, unsigned int len) 246 { 247 if ((len & 7) != 0) 248 fatal("cipher_encrypt: bad plaintext length %d", len); 249 250 switch (context->type) { 251 case SSH_CIPHER_NONE: 252 memcpy(dest, src, len); 253 break; 254 255 case SSH_CIPHER_3DES: 256 SSH_3CBC_ENCRYPT(context->u.des3.key1, 257 context->u.des3.key2, &context->u.des3.iv2, 258 context->u.des3.key3, &context->u.des3.iv3, 259 dest, (unsigned char *) src, len); 260 break; 261 262 case SSH_CIPHER_BLOWFISH: 263 swap_bytes(src, dest, len); 264 BF_cbc_encrypt(dest, dest, len, 265 &context->u.bf.key, context->u.bf.iv, 266 BF_ENCRYPT); 267 swap_bytes(dest, dest, len); 268 break; 269 270 default: 271 fatal("cipher_encrypt: unknown cipher: %s", cipher_name(context->type)); 272 } 273 } 274 275 /* Decrypts data using the cipher. */ 276 277 void 278 cipher_decrypt(CipherContext *context, unsigned char *dest, 279 const unsigned char *src, unsigned int len) 280 { 281 if ((len & 7) != 0) 282 fatal("cipher_decrypt: bad ciphertext length %d", len); 283 284 switch (context->type) { 285 case SSH_CIPHER_NONE: 286 memcpy(dest, src, len); 287 break; 288 289 case SSH_CIPHER_3DES: 290 SSH_3CBC_DECRYPT(context->u.des3.key1, 291 context->u.des3.key2, &context->u.des3.iv2, 292 context->u.des3.key3, &context->u.des3.iv3, 293 dest, (unsigned char *) src, len); 294 break; 295 296 case SSH_CIPHER_BLOWFISH: 297 swap_bytes(src, dest, len); 298 BF_cbc_encrypt((void *) dest, dest, len, 299 &context->u.bf.key, context->u.bf.iv, 300 BF_DECRYPT); 301 swap_bytes(dest, dest, len); 302 break; 303 304 default: 305 fatal("cipher_decrypt: unknown cipher: %s", cipher_name(context->type)); 306 } 307 } 308