Develop and Download Open Source Software

Browse Subversion Repository

Diff of /trunk/ttssh2/ttxssh/cipher.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.c revision 9210 by nmaya, Sat Apr 17 08:36:59 2021 UTC trunk/ttssh2/ttxssh/cipher.c revision 9255 by nmaya, Wed May 19 14:11:26 2021 UTC
# Line 35  Line 35 
35    
36  #include <openssl/evp.h>  #include <openssl/evp.h>
37    
38    #include "codeconv.h"
39    
40  // from cipher-3des.c  // from cipher-3des.c
41  extern const EVP_CIPHER* evp_ssh1_3des(void);  extern const EVP_CIPHER* evp_ssh1_3des(void);
42    
# Line 70  static const struct ssh2cipher ssh2_ciph Line 72  static const struct ssh2cipher ssh2_ciph
72  #endif // WITH_CAMELLIA_PRIVATE  #endif // WITH_CAMELLIA_PRIVATE
73          {SSH2_CIPHER_AES128_GCM,      "aes128-gcm@openssh.com",      16, 16, 0, 12, 16, EVP_aes_128_gcm}, // not RFC5647, PROTOCOL of OpenSSH          {SSH2_CIPHER_AES128_GCM,      "aes128-gcm@openssh.com",      16, 16, 0, 12, 16, EVP_aes_128_gcm}, // not RFC5647, PROTOCOL of OpenSSH
74          {SSH2_CIPHER_AES256_GCM,      "aes256-gcm@openssh.com",      16, 32, 0, 12, 16, EVP_aes_256_gcm}, // not RFC5647, PROTOCOL of OpenSSH          {SSH2_CIPHER_AES256_GCM,      "aes256-gcm@openssh.com",      16, 32, 0, 12, 16, EVP_aes_256_gcm}, // not RFC5647, PROTOCOL of OpenSSH
75          {SSH_CIPHER_NONE,             NULL,               0,  0,    0, 0, 0, NULL},          {SSH2_CIPHER_CHACHAPOLY,      "chacha20-poly1305@openssh.com",  8, 64, 0, 0, 16, EVP_enc_null},
76            {SSH_CIPHER_NONE,             "none",             8,  0,    0, 0, 0, EVP_enc_null},         // for no passphrase key file
77            {SSH_CIPHER_3DES,             "3des",             8, 16,    0, 0, 0, evp_ssh1_3des},        // for RSA1 key file
78  };  };
79    
80    
# Line 118  u_int get_cipher_discard_len(const struc Line 122  u_int get_cipher_discard_len(const struc
122  u_int get_cipher_iv_len(const struct ssh2cipher *cipher)  u_int get_cipher_iv_len(const struct ssh2cipher *cipher)
123  {  {
124          if (cipher) {          if (cipher) {
125                  if (cipher->iv_len != 0) {                  if (cipher->iv_len != 0 || cipher->id == SSH2_CIPHER_CHACHAPOLY) {
126                          return cipher->iv_len;                          return cipher->iv_len;
127                  }                  }
128                  else {                  else {
# Line 239  char *get_cipher_name(int cipher_id) Line 243  char *get_cipher_name(int cipher_id)
243                  return "aes128-gcm@openssh.com";                  return "aes128-gcm@openssh.com";
244          case SSH2_CIPHER_AES256_GCM:          case SSH2_CIPHER_AES256_GCM:
245                  return "aes256-gcm@openssh.com";                  return "aes256-gcm@openssh.com";
246            case SSH2_CIPHER_CHACHAPOLY:
247                    return "chacha20-poly1305@openssh.com(SSH2)";
248    
249          default:          default:
250                  return "Unknown";                  return "Unknown";
# Line 246  char *get_cipher_name(int cipher_id) Line 252  char *get_cipher_name(int cipher_id)
252  }  }
253    
254  // リストボックス表示名  // リストボックス表示名
255  char *get_listbox_cipher_name(int cipher_id, PTInstVar pvar)  wchar_t *get_listbox_cipher_nameW(int cipher_id, PTInstVar pvar)
256  {  {
257          switch (cipher_id) {          typedef struct {
258          case SSH_CIPHER_NONE:                  int no;
259                  UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER_BORDER", pvar,                  const char *nameA;
260                                    "<ciphers below this line are disabled>");          } list_t;
261                  return pvar->ts->UIMsg;          static const list_t list[] = {
262          case SSH_CIPHER_3DES:                  { SSH_CIPHER_3DES, "3DES(SSH1)" },
263                  return "3DES(SSH1)";                  { SSH_CIPHER_DES, "DES(SSH1)" },
264          case SSH_CIPHER_DES:                  { SSH_CIPHER_BLOWFISH, "Blowfish(SSH1)" },
265                  return "DES(SSH1)";                  { SSH2_CIPHER_AES128_CBC, "aes128-cbc(SSH2)" },
266          case SSH_CIPHER_BLOWFISH:                  { SSH2_CIPHER_AES192_CBC, "aes192-cbc(SSH2)" },
267                  return "Blowfish(SSH1)";                  { SSH2_CIPHER_AES256_CBC, "aes256-cbc(SSH2)" },
268                    { SSH2_CIPHER_3DES_CBC, "3des-cbc(SSH2)" },
269          // for SSH2(yutaka)                  { SSH2_CIPHER_BLOWFISH_CBC, "blowfish-cbc(SSH2)" },
270          case SSH2_CIPHER_AES128_CBC:                  { SSH2_CIPHER_AES128_CTR, "aes128-ctr(SSH2)" },
271                  return "aes128-cbc(SSH2)";                  { SSH2_CIPHER_AES192_CTR, "aes192-ctr(SSH2)" },
272          case SSH2_CIPHER_AES192_CBC:                  { SSH2_CIPHER_AES256_CTR, "aes256-ctr(SSH2)" },
273                  return "aes192-cbc(SSH2)";                  { SSH2_CIPHER_ARCFOUR, "arcfour(SSH2)" },
274          case SSH2_CIPHER_AES256_CBC:                  { SSH2_CIPHER_ARCFOUR128, "arcfour128(SSH2)" },
275                  return "aes256-cbc(SSH2)";                  { SSH2_CIPHER_ARCFOUR256, "arcfour256(SSH2)" },
276          case SSH2_CIPHER_3DES_CBC:                  { SSH2_CIPHER_CAST128_CBC, "cast128-cbc(SSH2)" },
277                  return "3des-cbc(SSH2)";                  { SSH2_CIPHER_3DES_CTR, "3des-ctr(SSH2)" },
278          case SSH2_CIPHER_BLOWFISH_CBC:                  { SSH2_CIPHER_BLOWFISH_CTR, "blowfish-ctr(SSH2)" },
279                  return "blowfish-cbc(SSH2)";                  { SSH2_CIPHER_CAST128_CTR, "cast128-ctr(SSH2)" },
280          case SSH2_CIPHER_AES128_CTR:                  { SSH2_CIPHER_CAMELLIA128_CBC, "camellia128-cbc(SSH2)" },
281                  return "aes128-ctr(SSH2)";                  { SSH2_CIPHER_CAMELLIA192_CBC, "camellia192-cbc(SSH2)" },
282          case SSH2_CIPHER_AES192_CTR:                  { SSH2_CIPHER_CAMELLIA256_CBC, "camellia256-cbc(SSH2)" },
283                  return "aes192-ctr(SSH2)";                  { SSH2_CIPHER_CAMELLIA128_CTR, "camellia128-ctr(SSH2)" },
284          case SSH2_CIPHER_AES256_CTR:                  { SSH2_CIPHER_CAMELLIA192_CTR, "camellia192-ctr(SSH2)" },
285                  return "aes256-ctr(SSH2)";                  { SSH2_CIPHER_CAMELLIA256_CTR, "camellia256-ctr(SSH2)" },
286          case SSH2_CIPHER_ARCFOUR:                  { SSH2_CIPHER_AES128_GCM, "aes128-gcm@openssh.com(SSH2)" },
287                  return "arcfour(SSH2)";                  { SSH2_CIPHER_AES256_GCM, "aes256-gcm@openssh.com(SSH2)" },
288          case SSH2_CIPHER_ARCFOUR128:                  { SSH2_CIPHER_CHACHAPOLY, "chacha20-poly1305@openssh.com(SSH2)" },
289                  return "arcfour128(SSH2)";          };
290          case SSH2_CIPHER_ARCFOUR256:          int i;
291                  return "arcfour256(SSH2)";          const list_t *p = list;
         case SSH2_CIPHER_CAST128_CBC:  
                 return "cast128-cbc(SSH2)";  
         case SSH2_CIPHER_3DES_CTR:  
                 return "3des-ctr(SSH2)";  
         case SSH2_CIPHER_BLOWFISH_CTR:  
                 return "blowfish-ctr(SSH2)";  
         case SSH2_CIPHER_CAST128_CTR:  
                 return "cast128-ctr(SSH2)";  
         case SSH2_CIPHER_CAMELLIA128_CBC:  
                 return "camellia128-cbc(SSH2)";  
         case SSH2_CIPHER_CAMELLIA192_CBC:  
                 return "camellia192-cbc(SSH2)";  
         case SSH2_CIPHER_CAMELLIA256_CBC:  
                 return "camellia256-cbc(SSH2)";  
         case SSH2_CIPHER_CAMELLIA128_CTR:  
                 return "camellia128-ctr(SSH2)";  
         case SSH2_CIPHER_CAMELLIA192_CTR:  
                 return "camellia192-ctr(SSH2)";  
         case SSH2_CIPHER_CAMELLIA256_CTR:  
                 return "camellia256-ctr(SSH2)";  
         case SSH2_CIPHER_AES128_GCM:  
                 return "aes128-gcm@openssh.com(SSH2)";  
         case SSH2_CIPHER_AES256_GCM:  
                 return "aes256-gcm@openssh.com(SSH2)";  
292    
293          default:          if (cipher_id == SSH_CIPHER_NONE) {
294                  return NULL;                  wchar_t uimsg[MAX_UIMSG];
295                    UTIL_get_lang_msgW("DLG_SSHSETUP_CIPHER_BORDER", pvar,
296                                                       L"<ciphers below this line are disabled>", uimsg);
297                    return _wcsdup(uimsg);
298            }
299            for (i = 0; i < _countof(list); p++,i++) {
300                    if (p->no == cipher_id) {
301                            return ToWcharA(p->nameA);
302                    }
303          }          }
304            return NULL;
305  }  }
306    
307  /*  /*
# Line 324  void normalize_cipher_order(char *buf) Line 315  void normalize_cipher_order(char *buf)
315          static char default_strings[] = {          static char default_strings[] = {
316                  SSH2_CIPHER_AES256_GCM,                  SSH2_CIPHER_AES256_GCM,
317                  SSH2_CIPHER_CAMELLIA256_CTR,                  SSH2_CIPHER_CAMELLIA256_CTR,
318                    SSH2_CIPHER_CHACHAPOLY,
319                  SSH2_CIPHER_AES256_CTR,                  SSH2_CIPHER_AES256_CTR,
320                  SSH2_CIPHER_CAMELLIA256_CBC,                  SSH2_CIPHER_CAMELLIA256_CBC,
321                  SSH2_CIPHER_AES256_CBC,                  SSH2_CIPHER_AES256_CBC,
# Line 472  void SSH2_update_cipher_myproposal(PTIns Line 464  void SSH2_update_cipher_myproposal(PTIns
464                          case SSH2_CIPHER_AES256_GCM:                          case SSH2_CIPHER_AES256_GCM:
465                                  c_str = "aes256-gcm@openssh.com,";                                  c_str = "aes256-gcm@openssh.com,";
466                                  break;                                  break;
467                            case SSH2_CIPHER_CHACHAPOLY:
468                                    c_str = "chacha20-poly1305@openssh.com,";
469                                    break;
470                          default:                          default:
471                                  continue;                                  continue;
472                  }                  }
# Line 488  void SSH2_update_cipher_myproposal(PTIns Line 483  void SSH2_update_cipher_myproposal(PTIns
483  //  //
484  // SSH2用アルゴリズムの初期化  // SSH2用アルゴリズムの初期化
485  //  //
486  void cipher_init_SSH2(EVP_CIPHER_CTX *evp,  int cipher_init_SSH2(
487                        const u_char *key, u_int keylen,          struct sshcipher_ctx **ccp, const struct ssh2cipher *cipher,
488                        const u_char *iv, u_int ivlen,          const u_char *key, u_int keylen,
489                        int do_encrypt,          const u_char *iv, u_int ivlen,
490                        const EVP_CIPHER *type,          int do_encrypt,
491                        int discard_len,          PTInstVar pvar)
492                        unsigned int authlen,  {
493                        PTInstVar pvar)          struct sshcipher_ctx *cc = NULL;
494  {          int ret = SSH_ERR_INTERNAL_ERROR;
495            const EVP_CIPHER *type;
496          int klen;          int klen;
497          unsigned char *junk = NULL, *discard = NULL;          unsigned char *junk = NULL, *discard = NULL;
498          char tmp[80];          char tmp[80];
499    
500          EVP_CIPHER_CTX_reset(evp);          *ccp = NULL;
501                    if ((cc = calloc(sizeof(*cc), 1)) == NULL) {
         if (EVP_CipherInit(evp, type, NULL, (u_char *)iv, (do_encrypt == CIPHER_ENCRYPT)) == 0) {  
502                  UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");                  UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
503                  _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 1);                  _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 1);
504                  notify_fatal_error(pvar, tmp, TRUE);                  notify_fatal_error(pvar, tmp, TRUE);
505                  return;                  return SSH_ERR_ALLOC_FAIL;
506          }          }
507          if (authlen &&  
508              !EVP_CIPHER_CTX_ctrl(evp, EVP_CTRL_GCM_SET_IV_FIXED, -1, (u_char *)iv)) {          if (keylen < cipher->key_len) {
509                  UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");                  UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
510                  _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 2);                  _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 2);
511                  notify_fatal_error(pvar, tmp, TRUE);                  notify_fatal_error(pvar, tmp, TRUE);
512                  return;                  ret = SSH_ERR_INVALID_ARGUMENT;
513                    goto out;
514            }
515            if (iv != NULL && ivlen < get_cipher_iv_len(cipher)) {
516                    UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
517                    _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 3);
518                    notify_fatal_error(pvar, tmp, TRUE);
519                    ret = SSH_ERR_INVALID_ARGUMENT;
520                    goto out;
521            }
522    
523            cc->cipher = cipher;
524            if (cipher->id == SSH2_CIPHER_CHACHAPOLY) {
525                    cc->cp_ctx = chachapoly_new(key, keylen);
526                    ret = cc->cp_ctx != NULL ? 0 : SSH_ERR_INVALID_ARGUMENT;
527                    if (ret == SSH_ERR_INVALID_ARGUMENT) {
528                            UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
529                            _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 4);
530                            notify_fatal_error(pvar, tmp, TRUE);
531                    }
532                    goto out;
533          }          }
534          klen = EVP_CIPHER_CTX_key_length(evp);          type = (*cipher->func)();
535            if ((cc->evp = EVP_CIPHER_CTX_new()) == NULL) {
536                    UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
537                    _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 5);
538                    notify_fatal_error(pvar, tmp, TRUE);
539                    ret = SSH_ERR_ALLOC_FAIL;
540                    goto out;
541            }
542            if (EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv, (do_encrypt == CIPHER_ENCRYPT)) == 0) {
543                    UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
544                    _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 6);
545                    notify_fatal_error(pvar, tmp, TRUE);
546                    ret = SSH_ERR_LIBCRYPTO_ERROR;
547                    goto out;
548            }
549            if (get_cipher_auth_len(cipher) &&
550                !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, -1, (u_char *)iv)) {
551                    UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
552                    _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 7);
553                    notify_fatal_error(pvar, tmp, TRUE);
554                    ret = SSH_ERR_LIBCRYPTO_ERROR;
555                    goto out;
556            }
557            klen = EVP_CIPHER_CTX_key_length(cc->evp);
558          if (klen > 0 && keylen != (u_int)klen) {          if (klen > 0 && keylen != (u_int)klen) {
559                  if (EVP_CIPHER_CTX_set_key_length(evp, keylen) == 0) {                  if (EVP_CIPHER_CTX_set_key_length(cc->evp, keylen) == 0) {
560                          UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");                          UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
561                          _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 3);                          _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 8);
562                          notify_fatal_error(pvar, tmp, TRUE);                          notify_fatal_error(pvar, tmp, TRUE);
563                          return;                          ret = SSH_ERR_LIBCRYPTO_ERROR;
564                            goto out;
565                  }                  }
566          }          }
567          if (EVP_CipherInit(evp, NULL, (u_char *)key, NULL, -1) == 0) {          if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {
568                  UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");                  UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
569                  _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 4);                  _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 9);
570                  notify_fatal_error(pvar, tmp, TRUE);                  notify_fatal_error(pvar, tmp, TRUE);
571                  return;                  ret = SSH_ERR_LIBCRYPTO_ERROR;
572                    goto out;
573          }          }
574    
575          if (discard_len > 0) {          if (cipher->discard_len > 0) {
576                  junk = malloc(discard_len);                  junk = malloc(cipher->discard_len);
577                  discard = malloc(discard_len);                  discard = malloc(cipher->discard_len);
578                  if (junk == NULL || discard == NULL ||                  if (junk == NULL || discard == NULL ||
579                      EVP_Cipher(evp, discard, junk, discard_len) == 0) {                      EVP_Cipher(cc->evp, discard, junk, cipher->discard_len) == 0) {
580                          UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");                          UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
581                          _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 5);                          _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 10);
582                          notify_fatal_error(pvar, tmp, TRUE);                          notify_fatal_error(pvar, tmp, TRUE);
583                  }                  }
584                  else {                  else {
585                          SecureZeroMemory(discard, discard_len);                          SecureZeroMemory(discard, cipher->discard_len);
586                  }                  }
587                  free(junk);                  free(junk);
588                  free(discard);                  free(discard);
589          }          }
590            ret = 0;
591    
592    out:
593            if (ret == 0) {
594                    *ccp = cc;
595            }
596            else {
597                    if (cc != NULL) {
598                            EVP_CIPHER_CTX_free(cc->evp);
599                            SecureZeroMemory(cc, sizeof(*cc));
600                    }
601            }
602            return ret;
603  }  }
604    
605  //  //
606  // SSH2用アルゴリズムの破棄  // SSH2用アルゴリズムの破棄
607  ///  ///
608  void cipher_free_SSH2(EVP_CIPHER_CTX *evp)  void cipher_free_SSH2(struct sshcipher_ctx *cc)
609  {  {
610          EVP_CIPHER_CTX_free(evp);          if (cc == NULL)
611                    return;
612            if (cc->cipher->id == SSH2_CIPHER_CHACHAPOLY) {
613                    chachapoly_free(cc->cp_ctx);
614                    cc->cp_ctx = NULL;
615            }
616            EVP_CIPHER_CTX_free(cc->evp);
617            cc->evp = NULL;
618            SecureZeroMemory(cc, sizeof(*cc));
619  }  }

Legend:
Removed from v.9210  
changed lines
  Added in v.9255

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26