cipher.c revision 126277
157429Smarkm/* 257429Smarkm * Author: Tatu Ylonen <ylo@cs.hut.fi> 357429Smarkm * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 457429Smarkm * All rights reserved 560576Skris * 665674Skris * As far as I am concerned, the code I have written for this software 765674Skris * can be used freely for any purpose. Any derived versions of this 865674Skris * software must be clearly marked as such, and if the derived work is 965674Skris * incompatible with the protocol description in the RFC file, it must be 1065674Skris * called by a name other than "ssh" or "Secure Shell". 1160576Skris * 1265674Skris * 1365674Skris * Copyright (c) 1999 Niels Provos. All rights reserved. 1492559Sdes * Copyright (c) 1999, 2000 Markus Friedl. All rights reserved. 1565674Skris * 1665674Skris * Redistribution and use in source and binary forms, with or without 1765674Skris * modification, are permitted provided that the following conditions 1865674Skris * are met: 1965674Skris * 1. Redistributions of source code must retain the above copyright 2065674Skris * notice, this list of conditions and the following disclaimer. 2165674Skris * 2. Redistributions in binary form must reproduce the above copyright 2265674Skris * notice, this list of conditions and the following disclaimer in the 2365674Skris * documentation and/or other materials provided with the distribution. 2465674Skris * 2565674Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2665674Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2765674Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2865674Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2965674Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 3065674Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3165674Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3265674Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3365674Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3465674Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3557429Smarkm */ 3657429Smarkm 3757429Smarkm#include "includes.h" 38126277SdesRCSID("$OpenBSD: cipher.c,v 1.68 2004/01/23 19:26:33 hshoexer Exp $"); 3957429Smarkm 4060576Skris#include "xmalloc.h" 4176262Sgreen#include "log.h" 4276262Sgreen#include "cipher.h" 4357429Smarkm 4457464Sgreen#include <openssl/md5.h> 4598684Sdes 4698941Sdes#if OPENSSL_VERSION_NUMBER < 0x00906000L 4798941Sdes#define SSH_OLD_EVP 4898941Sdes#define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data) 4998941Sdes#endif 5098941Sdes 5198684Sdes#if OPENSSL_VERSION_NUMBER < 0x00907000L 52124211Sdesextern const EVP_CIPHER *evp_rijndael(void); 53124211Sdesextern void ssh_rijndael_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); 5498684Sdes#endif 55126277Sdes 56126277Sdes#if !defined(EVP_CTRL_SET_ACSS_MODE) 57126277Sdes# if (OPENSSL_VERSION_NUMBER >= 0x00907000L) 58126277Sdesextern const EVP_CIPHER *evp_acss(void); 59126277Sdes# define EVP_acss evp_acss 60126277Sdes# define EVP_CTRL_SET_ACSS_MODE xxx /* used below */ 61126277Sdes# else 62126277Sdes# define EVP_acss NULL /* Don't try to support ACSS on older OpenSSL */ 63126277Sdes# endif /* (OPENSSL_VERSION_NUMBER >= 0x00906000L) */ 64126277Sdes#endif /* !defined(EVP_CTRL_SET_ACSS_MODE) */ 65126277Sdes 66124211Sdesextern const EVP_CIPHER *evp_ssh1_bf(void); 67124211Sdesextern const EVP_CIPHER *evp_ssh1_3des(void); 68124211Sdesextern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); 69124211Sdesextern const EVP_CIPHER *evp_aes_128_ctr(void); 70124211Sdesextern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); 7157429Smarkm 7292559Sdesstruct Cipher { 7392559Sdes char *name; 7492559Sdes int number; /* for ssh1 only */ 7592559Sdes u_int block_size; 7692559Sdes u_int key_len; 7798684Sdes const EVP_CIPHER *(*evptype)(void); 7892559Sdes} ciphers[] = { 7992559Sdes { "none", SSH_CIPHER_NONE, 8, 0, EVP_enc_null }, 8092559Sdes { "des", SSH_CIPHER_DES, 8, 8, EVP_des_cbc }, 8192559Sdes { "3des", SSH_CIPHER_3DES, 8, 16, evp_ssh1_3des }, 8292559Sdes { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, evp_ssh1_bf }, 8369591Sgreen 8492559Sdes { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, EVP_des_ede3_cbc }, 8592559Sdes { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, EVP_bf_cbc }, 8692559Sdes { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, EVP_cast5_cbc }, 8792559Sdes { "arcfour", SSH_CIPHER_SSH2, 8, 16, EVP_rc4 }, 8898684Sdes#if OPENSSL_VERSION_NUMBER < 0x00907000L 8992559Sdes { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, evp_rijndael }, 9092559Sdes { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, evp_rijndael }, 9192559Sdes { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, evp_rijndael }, 9298684Sdes { "rijndael-cbc@lysator.liu.se", 9398684Sdes SSH_CIPHER_SSH2, 16, 32, evp_rijndael }, 9498684Sdes#else 9598684Sdes { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, EVP_aes_128_cbc }, 9698684Sdes { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, EVP_aes_192_cbc }, 9798684Sdes { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc }, 9898684Sdes { "rijndael-cbc@lysator.liu.se", 9998684Sdes SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc }, 10098684Sdes#endif 101126277Sdes#if OPENSSL_VERSION_NUMBER >= 0x00905000L 102124211Sdes { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, evp_aes_128_ctr }, 103124211Sdes { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, evp_aes_128_ctr }, 104124211Sdes { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, evp_aes_128_ctr }, 105124211Sdes#endif 106126277Sdes#if defined(EVP_CTRL_SET_ACSS_MODE) 107126277Sdes { "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, EVP_acss }, 108126277Sdes#endif 10992559Sdes { NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL } 11092559Sdes}; 11169591Sgreen 11292559Sdes/*--*/ 11357429Smarkm 11498684Sdesu_int 115126277Sdescipher_blocksize(const Cipher *c) 11657429Smarkm{ 11792559Sdes return (c->block_size); 11857429Smarkm} 11999063Sdes 12098684Sdesu_int 121126277Sdescipher_keylen(const Cipher *c) 12269591Sgreen{ 12392559Sdes return (c->key_len); 12469591Sgreen} 12599063Sdes 12698684Sdesu_int 127126277Sdescipher_get_number(const Cipher *c) 12898684Sdes{ 12998684Sdes return (c->number); 13098684Sdes} 13169591Sgreen 13276262Sgreenu_int 13369591Sgreencipher_mask_ssh1(int client) 13457429Smarkm{ 13576262Sgreen u_int mask = 0; 13692559Sdes mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ 13757429Smarkm mask |= 1 << SSH_CIPHER_BLOWFISH; 13869591Sgreen if (client) { 13969591Sgreen mask |= 1 << SSH_CIPHER_DES; 14069591Sgreen } 14157429Smarkm return mask; 14257429Smarkm} 14369591Sgreen 14469591SgreenCipher * 14569591Sgreencipher_by_name(const char *name) 14660576Skris{ 14769591Sgreen Cipher *c; 14869591Sgreen for (c = ciphers; c->name != NULL; c++) 14969591Sgreen if (strcasecmp(c->name, name) == 0) 15069591Sgreen return c; 15169591Sgreen return NULL; 15260576Skris} 15357429Smarkm 15469591SgreenCipher * 15569591Sgreencipher_by_number(int id) 15657429Smarkm{ 15769591Sgreen Cipher *c; 15869591Sgreen for (c = ciphers; c->name != NULL; c++) 15969591Sgreen if (c->number == id) 16069591Sgreen return c; 16169591Sgreen return NULL; 16257429Smarkm} 16357429Smarkm 16460576Skris#define CIPHER_SEP "," 16560576Skrisint 16660576Skrisciphers_valid(const char *names) 16760576Skris{ 16869591Sgreen Cipher *c; 16965674Skris char *ciphers, *cp; 17060576Skris char *p; 17160576Skris 17261212Skris if (names == NULL || strcmp(names, "") == 0) 17360576Skris return 0; 17465674Skris ciphers = cp = xstrdup(names); 17569591Sgreen for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; 17692559Sdes (p = strsep(&cp, CIPHER_SEP))) { 17769591Sgreen c = cipher_by_name(p); 17869591Sgreen if (c == NULL || c->number != SSH_CIPHER_SSH2) { 17969591Sgreen debug("bad cipher %s [%s]", p, names); 18060576Skris xfree(ciphers); 18160576Skris return 0; 18269591Sgreen } else { 18369591Sgreen debug3("cipher ok: %s [%s]", p, names); 18460576Skris } 18560576Skris } 18669591Sgreen debug3("ciphers ok: [%s]", names); 18760576Skris xfree(ciphers); 18860576Skris return 1; 18960576Skris} 19060576Skris 19157429Smarkm/* 19257429Smarkm * Parses the name of the cipher. Returns the number of the corresponding 19357429Smarkm * cipher, or -1 on error. 19457429Smarkm */ 19557429Smarkm 19657429Smarkmint 19757429Smarkmcipher_number(const char *name) 19857429Smarkm{ 19969591Sgreen Cipher *c; 20061212Skris if (name == NULL) 20161212Skris return -1; 20269591Sgreen c = cipher_by_name(name); 20369591Sgreen return (c==NULL) ? -1 : c->number; 20457429Smarkm} 20557429Smarkm 20669591Sgreenchar * 20769591Sgreencipher_name(int id) 20857429Smarkm{ 20969591Sgreen Cipher *c = cipher_by_number(id); 21069591Sgreen return (c==NULL) ? "<unknown>" : c->name; 21157429Smarkm} 21257429Smarkm 21360576Skrisvoid 21469591Sgreencipher_init(CipherContext *cc, Cipher *cipher, 21592559Sdes const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, 21692559Sdes int encrypt) 21757429Smarkm{ 21892559Sdes static int dowarn = 1; 21998941Sdes#ifdef SSH_OLD_EVP 22098941Sdes EVP_CIPHER *type; 22198941Sdes#else 22292559Sdes const EVP_CIPHER *type; 22398941Sdes#endif 22492559Sdes int klen; 22592559Sdes 22692559Sdes if (cipher->number == SSH_CIPHER_DES) { 22792559Sdes if (dowarn) { 22892559Sdes error("Warning: use of DES is strongly discouraged " 22992559Sdes "due to cryptographic weaknesses"); 23092559Sdes dowarn = 0; 23192559Sdes } 23292559Sdes if (keylen > 8) 23392559Sdes keylen = 8; 23492559Sdes } 23592559Sdes cc->plaintext = (cipher->number == SSH_CIPHER_NONE); 23692559Sdes 23769591Sgreen if (keylen < cipher->key_len) 23869591Sgreen fatal("cipher_init: key length %d is insufficient for %s.", 23969591Sgreen keylen, cipher->name); 24069591Sgreen if (iv != NULL && ivlen < cipher->block_size) 24169591Sgreen fatal("cipher_init: iv length %d is insufficient for %s.", 24269591Sgreen ivlen, cipher->name); 24369591Sgreen cc->cipher = cipher; 24492559Sdes 24592559Sdes type = (*cipher->evptype)(); 24692559Sdes 24792559Sdes EVP_CIPHER_CTX_init(&cc->evp); 24898941Sdes#ifdef SSH_OLD_EVP 24998941Sdes if (type->key_len > 0 && type->key_len != keylen) { 25098941Sdes debug("cipher_init: set keylen (%d -> %d)", 25198941Sdes type->key_len, keylen); 25298941Sdes type->key_len = keylen; 25398941Sdes } 25498941Sdes EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv, 25598941Sdes (encrypt == CIPHER_ENCRYPT)); 25698941Sdes#else 25792559Sdes if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, 25892559Sdes (encrypt == CIPHER_ENCRYPT)) == 0) 25992559Sdes fatal("cipher_init: EVP_CipherInit failed for %s", 26092559Sdes cipher->name); 26192559Sdes klen = EVP_CIPHER_CTX_key_length(&cc->evp); 26292559Sdes if (klen > 0 && keylen != klen) { 263113911Sdes debug2("cipher_init: set keylen (%d -> %d)", klen, keylen); 26492559Sdes if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) 26592559Sdes fatal("cipher_init: set keylen failed (%d -> %d)", 26692559Sdes klen, keylen); 26792559Sdes } 26892559Sdes if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) 26992559Sdes fatal("cipher_init: EVP_CipherInit: set key failed for %s", 27092559Sdes cipher->name); 27198941Sdes#endif 27257429Smarkm} 27357429Smarkm 27460576Skrisvoid 27592559Sdescipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) 27660576Skris{ 27769591Sgreen if (len % cc->cipher->block_size) 27869591Sgreen fatal("cipher_encrypt: bad plaintext length %d", len); 27998941Sdes#ifdef SSH_OLD_EVP 28098941Sdes EVP_Cipher(&cc->evp, dest, (u_char *)src, len); 28198941Sdes#else 28292559Sdes if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0) 28392559Sdes fatal("evp_crypt: EVP_Cipher failed"); 28498941Sdes#endif 28560576Skris} 28660576Skris 28760576Skrisvoid 28892559Sdescipher_cleanup(CipherContext *cc) 28957429Smarkm{ 29098941Sdes#ifdef SSH_OLD_EVP 29198941Sdes EVP_CIPHER_CTX_cleanup(&cc->evp); 29298941Sdes#else 29392559Sdes if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) 29492559Sdes error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); 29598941Sdes#endif 29657429Smarkm} 29757429Smarkm 29869591Sgreen/* 29969591Sgreen * Selects the cipher, and keys if by computing the MD5 checksum of the 30069591Sgreen * passphrase and using the resulting 16 bytes as the key. 30169591Sgreen */ 30257429Smarkm 30360576Skrisvoid 30469591Sgreencipher_set_key_string(CipherContext *cc, Cipher *cipher, 30592559Sdes const char *passphrase, int encrypt) 30657429Smarkm{ 30769591Sgreen MD5_CTX md; 30876262Sgreen u_char digest[16]; 30957429Smarkm 31069591Sgreen MD5_Init(&md); 31169591Sgreen MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); 31269591Sgreen MD5_Final(digest, &md); 31357429Smarkm 31492559Sdes cipher_init(cc, cipher, digest, 16, NULL, 0, encrypt); 31557429Smarkm 31669591Sgreen memset(digest, 0, sizeof(digest)); 31769591Sgreen memset(&md, 0, sizeof(md)); 31857429Smarkm} 31992559Sdes 32092559Sdes/* 32198684Sdes * Exports an IV from the CipherContext required to export the key 32298684Sdes * state back from the unprivileged child to the privileged parent 32398684Sdes * process. 32498684Sdes */ 32598684Sdes 32698684Sdesint 327126277Sdescipher_get_keyiv_len(const CipherContext *cc) 32898684Sdes{ 32998684Sdes Cipher *c = cc->cipher; 33098684Sdes int ivlen; 33198684Sdes 33298684Sdes if (c->number == SSH_CIPHER_3DES) 33398684Sdes ivlen = 24; 33498684Sdes else 33598684Sdes ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); 33698684Sdes return (ivlen); 33798684Sdes} 33898684Sdes 33998684Sdesvoid 34098684Sdescipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) 34198684Sdes{ 34298684Sdes Cipher *c = cc->cipher; 34398684Sdes int evplen; 34498684Sdes 34598684Sdes switch (c->number) { 34698684Sdes case SSH_CIPHER_SSH2: 34798684Sdes case SSH_CIPHER_DES: 34898684Sdes case SSH_CIPHER_BLOWFISH: 34998684Sdes evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); 35098684Sdes if (evplen == 0) 35198684Sdes return; 35298684Sdes if (evplen != len) 35398684Sdes fatal("%s: wrong iv length %d != %d", __func__, 35498684Sdes evplen, len); 35598684Sdes#if OPENSSL_VERSION_NUMBER < 0x00907000L 356124211Sdes if (c->evptype == evp_rijndael) 357124211Sdes ssh_rijndael_iv(&cc->evp, 0, iv, len); 358124211Sdes else 35998684Sdes#endif 360124211Sdes if (c->evptype == evp_aes_128_ctr) 361124211Sdes ssh_aes_ctr_iv(&cc->evp, 0, iv, len); 362124211Sdes else 363124211Sdes memcpy(iv, cc->evp.iv, len); 36498684Sdes break; 365124211Sdes case SSH_CIPHER_3DES: 366124211Sdes ssh1_3des_iv(&cc->evp, 0, iv, 24); 367124211Sdes break; 36898684Sdes default: 36998684Sdes fatal("%s: bad cipher %d", __func__, c->number); 37098684Sdes } 37198684Sdes} 37298684Sdes 37398684Sdesvoid 37498684Sdescipher_set_keyiv(CipherContext *cc, u_char *iv) 37598684Sdes{ 37698684Sdes Cipher *c = cc->cipher; 37798684Sdes int evplen = 0; 37898684Sdes 37998684Sdes switch (c->number) { 38098684Sdes case SSH_CIPHER_SSH2: 38198684Sdes case SSH_CIPHER_DES: 38298684Sdes case SSH_CIPHER_BLOWFISH: 38398684Sdes evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); 38498684Sdes if (evplen == 0) 38598684Sdes return; 38698684Sdes#if OPENSSL_VERSION_NUMBER < 0x00907000L 387124211Sdes if (c->evptype == evp_rijndael) 388124211Sdes ssh_rijndael_iv(&cc->evp, 1, iv, evplen); 389124211Sdes else 39098684Sdes#endif 391124211Sdes if (c->evptype == evp_aes_128_ctr) 392124211Sdes ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen); 393124211Sdes else 394124211Sdes memcpy(cc->evp.iv, iv, evplen); 39598684Sdes break; 396124211Sdes case SSH_CIPHER_3DES: 397124211Sdes ssh1_3des_iv(&cc->evp, 1, iv, 24); 398124211Sdes break; 39998684Sdes default: 40098684Sdes fatal("%s: bad cipher %d", __func__, c->number); 40198684Sdes } 40298684Sdes} 40398684Sdes 40498684Sdes#if OPENSSL_VERSION_NUMBER < 0x00907000L 40598684Sdes#define EVP_X_STATE(evp) &(evp).c 40698684Sdes#define EVP_X_STATE_LEN(evp) sizeof((evp).c) 40798684Sdes#else 40898684Sdes#define EVP_X_STATE(evp) (evp).cipher_data 40998684Sdes#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size 41098684Sdes#endif 41198684Sdes 41298684Sdesint 413126277Sdescipher_get_keycontext(const CipherContext *cc, u_char *dat) 41498684Sdes{ 41598684Sdes Cipher *c = cc->cipher; 41698684Sdes int plen = 0; 41798684Sdes 418126277Sdes if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) { 41998684Sdes plen = EVP_X_STATE_LEN(cc->evp); 42098684Sdes if (dat == NULL) 42198684Sdes return (plen); 42298684Sdes memcpy(dat, EVP_X_STATE(cc->evp), plen); 42398684Sdes } 42498684Sdes return (plen); 42598684Sdes} 42698684Sdes 42798684Sdesvoid 42898684Sdescipher_set_keycontext(CipherContext *cc, u_char *dat) 42998684Sdes{ 43098684Sdes Cipher *c = cc->cipher; 43198684Sdes int plen; 43298684Sdes 433126277Sdes if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) { 43498684Sdes plen = EVP_X_STATE_LEN(cc->evp); 43598684Sdes memcpy(EVP_X_STATE(cc->evp), dat, plen); 43698684Sdes } 43798684Sdes} 438