int _libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(type), int encrypt, unsigned char *block, size_t blocklen) { unsigned char *pbOutput; unsigned long cbOutput, cbInput; int ret; (void)type; cbInput = (unsigned long)blocklen; if (encrypt) { ret = BCryptEncrypt(ctx->hKey, block, cbInput, NULL, ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0); } else { ret = BCryptDecrypt(ctx->hKey, block, cbInput, NULL, ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0); } if (BCRYPT_SUCCESS(ret)) { pbOutput = malloc(cbOutput); if (pbOutput) { if (encrypt) { ret = BCryptEncrypt(ctx->hKey, block, cbInput, NULL, ctx->pbIV, ctx->dwIV, pbOutput, cbOutput, &cbOutput, 0); } else { ret = BCryptDecrypt(ctx->hKey, block, cbInput, NULL, ctx->pbIV, ctx->dwIV, pbOutput, cbOutput, &cbOutput, 0); } if (BCRYPT_SUCCESS(ret)) { memcpy(block, pbOutput, cbOutput); } free(pbOutput); } else ret = STATUS_NO_MEMORY; } return BCRYPT_SUCCESS(ret) ? 0 : -1; }
static int aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) { NTSTATUS status; ULONG result; status = BCryptEncrypt(ctx->hKey, (PUCHAR)ctx->nonce, AES_BLOCK_SIZE, NULL, NULL, 0, (PUCHAR)ctx->encr_buf, AES_BLOCK_SIZE, &result, 0); return BCRYPT_SUCCESS(status) ? 0 : -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; }
int _libssh2_wincng_bignum_mod_exp(_libssh2_bn *r, _libssh2_bn *a, _libssh2_bn *p, _libssh2_bn *m, _libssh2_bn_ctx *bnctx) { BCRYPT_KEY_HANDLE hKey; BCRYPT_RSAKEY_BLOB *rsakey; unsigned char *key, *bignum; unsigned long keylen, offset, length; int ret; (void)bnctx; if (!r || !a || !p || !m) return -1; offset = sizeof(BCRYPT_RSAKEY_BLOB); keylen = offset + p->length + m->length; key = malloc(keylen); if (!key) return -1; /* http://msdn.microsoft.com/library/windows/desktop/aa375531.aspx */ rsakey = (BCRYPT_RSAKEY_BLOB *)key; rsakey->Magic = BCRYPT_RSAPUBLIC_MAGIC; rsakey->BitLength = m->length * 8; rsakey->cbPublicExp = p->length; rsakey->cbModulus = m->length; rsakey->cbPrime1 = 0; rsakey->cbPrime2 = 0; memcpy(key + offset, p->bignum, p->length); offset += p->length; memcpy(key + offset, m->bignum, m->length); ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, BCRYPT_RSAPUBLIC_BLOB, &hKey, key, keylen, BCRYPT_NO_KEY_VALIDATION); if (BCRYPT_SUCCESS(ret)) { ret = BCryptEncrypt(hKey, a->bignum, a->length, NULL, NULL, 0, NULL, 0, &length, BCRYPT_PAD_NONE); if (BCRYPT_SUCCESS(ret)) { if (!_libssh2_wincng_bignum_resize(r, length)) { length = max(a->length, length); bignum = malloc(length); if (bignum) { offset = length - a->length; memset(bignum, 0, offset); memcpy(bignum + offset, a->bignum, a->length); ret = BCryptEncrypt(hKey, bignum, length, NULL, NULL, 0, r->bignum, r->length, &offset, BCRYPT_PAD_NONE); free(bignum); if (BCRYPT_SUCCESS(ret)) { _libssh2_wincng_bignum_resize(r, offset); } } else ret = STATUS_NO_MEMORY; } else ret = STATUS_NO_MEMORY; } BCryptDestroyKey(hKey); } free(key); return BCRYPT_SUCCESS(ret) ? 0 : -1; }
UINT SfDecryptPayload( LPWSTR lpParameter ) { BOOL cond = FALSE, bSuccess = FALSE; PBYTE cng_object, hashdata, decrypted, enc_data, extracted; ULONG obj_sz, rlen, hdatasz, enc_data_size; BCRYPT_ALG_HANDLE h_alg = NULL; BCRYPT_HASH_HANDLE h_hash = NULL; BCRYPT_KEY_HANDLE h_rc4key = NULL; NTSTATUS status; HANDLE pheap = NULL; PIMAGE_FILE_HEADER fheader; PVOID pdll = NULL; WCHAR InputFile[MAX_PATH + 1], OutputFile[MAX_PATH + 1]; rlen = 0; RtlSecureZeroMemory(InputFile, sizeof(InputFile)); GetCommandLineParam(lpParameter, 1, InputFile, MAX_PATH, &rlen); if (rlen == 0) { SfcuiPrintText(g_ConOut, T_SFDECRYPTUSAGE, g_ConsoleOutput, FALSE); return (UINT)-1; } do { rlen = 0; GetCommandLineParam(lpParameter, 2, OutputFile, MAX_PATH, &rlen); if (rlen == 0) _strcpy(OutputFile, TEXT("out.bin")); pdll = SfuCreateFileMappingNoExec(InputFile); if (pdll == NULL) break; enc_data_size = 0; enc_data = SfuQueryResourceData(2, pdll, &enc_data_size); if (enc_data == NULL) break; fheader = &(RtlImageNtHeader(pdll)->FileHeader); status = BCryptOpenAlgorithmProvider(&h_alg, BCRYPT_MD5_ALGORITHM, NULL, 0); if (!NT_SUCCESS(status)) break; obj_sz = 0; rlen = 0; status = BCryptGetProperty(h_alg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&obj_sz, sizeof(obj_sz), &rlen, 0); if (!NT_SUCCESS(status)) break; hdatasz = 0; rlen = 0; status = BCryptGetProperty(h_alg, BCRYPT_HASH_LENGTH, (PUCHAR)&hdatasz, sizeof(hdatasz), &rlen, 0); if (!NT_SUCCESS(status)) break; pheap = HeapCreate(0, 0, 0); if (pheap == NULL) break; cng_object = HeapAlloc(pheap, HEAP_ZERO_MEMORY, obj_sz); if (cng_object == NULL) break; hashdata = HeapAlloc(pheap, HEAP_ZERO_MEMORY, hdatasz); if (hashdata == NULL) break; status = BCryptCreateHash(h_alg, &h_hash, cng_object, obj_sz, NULL, 0, 0); if (!NT_SUCCESS(status)) break; status = BCryptHashData(h_hash, (PUCHAR)fheader, sizeof(IMAGE_FILE_HEADER), 0); if (!NT_SUCCESS(status)) break; status = BCryptFinishHash(h_hash, hashdata, hdatasz, 0); if (!NT_SUCCESS(status)) break; BCryptDestroyHash(h_hash); BCryptCloseAlgorithmProvider(h_alg, 0); HeapFree(pheap, 0, cng_object); h_alg = NULL; h_hash = NULL; status = BCryptOpenAlgorithmProvider(&h_alg, BCRYPT_RC4_ALGORITHM, NULL, 0); if (!NT_SUCCESS(status)) break; obj_sz = 0; rlen = 0; status = BCryptGetProperty(h_alg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&obj_sz, sizeof(obj_sz), &rlen, 0); if (!NT_SUCCESS(status)) break; cng_object = HeapAlloc(pheap, HEAP_ZERO_MEMORY, obj_sz); if (cng_object == NULL) break; status = BCryptGenerateSymmetricKey(h_alg, &h_rc4key, cng_object, obj_sz, hashdata, hdatasz, 0); if (!NT_SUCCESS(status)) break; decrypted = HeapAlloc(pheap, HEAP_ZERO_MEMORY, enc_data_size); if (decrypted == NULL) break; rlen = 0; status = BCryptEncrypt(h_rc4key, enc_data, enc_data_size, NULL, NULL, 0, decrypted, enc_data_size, &rlen, 0); if (!NT_SUCCESS(status)) break; bSuccess = FALSE; enc_data_size = rlen; rlen = 0; extracted = SfcabExtractMemory(decrypted, enc_data_size, &rlen); if (extracted) { if (SfuWriteBufferToFile(OutputFile, extracted, rlen, FALSE, FALSE) == rlen) { bSuccess = TRUE; } LocalFree(extracted); } else { //failed to extract, drop cab as is if (SfuWriteBufferToFile(OutputFile, decrypted, enc_data_size, FALSE, FALSE) == enc_data_size) { bSuccess = TRUE; } } if (bSuccess) { SfcuiPrintText(g_ConOut, T_SFDECRYPTED, g_ConsoleOutput, FALSE); SfcuiPrintText(g_ConOut, OutputFile, g_ConsoleOutput, FALSE); } } while (cond); if (bSuccess == FALSE) { SfcuiPrintText(g_ConOut, T_SFDECRYPTFAIL, g_ConsoleOutput, FALSE); } if (h_rc4key != NULL) BCryptDestroyKey(h_rc4key); if (h_hash != NULL) BCryptDestroyHash(h_hash); if (h_alg != NULL) BCryptCloseAlgorithmProvider(h_alg, 0); if (pheap != NULL) HeapDestroy(pheap); if (pdll != 0) NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)pdll); return 0; }