| 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 |
|
|
| 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 |
|
|
| 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 { |
| 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"; |
| 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 |
/* |
/* |
| 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, |
| 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 |
} |
} |
| 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 |
} |
} |