[BACK]Return to cipher.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/cipher.c between version 1.97 and 1.98

version 1.97, 2014/02/07 06:55:54 version 1.98, 2014/04/29 18:01:49
Line 48 
Line 48 
 #include "buffer.h"  #include "buffer.h"
 #include "digest.h"  #include "digest.h"
   
   #ifdef WITH_SSH1
 extern const EVP_CIPHER *evp_ssh1_bf(void);  extern const EVP_CIPHER *evp_ssh1_bf(void);
 extern const EVP_CIPHER *evp_ssh1_3des(void);  extern const EVP_CIPHER *evp_ssh1_3des(void);
 extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);  extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
   #endif
   
 struct Cipher {  struct Cipher {
         char    *name;          char    *name;
Line 63 
Line 65 
         u_int   flags;          u_int   flags;
 #define CFLAG_CBC               (1<<0)  #define CFLAG_CBC               (1<<0)
 #define CFLAG_CHACHAPOLY        (1<<1)  #define CFLAG_CHACHAPOLY        (1<<1)
   #define CFLAG_AESCTR            (1<<2)
   #define CFLAG_NONE              (1<<3)
   #ifdef WITH_OPENSSL
         const EVP_CIPHER        *(*evptype)(void);          const EVP_CIPHER        *(*evptype)(void);
   #else
           void    *ignored;
   #endif
 };  };
   
 static const struct Cipher ciphers[] = {  static const struct Cipher ciphers[] = {
         { "none",       SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null },  #ifdef WITH_SSH1
         { "des",        SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },          { "des",        SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
         { "3des",       SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des },          { "3des",       SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des },
         { "blowfish",   SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf },          { "blowfish",   SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf },
   #endif
   #ifdef WITH_OPENSSL
           { "none",       SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null },
         { "3des-cbc",   SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc },          { "3des-cbc",   SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc },
         { "blowfish-cbc",          { "blowfish-cbc",
                         SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc },                          SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc },
Line 92 
Line 102 
                         SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm },                          SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm },
         { "aes256-gcm@openssh.com",          { "aes256-gcm@openssh.com",
                         SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm },                          SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm },
   #else
           { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL },
           { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL },
           { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, CFLAG_AESCTR, NULL },
           { "none",       SSH_CIPHER_NONE, 8, 0, 0, 0, 0, CFLAG_NONE, NULL },
   #endif
         { "chacha20-poly1305@openssh.com",          { "chacha20-poly1305@openssh.com",
                         SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL },                          SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL },
   
Line 258 
Line 274 
     const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,      const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
     int do_encrypt)      int do_encrypt)
 {  {
   #ifdef WITH_OPENSSL
         static int dowarn = 1;          static int dowarn = 1;
         const EVP_CIPHER *type;          const EVP_CIPHER *type;
         int klen;          int klen;
Line 272 
Line 289 
                 if (keylen > 8)                  if (keylen > 8)
                         keylen = 8;                          keylen = 8;
         }          }
   #endif
         cc->plaintext = (cipher->number == SSH_CIPHER_NONE);          cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
         cc->encrypt = do_encrypt;          cc->encrypt = do_encrypt;
   
Line 287 
Line 305 
                 chachapoly_init(&cc->cp_ctx, key, keylen);                  chachapoly_init(&cc->cp_ctx, key, keylen);
                 return;                  return;
         }          }
   #ifndef WITH_OPENSSL
           if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
                   aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen);
                   aesctr_ivsetup(&cc->ac_ctx, iv);
                   return;
           }
           if ((cc->cipher->flags & CFLAG_NONE) != 0)
                   return;
           fatal("unsupported cipher");
   #else
         type = (*cipher->evptype)();          type = (*cipher->evptype)();
         EVP_CIPHER_CTX_init(&cc->evp);          EVP_CIPHER_CTX_init(&cc->evp);
         if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,          if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
Line 319 
Line 347 
                 free(junk);                  free(junk);
                 free(discard);                  free(discard);
         }          }
   #endif
 }  }
   
 /*  /*
Line 340 
Line 369 
         if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)          if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
                 return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len,                  return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len,
                     aadlen, authlen, cc->encrypt);                      aadlen, authlen, cc->encrypt);
   #ifndef WITH_OPENSSL
           if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
                   if (aadlen)
                           memcpy(dest, src, aadlen);
                   aesctr_encrypt_bytes(&cc->ac_ctx, src + aadlen,
                       dest + aadlen, len);
                   return 0;
           }
           if ((cc->cipher->flags & CFLAG_NONE) != 0) {
                   memcpy(dest, src, aadlen + len);
                   return 0;
           }
           fatal("unsupported cipher");
   #else
         if (authlen) {          if (authlen) {
                 u_char lastiv[1];                  u_char lastiv[1];
   
Line 380 
Line 423 
                         fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__);                          fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__);
         }          }
         return 0;          return 0;
   #endif
 }  }
   
 /* Extract the packet length, including any decryption necessary beforehand */  /* Extract the packet length, including any decryption necessary beforehand */
Line 401 
Line 445 
 {  {
         if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)          if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
                 explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx));                  explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx));
           else if ((cc->cipher->flags & CFLAG_AESCTR) != 0)
                   explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx));
   #ifdef WITH_OPENSSL
         else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)          else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
                 error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");                  error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
   #endif
 }  }
   
 /*  /*
Line 435 
Line 483 
 cipher_get_keyiv_len(const CipherContext *cc)  cipher_get_keyiv_len(const CipherContext *cc)
 {  {
         const Cipher *c = cc->cipher;          const Cipher *c = cc->cipher;
         int ivlen;          int ivlen = 0;
   
         if (c->number == SSH_CIPHER_3DES)          if (c->number == SSH_CIPHER_3DES)
                 ivlen = 24;                  ivlen = 24;
         else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)          else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
                 ivlen = 0;                  ivlen = 0;
   #ifdef WITH_OPENSSL
         else          else
                 ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);                  ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);
   #endif
         return (ivlen);          return (ivlen);
 }  }
   
Line 450 
Line 500 
 cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)  cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
 {  {
         const Cipher *c = cc->cipher;          const Cipher *c = cc->cipher;
   #ifdef WITH_OPENSSL
         int evplen;          int evplen;
   #endif
   
         if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {          if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
                 if (len != 0)                  if (len != 0)
                         fatal("%s: wrong iv length %d != %d", __func__, len, 0);                          fatal("%s: wrong iv length %d != %d", __func__, len, 0);
                 return;                  return;
         }          }
           if ((cc->cipher->flags & CFLAG_NONE) != 0)
                   return;
   
         switch (c->number) {          switch (c->number) {
   #ifdef WITH_OPENSSL
         case SSH_CIPHER_SSH2:          case SSH_CIPHER_SSH2:
         case SSH_CIPHER_DES:          case SSH_CIPHER_DES:
         case SSH_CIPHER_BLOWFISH:          case SSH_CIPHER_BLOWFISH:
Line 475 
Line 530 
                 } else                  } else
                         memcpy(iv, cc->evp.iv, len);                          memcpy(iv, cc->evp.iv, len);
                 break;                  break;
   #endif
   #ifdef WITH_SSH1
         case SSH_CIPHER_3DES:          case SSH_CIPHER_3DES:
                 ssh1_3des_iv(&cc->evp, 0, iv, 24);                  ssh1_3des_iv(&cc->evp, 0, iv, 24);
                 break;                  break;
   #endif
         default:          default:
                 fatal("%s: bad cipher %d", __func__, c->number);                  fatal("%s: bad cipher %d", __func__, c->number);
         }          }
Line 487 
Line 545 
 cipher_set_keyiv(CipherContext *cc, u_char *iv)  cipher_set_keyiv(CipherContext *cc, u_char *iv)
 {  {
         const Cipher *c = cc->cipher;          const Cipher *c = cc->cipher;
   #ifdef WITH_OPENSSL
         int evplen = 0;          int evplen = 0;
   #endif
   
         if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)          if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
                 return;                  return;
           if ((cc->cipher->flags & CFLAG_NONE) != 0)
                   return;
   
         switch (c->number) {          switch (c->number) {
   #ifdef WITH_OPENSSL
         case SSH_CIPHER_SSH2:          case SSH_CIPHER_SSH2:
         case SSH_CIPHER_DES:          case SSH_CIPHER_DES:
         case SSH_CIPHER_BLOWFISH:          case SSH_CIPHER_BLOWFISH:
Line 507 
Line 570 
                 } else                  } else
                         memcpy(cc->evp.iv, iv, evplen);                          memcpy(cc->evp.iv, iv, evplen);
                 break;                  break;
   #endif
   #ifdef WITH_SSH1
         case SSH_CIPHER_3DES:          case SSH_CIPHER_3DES:
                 ssh1_3des_iv(&cc->evp, 1, iv, 24);                  ssh1_3des_iv(&cc->evp, 1, iv, 24);
                 break;                  break;
   #endif
         default:          default:
                 fatal("%s: bad cipher %d", __func__, c->number);                  fatal("%s: bad cipher %d", __func__, c->number);
         }          }
 }  }
   
   #ifdef WITH_OPENSSL
 #define EVP_X_STATE(evp)        (evp).cipher_data  #define EVP_X_STATE(evp)        (evp).cipher_data
 #define EVP_X_STATE_LEN(evp)    (evp).cipher->ctx_size  #define EVP_X_STATE_LEN(evp)    (evp).cipher->ctx_size
   #endif
   
 int  int
 cipher_get_keycontext(const CipherContext *cc, u_char *dat)  cipher_get_keycontext(const CipherContext *cc, u_char *dat)
 {  {
   #ifdef WITH_OPENSSL
         const Cipher *c = cc->cipher;          const Cipher *c = cc->cipher;
         int plen = 0;          int plen = 0;
   
Line 531 
Line 600 
                 memcpy(dat, EVP_X_STATE(cc->evp), plen);                  memcpy(dat, EVP_X_STATE(cc->evp), plen);
         }          }
         return (plen);          return (plen);
   #else
           return (0);
   #endif
 }  }
   
 void  void
 cipher_set_keycontext(CipherContext *cc, u_char *dat)  cipher_set_keycontext(CipherContext *cc, u_char *dat)
 {  {
   #ifdef WITH_OPENSSL
         const Cipher *c = cc->cipher;          const Cipher *c = cc->cipher;
         int plen;          int plen;
   
Line 543 
Line 616 
                 plen = EVP_X_STATE_LEN(cc->evp);                  plen = EVP_X_STATE_LEN(cc->evp);
                 memcpy(EVP_X_STATE(cc->evp), dat, plen);                  memcpy(EVP_X_STATE(cc->evp), dat, plen);
         }          }
   #endif
 }  }

Legend:
Removed from v.1.97  
changed lines
  Added in v.1.98