static int aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) { BCRYPT_ALG_HANDLE hAlg; BCRYPT_KEY_HANDLE hKey; DWORD keyObj_len, aes_key_len; PBYTE keyObj; ULONG result; NTSTATUS status; BCRYPT_KEY_LENGTHS_STRUCT key_lengths; ctx->hAlg = NULL; ctx->hKey = NULL; ctx->keyObj = NULL; switch (key_len) { case 16: aes_key_len = 128; break; case 24: aes_key_len = 192; break; case 32: aes_key_len = 256; break; default: return -1; } status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); if (!BCRYPT_SUCCESS(status)) return -1; status = BCryptGetProperty(hAlg, BCRYPT_KEY_LENGTHS, (PUCHAR)&key_lengths, sizeof(key_lengths), &result, 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } if (key_lengths.dwMinLength > aes_key_len || key_lengths.dwMaxLength < aes_key_len) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&keyObj_len, sizeof(keyObj_len), &result, 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } keyObj = (PBYTE)HeapAlloc(GetProcessHeap(), 0, keyObj_len); if (keyObj == NULL) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } status = BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE, (PUCHAR)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); HeapFree(GetProcessHeap(), 0, keyObj); return -1; } status = BCryptGenerateSymmetricKey(hAlg, &hKey, keyObj, keyObj_len, (PUCHAR)(uintptr_t)key, (ULONG)key_len, 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); HeapFree(GetProcessHeap(), 0, keyObj); return -1; } ctx->hAlg = hAlg; ctx->hKey = hKey; ctx->keyObj = keyObj; ctx->keyObj_len = keyObj_len; ctx->encr_pos = AES_BLOCK_SIZE; return 0; }
void _libssh2_wincng_init(void) { int ret; (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRNG, BCRYPT_RNG_ALGORITHM, NULL, 0); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashMD5, BCRYPT_MD5_ALGORITHM, NULL, 0); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA1, BCRYPT_SHA1_ALGORITHM, NULL, 0); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacMD5, BCRYPT_MD5_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA1, BCRYPT_SHA1_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRSA, BCRYPT_RSA_ALGORITHM, NULL, 0); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgDSA, BCRYPT_DSA_ALGORITHM, NULL, 0); ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgAES_CBC, BCRYPT_AES_ALGORITHM, NULL, 0); if (BCRYPT_SUCCESS(ret)) { ret = BCryptSetProperty(_libssh2_wincng.hAlgAES_CBC, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0); if (!BCRYPT_SUCCESS(ret)) { (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_CBC, 0); } } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRC4_NA, BCRYPT_RC4_ALGORITHM, NULL, 0); if (BCRYPT_SUCCESS(ret)) { ret = BCryptSetProperty(_libssh2_wincng.hAlgRC4_NA, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_NA, sizeof(BCRYPT_CHAIN_MODE_NA), 0); if (!BCRYPT_SUCCESS(ret)) { (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRC4_NA, 0); } } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlg3DES_CBC, BCRYPT_3DES_ALGORITHM, NULL, 0); if (BCRYPT_SUCCESS(ret)) { ret = BCryptSetProperty(_libssh2_wincng.hAlg3DES_CBC, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0); if (!BCRYPT_SUCCESS(ret)) { (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC, 0); } } }
int Everest_init(ENGINE *e) { // Initialize the global variables needed for BCrypt if (!NT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_ECDH_ALGORITHM, NULL, 0))) { fprintf(stderr, "Cannot open algorithm provider\n"); return 0; } if (!NT_SUCCESS(BCryptSetProperty(hAlg, BCRYPT_ECC_CURVE_NAME, (PUCHAR) BCRYPT_ECC_CURVE_25519, sizeof(BCRYPT_ECC_CURVE_25519), 0))) { fprintf(stderr, "Cannot select the right curve\n"); return 0; } // Initialize our new method bcrypt_x25519_meth = EVP_PKEY_meth_new(NID_X25519, 0); EVP_PKEY_meth_set_derive(bcrypt_x25519_meth, NULL, bcrypt_derive); EVP_PKEY_meth_set_ctrl(bcrypt_x25519_meth, bcrypt_ctrl, NULL); EVP_PKEY_meth_set_keygen(bcrypt_x25519_meth, NULL, bcrypt_keygen); return 1; }
int aes_transformkey(m0_kdbx_header_entry_t *hdr, uint8_t *tkey, size_t tkeylen) { BCRYPT_ALG_HANDLE aes = NULL; BCRYPT_KEY_HANDLE key = NULL; NTSTATUS status = 0; DWORD len_ciphertext = 0, tmp_len = 0, key_objectlen = 0; PBYTE key_object = NULL; uint64_t rounds = 0; // Open an algorithm handle. status = BCryptOpenAlgorithmProvider( &aes, BCRYPT_AES_ALGORITHM, NULL, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status); goto cleanup; } // Calculate the size of the buffer to hold the KeyObject. status = BCryptGetProperty( aes, BCRYPT_OBJECT_LENGTH, (PBYTE)&key_objectlen, sizeof(DWORD), &tmp_len, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptGetProperty\n", status); goto cleanup; } // Allocate the key object on the heap. key_object = (PBYTE)HeapAlloc(GetProcessHeap(), 0, key_objectlen); if(NULL == key_object) { printf("[!] memory allocation failed\n"); goto cleanup; } status = BCryptSetProperty( aes, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptSetProperty\n", status); goto cleanup; } // Generate the key from supplied input key bytes. status = BCryptGenerateSymmetricKey( aes, &key, key_object, key_objectlen, hdr[TRANSFORMSEED].data, hdr[TRANSFORMSEED].len, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptGenerateSymmetricKey\n", status); goto cleanup; } status = BCryptEncrypt( key, tkey, tkeylen, NULL, NULL, 0, NULL, 0, &len_ciphertext, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptEncrypt (calculate)\n", status); goto cleanup; } for(rounds = 0; rounds < hdr[TRANSFORMROUNDS].qw; rounds++) { status = BCryptEncrypt( key, tkey, tkeylen, NULL, NULL, 0, tkey, tkeylen, &tmp_len, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptEncrypt (encrypt)\n", status); goto cleanup; } } cleanup: if(aes) { BCryptCloseAlgorithmProvider(aes,0); } if (key) { BCryptDestroyKey(key); } if(key_object) { HeapFree(GetProcessHeap(), 0, key_object); } return status; }
bool aes_decrypt_check(m0_kdbx_header_entry_t *hdr, uint8_t *masterkey, m0_kdbx_payload_t *payload) { bool res = false; BCRYPT_ALG_HANDLE aes = NULL; BCRYPT_KEY_HANDLE ctx = NULL; NTSTATUS status = 0; DWORD len_ciphertext = 0, tmp_len = 0, key_objectlen = 0; PBYTE key_object = NULL; uint8_t plaintext[32] = {0}; uint8_t iv[256] = {0}; uint8_t ivlen = hdr[ENCRYPTIONIV].len & 0xFF; // we need to create a local copy of IV, as it is modified during decryption. memcpy(&iv, hdr[ENCRYPTIONIV].data, ivlen); // Open an algorithm handle. status = BCryptOpenAlgorithmProvider( &aes, BCRYPT_AES_ALGORITHM, NULL, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status); goto cleanup; } // Calculate the size of the buffer to hold the Key Object. status = BCryptGetProperty( aes, BCRYPT_OBJECT_LENGTH, (PBYTE)&key_objectlen, sizeof(DWORD), &tmp_len, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptGetProperty\n", status); goto cleanup; } // We should use preallocated memory for better performance... key_object = (PBYTE)HeapAlloc(GetProcessHeap(), 0, key_objectlen); if(NULL == key_object) { printf("[!] memory allocation failed\n"); goto cleanup; } status = BCryptSetProperty( aes, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptSetProperty\n", status); goto cleanup; } // Generate the key from supplied input key bytes. status = BCryptGenerateSymmetricKey( aes, &ctx, key_object, key_objectlen, masterkey, 32, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptGenerateSymmetricKey\n", status); goto cleanup; } status = BCryptDecrypt( ctx, payload->encrypted, hdr[STREAMSTARTBYTES].len, NULL, iv, ivlen, plaintext, sizeof(plaintext), &tmp_len, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptDecrypt\n", status); goto cleanup; } // success! if (0 == memcmp(plaintext, hdr[STREAMSTARTBYTES].data, hdr[STREAMSTARTBYTES].len)) { res = true; payload->decrypted = malloc(hdr[STREAMSTARTBYTES].len); memcpy(payload->decrypted, plaintext, hdr[STREAMSTARTBYTES].len); } cleanup: if(aes) { BCryptCloseAlgorithmProvider(aes,0); } if (ctx) { BCryptDestroyKey(ctx); } if(key_object) { HeapFree(GetProcessHeap(), 0, key_object); } return res; }