1264377Sdes/* $OpenBSD: cipher.c,v 1.97 2014/02/07 06:55:54 djm Exp $ */ 2224638Sbrooks/* $FreeBSD$ */ 357429Smarkm/* 457429Smarkm * Author: Tatu Ylonen <ylo@cs.hut.fi> 557429Smarkm * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 657429Smarkm * All rights reserved 760576Skris * 865674Skris * As far as I am concerned, the code I have written for this software 965674Skris * can be used freely for any purpose. Any derived versions of this 1065674Skris * software must be clearly marked as such, and if the derived work is 1165674Skris * incompatible with the protocol description in the RFC file, it must be 1265674Skris * called by a name other than "ssh" or "Secure Shell". 1360576Skris * 1465674Skris * 1565674Skris * Copyright (c) 1999 Niels Provos. All rights reserved. 1692559Sdes * Copyright (c) 1999, 2000 Markus Friedl. All rights reserved. 1765674Skris * 1865674Skris * Redistribution and use in source and binary forms, with or without 1965674Skris * modification, are permitted provided that the following conditions 2065674Skris * are met: 2165674Skris * 1. Redistributions of source code must retain the above copyright 2265674Skris * notice, this list of conditions and the following disclaimer. 2365674Skris * 2. Redistributions in binary form must reproduce the above copyright 2465674Skris * notice, this list of conditions and the following disclaimer in the 2565674Skris * documentation and/or other materials provided with the distribution. 2665674Skris * 2765674Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2865674Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2965674Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 3065674Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 3165674Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 3265674Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3365674Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3465674Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3565674Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3665674Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3757429Smarkm */ 3857429Smarkm 3957429Smarkm#include "includes.h" 4057429Smarkm 41162856Sdes#include <sys/types.h> 42162856Sdes 43162856Sdes#include <string.h> 44162856Sdes#include <stdarg.h> 45262566Sdes#include <stdio.h> 46162856Sdes 4760576Skris#include "xmalloc.h" 4876262Sgreen#include "log.h" 49262566Sdes#include "misc.h" 5076262Sgreen#include "cipher.h" 51264377Sdes#include "buffer.h" 52264377Sdes#include "digest.h" 5357429Smarkm 54149753Sdes/* compatibility with old or broken OpenSSL versions */ 55149753Sdes#include "openbsd-compat/openssl-compat.h" 5698941Sdes 57124211Sdesextern const EVP_CIPHER *evp_ssh1_bf(void); 58124211Sdesextern const EVP_CIPHER *evp_ssh1_3des(void); 59124211Sdesextern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); 6057429Smarkm 6192559Sdesstruct Cipher { 6292559Sdes char *name; 6392559Sdes int number; /* for ssh1 only */ 6492559Sdes u_int block_size; 6592559Sdes u_int key_len; 66248619Sdes u_int iv_len; /* defaults to block_size */ 67248619Sdes u_int auth_len; 68149753Sdes u_int discard_len; 69262566Sdes u_int flags; 70262566Sdes#define CFLAG_CBC (1<<0) 71262566Sdes#define CFLAG_CHACHAPOLY (1<<1) 7298684Sdes const EVP_CIPHER *(*evptype)(void); 73255767Sdes}; 74255767Sdes 75255767Sdesstatic const struct Cipher ciphers[] = { 76248619Sdes { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, 77248619Sdes { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, 78248619Sdes { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des }, 79248619Sdes { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf }, 8069591Sgreen 81248619Sdes { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, 82248619Sdes { "blowfish-cbc", 83248619Sdes SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc }, 84248619Sdes { "cast128-cbc", 85248619Sdes SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_cast5_cbc }, 86248619Sdes { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 0, EVP_rc4 }, 87248619Sdes { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 0, 0, 1536, 0, EVP_rc4 }, 88248619Sdes { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 0, 0, 1536, 0, EVP_rc4 }, 89248619Sdes { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc }, 90248619Sdes { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc }, 91248619Sdes { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, 9298684Sdes { "rijndael-cbc@lysator.liu.se", 93248619Sdes SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, 94248619Sdes { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, 95248619Sdes { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, 96248619Sdes { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, 97248619Sdes#ifdef OPENSSL_HAVE_EVPGCM 98248619Sdes { "aes128-gcm@openssh.com", 99248619Sdes SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, 100248619Sdes { "aes256-gcm@openssh.com", 101248619Sdes SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, 10298684Sdes#endif 103262566Sdes { "chacha20-poly1305@openssh.com", 104262566Sdes SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL }, 105248619Sdes { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } 10692559Sdes}; 10769591Sgreen 10892559Sdes/*--*/ 10957429Smarkm 110262566Sdes/* Returns a list of supported ciphers separated by the specified char. */ 111255767Sdeschar * 112262566Sdescipher_alg_list(char sep, int auth_only) 113255767Sdes{ 114255767Sdes char *ret = NULL; 115255767Sdes size_t nlen, rlen = 0; 116255767Sdes const Cipher *c; 117255767Sdes 118255767Sdes for (c = ciphers; c->name != NULL; c++) { 119255767Sdes if (c->number != SSH_CIPHER_SSH2) 120255767Sdes continue; 121262566Sdes if (auth_only && c->auth_len == 0) 122262566Sdes continue; 123255767Sdes if (ret != NULL) 124262566Sdes ret[rlen++] = sep; 125255767Sdes nlen = strlen(c->name); 126255767Sdes ret = xrealloc(ret, 1, rlen + nlen + 2); 127255767Sdes memcpy(ret + rlen, c->name, nlen + 1); 128255767Sdes rlen += nlen; 129255767Sdes } 130255767Sdes return ret; 131255767Sdes} 132255767Sdes 13398684Sdesu_int 134126277Sdescipher_blocksize(const Cipher *c) 13557429Smarkm{ 13692559Sdes return (c->block_size); 13757429Smarkm} 13899063Sdes 13998684Sdesu_int 140126277Sdescipher_keylen(const Cipher *c) 14169591Sgreen{ 14292559Sdes return (c->key_len); 14369591Sgreen} 14499063Sdes 14598684Sdesu_int 146262566Sdescipher_seclen(const Cipher *c) 147262566Sdes{ 148262566Sdes if (strcmp("3des-cbc", c->name) == 0) 149262566Sdes return 14; 150262566Sdes return cipher_keylen(c); 151262566Sdes} 152262566Sdes 153262566Sdesu_int 154248619Sdescipher_authlen(const Cipher *c) 155248619Sdes{ 156248619Sdes return (c->auth_len); 157248619Sdes} 158248619Sdes 159248619Sdesu_int 160248619Sdescipher_ivlen(const Cipher *c) 161248619Sdes{ 162262566Sdes /* 163262566Sdes * Default is cipher block size, except for chacha20+poly1305 that 164262566Sdes * needs no IV. XXX make iv_len == -1 default? 165262566Sdes */ 166262566Sdes return (c->iv_len != 0 || (c->flags & CFLAG_CHACHAPOLY) != 0) ? 167262566Sdes c->iv_len : c->block_size; 168248619Sdes} 169248619Sdes 170248619Sdesu_int 171126277Sdescipher_get_number(const Cipher *c) 17298684Sdes{ 17398684Sdes return (c->number); 17498684Sdes} 17569591Sgreen 17676262Sgreenu_int 177192595Sdescipher_is_cbc(const Cipher *c) 178192595Sdes{ 179262566Sdes return (c->flags & CFLAG_CBC) != 0; 180192595Sdes} 181192595Sdes 182192595Sdesu_int 18369591Sgreencipher_mask_ssh1(int client) 18457429Smarkm{ 18576262Sgreen u_int mask = 0; 18692559Sdes mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ 18757429Smarkm mask |= 1 << SSH_CIPHER_BLOWFISH; 18869591Sgreen if (client) { 18969591Sgreen mask |= 1 << SSH_CIPHER_DES; 19069591Sgreen } 19157429Smarkm return mask; 19257429Smarkm} 19369591Sgreen 194255767Sdesconst Cipher * 19569591Sgreencipher_by_name(const char *name) 19660576Skris{ 197255767Sdes const Cipher *c; 19869591Sgreen for (c = ciphers; c->name != NULL; c++) 199147005Sdes if (strcmp(c->name, name) == 0) 20069591Sgreen return c; 20169591Sgreen return NULL; 20260576Skris} 20357429Smarkm 204255767Sdesconst Cipher * 20569591Sgreencipher_by_number(int id) 20657429Smarkm{ 207255767Sdes const Cipher *c; 20869591Sgreen for (c = ciphers; c->name != NULL; c++) 20969591Sgreen if (c->number == id) 21069591Sgreen return c; 21169591Sgreen return NULL; 21257429Smarkm} 21357429Smarkm 21460576Skris#define CIPHER_SEP "," 21560576Skrisint 21660576Skrisciphers_valid(const char *names) 21760576Skris{ 218255767Sdes const Cipher *c; 219137019Sdes char *cipher_list, *cp; 22060576Skris char *p; 22160576Skris 22261212Skris if (names == NULL || strcmp(names, "") == 0) 22360576Skris return 0; 224137019Sdes cipher_list = cp = xstrdup(names); 22569591Sgreen for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; 22692559Sdes (p = strsep(&cp, CIPHER_SEP))) { 22769591Sgreen c = cipher_by_name(p); 228224638Sbrooks#ifdef NONE_CIPHER_ENABLED 229224638Sbrooks if (c == NULL || (c->number != SSH_CIPHER_SSH2 && 230224638Sbrooks c->number != SSH_CIPHER_NONE)) { 231224638Sbrooks#else 232224638Sbrooks if (c == NULL || (c->number != SSH_CIPHER_SSH2)) { 233224638Sbrooks#endif 23469591Sgreen debug("bad cipher %s [%s]", p, names); 235255767Sdes free(cipher_list); 23660576Skris return 0; 23760576Skris } 23860576Skris } 23969591Sgreen debug3("ciphers ok: [%s]", names); 240255767Sdes free(cipher_list); 24160576Skris return 1; 24260576Skris} 24360576Skris 24457429Smarkm/* 24557429Smarkm * Parses the name of the cipher. Returns the number of the corresponding 24657429Smarkm * cipher, or -1 on error. 24757429Smarkm */ 24857429Smarkm 24957429Smarkmint 25057429Smarkmcipher_number(const char *name) 25157429Smarkm{ 252255767Sdes const Cipher *c; 25361212Skris if (name == NULL) 25461212Skris return -1; 255147005Sdes for (c = ciphers; c->name != NULL; c++) 256147005Sdes if (strcasecmp(c->name, name) == 0) 257147005Sdes return c->number; 258147005Sdes return -1; 25957429Smarkm} 26057429Smarkm 26169591Sgreenchar * 26269591Sgreencipher_name(int id) 26357429Smarkm{ 264255767Sdes const Cipher *c = cipher_by_number(id); 26569591Sgreen return (c==NULL) ? "<unknown>" : c->name; 26657429Smarkm} 26757429Smarkm 26860576Skrisvoid 269255767Sdescipher_init(CipherContext *cc, const Cipher *cipher, 27092559Sdes const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, 271137019Sdes int do_encrypt) 27257429Smarkm{ 27392559Sdes static int dowarn = 1; 27498941Sdes#ifdef SSH_OLD_EVP 27598941Sdes EVP_CIPHER *type; 27698941Sdes#else 27792559Sdes const EVP_CIPHER *type; 278149753Sdes int klen; 27998941Sdes#endif 280149753Sdes u_char *junk, *discard; 28192559Sdes 28292559Sdes if (cipher->number == SSH_CIPHER_DES) { 28392559Sdes if (dowarn) { 28492559Sdes error("Warning: use of DES is strongly discouraged " 28592559Sdes "due to cryptographic weaknesses"); 28692559Sdes dowarn = 0; 28792559Sdes } 28892559Sdes if (keylen > 8) 28992559Sdes keylen = 8; 29092559Sdes } 29192559Sdes cc->plaintext = (cipher->number == SSH_CIPHER_NONE); 292248619Sdes cc->encrypt = do_encrypt; 29392559Sdes 29469591Sgreen if (keylen < cipher->key_len) 29569591Sgreen fatal("cipher_init: key length %d is insufficient for %s.", 29669591Sgreen keylen, cipher->name); 297248619Sdes if (iv != NULL && ivlen < cipher_ivlen(cipher)) 29869591Sgreen fatal("cipher_init: iv length %d is insufficient for %s.", 29969591Sgreen ivlen, cipher->name); 30069591Sgreen cc->cipher = cipher; 30192559Sdes 302262566Sdes if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { 303262566Sdes chachapoly_init(&cc->cp_ctx, key, keylen); 304262566Sdes return; 305262566Sdes } 30692559Sdes type = (*cipher->evptype)(); 30792559Sdes EVP_CIPHER_CTX_init(&cc->evp); 30898941Sdes#ifdef SSH_OLD_EVP 30998941Sdes if (type->key_len > 0 && type->key_len != keylen) { 31098941Sdes debug("cipher_init: set keylen (%d -> %d)", 31198941Sdes type->key_len, keylen); 31298941Sdes type->key_len = keylen; 31398941Sdes } 31498941Sdes EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv, 315137019Sdes (do_encrypt == CIPHER_ENCRYPT)); 31698941Sdes#else 31792559Sdes if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, 318137019Sdes (do_encrypt == CIPHER_ENCRYPT)) == 0) 31992559Sdes fatal("cipher_init: EVP_CipherInit failed for %s", 32092559Sdes cipher->name); 321248619Sdes if (cipher_authlen(cipher) && 322248619Sdes !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, 323248619Sdes -1, (u_char *)iv)) 324248619Sdes fatal("cipher_init: EVP_CTRL_GCM_SET_IV_FIXED failed for %s", 325248619Sdes cipher->name); 32692559Sdes klen = EVP_CIPHER_CTX_key_length(&cc->evp); 327149753Sdes if (klen > 0 && keylen != (u_int)klen) { 328113911Sdes debug2("cipher_init: set keylen (%d -> %d)", klen, keylen); 32992559Sdes if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) 33092559Sdes fatal("cipher_init: set keylen failed (%d -> %d)", 33192559Sdes klen, keylen); 33292559Sdes } 33392559Sdes if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) 33492559Sdes fatal("cipher_init: EVP_CipherInit: set key failed for %s", 33592559Sdes cipher->name); 33698941Sdes#endif 337149753Sdes 338149753Sdes if (cipher->discard_len > 0) { 339149753Sdes junk = xmalloc(cipher->discard_len); 340149753Sdes discard = xmalloc(cipher->discard_len); 341149753Sdes if (EVP_Cipher(&cc->evp, discard, junk, 342149753Sdes cipher->discard_len) == 0) 343149753Sdes fatal("evp_crypt: EVP_Cipher failed during discard"); 344264377Sdes explicit_bzero(discard, cipher->discard_len); 345255767Sdes free(junk); 346255767Sdes free(discard); 347149753Sdes } 34857429Smarkm} 34957429Smarkm 350248619Sdes/* 351248619Sdes * cipher_crypt() operates as following: 352248619Sdes * Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'. 353248619Sdes * Theses bytes are treated as additional authenticated data for 354248619Sdes * authenticated encryption modes. 355248619Sdes * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. 356248619Sdes * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag. 357248619Sdes * This tag is written on encryption and verified on decryption. 358248619Sdes * Both 'aadlen' and 'authlen' can be set to 0. 359262566Sdes * cipher_crypt() returns 0 on success and -1 if the decryption integrity 360262566Sdes * check fails. 361248619Sdes */ 362262566Sdesint 363262566Sdescipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src, 364248619Sdes u_int len, u_int aadlen, u_int authlen) 36560576Skris{ 366262566Sdes if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 367262566Sdes return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len, 368262566Sdes aadlen, authlen, cc->encrypt); 369248619Sdes if (authlen) { 370248619Sdes u_char lastiv[1]; 371248619Sdes 372248619Sdes if (authlen != cipher_authlen(cc->cipher)) 373248619Sdes fatal("%s: authlen mismatch %d", __func__, authlen); 374248619Sdes /* increment IV */ 375248619Sdes if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, 376248619Sdes 1, lastiv)) 377248619Sdes fatal("%s: EVP_CTRL_GCM_IV_GEN", __func__); 378248619Sdes /* set tag on decyption */ 379248619Sdes if (!cc->encrypt && 380248619Sdes !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG, 381248619Sdes authlen, (u_char *)src + aadlen + len)) 382248619Sdes fatal("%s: EVP_CTRL_GCM_SET_TAG", __func__); 383248619Sdes } 384248619Sdes if (aadlen) { 385248619Sdes if (authlen && 386248619Sdes EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0) 387248619Sdes fatal("%s: EVP_Cipher(aad) failed", __func__); 388248619Sdes memcpy(dest, src, aadlen); 389248619Sdes } 39069591Sgreen if (len % cc->cipher->block_size) 391248619Sdes fatal("%s: bad plaintext length %d", __func__, len); 392248619Sdes if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen, 393248619Sdes len) < 0) 394248619Sdes fatal("%s: EVP_Cipher failed", __func__); 395248619Sdes if (authlen) { 396248619Sdes /* compute tag (on encrypt) or verify tag (on decrypt) */ 397248619Sdes if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) { 398248619Sdes if (cc->encrypt) 399248619Sdes fatal("%s: EVP_Cipher(final) failed", __func__); 400248619Sdes else 401262566Sdes return -1; 402248619Sdes } 403248619Sdes if (cc->encrypt && 404248619Sdes !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, 405248619Sdes authlen, dest + aadlen + len)) 406248619Sdes fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__); 407248619Sdes } 408262566Sdes return 0; 40960576Skris} 41060576Skris 411262566Sdes/* Extract the packet length, including any decryption necessary beforehand */ 412262566Sdesint 413262566Sdescipher_get_length(CipherContext *cc, u_int *plenp, u_int seqnr, 414262566Sdes const u_char *cp, u_int len) 415262566Sdes{ 416262566Sdes if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 417262566Sdes return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr, 418262566Sdes cp, len); 419262566Sdes if (len < 4) 420262566Sdes return -1; 421262566Sdes *plenp = get_u32(cp); 422262566Sdes return 0; 423262566Sdes} 424262566Sdes 42560576Skrisvoid 42692559Sdescipher_cleanup(CipherContext *cc) 42757429Smarkm{ 428262566Sdes if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 429264377Sdes explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); 430262566Sdes else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) 43192559Sdes error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); 43257429Smarkm} 43357429Smarkm 43469591Sgreen/* 43569591Sgreen * Selects the cipher, and keys if by computing the MD5 checksum of the 43669591Sgreen * passphrase and using the resulting 16 bytes as the key. 43769591Sgreen */ 43857429Smarkm 43960576Skrisvoid 440255767Sdescipher_set_key_string(CipherContext *cc, const Cipher *cipher, 441137019Sdes const char *passphrase, int do_encrypt) 44257429Smarkm{ 44376262Sgreen u_char digest[16]; 44457429Smarkm 445264377Sdes if (ssh_digest_memory(SSH_DIGEST_MD5, passphrase, strlen(passphrase), 446264377Sdes digest, sizeof(digest)) < 0) 447264377Sdes fatal("%s: md5 failed", __func__); 44857429Smarkm 449137019Sdes cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt); 45057429Smarkm 451264377Sdes explicit_bzero(digest, sizeof(digest)); 45257429Smarkm} 45392559Sdes 45492559Sdes/* 45598684Sdes * Exports an IV from the CipherContext required to export the key 45698684Sdes * state back from the unprivileged child to the privileged parent 45798684Sdes * process. 45898684Sdes */ 45998684Sdes 46098684Sdesint 461126277Sdescipher_get_keyiv_len(const CipherContext *cc) 46298684Sdes{ 463255767Sdes const Cipher *c = cc->cipher; 46498684Sdes int ivlen; 46598684Sdes 46698684Sdes if (c->number == SSH_CIPHER_3DES) 46798684Sdes ivlen = 24; 468262566Sdes else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 469262566Sdes ivlen = 0; 47098684Sdes else 47198684Sdes ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); 47298684Sdes return (ivlen); 47398684Sdes} 47498684Sdes 47598684Sdesvoid 47698684Sdescipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) 47798684Sdes{ 478255767Sdes const Cipher *c = cc->cipher; 47998684Sdes int evplen; 48098684Sdes 481262566Sdes if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { 482262566Sdes if (len != 0) 483262566Sdes fatal("%s: wrong iv length %d != %d", __func__, len, 0); 484262566Sdes return; 485262566Sdes } 486262566Sdes 48798684Sdes switch (c->number) { 488224638Sbrooks#ifdef NONE_CIPHER_ENABLED 489224638Sbrooks case SSH_CIPHER_NONE: 490224638Sbrooks#endif 49198684Sdes case SSH_CIPHER_SSH2: 49298684Sdes case SSH_CIPHER_DES: 49398684Sdes case SSH_CIPHER_BLOWFISH: 49498684Sdes evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); 495149753Sdes if (evplen <= 0) 49698684Sdes return; 497149753Sdes if ((u_int)evplen != len) 49898684Sdes fatal("%s: wrong iv length %d != %d", __func__, 49998684Sdes evplen, len); 500157019Sdes#ifdef USE_BUILTIN_RIJNDAEL 501124211Sdes if (c->evptype == evp_rijndael) 502124211Sdes ssh_rijndael_iv(&cc->evp, 0, iv, len); 503124211Sdes else 50498684Sdes#endif 505248619Sdes#ifndef OPENSSL_HAVE_EVPCTR 506124211Sdes if (c->evptype == evp_aes_128_ctr) 507124211Sdes ssh_aes_ctr_iv(&cc->evp, 0, iv, len); 508124211Sdes else 509248619Sdes#endif 510248619Sdes memcpy(iv, cc->evp.iv, len); 51198684Sdes break; 512124211Sdes case SSH_CIPHER_3DES: 513124211Sdes ssh1_3des_iv(&cc->evp, 0, iv, 24); 514124211Sdes break; 51598684Sdes default: 51698684Sdes fatal("%s: bad cipher %d", __func__, c->number); 51798684Sdes } 51898684Sdes} 51998684Sdes 52098684Sdesvoid 52198684Sdescipher_set_keyiv(CipherContext *cc, u_char *iv) 52298684Sdes{ 523255767Sdes const Cipher *c = cc->cipher; 52498684Sdes int evplen = 0; 52598684Sdes 526262566Sdes if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 527262566Sdes return; 528262566Sdes 52998684Sdes switch (c->number) { 530224638Sbrooks#ifdef NONE_CIPHER_ENABLED 531224638Sbrooks case SSH_CIPHER_NONE: 532224638Sbrooks#endif 53398684Sdes case SSH_CIPHER_SSH2: 53498684Sdes case SSH_CIPHER_DES: 53598684Sdes case SSH_CIPHER_BLOWFISH: 53698684Sdes evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); 53798684Sdes if (evplen == 0) 53898684Sdes return; 539157019Sdes#ifdef USE_BUILTIN_RIJNDAEL 540124211Sdes if (c->evptype == evp_rijndael) 541124211Sdes ssh_rijndael_iv(&cc->evp, 1, iv, evplen); 542124211Sdes else 54398684Sdes#endif 544248619Sdes#ifndef OPENSSL_HAVE_EVPCTR 545124211Sdes if (c->evptype == evp_aes_128_ctr) 546124211Sdes ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen); 547124211Sdes else 548248619Sdes#endif 549248619Sdes memcpy(cc->evp.iv, iv, evplen); 55098684Sdes break; 551124211Sdes case SSH_CIPHER_3DES: 552124211Sdes ssh1_3des_iv(&cc->evp, 1, iv, 24); 553124211Sdes break; 55498684Sdes default: 55598684Sdes fatal("%s: bad cipher %d", __func__, c->number); 55698684Sdes } 55798684Sdes} 55898684Sdes 55998684Sdesint 560126277Sdescipher_get_keycontext(const CipherContext *cc, u_char *dat) 56198684Sdes{ 562255767Sdes const Cipher *c = cc->cipher; 56398684Sdes int plen = 0; 56498684Sdes 565248619Sdes if (c->evptype == EVP_rc4) { 56698684Sdes plen = EVP_X_STATE_LEN(cc->evp); 56798684Sdes if (dat == NULL) 56898684Sdes return (plen); 56998684Sdes memcpy(dat, EVP_X_STATE(cc->evp), plen); 57098684Sdes } 57198684Sdes return (plen); 57298684Sdes} 57398684Sdes 57498684Sdesvoid 57598684Sdescipher_set_keycontext(CipherContext *cc, u_char *dat) 57698684Sdes{ 577255767Sdes const Cipher *c = cc->cipher; 57898684Sdes int plen; 57998684Sdes 580248619Sdes if (c->evptype == EVP_rc4) { 58198684Sdes plen = EVP_X_STATE_LEN(cc->evp); 58298684Sdes memcpy(EVP_X_STATE(cc->evp), dat, plen); 58398684Sdes } 58498684Sdes} 585