[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.90 and 1.91

version 1.90, 2013/11/07 11:58:27 version 1.91, 2013/11/21 00:45:44
Line 41 
Line 41 
   
 #include <string.h>  #include <string.h>
 #include <stdarg.h>  #include <stdarg.h>
   #include <stdio.h>
   
 #include "xmalloc.h"  #include "xmalloc.h"
 #include "log.h"  #include "log.h"
   #include "misc.h"
 #include "cipher.h"  #include "cipher.h"
   
 extern const EVP_CIPHER *evp_ssh1_bf(void);  extern const EVP_CIPHER *evp_ssh1_bf(void);
Line 58 
Line 60 
         u_int   iv_len;         /* defaults to block_size */          u_int   iv_len;         /* defaults to block_size */
         u_int   auth_len;          u_int   auth_len;
         u_int   discard_len;          u_int   discard_len;
         u_int   cbc_mode;          u_int   flags;
   #define CFLAG_CBC               (1<<0)
   #define CFLAG_CHACHAPOLY        (1<<1)
         const EVP_CIPHER        *(*evptype)(void);          const EVP_CIPHER        *(*evptype)(void);
 };  };
   
Line 88 
Line 92 
                         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 },
           { "chacha20-poly1305@openssh.com",
                           SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL },
   
         { NULL,         SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL }          { NULL,         SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL }
 };  };
Line 96 
Line 102 
   
 /* Returns a list of supported ciphers separated by the specified char. */  /* Returns a list of supported ciphers separated by the specified char. */
 char *  char *
 cipher_alg_list(char sep)  cipher_alg_list(char sep, int auth_only)
 {  {
         char *ret = NULL;          char *ret = NULL;
         size_t nlen, rlen = 0;          size_t nlen, rlen = 0;
Line 105 
Line 111 
         for (c = ciphers; c->name != NULL; c++) {          for (c = ciphers; c->name != NULL; c++) {
                 if (c->number != SSH_CIPHER_SSH2)                  if (c->number != SSH_CIPHER_SSH2)
                         continue;                          continue;
                   if (auth_only && c->auth_len == 0)
                           continue;
                 if (ret != NULL)                  if (ret != NULL)
                         ret[rlen++] = sep;                          ret[rlen++] = sep;
                 nlen = strlen(c->name);                  nlen = strlen(c->name);
Line 136 
Line 144 
 u_int  u_int
 cipher_ivlen(const Cipher *c)  cipher_ivlen(const Cipher *c)
 {  {
         return (c->iv_len ? c->iv_len : c->block_size);          /*
            * Default is cipher block size, except for chacha20+poly1305 that
            * needs no IV. XXX make iv_len == -1 default?
            */
           return (c->iv_len != 0 || (c->flags & CFLAG_CHACHAPOLY) != 0) ?
               c->iv_len : c->block_size;
 }  }
   
 u_int  u_int
Line 148 
Line 161 
 u_int  u_int
 cipher_is_cbc(const Cipher *c)  cipher_is_cbc(const Cipher *c)
 {  {
         return (c->cbc_mode);          return (c->flags & CFLAG_CBC) != 0;
 }  }
   
 u_int  u_int
Line 264 
Line 277 
                     ivlen, cipher->name);                      ivlen, cipher->name);
         cc->cipher = cipher;          cc->cipher = cipher;
   
           if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
                   chachapoly_init(&cc->cp_ctx, key, keylen);
                   return;
           }
         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,
             (do_encrypt == CIPHER_ENCRYPT)) == 0)              (do_encrypt == CIPHER_ENCRYPT)) == 0)
Line 310 
Line 326 
  * Both 'aadlen' and 'authlen' can be set to 0.   * Both 'aadlen' and 'authlen' can be set to 0.
  */   */
 void  void
 cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src,  cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src,
     u_int len, u_int aadlen, u_int authlen)      u_int len, u_int aadlen, u_int authlen)
 {  {
           if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
                   if (chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len, aadlen,
                       authlen, cc->encrypt) != 0)
                           fatal("Decryption integrity check failed");
                   return;
           }
         if (authlen) {          if (authlen) {
                 u_char lastiv[1];                  u_char lastiv[1];
   
Line 354 
Line 376 
         }          }
 }  }
   
   /* Extract the packet length, including any decryption necessary beforehand */
   int
   cipher_get_length(CipherContext *cc, u_int *plenp, u_int seqnr,
       const u_char *cp, u_int len)
   {
           if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
                   return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr,
                       cp, len);
           if (len < 4)
                   return -1;
           *plenp = get_u32(cp);
           return 0;
   }
   
 void  void
 cipher_cleanup(CipherContext *cc)  cipher_cleanup(CipherContext *cc)
 {  {
         if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)          if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
                   bzero(&cc->cp_ctx, sizeof(&cc->cp_ctx));
           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");
 }  }
   
Line 397 
Line 435 
   
         if (c->number == SSH_CIPHER_3DES)          if (c->number == SSH_CIPHER_3DES)
                 ivlen = 24;                  ivlen = 24;
           else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
                   ivlen = 0;
         else          else
                 ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);                  ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);
         return (ivlen);          return (ivlen);
Line 408 
Line 448 
         const Cipher *c = cc->cipher;          const Cipher *c = cc->cipher;
         int evplen;          int evplen;
   
           if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
                   if (len != 0)
                           fatal("%s: wrong iv length %d != %d", __func__, len, 0);
                   return;
           }
   
         switch (c->number) {          switch (c->number) {
         case SSH_CIPHER_SSH2:          case SSH_CIPHER_SSH2:
         case SSH_CIPHER_DES:          case SSH_CIPHER_DES:
Line 438 
Line 484 
 {  {
         const Cipher *c = cc->cipher;          const Cipher *c = cc->cipher;
         int evplen = 0;          int evplen = 0;
   
           if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
                   return;
   
         switch (c->number) {          switch (c->number) {
         case SSH_CIPHER_SSH2:          case SSH_CIPHER_SSH2:

Legend:
Removed from v.1.90  
changed lines
  Added in v.1.91