1323134Sdes/* $OpenBSD: cipher.c,v 1.102 2016/08/03 05:41:57 djm Exp $ */ 257429Smarkm/* 357429Smarkm * Author: Tatu Ylonen <ylo@cs.hut.fi> 457429Smarkm * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 557429Smarkm * All rights reserved 660576Skris * 765674Skris * As far as I am concerned, the code I have written for this software 865674Skris * can be used freely for any purpose. Any derived versions of this 965674Skris * software must be clearly marked as such, and if the derived work is 1065674Skris * incompatible with the protocol description in the RFC file, it must be 1165674Skris * called by a name other than "ssh" or "Secure Shell". 1260576Skris * 1365674Skris * 1465674Skris * Copyright (c) 1999 Niels Provos. All rights reserved. 1592559Sdes * Copyright (c) 1999, 2000 Markus Friedl. All rights reserved. 1665674Skris * 1765674Skris * Redistribution and use in source and binary forms, with or without 1865674Skris * modification, are permitted provided that the following conditions 1965674Skris * are met: 2065674Skris * 1. Redistributions of source code must retain the above copyright 2165674Skris * notice, this list of conditions and the following disclaimer. 2265674Skris * 2. Redistributions in binary form must reproduce the above copyright 2365674Skris * notice, this list of conditions and the following disclaimer in the 2465674Skris * documentation and/or other materials provided with the distribution. 2565674Skris * 2665674Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2765674Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2865674Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2965674Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 3065674Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 3165674Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3265674Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3365674Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3465674Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3565674Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3657429Smarkm */ 3757429Smarkm 3857429Smarkm#include "includes.h" 3957429Smarkm 40162856Sdes#include <sys/types.h> 41162856Sdes 42162856Sdes#include <string.h> 43162856Sdes#include <stdarg.h> 44261320Sdes#include <stdio.h> 45162856Sdes 46294328Sdes#include "cipher.h" 47261320Sdes#include "misc.h" 48294328Sdes#include "sshbuf.h" 49294328Sdes#include "ssherr.h" 50263712Sdes#include "digest.h" 5157429Smarkm 52149753Sdes#include "openbsd-compat/openssl-compat.h" 5398941Sdes 54294328Sdes#ifdef WITH_SSH1 55124211Sdesextern const EVP_CIPHER *evp_ssh1_bf(void); 56124211Sdesextern const EVP_CIPHER *evp_ssh1_3des(void); 57294328Sdesextern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); 58294328Sdes#endif 5957429Smarkm 60323134Sdesstruct sshcipher_ctx { 61323134Sdes int plaintext; 62323134Sdes int encrypt; 63323134Sdes EVP_CIPHER_CTX *evp; 64323134Sdes struct chachapoly_ctx cp_ctx; /* XXX union with evp? */ 65323134Sdes struct aesctr_ctx ac_ctx; /* XXX union with evp? */ 66323134Sdes const struct sshcipher *cipher; 67323134Sdes}; 68323134Sdes 69294328Sdesstruct sshcipher { 7092559Sdes char *name; 7192559Sdes int number; /* for ssh1 only */ 7292559Sdes u_int block_size; 7392559Sdes u_int key_len; 74248619Sdes u_int iv_len; /* defaults to block_size */ 75248619Sdes u_int auth_len; 76149753Sdes u_int discard_len; 77261320Sdes u_int flags; 78261320Sdes#define CFLAG_CBC (1<<0) 79261320Sdes#define CFLAG_CHACHAPOLY (1<<1) 80294328Sdes#define CFLAG_AESCTR (1<<2) 81294328Sdes#define CFLAG_NONE (1<<3) 82294328Sdes#ifdef WITH_OPENSSL 8398684Sdes const EVP_CIPHER *(*evptype)(void); 84294328Sdes#else 85294328Sdes void *ignored; 86294328Sdes#endif 87255767Sdes}; 88255767Sdes 89294328Sdesstatic const struct sshcipher ciphers[] = { 90294328Sdes#ifdef WITH_SSH1 91248619Sdes { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, 92248619Sdes { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des }, 93323129Sdes# ifndef OPENSSL_NO_BF 94248619Sdes { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf }, 95323129Sdes# endif /* OPENSSL_NO_BF */ 96294328Sdes#endif /* WITH_SSH1 */ 97294328Sdes#ifdef WITH_OPENSSL 98294328Sdes { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, 99248619Sdes { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, 100323129Sdes# ifndef OPENSSL_NO_BF 101248619Sdes { "blowfish-cbc", 102248619Sdes SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc }, 103323129Sdes# endif /* OPENSSL_NO_BF */ 104323129Sdes# ifndef OPENSSL_NO_CAST 105248619Sdes { "cast128-cbc", 106248619Sdes SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_cast5_cbc }, 107323129Sdes# endif /* OPENSSL_NO_CAST */ 108323129Sdes# ifndef OPENSSL_NO_RC4 109248619Sdes { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 0, EVP_rc4 }, 110248619Sdes { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 0, 0, 1536, 0, EVP_rc4 }, 111248619Sdes { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 0, 0, 1536, 0, EVP_rc4 }, 112323129Sdes# endif /* OPENSSL_NO_RC4 */ 113248619Sdes { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc }, 114248619Sdes { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc }, 115248619Sdes { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, 11698684Sdes { "rijndael-cbc@lysator.liu.se", 117248619Sdes SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, 118248619Sdes { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, 119248619Sdes { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, 120248619Sdes { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, 121294328Sdes# ifdef OPENSSL_HAVE_EVPGCM 122248619Sdes { "aes128-gcm@openssh.com", 123248619Sdes SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, 124248619Sdes { "aes256-gcm@openssh.com", 125248619Sdes SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, 126294328Sdes# endif /* OPENSSL_HAVE_EVPGCM */ 127294328Sdes#else /* WITH_OPENSSL */ 128294328Sdes { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL }, 129294328Sdes { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL }, 130294328Sdes { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, CFLAG_AESCTR, NULL }, 131294328Sdes { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, CFLAG_NONE, NULL }, 132294328Sdes#endif /* WITH_OPENSSL */ 133261320Sdes { "chacha20-poly1305@openssh.com", 134261320Sdes SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL }, 135294328Sdes 136248619Sdes { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } 13792559Sdes}; 13869591Sgreen 13992559Sdes/*--*/ 14057429Smarkm 141294328Sdes/* Returns a comma-separated list of supported ciphers. */ 142255767Sdeschar * 143261320Sdescipher_alg_list(char sep, int auth_only) 144255767Sdes{ 145294328Sdes char *tmp, *ret = NULL; 146255767Sdes size_t nlen, rlen = 0; 147294328Sdes const struct sshcipher *c; 148255767Sdes 149255767Sdes for (c = ciphers; c->name != NULL; c++) { 150255767Sdes if (c->number != SSH_CIPHER_SSH2) 151255767Sdes continue; 152261320Sdes if (auth_only && c->auth_len == 0) 153261320Sdes continue; 154255767Sdes if (ret != NULL) 155261320Sdes ret[rlen++] = sep; 156255767Sdes nlen = strlen(c->name); 157294328Sdes if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { 158294328Sdes free(ret); 159294328Sdes return NULL; 160294328Sdes } 161294328Sdes ret = tmp; 162255767Sdes memcpy(ret + rlen, c->name, nlen + 1); 163255767Sdes rlen += nlen; 164255767Sdes } 165255767Sdes return ret; 166255767Sdes} 167255767Sdes 16898684Sdesu_int 169294328Sdescipher_blocksize(const struct sshcipher *c) 17057429Smarkm{ 17192559Sdes return (c->block_size); 17257429Smarkm} 17399063Sdes 17498684Sdesu_int 175294328Sdescipher_keylen(const struct sshcipher *c) 17669591Sgreen{ 17792559Sdes return (c->key_len); 17869591Sgreen} 17999063Sdes 18098684Sdesu_int 181294328Sdescipher_seclen(const struct sshcipher *c) 182261320Sdes{ 183261320Sdes if (strcmp("3des-cbc", c->name) == 0) 184261320Sdes return 14; 185261320Sdes return cipher_keylen(c); 186261320Sdes} 187261320Sdes 188261320Sdesu_int 189294328Sdescipher_authlen(const struct sshcipher *c) 190248619Sdes{ 191248619Sdes return (c->auth_len); 192248619Sdes} 193248619Sdes 194248619Sdesu_int 195294328Sdescipher_ivlen(const struct sshcipher *c) 196248619Sdes{ 197261320Sdes /* 198261320Sdes * Default is cipher block size, except for chacha20+poly1305 that 199261320Sdes * needs no IV. XXX make iv_len == -1 default? 200261320Sdes */ 201261320Sdes return (c->iv_len != 0 || (c->flags & CFLAG_CHACHAPOLY) != 0) ? 202261320Sdes c->iv_len : c->block_size; 203248619Sdes} 204248619Sdes 205248619Sdesu_int 206294328Sdescipher_get_number(const struct sshcipher *c) 20798684Sdes{ 20898684Sdes return (c->number); 20998684Sdes} 21069591Sgreen 21176262Sgreenu_int 212294328Sdescipher_is_cbc(const struct sshcipher *c) 213192595Sdes{ 214261320Sdes return (c->flags & CFLAG_CBC) != 0; 215192595Sdes} 216192595Sdes 217192595Sdesu_int 218323134Sdescipher_ctx_is_plaintext(struct sshcipher_ctx *cc) 219323134Sdes{ 220323134Sdes return cc->plaintext; 221323134Sdes} 222323134Sdes 223323134Sdesu_int 224323134Sdescipher_ctx_get_number(struct sshcipher_ctx *cc) 225323134Sdes{ 226323134Sdes return cc->cipher->number; 227323134Sdes} 228323134Sdes 229323134Sdesu_int 23069591Sgreencipher_mask_ssh1(int client) 23157429Smarkm{ 23276262Sgreen u_int mask = 0; 23392559Sdes mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ 23457429Smarkm mask |= 1 << SSH_CIPHER_BLOWFISH; 23569591Sgreen if (client) { 23669591Sgreen mask |= 1 << SSH_CIPHER_DES; 23769591Sgreen } 23857429Smarkm return mask; 23957429Smarkm} 24069591Sgreen 241294328Sdesconst struct sshcipher * 24269591Sgreencipher_by_name(const char *name) 24360576Skris{ 244294328Sdes const struct sshcipher *c; 24569591Sgreen for (c = ciphers; c->name != NULL; c++) 246147005Sdes if (strcmp(c->name, name) == 0) 24769591Sgreen return c; 24869591Sgreen return NULL; 24960576Skris} 25057429Smarkm 251294328Sdesconst struct sshcipher * 25269591Sgreencipher_by_number(int id) 25357429Smarkm{ 254294328Sdes const struct sshcipher *c; 25569591Sgreen for (c = ciphers; c->name != NULL; c++) 25669591Sgreen if (c->number == id) 25769591Sgreen return c; 25869591Sgreen return NULL; 25957429Smarkm} 26057429Smarkm 26160576Skris#define CIPHER_SEP "," 26260576Skrisint 26360576Skrisciphers_valid(const char *names) 26460576Skris{ 265294328Sdes const struct sshcipher *c; 266137019Sdes char *cipher_list, *cp; 26760576Skris char *p; 26860576Skris 26961212Skris if (names == NULL || strcmp(names, "") == 0) 27060576Skris return 0; 271294328Sdes if ((cipher_list = cp = strdup(names)) == NULL) 272294328Sdes return 0; 27369591Sgreen for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; 27492559Sdes (p = strsep(&cp, CIPHER_SEP))) { 27569591Sgreen c = cipher_by_name(p); 276291198Sdes if (c == NULL || c->number != SSH_CIPHER_SSH2) { 277255767Sdes free(cipher_list); 27860576Skris return 0; 27960576Skris } 28060576Skris } 281255767Sdes free(cipher_list); 28260576Skris return 1; 28360576Skris} 28460576Skris 28557429Smarkm/* 28657429Smarkm * Parses the name of the cipher. Returns the number of the corresponding 28757429Smarkm * cipher, or -1 on error. 28857429Smarkm */ 28957429Smarkm 29057429Smarkmint 29157429Smarkmcipher_number(const char *name) 29257429Smarkm{ 293294328Sdes const struct sshcipher *c; 29461212Skris if (name == NULL) 29561212Skris return -1; 296147005Sdes for (c = ciphers; c->name != NULL; c++) 297147005Sdes if (strcasecmp(c->name, name) == 0) 298147005Sdes return c->number; 299147005Sdes return -1; 30057429Smarkm} 30157429Smarkm 30269591Sgreenchar * 30369591Sgreencipher_name(int id) 30457429Smarkm{ 305294328Sdes const struct sshcipher *c = cipher_by_number(id); 30669591Sgreen return (c==NULL) ? "<unknown>" : c->name; 30757429Smarkm} 30857429Smarkm 309294328Sdesconst char * 310294328Sdescipher_warning_message(const struct sshcipher_ctx *cc) 311294328Sdes{ 312294328Sdes if (cc == NULL || cc->cipher == NULL) 313294328Sdes return NULL; 314294328Sdes if (cc->cipher->number == SSH_CIPHER_DES) 315294328Sdes return "use of DES is strongly discouraged due to " 316294328Sdes "cryptographic weaknesses"; 317294328Sdes return NULL; 318294328Sdes} 319294328Sdes 320294328Sdesint 321323134Sdescipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, 32292559Sdes const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, 323137019Sdes int do_encrypt) 32457429Smarkm{ 325323134Sdes struct sshcipher_ctx *cc = NULL; 326323134Sdes int ret = SSH_ERR_INTERNAL_ERROR; 327294328Sdes#ifdef WITH_OPENSSL 32892559Sdes const EVP_CIPHER *type; 329149753Sdes int klen; 330149753Sdes u_char *junk, *discard; 331323134Sdes#endif 33292559Sdes 333323134Sdes *ccp = NULL; 334323134Sdes if ((cc = calloc(sizeof(*cc), 1)) == NULL) 335323134Sdes return SSH_ERR_ALLOC_FAIL; 336323134Sdes 33792559Sdes if (cipher->number == SSH_CIPHER_DES) { 33892559Sdes if (keylen > 8) 33992559Sdes keylen = 8; 34092559Sdes } 341323134Sdes 34292559Sdes cc->plaintext = (cipher->number == SSH_CIPHER_NONE); 343248619Sdes cc->encrypt = do_encrypt; 34492559Sdes 345294328Sdes if (keylen < cipher->key_len || 346323134Sdes (iv != NULL && ivlen < cipher_ivlen(cipher))) { 347323134Sdes ret = SSH_ERR_INVALID_ARGUMENT; 348323134Sdes goto out; 349323134Sdes } 350294328Sdes 35169591Sgreen cc->cipher = cipher; 352261320Sdes if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { 353323134Sdes ret = chachapoly_init(&cc->cp_ctx, key, keylen); 354323134Sdes goto out; 355261320Sdes } 356294328Sdes#ifndef WITH_OPENSSL 357294328Sdes if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { 358294328Sdes aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); 359294328Sdes aesctr_ivsetup(&cc->ac_ctx, iv); 360323134Sdes ret = 0; 361323134Sdes goto out; 362294328Sdes } 363323134Sdes if ((cc->cipher->flags & CFLAG_NONE) != 0) { 364323134Sdes ret = 0; 365323134Sdes goto out; 366323134Sdes } 367323134Sdes ret = SSH_ERR_INVALID_ARGUMENT; 368323134Sdes goto out; 369323134Sdes#else /* WITH_OPENSSL */ 37092559Sdes type = (*cipher->evptype)(); 371323134Sdes if ((cc->evp = EVP_CIPHER_CTX_new()) == NULL) { 372323134Sdes ret = SSH_ERR_ALLOC_FAIL; 373323134Sdes goto out; 374323134Sdes } 375323134Sdes if (EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv, 376294328Sdes (do_encrypt == CIPHER_ENCRYPT)) == 0) { 377294328Sdes ret = SSH_ERR_LIBCRYPTO_ERROR; 378323134Sdes goto out; 37998941Sdes } 380248619Sdes if (cipher_authlen(cipher) && 381323134Sdes !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, 382294328Sdes -1, (u_char *)iv)) { 383294328Sdes ret = SSH_ERR_LIBCRYPTO_ERROR; 384323134Sdes goto out; 385294328Sdes } 386323134Sdes klen = EVP_CIPHER_CTX_key_length(cc->evp); 387149753Sdes if (klen > 0 && keylen != (u_int)klen) { 388323134Sdes if (EVP_CIPHER_CTX_set_key_length(cc->evp, keylen) == 0) { 389294328Sdes ret = SSH_ERR_LIBCRYPTO_ERROR; 390323134Sdes goto out; 391294328Sdes } 39292559Sdes } 393323134Sdes if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) { 394294328Sdes ret = SSH_ERR_LIBCRYPTO_ERROR; 395323134Sdes goto out; 396294328Sdes } 397149753Sdes 398149753Sdes if (cipher->discard_len > 0) { 399294328Sdes if ((junk = malloc(cipher->discard_len)) == NULL || 400294328Sdes (discard = malloc(cipher->discard_len)) == NULL) { 401296633Sdes free(junk); 402294328Sdes ret = SSH_ERR_ALLOC_FAIL; 403323134Sdes goto out; 404294328Sdes } 405323134Sdes ret = EVP_Cipher(cc->evp, discard, junk, cipher->discard_len); 406263712Sdes explicit_bzero(discard, cipher->discard_len); 407255767Sdes free(junk); 408255767Sdes free(discard); 409294328Sdes if (ret != 1) { 410294328Sdes ret = SSH_ERR_LIBCRYPTO_ERROR; 411323134Sdes goto out; 412294328Sdes } 413149753Sdes } 414323134Sdes ret = 0; 415323134Sdes#endif /* WITH_OPENSSL */ 416323134Sdes out: 417323134Sdes if (ret == 0) { 418323134Sdes /* success */ 419323134Sdes *ccp = cc; 420323134Sdes } else { 421323134Sdes if (cc != NULL) { 422323134Sdes#ifdef WITH_OPENSSL 423323134Sdes if (cc->evp != NULL) 424323134Sdes EVP_CIPHER_CTX_free(cc->evp); 425323134Sdes#endif /* WITH_OPENSSL */ 426323134Sdes explicit_bzero(cc, sizeof(*cc)); 427323134Sdes free(cc); 428323134Sdes } 429323134Sdes } 430323134Sdes return ret; 43157429Smarkm} 43257429Smarkm 433248619Sdes/* 434248619Sdes * cipher_crypt() operates as following: 435248619Sdes * Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'. 436248619Sdes * Theses bytes are treated as additional authenticated data for 437248619Sdes * authenticated encryption modes. 438248619Sdes * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. 439248619Sdes * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag. 440248619Sdes * This tag is written on encryption and verified on decryption. 441248619Sdes * Both 'aadlen' and 'authlen' can be set to 0. 442248619Sdes */ 443261320Sdesint 444294328Sdescipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, 445294328Sdes const u_char *src, u_int len, u_int aadlen, u_int authlen) 44660576Skris{ 447294328Sdes if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { 448294328Sdes return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, 449294328Sdes len, aadlen, authlen, cc->encrypt); 450294328Sdes } 451294328Sdes#ifndef WITH_OPENSSL 452294328Sdes if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { 453294328Sdes if (aadlen) 454294328Sdes memcpy(dest, src, aadlen); 455294328Sdes aesctr_encrypt_bytes(&cc->ac_ctx, src + aadlen, 456294328Sdes dest + aadlen, len); 457294328Sdes return 0; 458294328Sdes } 459294328Sdes if ((cc->cipher->flags & CFLAG_NONE) != 0) { 460294328Sdes memcpy(dest, src, aadlen + len); 461294328Sdes return 0; 462294328Sdes } 463294328Sdes return SSH_ERR_INVALID_ARGUMENT; 464294328Sdes#else 465248619Sdes if (authlen) { 466248619Sdes u_char lastiv[1]; 467248619Sdes 468248619Sdes if (authlen != cipher_authlen(cc->cipher)) 469294328Sdes return SSH_ERR_INVALID_ARGUMENT; 470248619Sdes /* increment IV */ 471323134Sdes if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, 472248619Sdes 1, lastiv)) 473294328Sdes return SSH_ERR_LIBCRYPTO_ERROR; 474248619Sdes /* set tag on decyption */ 475248619Sdes if (!cc->encrypt && 476323134Sdes !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG, 477248619Sdes authlen, (u_char *)src + aadlen + len)) 478294328Sdes return SSH_ERR_LIBCRYPTO_ERROR; 479248619Sdes } 480248619Sdes if (aadlen) { 481248619Sdes if (authlen && 482323134Sdes EVP_Cipher(cc->evp, NULL, (u_char *)src, aadlen) < 0) 483294328Sdes return SSH_ERR_LIBCRYPTO_ERROR; 484248619Sdes memcpy(dest, src, aadlen); 485248619Sdes } 48669591Sgreen if (len % cc->cipher->block_size) 487294328Sdes return SSH_ERR_INVALID_ARGUMENT; 488323134Sdes if (EVP_Cipher(cc->evp, dest + aadlen, (u_char *)src + aadlen, 489248619Sdes len) < 0) 490294328Sdes return SSH_ERR_LIBCRYPTO_ERROR; 491248619Sdes if (authlen) { 492248619Sdes /* compute tag (on encrypt) or verify tag (on decrypt) */ 493323134Sdes if (EVP_Cipher(cc->evp, NULL, NULL, 0) < 0) 494294328Sdes return cc->encrypt ? 495294328Sdes SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID; 496248619Sdes if (cc->encrypt && 497323134Sdes !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_GET_TAG, 498248619Sdes authlen, dest + aadlen + len)) 499294328Sdes return SSH_ERR_LIBCRYPTO_ERROR; 500248619Sdes } 501261320Sdes return 0; 502294328Sdes#endif 50360576Skris} 50460576Skris 505261320Sdes/* Extract the packet length, including any decryption necessary beforehand */ 506261320Sdesint 507294328Sdescipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr, 508261320Sdes const u_char *cp, u_int len) 509261320Sdes{ 510261320Sdes if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 511261320Sdes return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr, 512261320Sdes cp, len); 513261320Sdes if (len < 4) 514294328Sdes return SSH_ERR_MESSAGE_INCOMPLETE; 515261320Sdes *plenp = get_u32(cp); 516261320Sdes return 0; 517261320Sdes} 518261320Sdes 519323134Sdesvoid 520323134Sdescipher_free(struct sshcipher_ctx *cc) 52157429Smarkm{ 522323134Sdes if (cc == NULL) 523323134Sdes return; 524261320Sdes if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 525263712Sdes explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); 526294328Sdes else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) 527294328Sdes explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx)); 528294328Sdes#ifdef WITH_OPENSSL 529323134Sdes if (cc->evp != NULL) { 530323134Sdes EVP_CIPHER_CTX_free(cc->evp); 531323134Sdes cc->evp = NULL; 532323134Sdes } 533294328Sdes#endif 534323134Sdes explicit_bzero(cc, sizeof(*cc)); 535323134Sdes free(cc); 53657429Smarkm} 53757429Smarkm 53869591Sgreen/* 53969591Sgreen * Selects the cipher, and keys if by computing the MD5 checksum of the 54069591Sgreen * passphrase and using the resulting 16 bytes as the key. 54169591Sgreen */ 542294328Sdesint 543323134Sdescipher_set_key_string(struct sshcipher_ctx **ccp, 544323134Sdes const struct sshcipher *cipher, const char *passphrase, int do_encrypt) 54557429Smarkm{ 54676262Sgreen u_char digest[16]; 547294328Sdes int r = SSH_ERR_INTERNAL_ERROR; 54857429Smarkm 549294328Sdes if ((r = ssh_digest_memory(SSH_DIGEST_MD5, 550294328Sdes passphrase, strlen(passphrase), 551294328Sdes digest, sizeof(digest))) != 0) 552294328Sdes goto out; 55357429Smarkm 554323134Sdes r = cipher_init(ccp, cipher, digest, 16, NULL, 0, do_encrypt); 555294328Sdes out: 556263712Sdes explicit_bzero(digest, sizeof(digest)); 557294328Sdes return r; 55857429Smarkm} 55992559Sdes 56092559Sdes/* 561294328Sdes * Exports an IV from the sshcipher_ctx required to export the key 56298684Sdes * state back from the unprivileged child to the privileged parent 56398684Sdes * process. 56498684Sdes */ 56598684Sdesint 566294328Sdescipher_get_keyiv_len(const struct sshcipher_ctx *cc) 56798684Sdes{ 568294328Sdes const struct sshcipher *c = cc->cipher; 569294328Sdes int ivlen = 0; 57098684Sdes 57198684Sdes if (c->number == SSH_CIPHER_3DES) 57298684Sdes ivlen = 24; 573261320Sdes else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 574261320Sdes ivlen = 0; 575294332Sdes else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) 576294332Sdes ivlen = sizeof(cc->ac_ctx.ctr); 577294328Sdes#ifdef WITH_OPENSSL 57898684Sdes else 579323134Sdes ivlen = EVP_CIPHER_CTX_iv_length(cc->evp); 580294328Sdes#endif /* WITH_OPENSSL */ 58198684Sdes return (ivlen); 58298684Sdes} 58398684Sdes 584294328Sdesint 585294328Sdescipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len) 58698684Sdes{ 587294328Sdes const struct sshcipher *c = cc->cipher; 588294328Sdes#ifdef WITH_OPENSSL 589294328Sdes int evplen; 590294328Sdes#endif 59198684Sdes 592261320Sdes if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { 593261320Sdes if (len != 0) 594294328Sdes return SSH_ERR_INVALID_ARGUMENT; 595294328Sdes return 0; 596261320Sdes } 597294332Sdes if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { 598294332Sdes if (len != sizeof(cc->ac_ctx.ctr)) 599294332Sdes return SSH_ERR_INVALID_ARGUMENT; 600294332Sdes memcpy(iv, cc->ac_ctx.ctr, len); 601294332Sdes return 0; 602294332Sdes } 603294328Sdes if ((cc->cipher->flags & CFLAG_NONE) != 0) 604294328Sdes return 0; 605261320Sdes 60698684Sdes switch (c->number) { 607294328Sdes#ifdef WITH_OPENSSL 60898684Sdes case SSH_CIPHER_SSH2: 60998684Sdes case SSH_CIPHER_DES: 61098684Sdes case SSH_CIPHER_BLOWFISH: 611323134Sdes evplen = EVP_CIPHER_CTX_iv_length(cc->evp); 612294328Sdes if (evplen == 0) 613294328Sdes return 0; 614294328Sdes else if (evplen < 0) 615294328Sdes return SSH_ERR_LIBCRYPTO_ERROR; 616149753Sdes if ((u_int)evplen != len) 617294328Sdes return SSH_ERR_INVALID_ARGUMENT; 618248619Sdes#ifndef OPENSSL_HAVE_EVPCTR 619124211Sdes if (c->evptype == evp_aes_128_ctr) 620323134Sdes ssh_aes_ctr_iv(cc->evp, 0, iv, len); 621124211Sdes else 622248619Sdes#endif 623294328Sdes if (cipher_authlen(c)) { 624323134Sdes if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, 625294328Sdes len, iv)) 626294328Sdes return SSH_ERR_LIBCRYPTO_ERROR; 627294328Sdes } else 628323134Sdes memcpy(iv, cc->evp->iv, len); 62998684Sdes break; 630294328Sdes#endif 631294328Sdes#ifdef WITH_SSH1 632124211Sdes case SSH_CIPHER_3DES: 633323134Sdes return ssh1_3des_iv(cc->evp, 0, iv, 24); 634294328Sdes#endif 63598684Sdes default: 636294328Sdes return SSH_ERR_INVALID_ARGUMENT; 63798684Sdes } 638294328Sdes return 0; 63998684Sdes} 64098684Sdes 641294328Sdesint 642294328Sdescipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv) 64398684Sdes{ 644294328Sdes const struct sshcipher *c = cc->cipher; 645294328Sdes#ifdef WITH_OPENSSL 646294328Sdes int evplen = 0; 647294328Sdes#endif 64898684Sdes 649261320Sdes if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 650294328Sdes return 0; 651294328Sdes if ((cc->cipher->flags & CFLAG_NONE) != 0) 652294328Sdes return 0; 653261320Sdes 65498684Sdes switch (c->number) { 655294328Sdes#ifdef WITH_OPENSSL 65698684Sdes case SSH_CIPHER_SSH2: 65798684Sdes case SSH_CIPHER_DES: 65898684Sdes case SSH_CIPHER_BLOWFISH: 659323134Sdes evplen = EVP_CIPHER_CTX_iv_length(cc->evp); 660294328Sdes if (evplen <= 0) 661294328Sdes return SSH_ERR_LIBCRYPTO_ERROR; 662323134Sdes#ifndef OPENSSL_HAVE_EVPCTR 663323134Sdes /* XXX iv arg is const, but ssh_aes_ctr_iv isn't */ 664323134Sdes if (c->evptype == evp_aes_128_ctr) 665323134Sdes ssh_aes_ctr_iv(cc->evp, 1, (u_char *)iv, evplen); 666323134Sdes else 667323134Sdes#endif 668294328Sdes if (cipher_authlen(c)) { 669294328Sdes /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */ 670323134Sdes if (!EVP_CIPHER_CTX_ctrl(cc->evp, 671294328Sdes EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) 672294328Sdes return SSH_ERR_LIBCRYPTO_ERROR; 673294328Sdes } else 674323134Sdes memcpy(cc->evp->iv, iv, evplen); 675294328Sdes break; 67698684Sdes#endif 677294328Sdes#ifdef WITH_SSH1 678294328Sdes case SSH_CIPHER_3DES: 679323134Sdes return ssh1_3des_iv(cc->evp, 1, (u_char *)iv, 24); 680248619Sdes#endif 68198684Sdes default: 682294328Sdes return SSH_ERR_INVALID_ARGUMENT; 68398684Sdes } 684294328Sdes return 0; 68598684Sdes} 68698684Sdes 687294328Sdes#ifdef WITH_OPENSSL 688323134Sdes#define EVP_X_STATE(evp) (evp)->cipher_data 689323134Sdes#define EVP_X_STATE_LEN(evp) (evp)->cipher->ctx_size 690294328Sdes#endif 691294328Sdes 69298684Sdesint 693294328Sdescipher_get_keycontext(const struct sshcipher_ctx *cc, u_char *dat) 69498684Sdes{ 695323129Sdes#if defined(WITH_OPENSSL) && !defined(OPENSSL_NO_RC4) 696294328Sdes const struct sshcipher *c = cc->cipher; 69798684Sdes int plen = 0; 69898684Sdes 699248619Sdes if (c->evptype == EVP_rc4) { 70098684Sdes plen = EVP_X_STATE_LEN(cc->evp); 70198684Sdes if (dat == NULL) 70298684Sdes return (plen); 70398684Sdes memcpy(dat, EVP_X_STATE(cc->evp), plen); 70498684Sdes } 70598684Sdes return (plen); 706294328Sdes#else 707294328Sdes return 0; 708294328Sdes#endif 70998684Sdes} 71098684Sdes 71198684Sdesvoid 712294328Sdescipher_set_keycontext(struct sshcipher_ctx *cc, const u_char *dat) 71398684Sdes{ 714323129Sdes#if defined(WITH_OPENSSL) && !defined(OPENSSL_NO_RC4) 715294328Sdes const struct sshcipher *c = cc->cipher; 71698684Sdes int plen; 71798684Sdes 718248619Sdes if (c->evptype == EVP_rc4) { 71998684Sdes plen = EVP_X_STATE_LEN(cc->evp); 72098684Sdes memcpy(EVP_X_STATE(cc->evp), dat, plen); 72198684Sdes } 722294328Sdes#endif 72398684Sdes} 724