cipher.c revision 61212
157429Smarkm/* 260576Skris * 357429Smarkm * cipher.c 460576Skris * 557429Smarkm * Author: Tatu Ylonen <ylo@cs.hut.fi> 660576Skris * 757429Smarkm * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 857429Smarkm * All rights reserved 960576Skris * 1057429Smarkm * Created: Wed Apr 19 17:41:39 1995 ylo 1160576Skris * 1257464Sgreen * $FreeBSD: head/crypto/openssh/cipher.c 61212 2000-06-03 09:58:15Z kris $ 1357429Smarkm */ 1457429Smarkm 1557429Smarkm#include "includes.h" 1661212SkrisRCSID("$Id: cipher.c,v 1.27 2000/05/22 18:42:00 markus Exp $"); 1757429Smarkm 1857429Smarkm#include "ssh.h" 1957429Smarkm#include "cipher.h" 2060576Skris#include "xmalloc.h" 2157429Smarkm 2257464Sgreen#include <openssl/md5.h> 2357429Smarkm 2457429Smarkm/* 2560576Skris * This is used by SSH1: 2657429Smarkm * 2760576Skris * What kind of triple DES are these 2 routines? 2860576Skris * 2957429Smarkm * Why is there a redundant initialization vector? 3057429Smarkm * 3157429Smarkm * If only iv3 was used, then, this would till effect have been 3257429Smarkm * outer-cbc. However, there is also a private iv1 == iv2 which 3357429Smarkm * perhaps makes differential analysis easier. On the other hand, the 3457429Smarkm * private iv1 probably makes the CRC-32 attack ineffective. This is a 3557429Smarkm * result of that there is no longer any known iv1 to use when 3657429Smarkm * choosing the X block. 3757429Smarkm */ 3857429Smarkmvoid 3957429SmarkmSSH_3CBC_ENCRYPT(des_key_schedule ks1, 4057429Smarkm des_key_schedule ks2, des_cblock * iv2, 4157429Smarkm des_key_schedule ks3, des_cblock * iv3, 4257429Smarkm unsigned char *dest, unsigned char *src, 4357429Smarkm unsigned int len) 4457429Smarkm{ 4557429Smarkm des_cblock iv1; 4657429Smarkm 4757429Smarkm memcpy(&iv1, iv2, 8); 4857429Smarkm 4957429Smarkm des_cbc_encrypt(src, dest, len, ks1, &iv1, DES_ENCRYPT); 5057429Smarkm memcpy(&iv1, dest + len - 8, 8); 5157429Smarkm 5257429Smarkm des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_DECRYPT); 5357429Smarkm memcpy(iv2, &iv1, 8); /* Note how iv1 == iv2 on entry and exit. */ 5457429Smarkm 5557429Smarkm des_cbc_encrypt(dest, dest, len, ks3, iv3, DES_ENCRYPT); 5657429Smarkm memcpy(iv3, dest + len - 8, 8); 5757429Smarkm} 5857429Smarkm 5957429Smarkmvoid 6057429SmarkmSSH_3CBC_DECRYPT(des_key_schedule ks1, 6157429Smarkm des_key_schedule ks2, des_cblock * iv2, 6257429Smarkm des_key_schedule ks3, des_cblock * iv3, 6357429Smarkm unsigned char *dest, unsigned char *src, 6457429Smarkm unsigned int len) 6557429Smarkm{ 6657429Smarkm des_cblock iv1; 6757429Smarkm 6857429Smarkm memcpy(&iv1, iv2, 8); 6957429Smarkm 7057429Smarkm des_cbc_encrypt(src, dest, len, ks3, iv3, DES_DECRYPT); 7157429Smarkm memcpy(iv3, src + len - 8, 8); 7257429Smarkm 7357429Smarkm des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_ENCRYPT); 7457429Smarkm memcpy(iv2, dest + len - 8, 8); 7557429Smarkm 7657429Smarkm des_cbc_encrypt(dest, dest, len, ks1, &iv1, DES_DECRYPT); 7757429Smarkm /* memcpy(&iv1, iv2, 8); */ 7857429Smarkm /* Note how iv1 == iv2 on entry and exit. */ 7957429Smarkm} 8057429Smarkm 8157429Smarkm/* 8260576Skris * SSH1 uses a variation on Blowfish, all bytes must be swapped before 8357429Smarkm * and after encryption/decryption. Thus the swap_bytes stuff (yuk). 8457429Smarkm */ 8557429Smarkmstatic void 8657429Smarkmswap_bytes(const unsigned char *src, unsigned char *dst_, int n) 8757429Smarkm{ 8857429Smarkm /* dst must be properly aligned. */ 8957429Smarkm u_int32_t *dst = (u_int32_t *) dst_; 9057429Smarkm union { 9157429Smarkm u_int32_t i; 9257429Smarkm char c[4]; 9357429Smarkm } t; 9457429Smarkm 9557429Smarkm /* Process 8 bytes every lap. */ 9657429Smarkm for (n = n / 8; n > 0; n--) { 9757429Smarkm t.c[3] = *src++; 9857429Smarkm t.c[2] = *src++; 9957429Smarkm t.c[1] = *src++; 10057429Smarkm t.c[0] = *src++; 10157429Smarkm *dst++ = t.i; 10257429Smarkm 10357429Smarkm t.c[3] = *src++; 10457429Smarkm t.c[2] = *src++; 10557429Smarkm t.c[1] = *src++; 10657429Smarkm t.c[0] = *src++; 10757429Smarkm *dst++ = t.i; 10857429Smarkm } 10957429Smarkm} 11057429Smarkm 11157429Smarkm/* 11257429Smarkm * Names of all encryption algorithms. 11357429Smarkm * These must match the numbers defined in cipher.h. 11457429Smarkm */ 11557429Smarkmstatic char *cipher_names[] = 11657429Smarkm{ 11757429Smarkm "none", 11857429Smarkm "idea", 11957429Smarkm "des", 12057429Smarkm "3des", 12157429Smarkm "tss", 12257429Smarkm "rc4", 12360576Skris "blowfish", 12460576Skris "reserved", 12560576Skris "blowfish-cbc", 12660576Skris "3des-cbc", 12760576Skris "arcfour", 12860576Skris "cast128-cbc" 12957429Smarkm}; 13057429Smarkm 13157429Smarkm/* 13257429Smarkm * Returns a bit mask indicating which ciphers are supported by this 13357429Smarkm * implementation. The bit mask has the corresponding bit set of each 13457429Smarkm * supported cipher. 13557429Smarkm */ 13657429Smarkm 13760576Skrisunsigned int 13860576Skriscipher_mask1() 13957429Smarkm{ 14057429Smarkm unsigned int mask = 0; 14157429Smarkm mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ 14257429Smarkm mask |= 1 << SSH_CIPHER_BLOWFISH; 14357429Smarkm return mask; 14457429Smarkm} 14560576Skrisunsigned int 14660576Skriscipher_mask2() 14760576Skris{ 14860576Skris unsigned int mask = 0; 14960576Skris mask |= 1 << SSH_CIPHER_BLOWFISH_CBC; 15060576Skris mask |= 1 << SSH_CIPHER_3DES_CBC; 15160576Skris mask |= 1 << SSH_CIPHER_ARCFOUR; 15260576Skris mask |= 1 << SSH_CIPHER_CAST128_CBC; 15360576Skris return mask; 15460576Skris} 15560576Skrisunsigned int 15660576Skriscipher_mask() 15760576Skris{ 15860576Skris return cipher_mask1() | cipher_mask2(); 15960576Skris} 16057429Smarkm 16157429Smarkm/* Returns the name of the cipher. */ 16257429Smarkm 16357429Smarkmconst char * 16457429Smarkmcipher_name(int cipher) 16557429Smarkm{ 16657429Smarkm if (cipher < 0 || cipher >= sizeof(cipher_names) / sizeof(cipher_names[0]) || 16757429Smarkm cipher_names[cipher] == NULL) 16860576Skris fatal("cipher_name: bad cipher name: %d", cipher); 16957429Smarkm return cipher_names[cipher]; 17057429Smarkm} 17157429Smarkm 17260576Skris/* Returns 1 if the name of the ciphers are valid. */ 17360576Skris 17460576Skris#define CIPHER_SEP "," 17560576Skrisint 17660576Skrisciphers_valid(const char *names) 17760576Skris{ 17860576Skris char *ciphers; 17960576Skris char *p; 18060576Skris int i; 18160576Skris 18261212Skris if (names == NULL || strcmp(names, "") == 0) 18360576Skris return 0; 18460576Skris ciphers = xstrdup(names); 18560576Skris for ((p = strtok(ciphers, CIPHER_SEP)); p; (p = strtok(NULL, CIPHER_SEP))) { 18660576Skris i = cipher_number(p); 18760576Skris if (i == -1 || !(cipher_mask2() & (1 << i))) { 18860576Skris xfree(ciphers); 18960576Skris return 0; 19060576Skris } 19160576Skris } 19260576Skris xfree(ciphers); 19360576Skris return 1; 19460576Skris} 19560576Skris 19657429Smarkm/* 19757429Smarkm * Parses the name of the cipher. Returns the number of the corresponding 19857429Smarkm * cipher, or -1 on error. 19957429Smarkm */ 20057429Smarkm 20157429Smarkmint 20257429Smarkmcipher_number(const char *name) 20357429Smarkm{ 20457429Smarkm int i; 20561212Skris if (name == NULL) 20661212Skris return -1; 20757429Smarkm for (i = 0; i < sizeof(cipher_names) / sizeof(cipher_names[0]); i++) 20857429Smarkm if (strcmp(cipher_names[i], name) == 0 && 20957429Smarkm (cipher_mask() & (1 << i))) 21057429Smarkm return i; 21157429Smarkm return -1; 21257429Smarkm} 21357429Smarkm 21457429Smarkm/* 21557429Smarkm * Selects the cipher, and keys if by computing the MD5 checksum of the 21657429Smarkm * passphrase and using the resulting 16 bytes as the key. 21757429Smarkm */ 21857429Smarkm 21960576Skrisvoid 22060576Skriscipher_set_key_string(CipherContext *context, int cipher, const char *passphrase) 22157429Smarkm{ 22257429Smarkm MD5_CTX md; 22357429Smarkm unsigned char digest[16]; 22457429Smarkm 22557429Smarkm MD5_Init(&md); 22657429Smarkm MD5_Update(&md, (const unsigned char *) passphrase, strlen(passphrase)); 22757429Smarkm MD5_Final(digest, &md); 22857429Smarkm 22960576Skris cipher_set_key(context, cipher, digest, 16); 23057429Smarkm 23157429Smarkm memset(digest, 0, sizeof(digest)); 23257429Smarkm memset(&md, 0, sizeof(md)); 23357429Smarkm} 23457429Smarkm 23557429Smarkm/* Selects the cipher to use and sets the key. */ 23657429Smarkm 23760576Skrisvoid 23860576Skriscipher_set_key(CipherContext *context, int cipher, const unsigned char *key, 23960576Skris int keylen) 24057429Smarkm{ 24157429Smarkm unsigned char padded[32]; 24257429Smarkm 24357429Smarkm /* Set cipher type. */ 24457429Smarkm context->type = cipher; 24557429Smarkm 24657429Smarkm /* Get 32 bytes of key data. Pad if necessary. (So that code 24757429Smarkm below does not need to worry about key size). */ 24857429Smarkm memset(padded, 0, sizeof(padded)); 24957429Smarkm memcpy(padded, key, keylen < sizeof(padded) ? keylen : sizeof(padded)); 25057429Smarkm 25157429Smarkm /* Initialize the initialization vector. */ 25257429Smarkm switch (cipher) { 25357429Smarkm case SSH_CIPHER_NONE: 25457429Smarkm /* 25557429Smarkm * Has to stay for authfile saving of private key with no 25657429Smarkm * passphrase 25757429Smarkm */ 25857429Smarkm break; 25957429Smarkm 26057429Smarkm case SSH_CIPHER_3DES: 26157429Smarkm /* 26257429Smarkm * Note: the least significant bit of each byte of key is 26357429Smarkm * parity, and must be ignored by the implementation. 16 26457429Smarkm * bytes of key are used (first and last keys are the same). 26557429Smarkm */ 26657429Smarkm if (keylen < 16) 26757429Smarkm error("Key length %d is insufficient for 3DES.", keylen); 26857429Smarkm des_set_key((void *) padded, context->u.des3.key1); 26957429Smarkm des_set_key((void *) (padded + 8), context->u.des3.key2); 27057429Smarkm if (keylen <= 16) 27157429Smarkm des_set_key((void *) padded, context->u.des3.key3); 27257429Smarkm else 27357429Smarkm des_set_key((void *) (padded + 16), context->u.des3.key3); 27457429Smarkm memset(context->u.des3.iv2, 0, sizeof(context->u.des3.iv2)); 27557429Smarkm memset(context->u.des3.iv3, 0, sizeof(context->u.des3.iv3)); 27657429Smarkm break; 27757429Smarkm 27857429Smarkm case SSH_CIPHER_BLOWFISH: 27960576Skris if (keylen < 16) 28060576Skris error("Key length %d is insufficient for blowfish.", keylen); 28157429Smarkm BF_set_key(&context->u.bf.key, keylen, padded); 28257429Smarkm memset(context->u.bf.iv, 0, 8); 28357429Smarkm break; 28457429Smarkm 28560576Skris case SSH_CIPHER_3DES_CBC: 28660576Skris case SSH_CIPHER_BLOWFISH_CBC: 28760576Skris case SSH_CIPHER_ARCFOUR: 28860576Skris case SSH_CIPHER_CAST128_CBC: 28960576Skris fatal("cipher_set_key: illegal cipher: %s", cipher_name(cipher)); 29060576Skris break; 29160576Skris 29257429Smarkm default: 29357429Smarkm fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher)); 29457429Smarkm } 29557429Smarkm memset(padded, 0, sizeof(padded)); 29657429Smarkm} 29757429Smarkm 29860576Skrisvoid 29960576Skriscipher_set_key_iv(CipherContext * context, int cipher, 30060576Skris const unsigned char *key, int keylen, 30160576Skris const unsigned char *iv, int ivlen) 30260576Skris{ 30360576Skris /* Set cipher type. */ 30460576Skris context->type = cipher; 30560576Skris 30660576Skris /* Initialize the initialization vector. */ 30760576Skris switch (cipher) { 30860576Skris case SSH_CIPHER_NONE: 30960576Skris break; 31060576Skris 31160576Skris case SSH_CIPHER_3DES: 31260576Skris case SSH_CIPHER_BLOWFISH: 31360576Skris fatal("cipher_set_key_iv: illegal cipher: %s", cipher_name(cipher)); 31460576Skris break; 31560576Skris 31660576Skris case SSH_CIPHER_3DES_CBC: 31760576Skris if (keylen < 24) 31860576Skris error("Key length %d is insufficient for 3des-cbc.", keylen); 31960576Skris des_set_key((void *) key, context->u.des3.key1); 32060576Skris des_set_key((void *) (key+8), context->u.des3.key2); 32160576Skris des_set_key((void *) (key+16), context->u.des3.key3); 32260576Skris if (ivlen < 8) 32360576Skris error("IV length %d is insufficient for 3des-cbc.", ivlen); 32460576Skris memcpy(context->u.des3.iv3, (char *)iv, 8); 32560576Skris break; 32660576Skris 32760576Skris case SSH_CIPHER_BLOWFISH_CBC: 32860576Skris if (keylen < 16) 32960576Skris error("Key length %d is insufficient for blowfish.", keylen); 33060576Skris if (ivlen < 8) 33160576Skris error("IV length %d is insufficient for blowfish.", ivlen); 33260576Skris BF_set_key(&context->u.bf.key, keylen, (unsigned char *)key); 33360576Skris memcpy(context->u.bf.iv, (char *)iv, 8); 33460576Skris break; 33560576Skris 33660576Skris case SSH_CIPHER_ARCFOUR: 33760576Skris if (keylen < 16) 33860576Skris error("Key length %d is insufficient for arcfour.", keylen); 33960576Skris RC4_set_key(&context->u.rc4, keylen, (unsigned char *)key); 34060576Skris break; 34160576Skris 34260576Skris case SSH_CIPHER_CAST128_CBC: 34360576Skris if (keylen < 16) 34460576Skris error("Key length %d is insufficient for cast128.", keylen); 34560576Skris if (ivlen < 8) 34660576Skris error("IV length %d is insufficient for cast128.", ivlen); 34760576Skris CAST_set_key(&context->u.cast.key, keylen, (unsigned char *) key); 34860576Skris memcpy(context->u.cast.iv, (char *)iv, 8); 34960576Skris break; 35060576Skris 35160576Skris default: 35260576Skris fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher)); 35360576Skris } 35460576Skris} 35560576Skris 35657429Smarkm/* Encrypts data using the cipher. */ 35757429Smarkm 35860576Skrisvoid 35957429Smarkmcipher_encrypt(CipherContext *context, unsigned char *dest, 36057429Smarkm const unsigned char *src, unsigned int len) 36157429Smarkm{ 36257429Smarkm if ((len & 7) != 0) 36357429Smarkm fatal("cipher_encrypt: bad plaintext length %d", len); 36457429Smarkm 36557429Smarkm switch (context->type) { 36657429Smarkm case SSH_CIPHER_NONE: 36757429Smarkm memcpy(dest, src, len); 36857429Smarkm break; 36957429Smarkm 37057429Smarkm case SSH_CIPHER_3DES: 37157429Smarkm SSH_3CBC_ENCRYPT(context->u.des3.key1, 37257429Smarkm context->u.des3.key2, &context->u.des3.iv2, 37357429Smarkm context->u.des3.key3, &context->u.des3.iv3, 37457429Smarkm dest, (unsigned char *) src, len); 37557429Smarkm break; 37657429Smarkm 37757429Smarkm case SSH_CIPHER_BLOWFISH: 37857429Smarkm swap_bytes(src, dest, len); 37957429Smarkm BF_cbc_encrypt(dest, dest, len, 38060576Skris &context->u.bf.key, context->u.bf.iv, 38157429Smarkm BF_ENCRYPT); 38257429Smarkm swap_bytes(dest, dest, len); 38357429Smarkm break; 38457429Smarkm 38560576Skris case SSH_CIPHER_BLOWFISH_CBC: 38660576Skris BF_cbc_encrypt((void *)src, dest, len, 38760576Skris &context->u.bf.key, context->u.bf.iv, 38860576Skris BF_ENCRYPT); 38960576Skris break; 39060576Skris 39160576Skris case SSH_CIPHER_3DES_CBC: 39260576Skris des_ede3_cbc_encrypt(src, dest, len, 39360576Skris context->u.des3.key1, context->u.des3.key2, 39460576Skris context->u.des3.key3, &context->u.des3.iv3, DES_ENCRYPT); 39560576Skris break; 39660576Skris 39760576Skris case SSH_CIPHER_ARCFOUR: 39860576Skris RC4(&context->u.rc4, len, (unsigned char *)src, dest); 39960576Skris break; 40060576Skris 40160576Skris case SSH_CIPHER_CAST128_CBC: 40260576Skris CAST_cbc_encrypt(src, dest, len, 40360576Skris &context->u.cast.key, context->u.cast.iv, CAST_ENCRYPT); 40460576Skris break; 40560576Skris 40657429Smarkm default: 40757429Smarkm fatal("cipher_encrypt: unknown cipher: %s", cipher_name(context->type)); 40857429Smarkm } 40957429Smarkm} 41057429Smarkm 41157429Smarkm/* Decrypts data using the cipher. */ 41257429Smarkm 41360576Skrisvoid 41457429Smarkmcipher_decrypt(CipherContext *context, unsigned char *dest, 41557429Smarkm const unsigned char *src, unsigned int len) 41657429Smarkm{ 41757429Smarkm if ((len & 7) != 0) 41857429Smarkm fatal("cipher_decrypt: bad ciphertext length %d", len); 41957429Smarkm 42057429Smarkm switch (context->type) { 42157429Smarkm case SSH_CIPHER_NONE: 42257429Smarkm memcpy(dest, src, len); 42357429Smarkm break; 42457429Smarkm 42557429Smarkm case SSH_CIPHER_3DES: 42657429Smarkm SSH_3CBC_DECRYPT(context->u.des3.key1, 42757429Smarkm context->u.des3.key2, &context->u.des3.iv2, 42857429Smarkm context->u.des3.key3, &context->u.des3.iv3, 42957429Smarkm dest, (unsigned char *) src, len); 43057429Smarkm break; 43157429Smarkm 43257429Smarkm case SSH_CIPHER_BLOWFISH: 43357429Smarkm swap_bytes(src, dest, len); 43457429Smarkm BF_cbc_encrypt((void *) dest, dest, len, 43557429Smarkm &context->u.bf.key, context->u.bf.iv, 43657429Smarkm BF_DECRYPT); 43757429Smarkm swap_bytes(dest, dest, len); 43857429Smarkm break; 43957429Smarkm 44060576Skris case SSH_CIPHER_BLOWFISH_CBC: 44160576Skris BF_cbc_encrypt((void *) src, dest, len, 44260576Skris &context->u.bf.key, context->u.bf.iv, 44360576Skris BF_DECRYPT); 44460576Skris break; 44560576Skris 44660576Skris case SSH_CIPHER_3DES_CBC: 44760576Skris des_ede3_cbc_encrypt(src, dest, len, 44860576Skris context->u.des3.key1, context->u.des3.key2, 44960576Skris context->u.des3.key3, &context->u.des3.iv3, DES_DECRYPT); 45060576Skris break; 45160576Skris 45260576Skris case SSH_CIPHER_ARCFOUR: 45360576Skris RC4(&context->u.rc4, len, (unsigned char *)src, dest); 45460576Skris break; 45560576Skris 45660576Skris case SSH_CIPHER_CAST128_CBC: 45760576Skris CAST_cbc_encrypt(src, dest, len, 45860576Skris &context->u.cast.key, context->u.cast.iv, CAST_DECRYPT); 45960576Skris break; 46060576Skris 46157429Smarkm default: 46257429Smarkm fatal("cipher_decrypt: unknown cipher: %s", cipher_name(context->type)); 46357429Smarkm } 46457429Smarkm} 465