| 620 | } |
| 621 | |
| 622 | bool CryptConfig::decrypt_key(LPCTSTR password) |
| 623 | { |
| 624 | |
| 625 | bool bret = true; |
| 626 | |
| 627 | shared_ptr<EVP_CIPHER_CTX> context = nullptr; |
| 628 | |
| 629 | try { |
| 630 | if (m_encrypted_key.size() == 0 || m_encrypted_key_salt.size() == 0 || GetMasterKeyLength() == 0) |
| 631 | return false; |
| 632 | |
| 633 | LockZeroBuffer<char> pass_buf(4*MAX_PASSWORD_LEN+1, false); |
| 634 | |
| 635 | if (!pass_buf.IsLocked()) |
| 636 | throw (-1); |
| 637 | |
| 638 | const char *pass = unicode_to_utf8(password, pass_buf.m_buf, pass_buf.m_len-1); |
| 639 | |
| 640 | if (!pass) { |
| 641 | throw (-1); |
| 642 | } |
| 643 | |
| 644 | LockZeroBuffer<unsigned char> pwkey(GetMasterKeyLength(), false); |
| 645 | |
| 646 | LockZeroBuffer<unsigned char> pwkeyHKDF(GetMasterKeyLength(), false); |
| 647 | |
| 648 | if (!pwkey.IsLocked()) |
| 649 | throw(-1); |
| 650 | |
| 651 | if (m_HKDF && !pwkeyHKDF.IsLocked()) |
| 652 | throw(-1); |
| 653 | |
| 654 | int result = EVP_PBE_scrypt(pass, strlen(pass), &m_encrypted_key_salt[0], |
| 655 | m_encrypted_key_salt.size(), m_N, m_R, m_P, scrypt_mem(), pwkey.m_buf, |
| 656 | GetMasterKeyLength()); |
| 657 | |
| 658 | if (result != 1) |
| 659 | throw (-1); |
| 660 | |
| 661 | unsigned char adata[8]; |
| 662 | |
| 663 | const int adata_len = sizeof(adata); |
| 664 | |
| 665 | memset(adata, 0, adata_len); |
| 666 | |
| 667 | int ivlen = m_HKDF ? HKDF_MASTER_IV_LEN : ORIG_MASTER_IV_LEN; |
| 668 | |
| 669 | const int taglen = BLOCK_TAG_LEN; |
| 670 | |
| 671 | unsigned char *ciphertext = &(m_encrypted_key)[0] + ivlen; |
| 672 | int ciphertext_len = (int)m_encrypted_key.size() - ivlen - taglen; |
| 673 | unsigned char *tag = &(m_encrypted_key)[0] + m_encrypted_key.size() - taglen; |
| 674 | |
| 675 | unsigned char *iv = &(m_encrypted_key)[0]; |
| 676 | |
| 677 | if (ciphertext_len != MASTER_KEY_LEN) |
| 678 | throw (-1); |
| 679 |
no test coverage detected