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}
| 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 */ 35void 36SSH_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 56void 57SSH_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 */ 82static void 83swap_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 108void (*cipher_attack_detected) (const char *fmt,...) = fatal; 109 110static inline void 111detect_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 */ 124static 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 141unsigned int 142cipher_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 152const char * 153cipher_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 166int 167cipher_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 182void 183cipher_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 201void 202cipher_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 255void 256cipher_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 289void 290cipher_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}
|