CPP 62
E Guest on 27th October 2023 03:58:45 AM
  1. #include "includes.hpp"
  2.  
  3. BOOL ReadFileToByteArray( const char* szFileName, PBYTE* lpBuffer, PDWORD dwDataLen )
  4. {
  5.         BOOL bResult = FALSE;
  6.  
  7.         HANDLE hFile = nullptr;
  8.  
  9.         if( !szFileName || !lpBuffer || !dwDataLen )
  10.         {
  11.                 printf( __FUNCTION__ " -- Invalid params!\n" );
  12.                 goto Exit;
  13.         }
  14.  
  15.         hFile = ::CreateFileA( szFileName, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr );
  16.         if( !hFile || hFile == INVALID_HANDLE_VALUE )
  17.         {
  18.                 printf( __FUNCTION__ " -- CreateFileA failed %d\n", ::GetLastError( ) );
  19.                 goto Exit;
  20.         }
  21.  
  22.         *dwDataLen = ::GetFileSize( hFile, nullptr );
  23.  
  24.         //
  25.         // VirtualAlloc is ideal to work with files.
  26.         //
  27.         *lpBuffer = ( PBYTE )::VirtualAlloc( nullptr, *dwDataLen, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE );
  28.  
  29.         bResult = ( *lpBuffer != nullptr );
  30.         if( !bResult )
  31.         {
  32.                 printf( __FUNCTION__ " -- VirtualAlloc failed %d\n", ::GetLastError( ) );
  33.                 goto Exit;
  34.         }
  35.  
  36.         {
  37.                 DWORD dwRead = NULL;
  38.                 bResult = ::ReadFile( hFile, *lpBuffer, *dwDataLen, &dwRead, nullptr );
  39.                 if( !bResult )
  40.                 {
  41.                         ::VirtualFree( *lpBuffer, 0, MEM_RELEASE );
  42.                         *lpBuffer = nullptr;
  43.  
  44.                         printf( __FUNCTION__ " -- ReadFile failed %d\n", ::GetLastError( ) );
  45.                 }
  46.         }
  47.  
  48. Exit:
  49.         if( hFile )
  50.                 ::CloseHandle( hFile );
  51.  
  52.         return bResult;
  53. }
  54.  
  55. BOOL BCryptImportPrivateKey( BCRYPT_ALG_HANDLE hProvider, PBYTE lpData, ULONG dwDataLen, BCRYPT_KEY_HANDLE* hKey )
  56. {
  57.         BOOL bResult = FALSE;
  58.         NTSTATUS Status = NO_ERROR;
  59.  
  60.         ULONG cb = 0;
  61.         PCRYPT_PRIVATE_KEY_INFO PrivateKeyInfo = nullptr;
  62.         BCRYPT_RSAKEY_BLOB* prkb = nullptr;
  63.  
  64.         bResult = ::CryptDecodeObjectEx(
  65.                 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  66.                 PKCS_PRIVATE_KEY_INFO,
  67.                 lpData,
  68.                 dwDataLen,
  69.                 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG,
  70.                 0, ( void** )&PrivateKeyInfo, &cb
  71.         );
  72.  
  73.         if( !bResult )
  74.         {
  75.                 printf( __FUNCTION__ " -- CryptDecodeObjectEx failed 0x%X\n", ::GetLastError( ) );
  76.                 goto Exit;
  77.         }
  78.  
  79.         bResult = ::CryptDecodeObjectEx(
  80.                 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  81.                 CNG_RSA_PRIVATE_KEY_BLOB,
  82.                 PrivateKeyInfo->PrivateKey.pbData,
  83.                 PrivateKeyInfo->PrivateKey.cbData,
  84.                 CRYPT_DECODE_ALLOC_FLAG,
  85.                 0, ( void** )&prkb, &cb
  86.         );
  87.  
  88.         if( !bResult )
  89.         {
  90.                 printf( __FUNCTION__ " -- CryptDecodeObjectEx failed 0x%X\n", ::GetLastError( ) );
  91.                 goto Exit;
  92.         }
  93.  
  94.         Status = ::BCryptImportKeyPair(
  95.                 hProvider,
  96.                 NULL,
  97.                 BCRYPT_RSAPRIVATE_BLOB,
  98.                 hKey,
  99.                 ( PUCHAR )prkb,
  100.                 cb,
  101.                 0 );
  102.  
  103.         bResult = ( Status == NO_ERROR );
  104.         if( !bResult )
  105.         {
  106.                 printf( __FUNCTION__ " -- BCryptImportKey failed 0x%X\n", Status );
  107.                 goto Exit;
  108.         }
  109.  
  110. Exit:
  111.         if( prkb )
  112.                 ::LocalFree( prkb );
  113.  
  114.         if( PrivateKeyInfo )
  115.                 ::LocalFree( PrivateKeyInfo );
  116.  
  117.         return bResult;
  118. }
  119.  
  120. BOOL BCryptImportPublicKey( BCRYPT_ALG_HANDLE hProvider, PBYTE lpData, ULONG dwDataLen, BCRYPT_KEY_HANDLE* hKey )
  121. {
  122.         BOOL bResult = FALSE;
  123.         NTSTATUS Status = NO_ERROR;
  124.  
  125.         union
  126.         {
  127.                 PVOID pvStructInfo;
  128.                 PCERT_INFO pCertInfo;
  129.                 PCERT_PUBLIC_KEY_INFO PublicKeyInfo;
  130.         };
  131.  
  132.         ULONG cb = 0;
  133.         BCRYPT_RSAKEY_BLOB* prkb = nullptr;
  134.  
  135.         bResult = ::CryptDecodeObjectEx( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  136.                 X509_PUBLIC_KEY_INFO,
  137.                 lpData,
  138.                 dwDataLen,
  139.                 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, 0, &pvStructInfo, &cb );
  140.  
  141.         if( !bResult )
  142.         {
  143.                 printf( __FUNCTION__ " -- CryptDecodeObjectEx failed 0x%X\n", ::GetLastError( ) );
  144.                 goto Exit;
  145.         }
  146.  
  147.         bResult = ::CryptDecodeObjectEx( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  148.                 CNG_RSA_PUBLIC_KEY_BLOB,
  149.                 PublicKeyInfo->PublicKey.pbData,
  150.                 PublicKeyInfo->PublicKey.cbData,
  151.                 CRYPT_DECODE_ALLOC_FLAG, 0, ( void** )&prkb, &cb );
  152.  
  153.         if( !bResult )
  154.         {
  155.                 printf( __FUNCTION__ " -- CryptDecodeObjectEx failed 0x%X\n", ::GetLastError( ) );
  156.                 goto Exit;
  157.         }
  158.  
  159.         Status = BCryptImportKeyPair(
  160.                 hProvider,
  161.                 NULL,
  162.                 BCRYPT_RSAPUBLIC_BLOB,
  163.                 hKey,
  164.                 ( PUCHAR )prkb,
  165.                 cb,
  166.                 0 );
  167.  
  168.         bResult = ( Status == NO_ERROR );
  169.         if( !bResult )
  170.         {
  171.                 printf( __FUNCTION__ " -- BCryptImportKey failed 0x%X\n", Status );
  172.                 goto Exit;
  173.         }
  174.  
  175. Exit:
  176.         if( prkb )
  177.                 ::LocalFree( prkb );
  178.  
  179.         if( pvStructInfo )
  180.                 ::LocalFree( pvStructInfo );
  181.  
  182.         return bResult;
  183. }
  184.  
  185. BOOL RSADecrypt( PBYTE pbInputData, DWORD dwInputDataSize, PBYTE* lpDecryptedBuffer, PDWORD dwDecryptedBufferLen )
  186. {
  187.         NTSTATUS Status = NO_ERROR;
  188.         BOOL bResult = FALSE;
  189.  
  190.         if( !pbInputData || dwInputDataSize <= 0 || !lpDecryptedBuffer || !dwDecryptedBufferLen )
  191.         {
  192.                 printf( __FUNCTION__ " -- Invalid params!\n" );
  193.                 return FALSE;
  194.         }
  195.  
  196.         BCRYPT_ALG_HANDLE hProvider = NULL;
  197.         BCRYPT_KEY_HANDLE hKey = NULL;
  198.  
  199.         LPBYTE pbKeyBuffer = nullptr;
  200.         DWORD dwKeyBufferLen = 0;
  201.  
  202.         BYTE DERPrivKey[ 2048 ]{ };
  203.         DWORD DERPrivKeyLen = sizeof( DERPrivKey );
  204.  
  205.         //
  206.         // Open the RSA crypto provider
  207.         //
  208.         Status = ::BCryptOpenAlgorithmProvider(
  209.                 &hProvider,
  210.                 BCRYPT_RSA_ALGORITHM,
  211.                 NULL,
  212.                 0 );
  213.  
  214.         bResult = ( Status == NO_ERROR );
  215.         if( !bResult )
  216.         {
  217.                 printf( __FUNCTION__ " -- BCryptOpenAlgorithmProvider failed 0x%X\n", Status );
  218.                 goto Exit;
  219.         }
  220.  
  221.         //
  222.         // Read public key from disk
  223.         //
  224.         bResult = ReadFileToByteArray( RSA_PRIVATE_KEY_FILENAME, &pbKeyBuffer, &dwKeyBufferLen );
  225.         if( !bResult )
  226.         {
  227.                 printf( __FUNCTION__ " -- ReadFileToByteArray failed!\n" );
  228.                 goto Exit;
  229.         }
  230.  
  231.         //
  232.         // Convert PEM to DER
  233.         //
  234.         bResult = ::CryptStringToBinaryA(
  235.                 ( LPCSTR )pbKeyBuffer,
  236.                 0,
  237.                 CRYPT_STRING_BASE64HEADER,
  238.                 DERPrivKey,
  239.                 &DERPrivKeyLen,
  240.                 NULL,
  241.                 NULL );
  242.  
  243.         if( !bResult )
  244.         {
  245.                 printf( __FUNCTION__ " -- CryptStringToBinaryA failed 0x%X\n", ::GetLastError( ) );
  246.                 goto Exit;
  247.         }
  248.  
  249.         //
  250.         // Import RSA Public Key
  251.         //
  252.         bResult = ::BCryptImportPrivateKey( hProvider, DERPrivKey, DERPrivKeyLen, &hKey );
  253.         if( !bResult )
  254.         {
  255.                 printf( __FUNCTION__ " -- BCryptImportKeyPair failed!\n" );
  256.                 goto Exit;
  257.         }
  258.  
  259.         //
  260.         // Get Required encrypted buffer length
  261.         //
  262.         Status = ::BCryptDecrypt(
  263.                 hKey,
  264.                 pbInputData,
  265.                 dwInputDataSize,
  266.                 NULL,
  267.                 NULL,
  268.                 0,
  269.                 NULL,
  270.                 0,
  271.                 dwDecryptedBufferLen,
  272.                 BCRYPT_PAD_PKCS1 );
  273.  
  274.         bResult = ( Status == NO_ERROR );
  275.         if( !bResult )
  276.         {
  277.                 printf( __FUNCTION__ " -- BCryptDecrypt failed 0x%X\n", Status );
  278.                 goto Exit;
  279.         }
  280.  
  281.         //
  282.         // Allocate buffer for output ciphertext, HeapAlloc is used because RSA block sizes are not huge
  283.         //
  284.         *lpDecryptedBuffer = ( PBYTE )::HeapAlloc( ::GetProcessHeap( ), HEAP_ZERO_MEMORY, *dwDecryptedBufferLen );
  285.  
  286.         bResult = ( *lpDecryptedBuffer != nullptr );
  287.         if( !bResult )
  288.         {
  289.                 printf( __FUNCTION__ " -- HeapAlloc failed %d\n", ::GetLastError( ) );
  290.                 goto Exit;
  291.         }
  292.  
  293.         //
  294.         // Perform encryption
  295.         //
  296.         Status = ::BCryptDecrypt(
  297.                 hKey,
  298.                 pbInputData,
  299.                 dwInputDataSize,
  300.                 NULL,
  301.                 NULL,
  302.                 0,
  303.                 *lpDecryptedBuffer,
  304.                 *dwDecryptedBufferLen,
  305.                 dwDecryptedBufferLen,
  306.                 BCRYPT_PAD_PKCS1 );
  307.  
  308.         bResult = ( Status == NO_ERROR );
  309.         if( !bResult )
  310.         {
  311.                 //
  312.                 // Since we're returning FALSE we wanna release the heap buffer here.
  313.                 //
  314.                 ::HeapFree( ::GetProcessHeap( ), 0, *lpDecryptedBuffer );
  315.                 *lpDecryptedBuffer = nullptr;
  316.  
  317.                 printf( __FUNCTION__ " -- BCryptDecrypt failed 0x%X\n", Status );
  318.                 goto Exit;
  319.         }
  320.  
  321. Exit:
  322.         if( DERPrivKey )
  323.                 ::LocalFree( DERPrivKey );
  324.  
  325.         if( pbKeyBuffer )
  326.                 ::VirtualFree( pbKeyBuffer, 0, MEM_RELEASE );
  327.  
  328.         if( hKey )
  329.                 ::BCryptDestroyKey( hKey );
  330.  
  331.         if( hProvider )
  332.                 ::BCryptCloseAlgorithmProvider( hProvider, 0 );
  333.  
  334.         return bResult;
  335. }
  336.  
  337. BOOL RSAEncrypt( PBYTE pbInputData, DWORD dwInputDataSize, PBYTE* lpEncryptedBuffer, PDWORD dwEncryptedBufferLen )
  338. {
  339.         NTSTATUS Status = NO_ERROR;
  340.         BOOL bResult = FALSE;
  341.  
  342.         if( !pbInputData || dwInputDataSize <= 0 || !lpEncryptedBuffer || !dwEncryptedBufferLen )
  343.         {
  344.                 printf( __FUNCTION__ " -- Invalid params!\n" );
  345.                 return FALSE;
  346.         }
  347.  
  348.         BCRYPT_ALG_HANDLE hProvider = NULL;
  349.         BCRYPT_KEY_HANDLE hKey = NULL;
  350.  
  351.         LPBYTE pbKeyBuffer = nullptr;
  352.         DWORD dwKeyBufferLen = 0;
  353.  
  354.         BYTE DERPubKey[ 2048 ]{ };
  355.         DWORD DERPubKeyLen = sizeof( DERPubKey );
  356.  
  357.         //
  358.         // Open the RSA crypto provider
  359.         //
  360.         Status = ::BCryptOpenAlgorithmProvider(
  361.                 &hProvider,
  362.                 BCRYPT_RSA_ALGORITHM,
  363.                 NULL,
  364.                 0 );
  365.  
  366.         bResult = ( Status == NO_ERROR );
  367.         if( !bResult )
  368.         {
  369.                 printf( __FUNCTION__ " -- BCryptOpenAlgorithmProvider failed 0x%X\n", Status );
  370.                 goto Exit;
  371.         }
  372.  
  373.         //
  374.         // Read public key from disk
  375.         //
  376.         bResult = ReadFileToByteArray( RSA_PUBLIC_KEY_FILENAME, &pbKeyBuffer, &dwKeyBufferLen );
  377.         if( !bResult )
  378.         {
  379.                 printf( __FUNCTION__ " -- ReadFileToByteArray failed!\n" );
  380.                 goto Exit;
  381.         }
  382.  
  383.         //
  384.         // Convert PEM to DER
  385.         //
  386.         bResult = ::CryptStringToBinaryA( ( LPCSTR )pbKeyBuffer,
  387.                 0,
  388.                 CRYPT_STRING_BASE64HEADER,
  389.                 DERPubKey,
  390.                 &DERPubKeyLen,
  391.                 NULL,
  392.                 NULL );
  393.  
  394.         if( !bResult )
  395.         {
  396.                 printf( __FUNCTION__ " -- CryptStringToBinaryA failed 0x%X\n", ::GetLastError( ) );
  397.                 goto Exit;
  398.         }
  399.  
  400.         //
  401.         // Import AES Public Key
  402.         //
  403.         bResult = BCryptImportPublicKey( hProvider, DERPubKey, DERPubKeyLen, &hKey );
  404.         if( !bResult )
  405.         {
  406.                 printf( __FUNCTION__ " -- BCryptImportKeyPair failed!\n" );
  407.                 goto Exit;
  408.         }
  409.  
  410.         //
  411.         // Get Required encrypted buffer length
  412.         //
  413.         Status = ::BCryptEncrypt(
  414.                 hKey,
  415.                 pbInputData,
  416.                 dwInputDataSize,
  417.                 NULL,
  418.                 NULL,
  419.                 0,
  420.                 NULL,
  421.                 0,
  422.                 dwEncryptedBufferLen,
  423.                 BCRYPT_PAD_PKCS1 );
  424.  
  425.         bResult = ( Status == NO_ERROR );
  426.         if( !bResult )
  427.         {
  428.                 printf( __FUNCTION__ " -- BCryptEncrypt failed 0x%X\n", Status );
  429.                 goto Exit;
  430.         }
  431.  
  432.         //
  433.         // Allocate buffer for output ciphertext, HeapAlloc is used because RSA block sizes are not huge
  434.         //
  435.         *lpEncryptedBuffer = ( PBYTE )::HeapAlloc( ::GetProcessHeap( ), HEAP_ZERO_MEMORY, *dwEncryptedBufferLen );
  436.  
  437.         bResult = ( *lpEncryptedBuffer != nullptr );
  438.         if( !bResult )
  439.         {
  440.                 printf( __FUNCTION__ " -- HeapAlloc failed %d\n", ::GetLastError( ) );
  441.                 goto Exit;
  442.         }
  443.  
  444.         //
  445.         // Perform encryption
  446.         //
  447.         Status = ::BCryptEncrypt(
  448.                 hKey,
  449.                 pbInputData,
  450.                 dwInputDataSize,
  451.                 NULL,
  452.                 NULL,
  453.                 0,
  454.                 *lpEncryptedBuffer,
  455.                 *dwEncryptedBufferLen,
  456.                 dwEncryptedBufferLen,
  457.                 BCRYPT_PAD_PKCS1 );
  458.  
  459.         bResult = ( Status == NO_ERROR );
  460.         if( !bResult )
  461.         {
  462.                 //
  463.                 // Since we're returning FALSE we wanna release the heap buffer here.
  464.                 //
  465.                 ::HeapFree( ::GetProcessHeap( ), 0, *lpEncryptedBuffer );
  466.                 *lpEncryptedBuffer = nullptr;
  467.  
  468.                 printf( __FUNCTION__ " -- BCryptEncrypt failed 0x%X\n", Status );
  469.                 goto Exit;
  470.         }
  471.  
  472. Exit:
  473.         if( pbKeyBuffer )
  474.                 ::VirtualFree( pbKeyBuffer, 0, MEM_RELEASE );
  475.  
  476.         if( hKey )
  477.                 ::BCryptDestroyKey( hKey );
  478.  
  479.         if( hProvider )
  480.                 ::BCryptCloseAlgorithmProvider( hProvider, 0 );
  481.  
  482.         return bResult;
  483. }
  484.  
  485. BOOL AESEncrypt( PBYTE pbInputData, DWORD dwInputDataSize, PBYTE pbKey, DWORD dwKeyLen, PBYTE pbIV, DWORD dwIVLen, PBYTE* lpEncryptedBuffer, PDWORD dwEncryptedBufferLen )
  486. {
  487.         NTSTATUS Status = NO_ERROR;
  488.         BOOL bResult = FALSE;
  489.  
  490.         if( !pbInputData || dwInputDataSize <= 0 || !lpEncryptedBuffer || !dwEncryptedBufferLen )
  491.         {
  492.                 printf( __FUNCTION__ " -- Invalid params!\n" );
  493.                 return FALSE;
  494.         }
  495.  
  496.         BCRYPT_ALG_HANDLE hProvider = NULL;
  497.         BCRYPT_KEY_HANDLE hKey = NULL;
  498.  
  499.         BYTE TempInitVector[ 16 ]{ };
  500.         memcpy( TempInitVector, pbIV, dwIVLen );
  501.  
  502.         //
  503.         // Open Crypto Provider for AES
  504.         //
  505.         Status = ::BCryptOpenAlgorithmProvider(
  506.                 &hProvider,
  507.                 BCRYPT_AES_ALGORITHM,
  508.                 NULL,
  509.                 0 );
  510.  
  511.         bResult = ( Status == NO_ERROR );
  512.         if( !bResult )
  513.         {
  514.                 printf( __FUNCTION__ " -- BCryptOpenAlgorithmProvider failed 0x%X\n", Status );
  515.                 goto Exit;
  516.         }
  517.  
  518.         //
  519.         // Set the encryption key
  520.         //
  521.         Status = ::BCryptGenerateSymmetricKey(
  522.                 hProvider,
  523.                 &hKey,
  524.                 NULL,
  525.                 0,
  526.                 pbKey,
  527.                 dwKeyLen,
  528.                 0 );
  529.  
  530.         bResult = ( Status == NO_ERROR );
  531.         if( !bResult )
  532.         {
  533.                 printf( __FUNCTION__ " -- BCryptGenerateSymmetricKey failed 0x%X\n", Status );
  534.                 goto Exit;
  535.         }
  536.  
  537.         //
  538.         // Get Required encrypted buffer length
  539.         //
  540.         Status = ::BCryptEncrypt(
  541.                 hKey,
  542.                 pbInputData,
  543.                 dwInputDataSize,
  544.                 NULL,
  545.                 TempInitVector,
  546.                 dwIVLen,
  547.                 NULL,
  548.                 0,
  549.                 dwEncryptedBufferLen,
  550.                 BCRYPT_BLOCK_PADDING );
  551.  
  552.         bResult = ( Status == NO_ERROR );
  553.         if( !bResult )
  554.         {
  555.                 printf( __FUNCTION__ " -- BCryptEncrypt failed 0x%X\n", Status );
  556.                 goto Exit;
  557.         }
  558.  
  559.         //
  560.         // Allocate buffer for output ciphertext, VirtualAlloc will be used because we may store huge data
  561.         //
  562.         *lpEncryptedBuffer = ( PBYTE )::VirtualAlloc( nullptr, *dwEncryptedBufferLen, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE );
  563.  
  564.         bResult = ( *lpEncryptedBuffer != nullptr );
  565.         if( !bResult )
  566.         {
  567.                 printf( __FUNCTION__ " -- VirtualAlloc failed %d\n", ::GetLastError( ) );
  568.                 goto Exit;
  569.         }
  570.  
  571.         //
  572.         // Perform encryption
  573.         //
  574.         Status = ::BCryptEncrypt(
  575.                 hKey,
  576.                 pbInputData,
  577.                 dwInputDataSize,
  578.                 NULL,
  579.                 TempInitVector,
  580.                 dwIVLen,
  581.                 *lpEncryptedBuffer,
  582.                 *dwEncryptedBufferLen,
  583.                 dwEncryptedBufferLen,
  584.                 BCRYPT_BLOCK_PADDING );
  585.  
  586.         bResult = ( Status == NO_ERROR );
  587.         if( !bResult )
  588.         {
  589.                 //
  590.                 // Since we're returning FALSE we wanna release the heap buffer here.
  591.                 //
  592.                 ::HeapFree( ::GetProcessHeap( ), 0, *lpEncryptedBuffer );
  593.                 *lpEncryptedBuffer = nullptr;
  594.  
  595.                 printf( __FUNCTION__ " -- BCryptEncrypt failed 0x%X\n", Status );
  596.                 goto Exit;
  597.         }
  598.  
  599. Exit:
  600.         if( hKey )
  601.                 ::BCryptDestroyKey( hKey );
  602.  
  603.         if( hProvider )
  604.                 ::BCryptCloseAlgorithmProvider( hProvider, 0 );
  605.  
  606.         return bResult;
  607. }
  608.  
  609. BOOL AESDecrypt( PBYTE pbInputData, DWORD dwInputDataSize, PBYTE pbKey, DWORD dwKeyLen, PBYTE pbIV, DWORD dwIVLen, PBYTE* lpDecryptedBuffer, PDWORD dwDecryptedBufferLen )
  610. {
  611.         NTSTATUS Status = NO_ERROR;
  612.         BOOL bResult = FALSE;
  613.  
  614.         if( !pbInputData || dwInputDataSize <= 0 || !lpDecryptedBuffer || !dwDecryptedBufferLen )
  615.         {
  616.                 printf( __FUNCTION__ " -- Invalid params!\n" );
  617.                 return FALSE;
  618.         }
  619.  
  620.         BCRYPT_ALG_HANDLE hProvider = NULL;
  621.         BCRYPT_KEY_HANDLE hKey = NULL;
  622.  
  623.         BYTE TempInitVector[ 16 ]{ };
  624.         memcpy( TempInitVector, pbIV, dwIVLen );
  625.  
  626.         //
  627.         // Open Crypto Provider for AES
  628.         //
  629.         Status = ::BCryptOpenAlgorithmProvider(
  630.                 &hProvider,
  631.                 BCRYPT_AES_ALGORITHM,
  632.                 NULL,
  633.                 0 );
  634.  
  635.         bResult = ( Status == NO_ERROR );
  636.         if( !bResult )
  637.         {
  638.                 printf( __FUNCTION__ " -- BCryptOpenAlgorithmProvider failed 0x%X\n", Status );
  639.                 goto Exit;
  640.         }
  641.  
  642.         //
  643.         // Set the encryption key
  644.         //
  645.         Status = ::BCryptGenerateSymmetricKey(
  646.                 hProvider,
  647.                 &hKey,
  648.                 NULL,
  649.                 0,
  650.                 pbKey,
  651.                 dwKeyLen,
  652.                 0 );
  653.  
  654.         bResult = ( Status == NO_ERROR );
  655.         if( !bResult )
  656.         {
  657.                 printf( __FUNCTION__ " -- BCryptGenerateSymmetricKey failed 0x%X\n", Status );
  658.                 goto Exit;
  659.         }
  660.  
  661.         //
  662.         // Get Required encrypted buffer length
  663.         //
  664.         Status = ::BCryptDecrypt(
  665.                 hKey,
  666.                 pbInputData,
  667.                 dwInputDataSize,
  668.                 NULL,
  669.                 TempInitVector,
  670.                 dwIVLen,
  671.                 NULL,
  672.                 0,
  673.                 dwDecryptedBufferLen,
  674.                 BCRYPT_BLOCK_PADDING );
  675.  
  676.         bResult = ( Status == NO_ERROR );
  677.         if( !bResult )
  678.         {
  679.                 printf( __FUNCTION__ " -- BCryptDecrypt failed 0x%X\n", Status );
  680.                 goto Exit;
  681.         }
  682.  
  683.         //
  684.         // Allocate buffer for output ciphertext, VirtualAlloc will be used because we may store huge data
  685.         //
  686.         *lpDecryptedBuffer = ( PBYTE )::VirtualAlloc( nullptr, *dwDecryptedBufferLen, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE );
  687.  
  688.         bResult = ( *lpDecryptedBuffer != nullptr );
  689.         if( !bResult )
  690.         {
  691.                 printf( __FUNCTION__ " -- VirtualAlloc failed %d\n", ::GetLastError( ) );
  692.                 goto Exit;
  693.         }
  694.  
  695.         //
  696.         // Perform encryption
  697.         //
  698.         Status = ::BCryptDecrypt(
  699.                 hKey,
  700.                 pbInputData,
  701.                 dwInputDataSize,
  702.                 NULL,
  703.                 TempInitVector,
  704.                 dwIVLen,
  705.                 *lpDecryptedBuffer,
  706.                 *dwDecryptedBufferLen,
  707.                 dwDecryptedBufferLen,
  708.                 BCRYPT_BLOCK_PADDING );
  709.  
  710.         bResult = ( Status == NO_ERROR );
  711.         if( !bResult )
  712.         {
  713.                 //
  714.                 // Since we're returning FALSE we wanna release the heap buffer here.
  715.                 //
  716.                 ::HeapFree( ::GetProcessHeap( ), 0, *lpDecryptedBuffer );
  717.                 *lpDecryptedBuffer = nullptr;
  718.  
  719.                 printf( __FUNCTION__ " -- BCryptDecrypt failed 0x%X\n", Status );
  720.                 goto Exit;
  721.         }
  722.  
  723. Exit:
  724.         if( hKey )
  725.                 ::BCryptDestroyKey( hKey );
  726.  
  727.         if( hProvider )
  728.                 ::BCryptCloseAlgorithmProvider( hProvider, 0 );
  729.  
  730.         return bResult;
  731. }

Text Paste is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

Login or Register to edit or fork this paste. It's free.