Beispiel #1
0
void Widget::on_decryptFile_clicked()
{
    HCRYPTPROV cryptProv;
    HCRYPTKEY hKey;
    BYTE* key;
    QFile keyV("key.dat");
    DWORD keyBlobLen = 0;
    if (!keyV.exists())
    {
        QMessageBox::critical(0, "Ошибка", "Отсутствует ключ", QMessageBox::Ok);
        return;
    }
    keyV.open(QIODevice::ReadOnly);

    if (!CryptAcquireContext(&cryptProv, NULL, MS_DEF_RSA_SCHANNEL_PROV, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT))
    {
        QMessageBox::critical(0, "Ошибка", "Получение контекста криптопровайдера. " + GetErrorString(GetLastError()), QMessageBox::Ok);
        return;
    }
    keyV.read((char *)&keyBlobLen, sizeof(keyBlobLen));
    key = new BYTE[keyBlobLen];
    memset(key, 0, keyBlobLen);
    keyV.read((char *)key, keyBlobLen);
    keyV.close();
    CryptImportKey(cryptProv, key, keyBlobLen, 0, 0, &hKey);
    delete[] key;
    DecodingFile(fName, hKey);
    QMessageBox::information(0, "Процесс завершён", "Файл успешно расшифрован", QMessageBox::Ok);
}
Beispiel #2
0
CryptoKey::CryptoKey(HCRYPTPROV cryptProv, const ByteVector& keyMaterial, const ByteVector& iv)
         :handle(NULL)
{
    if (keyMaterial.size() != 0x10)
        throw logic_error("Invalid key length. Expected 128b");
    if (iv.size() != 0x10)
        throw logic_error("Invalid IV length. Expected 128b");

    byte_t blobHeader[] = { 
        // Header
        0x08,                               //plaintextblob
        CUR_BLOB_VERSION, 
        0x00, 0x00,
        ALG_SID_AES_128, 0x66, 0x00, 0x00,  //ALG_ID
        0x10, 0x00, 0x00, 0x00};            //key length in bytes
    
    ByteVector keyToImport;
    keyToImport.append(blobHeader, sizeof(blobHeader));
    keyToImport.append(keyMaterial);

    // import key
    TOE(CryptImportKey(cryptProv, keyToImport.c_ptr(), static_cast<DWORD>(keyToImport.size()),
                       0, 0, &handle), "CryptImportKey");
    
    // set IV
    TOE(CryptSetKeyParam(handle, KP_IV, const_cast<byte_t*>(iv.c_ptr()), 0), "CryptSetKeyParam(IV)");
}
Beispiel #3
0
BOOL kull_m_crypto_hkey(HCRYPTPROV hProv, DWORD calgid, LPCVOID key, DWORD keyLen, DWORD flags, HCRYPTKEY *hKey, HCRYPTPROV *hSessionProv)
{
	BOOL status = FALSE;
	PGENERICKEY_BLOB keyBlob;
	DWORD szBlob = sizeof(GENERICKEY_BLOB) + keyLen;
	
	if(calgid != CALG_3DES)
	{
		if(keyBlob = (PGENERICKEY_BLOB) LocalAlloc(LPTR, szBlob))
		{
			keyBlob->Header.bType = PLAINTEXTKEYBLOB;
			keyBlob->Header.bVersion = CUR_BLOB_VERSION;
			keyBlob->Header.reserved = 0;
			keyBlob->Header.aiKeyAlg = calgid;
			keyBlob->dwKeyLen = keyLen;
			RtlCopyMemory((PBYTE) keyBlob + sizeof(GENERICKEY_BLOB), key, keyBlob->dwKeyLen);
			status = CryptImportKey(hProv, (LPCBYTE) keyBlob, szBlob, 0, flags, hKey);
			LocalFree(keyBlob);
		}
	}
	else if(hSessionProv)
		status = kull_m_crypto_hkey_session(calgid, key, keyLen, flags, hKey, hSessionProv);
	
	return status;
}
Beispiel #4
0
bool VerifySHA1Signature(const void *data, size_t dataLen, const char *hexSignature, const void *pubkey, size_t pubkeyLen)
{
    HCRYPTPROV hProv = 0;
    HCRYPTKEY hPubKey = 0;
    HCRYPTHASH hHash = 0;
    BOOL ok = false;
    ScopedMem<BYTE> signature;
    size_t signatureLen;

#define Check(val) if ((ok = (val)) == FALSE) goto CleanUp
    Check(ExtractSignature(hexSignature, data, dataLen, signature, signatureLen));
    Check(CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT));
    Check(CryptImportKey(hProv, (const BYTE *)pubkey, (DWORD)pubkeyLen, 0, 0, &hPubKey));
    Check(CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash));
#ifdef _WIN64
    for (; dataLen > DWORD_MAX; data = (const BYTE *)data + DWORD_MAX, dataLen -= DWORD_MAX) {
        Check(CryptHashData(hHash, (const BYTE *)data, DWORD_MAX, 0));
    }
#endif
    Check(dataLen <= DWORD_MAX && pubkeyLen <= DWORD_MAX && signatureLen <= DWORD_MAX);
    Check(CryptHashData(hHash, (const BYTE *)data, (DWORD)dataLen, 0));
    Check(CryptVerifySignature(hHash, signature, (DWORD)signatureLen, hPubKey, NULL, 0));
#undef Check

CleanUp:
    if (hHash)
        CryptDestroyHash(hHash);
    if (hProv)
        CryptReleaseContext(hProv, 0);
    return ok;
}
// open key file
BOOL open_key(char *key_file)
{
    BOOL   bStatus = FALSE;
    HANDLE hFile;
    DWORD  dwRead;
    // open private key
    hFile = CreateFile(key_file, GENERIC_READ,
                       FILE_SHARE_READ, NULL, OPEN_EXISTING,
                       FILE_ATTRIBUTE_NORMAL, NULL);

    if (hFile != INVALID_HANDLE_VALUE) {
        dwBlob = GetFileSize(hFile, NULL);

        if (dwBlob != 0 && (pbBlob = (PBYTE)xmalloc(dwBlob)) != NULL) {
            // read key
            ReadFile(hFile, pbBlob, dwBlob, &dwRead, NULL);
            printf("  [ read %i bytes from %s\n", dwBlob, key_file);
            // import key into object
            bStatus = CryptImportKey(hProv, pbBlob, dwBlob, 0, 0, &hKey);
        } else {
            xstrerror("HeapAlloc()");
        }

        // close key file
        CloseHandle(hFile);
    } else {
        xstrerror("CreateFile(%s)", key_file);
    }

    return bStatus;
}
Beispiel #6
0
/**
 * Creates an RSA public key with the given modulus and public exponent
 */
int import_RSA_key(RSA_key_t *rsa, uint32_t exponent,
                   const unsigned char *modulus, uint16_t modlen)
{
    char keyblob[BLOBLEN];
    BLOBHEADER *bheader;
    RSAPUBKEY *pubkeyheader;
    BYTE *blob_modulus;
    int bloblen, i;

    bheader = (BLOBHEADER *)keyblob;
    pubkeyheader = (RSAPUBKEY *)(keyblob + sizeof(BLOBHEADER));
    blob_modulus = (BYTE *)pubkeyheader + sizeof(RSAPUBKEY);

    memset(keyblob, 0, sizeof(keyblob));
    bheader->bType = PUBLICKEYBLOB;
    bheader->bVersion = CUR_BLOB_VERSION;
    bheader->aiKeyAlg = CALG_RSA_KEYX;
    pubkeyheader->magic = 0x31415352;
    pubkeyheader->bitlen = modlen * 8;
    pubkeyheader->pubexp = exponent;
    // CrypoAPI expects the modulus in little endian, so reverse the bytes
    for (i = 0; i < modlen; i++) {
        blob_modulus[i] = modulus[modlen - i - 1];
    }

    bloblen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + modlen;
    if (!CryptImportKey(base_prov, keyblob, bloblen, 0, 0, rsa)) {
        mserror("CryptImportKey failed");
        return 0;
    }

    return 1;
}
Beispiel #7
0
void Widget::on_keyErr_clicked()
{
    DWORD keyBlobLen, blockLen = 0;
    BYTE *keyBlob, *srcData, *newData, *blockData1, *blockData2;
    HCRYPTPROV hCryptProv;
    HCRYPTKEY hKey, dhKey;
    QVector<int> values;
    QFile myFile(fName);

    plot->clear();
    if (myFile.exists())
        myFile.open(QIODevice::ReadOnly);
    else
    {
        QMessageBox::critical(0, "Ошибка", "Файл не выбран", QMessageBox::Ok);
        return;
    }
    CryptAcquireContext(&hCryptProv, NULL, MS_DEF_RSA_SCHANNEL_PROV, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
    CryptGenKey(hCryptProv, CALG_AES_256, 0, &hKey);
    CryptEncrypt(hKey, 0, true, 0, NULL, &blockLen, myFile.size());
    srcData = new BYTE[block * blockLen];
    newData = new BYTE[block * blockLen];
    blockData1  = new BYTE[blockLen];
    blockData2  = new BYTE[blockLen];
    myFile.read((char*)srcData, block * blockLen);
    myFile.close();
    memcpy((char*)newData, (char*)srcData, block * blockLen);
    newData[0] = -newData[0];
    CryptDuplicateKey(hKey, NULL, 0, &dhKey);
    CryptExportKey(dhKey, 0, SIMPLEBLOB, 0, NULL, &keyBlobLen);
    keyBlob = new BYTE[keyBlobLen];
    CryptExportKey(dhKey, 0, SIMPLEBLOB, 0, keyBlob, &keyBlobLen);
    keyBlob[0] = -keyBlob[0];
    CryptImportKey(hCryptProv, keyBlob, keyBlobLen, 0, 0, &dhKey);
    for (uint i = 0; i < (block * blockLen); i++)
    {
        CryptEncrypt(hKey, 0, i < 2, 0, srcData + i, &blockLen, block * blockLen);
        CryptEncrypt(dhKey, 0, i < 2, 0, newData + i, &blockLen, block * blockLen);
    }
    for(uint i = 0; i < (block * blockLen); i += blockLen)
    {
        int k = 0;
        memcpy(blockData1, srcData + i, blockLen);
        memcpy(blockData2, newData + i, blockLen);
        for (uint j = i; j < (i + blockLen); j++)
            k += trueBitsCount(srcData[j] ^ newData[j]);
        values.push_back(k);
    }
    delete[] newData;
    delete[] srcData;
    delete[] blockData1;
    delete[] blockData2;
    delete[] keyBlob;
    CryptReleaseContext(hCryptProv, 0);
    CryptDestroyKey(hKey);
    CryptDestroyKey(dhKey);
    DrawPlot(plot, values);
    plot->show();
}
/**
 *
 * save public or private key to PEM format
 *
 * ifile   : name of file to write PEM encoded key
 * pemType : type of key being saved
 * rsa     : RSA object with public and private keys
 *
 */
int rsa_read_key(RSA* rsa,
                 const char* ifile, int pemType)
{
    LPVOID                  derData, keyData;
    PCRYPT_PRIVATE_KEY_INFO pki = 0;
    DWORD                   pkiLen, derLen, keyLen;
    BOOL                    ok = FALSE;
    // decode base64 string ignoring headers
    derData = rsa_read_pem(ifile, &derLen);

    if (derData != NULL) {
        // decode DER
        // is it a public key?
        if (pemType == RSA_PUBLIC_KEY) {
            if (CryptDecodeObjectEx(
                    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                    X509_PUBLIC_KEY_INFO, derData, derLen,
                    CRYPT_DECODE_ALLOC_FLAG, NULL,
                    &keyData, &keyLen)) {
                // if decode ok, import it
                ok = CryptImportPublicKeyInfo(rsa->prov, X509_ASN_ENCODING,
                                              (PCERT_PUBLIC_KEY_INFO)keyData, &rsa->pubkey);
                // release allocated memory
                LocalFree(keyData);
            }
        } else {
            // convert the PKCS#8 data to private key info
            if (CryptDecodeObjectEx(
                    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                    PKCS_PRIVATE_KEY_INFO, derData, derLen,
                    CRYPT_DECODE_ALLOC_FLAG,
                    NULL, &pki, &pkiLen)) {
                // then convert the private key to private key blob
                if (CryptDecodeObjectEx(
                        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                        PKCS_RSA_PRIVATE_KEY,
                        pki->PrivateKey.pbData,
                        pki->PrivateKey.cbData,
                        CRYPT_DECODE_ALLOC_FLAG, NULL,
                        &keyData, &keyLen)) {
                    // if decode ok, import it
                    ok = CryptImportKey(rsa->prov, keyData, keyLen,
                                        0, CRYPT_EXPORTABLE, &rsa->privkey);
                    // release data
                    LocalFree(keyData);
                }

                // release private key info
                LocalFree(pki);
            }
        }

        xfree(derData);
    }

    return ok;
}
Beispiel #9
0
static HCRYPTKEY create_des_key(unsigned char *key) {

    HCRYPTKEY hSessionKey, hPrivateKey;
    DWORD dlen = 8;
    BLOBHEADER *pbh;
    char buf[sizeof(BLOBHEADER) + sizeof(ALG_ID) + 256];

    /*
     * Need special private key to encrypt session key so we can
     * import session key, since only encrypted session keys can be
     * imported
     */
    if(CryptImportKey(hCryptProv, PrivateKeyWithExponentOfOne,
		      sizeof(PrivateKeyWithExponentOfOne),
		      0, 0, &hPrivateKey) == 0)
	return 0;

    /* now encrypt session key using special private key */
    memcpy(buf + sizeof(BLOBHEADER) + sizeof(ALG_ID), key, 8);
    if(CryptEncrypt(hPrivateKey, 0, TRUE, 0,
		    buf + sizeof(BLOBHEADER) + sizeof(ALG_ID),
		    &dlen, 256) == 0)
	return 0;

    /* build session key blob */
    pbh = (BLOBHEADER*)buf;
    pbh->bType = SIMPLEBLOB;
    pbh->bVersion = 0x02;
    pbh->reserved = 0;
    pbh->aiKeyAlg = CALG_DES;
    *((ALG_ID*)(buf+sizeof(BLOBHEADER))) = CALG_RSA_KEYX;

    /* import session key into key container */
    if(CryptImportKey(hCryptProv, buf,
		      dlen + sizeof(BLOBHEADER) + sizeof(ALG_ID),
		      hPrivateKey, 0, &hSessionKey) == 0)
	return 0;

    if(hPrivateKey)
	CryptDestroyKey(hPrivateKey);

    return hSessionKey;

}
Beispiel #10
0
void * aes_encrypt_init(const u8 *key, size_t len)
{
	struct aes_context *akey;
	struct {
		BLOBHEADER hdr;
		DWORD len;
		BYTE key[16];
	} key_blob;
	DWORD mode = CRYPT_MODE_ECB;

	if (len != 16)
		return NULL;

	key_blob.hdr.bType = PLAINTEXTKEYBLOB;
	key_blob.hdr.bVersion = CUR_BLOB_VERSION;
	key_blob.hdr.reserved = 0;
	key_blob.hdr.aiKeyAlg = CALG_AES_128;
	key_blob.len = len;
	os_memcpy(key_blob.key, key, len);

	akey = os_zalloc(sizeof(*akey));
	if (akey == NULL)
		return NULL;

	if (!CryptAcquireContext(&akey->prov, NULL,
				 MS_ENH_RSA_AES_PROV, PROV_RSA_AES,
				 CRYPT_VERIFYCONTEXT)) {
 		wpa_printf(MSG_DEBUG, "CryptoAPI: CryptAcquireContext failed: "
			   "%d", (int) GetLastError());
		os_free(akey);
		return NULL;
	}

	if (!CryptImportKey(akey->prov, (BYTE *) &key_blob, sizeof(key_blob),
			    0, 0, &akey->ckey)) {
 		wpa_printf(MSG_DEBUG, "CryptoAPI: CryptImportKey failed: %d",
			   (int) GetLastError());
		CryptReleaseContext(akey->prov, 0);
		os_free(akey);
		return NULL;
	}

	if (!CryptSetKeyParam(akey->ckey, KP_MODE, (BYTE *) &mode, 0)) {
 		wpa_printf(MSG_DEBUG, "CryptoAPI: CryptSetKeyParam(KP_MODE) "
			   "failed: %d", (int) GetLastError());
		CryptDestroyKey(akey->ckey);
		CryptReleaseContext(akey->prov, 0);
		os_free(akey);
		return NULL;
	}

	return akey;
}
Beispiel #11
0
BOOL rsautil_initdefaultkey(HCRYPTPROV *hProv, HCRYPTKEY *hKey)
{
	BOOL status = FALSE;
	if(CryptAcquireContext(hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
	{
		if(!(status = CryptImportKey(*hProv, default_user_pky, sizeof(default_user_pky), 0, 0, hKey)))
		{
			PRINT_ERROR_AUTO(L"CryptImportKey");
			CryptReleaseContext(*hProv, 0);
		}
	}
	else PRINT_ERROR_AUTO(L"CryptAcquireContext");
	return status;
}
Beispiel #12
0
BOOL DecryptData(char *buffer, DWORD *dwBufferSize) {
	HCRYPTPROV hProv = 0;
	HCRYPTKEY hKey = 0;
	DWORD dwCount;
	DWORD dwBlobLen;
	BOOL res=FALSE;
	DWORD srcIndex;
	LONG lError;

	// Get a handle to the default provider.
	if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) goto done;

    // Get a handle to key exchange key.

	dwBlobLen=*(DWORD*)buffer;
	// Determine the size of the key blob and allocate memory.
	if(!CryptImportKey(hProv, (PBYTE)(buffer+sizeof(DWORD)), dwBlobLen, 0, 0, &hKey)) {
     //if(GetLastError()==NTE_NO_KEY)
     	MessageBox(0,MakeErrorMessage(GetLastError()),"CryptImportKey",MB_OK|MB_ICONERROR);
     goto done;
    }
	
	srcIndex=dwBlobLen+sizeof(DWORD);
	

	while(srcIndex<*dwBufferSize) {    
		dwCount = min(BLOCK_SIZE,*dwBufferSize-srcIndex);	
		if(!CryptDecrypt(hKey, 0, srcIndex+dwCount>=*dwBufferSize, 0, (PBYTE)buffer+srcIndex, &dwCount)) {
			goto done;    
		}    
		srcIndex+=dwCount;
	}
	*dwBufferSize=dwBlobLen+sizeof(DWORD);
	res=TRUE;

done:
	lError=GetLastError();
	// Destroy the session key.
	if(hKey != 0) CryptDestroyKey(hKey);
	// Destroy the key exchange key.
	if(hProv != 0) CryptReleaseContext(hProv, 0);
	//if(pbBuffer) free(pbBuffer);
	SetLastError(lError);
	return res;
}
Beispiel #13
0
/**
 * Creates an RSA public key with the given modulus and public exponent
 */
int import_RSA_key(RSA_key_t *rsa, const unsigned char *keyblob,
                   uint16_t bloblen)
{
    struct rsa_blob_t *rsablob;
    const unsigned char *modulus;
    char ms_keyblob[BLOBLEN];
    BLOBHEADER *bheader;
    RSAPUBKEY *pubkeyheader;
    BYTE *ms_blob_modulus;
    int ms_bloblen, modlen, i;

    rsablob = (struct rsa_blob_t *)keyblob;
    modulus = keyblob + sizeof(struct rsa_blob_t);
    modlen = ntohs(rsablob->modlen);

    if (sizeof(struct rsa_blob_t) + modlen != bloblen) {
        log0(0, 0, 0, "Error importing RSA key: invalid length");
        return 0;
    } 

    bheader = (BLOBHEADER *)ms_keyblob;
    pubkeyheader = (RSAPUBKEY *)(ms_keyblob + sizeof(BLOBHEADER));
    ms_blob_modulus = (BYTE *)pubkeyheader + sizeof(RSAPUBKEY);

    memset(ms_keyblob, 0, sizeof(ms_keyblob));
    bheader->bType = PUBLICKEYBLOB;
    bheader->bVersion = CUR_BLOB_VERSION;
    bheader->aiKeyAlg = CALG_RSA_KEYX;
    pubkeyheader->magic = 0x31415352;
    pubkeyheader->bitlen = modlen * 8;
    pubkeyheader->pubexp = ntohl(rsablob->exponent);
    // CrypoAPI expects the modulus in little endian, so reverse the bytes
    for (i = 0; i < modlen; i++) {
        ms_blob_modulus[i] = modulus[modlen - i - 1];
    }

    ms_bloblen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + modlen;
    if (!CryptImportKey(base_prov, ms_keyblob, ms_bloblen, 0, 0, rsa)) {
        mserror("CryptImportKey failed");
        return 0;
    }

    return 1;
}
	inline cryptkey_ptr_t import_cryptkey_ptr(HCRYPTPROV hProv, char const * const data, DWORD const size, HCRYPTKEY const pub_key, DWORD const flags)
	{
		HCRYPTKEY tmp;

		if( !CryptImportKey(hProv, reinterpret_cast<BYTE const*>(data), size, pub_key, flags, &tmp ) )
		{
			DWORD const errc = GetLastError();
			STCRYPT_THROW_EXCEPTION( exception::cryptoapi_error() << exception::cryptoapi_einfo(errc) );
		}

		std::auto_ptr<HCRYPTKEY> HCRYPTKEY_mem;
		try {
			HCRYPTKEY_mem.reset(new HCRYPTKEY(tmp));
		}catch(...){
			BOOL const r = CryptDestroyKey(tmp); assert(r);
			throw;
		}

		return cryptkey_ptr_t  ( HCRYPTKEY_mem.release(), delete_HCRYPTKEY );
	}
static void setup_x509_schannel_create_mocks(void)
{
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is creating the handle storage space*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("certificate", 0, CRYPT_STRING_ANY, NULL, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "how big is the certificate binary size?"*/
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is creating the binary storage for the certificate*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("certificate", 0, CRYPT_STRING_ANY, IGNORED_PTR_ARG, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "fill in the certificate in this binary buffer"*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("private key", 0, CRYPT_STRING_ANY, NULL, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "how big is the private key binary size?"*/
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is creating the binary storage for the private key*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("private key", 0, CRYPT_STRING_ANY, IGNORED_PTR_ARG, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "fill in the private key in this binary buffer"*/
    STRICT_EXPECTED_CALL(CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, IGNORED_PTR_ARG, IGNORED_NUM_ARG, 0, NULL, NULL, IGNORED_PTR_ARG)); /*this is asking "how big is the decoded private key? (from binary)*/
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is allocating space for the decoded private key*/
    STRICT_EXPECTED_CALL(CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, IGNORED_PTR_ARG, IGNORED_NUM_ARG, 0, NULL, IGNORED_PTR_ARG, IGNORED_PTR_ARG)); /*this is asking "how big is the decoded private key? (from binary)*/
    STRICT_EXPECTED_CALL(CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, IGNORED_PTR_ARG, IGNORED_NUM_ARG)); /*create a certificate context from an encoded certificate*/
    STRICT_EXPECTED_CALL(CryptAcquireContextA(IGNORED_PTR_ARG, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)); /*this is acquire a handle to a key container within a cryptographic service provider*/
    STRICT_EXPECTED_CALL(CryptImportKey((HCRYPTPROV)IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_NUM_ARG, (HCRYPTKEY)NULL, 0, IGNORED_PTR_ARG)) /*tranferring the key from the blob to the cryptrographic key provider*/
        .IgnoreArgument_hProv();
    STRICT_EXPECTED_CALL(CertSetCertificateContextProperty(IGNORED_PTR_ARG, CERT_KEY_PROV_HANDLE_PROP_ID, 0, IGNORED_PTR_ARG)); /*give the private key*/
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
}
Beispiel #16
0
void checkSig(unsigned char *tucHashBuf,
			  unsigned char *tucSignature, DWORD dwSignatureLen,
			  unsigned char *tucPubKeyBlob, DWORD dwPubKeyBlobLen)
{
	HCRYPTPROV hProv;
	HCRYPTKEY hPubKey;
	HCRYPTHASH hHash;
	DWORD err;
	int errors = 0;

	if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0))
		ERR_LOG_RET("CryptAcquireContext()");

	if (!CryptImportKey(hProv, tucPubKeyBlob, dwPubKeyBlobLen, 0, 0, &hPubKey))
		ERR_LOG_RET("CryptImportKey()");

	if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
		ERR_LOG_RET("CryptCreateHash(CALG_MD5)");

	if (!CryptSetHashParam(hHash, HP_HASHVAL, tucHashBuf, 0))
		ERR_LOG_RET("CryptSetHashParam(HP_HASHVAL)");

	if (!CryptVerifySignature(hHash, tucSignature, dwSignatureLen, hPubKey, NULL, 0))
	{
		err = GetLastError();
		printf("ERR (line %d): CryptVerifySignature() returned %s (0x%0x)\n", __LINE__, e2str(err), err);
		errors++;
	}

	if (!CryptDestroyHash(hHash))
		ERR_LOG_RET("CryptDestroyHash()");

	if (!CryptDestroyKey(hPubKey))
		ERR_LOG_RET("CryptDestroyKey()");

	CryptReleaseContext(hProv, 0);

done:
	return;
}
Beispiel #17
0
bool mod_crypto::genericDecrypt(BYTE * data, SIZE_T dataSize, const BYTE * key, SIZE_T keySize, ALG_ID algorithme, BYTE * destBuffer, SIZE_T destBufferSize)
{
	bool retour = false;
	HCRYPTPROV hCryptProv = NULL; 
	HCRYPTKEY hKey = NULL;
	PBYTE buffer = data;
	DWORD dwWorkingBufferLength = dataSize;
	
	if(destBuffer && destBufferSize >= dataSize)
	{
		RtlCopyMemory(destBuffer, data, dataSize);
		buffer = destBuffer;
	}
	
	if((algorithme == CALG_RC4) && (keySize > 16))
	{
		fullRC4(buffer, dataSize, key, keySize);
		retour = true;
	}
	else
	{
		if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
		{
			GENERICKEY_BLOB myKeyHead = {{PLAINTEXTKEYBLOB, CUR_BLOB_VERSION, 0, algorithme}, keySize};
			BYTE * myKey = new BYTE[sizeof(GENERICKEY_BLOB) + keySize];
			RtlCopyMemory(myKey, &myKeyHead, sizeof(GENERICKEY_BLOB));
			RtlCopyMemory(myKey + sizeof(GENERICKEY_BLOB), key, keySize);

			if(CryptImportKey(hCryptProv, myKey, sizeof(GENERICKEY_BLOB) + keySize, 0, CRYPT_EXPORTABLE, &hKey))
			{
				if(CryptDecrypt(hKey, NULL, TRUE, 0, buffer, &dwWorkingBufferLength) || ((algorithme == CALG_DES) && (GetLastError() == NTE_BAD_DATA))) // évite les erreurs de parités http://support.microsoft.com/kb/331367/
					retour = (dwWorkingBufferLength == dataSize);
				CryptDestroyKey(hKey);
			}
			delete[] myKey;
			CryptReleaseContext(hCryptProv, 0);
		}
	}
	return retour;
}
Beispiel #18
0
BOOL WINAPI CryptGenKeyHook(_In_ HCRYPTPROV hProv,
                            _In_ ALG_ID Algid,
                            _In_ DWORD dwFlags,
                            _Out_ HCRYPTKEY* phKey) {
  fputs("In CryptGenKeyHook...", log);

  DWORD keySize = dwFlags >> 16;
  if (keySize) {
    BYTE* keyBlob;
    DWORD keyBlobSize;
    if (GenWeakKey(keySize, Algid, &keyBlob, &keyBlobSize)) {
      fprintf(log, "Generate weak key, size: %d, blob: %d\n", keySize,
              keyBlobSize);
      fflush(log);
      return CryptImportKey(hProv, keyBlob, keyBlobSize, 0, 0, phKey);
    }
  }

  fputs("Using true CryptGenKey...", log);
  fflush(log);
  return SavedCryptGenKey(hProv, Algid, dwFlags, phKey);
}
Beispiel #19
0
void CKeyPair::LoadFromFile(PCHAR szFileName) 
{

	DWORD dwKeySize;
	BYTE *pbKeyBlob;
	FILE *fiKey;

	// Load the private key from a file
	fopen_s(&fiKey, (CHAR*)szFileName, "rb");
	fread(&dwKeySize, sizeof(dwKeySize), 1, fiKey);
	pbKeyBlob = new BYTE[dwKeySize];
	fread(pbKeyBlob, 1, dwKeySize, fiKey);
	fclose(fiKey);

	// Load the key pair
	HCRYPTPROV hCryptProv = m_pContext->GetProvider();
	CryptImportKey(hCryptProv, pbKeyBlob, dwKeySize, NULL, CRYPT_EXPORTABLE, &m_hCryptKey);

	// Clean up memory
	delete[] pbKeyBlob;

}
CryptAES::CryptAES(BYTE *pKey, BYTE *pIV)
{
    this->hProv = NULL;
    this->hKey = NULL;

    if (CryptAcquireContext(&this->hProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) {
        AESKEY128 AESBlob;

        for (int i = 0; i < 16; i++)
            AESBlob.pKey[i] = pKey[i];

        CryptImportKey(this->hProv, reinterpret_cast<BYTE*>(&AESBlob), sizeof(AESBlob), NULL, 0, &this->hKey);

        if (this->hKey) {
            DWORD dwMode = CRYPT_MODE_CBC,
                  dwPadding = PKCS5_PADDING;
            CryptSetKeyParam(this->hKey, KP_IV, pIV, 0);
            CryptSetKeyParam(this->hKey, KP_MODE, reinterpret_cast<BYTE*>(&dwMode), 0);
            CryptSetKeyParam(this->hKey, KP_PADDING, reinterpret_cast<BYTE*>(&dwPadding), 0);
        }
    }
}
Beispiel #21
0
//-----------------------------------------------------------------------------
// swCreateAESKeyFromKeyData()
//-----------------------------------------------------------------------------
// Crée la clé AES à partir de données de la clé (256 bits / 32 octets)
// et l'importe dans le ghProv
//-----------------------------------------------------------------------------
// [in] cszMasterPwd = mot de passe maitre
// [in/out] hKey = handle de clé
//-----------------------------------------------------------------------------
// Retour : 0 si OK
//-----------------------------------------------------------------------------
int swCreateAESKeyFromKeyData(BYTE *pAESKeyData,HCRYPTKEY *phKey)
{
	int iAESKeySize;
	KEYBLOB *pAESKey=NULL;
	BOOL brc;
	int rc=-1;
	TRACE((TRACE_ENTER,_F_,""));
	BYTE ZeroBuf[AES256_KEY_LEN];

	// 
	ZeroMemory(ZeroBuf,AES256_KEY_LEN);
	if (memcmp(pAESKeyData,ZeroBuf,AES256_KEY_LEN)==0) 
	{
		TRACE((TRACE_ERROR,_F_,"pAESKeyData is zerobuf")); 
		goto end;
	}

	// Crée la clé AES
	iAESKeySize=sizeof(KEYBLOB)+AES256_KEY_LEN;
	pAESKey=(KEYBLOB*)malloc(iAESKeySize);
	if (pAESKey==NULL) { TRACE((TRACE_ERROR,_F_,"malloc(%d)",iAESKeySize)); goto end; }
	ZeroMemory(pAESKey,iAESKeySize);
	pAESKey->header.bType=PLAINTEXTKEYBLOB;
	pAESKey->header.bVersion=CUR_BLOB_VERSION;
	pAESKey->header.reserved=0;
	pAESKey->header.aiKeyAlg=CALG_AES_256;
	pAESKey->dwKeySize=AES256_KEY_LEN;
	memcpy(pAESKey->KeyData,pAESKeyData,AES256_KEY_LEN);
	TRACE_BUFFER((TRACE_DEBUG,_F_,(BYTE*)pAESKey,iAESKeySize,"pAESKey (iAESKeySize=%d)",iAESKeySize));
	brc= CryptImportKey(ghProv,(LPBYTE)pAESKey,iAESKeySize,NULL,0,phKey);
	if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptImportKey()=0x%08lx",GetLastError())); goto end; }
	rc=0;
end:
	if (pAESKey!=NULL) free(pAESKey);
	TRACE((TRACE_LEAVE,_F_,"rc=%d",rc));
	return rc;
}
Beispiel #22
0
void kuhl_m_iis_apphost_provider_decrypt(int argc, wchar_t * argv[], PCWSTR keyContainerName, BOOL isMachine, LPCBYTE sessionKey, DWORD szSessionKey, LPCBYTE data, DWORD szData)
{
	BOOL isLive;
	PBYTE liveData;
	DWORD szLiveData, szPvk;
	HCRYPTPROV hProv;
	HCRYPTKEY hKey = 0, hSessionKey;
	PPVK_FILE_HDR pvk = NULL;
	PCWSTR pvkName = NULL;

	isLive = kull_m_string_args_byName(argc, argv, L"live", NULL, NULL);
	if(!kull_m_string_args_byName(argc, argv, keyContainerName, &pvkName, NULL))
		kull_m_string_args_byName(argc, argv, L"pvk", &pvkName, NULL);

	if(isLive || pvkName)
	{
		if(liveData = (PBYTE) LocalAlloc(LPTR, szData))
		{
			RtlCopyMemory(liveData, data, szData);
			szLiveData = szData;
			if(isLive)
				kprintf(L"  | Live Key  : %s - %s : ", keyContainerName, isMachine ? L"machine" : L"user");
			if(CryptAcquireContext(&hProv, isLive ? keyContainerName : NULL, (MIMIKATZ_NT_BUILD_NUMBER <= KULL_M_WIN_BUILD_XP) ? MS_ENH_RSA_AES_PROV_XP : MS_ENH_RSA_AES_PROV , PROV_RSA_AES, (isLive ? 0 : CRYPT_VERIFYCONTEXT) | (isMachine ? CRYPT_MACHINE_KEYSET : 0)))
			{
				if(isLive)
					kprintf(L"OK\n");
				else
				{

					if(kull_m_file_readData(pvkName, (PBYTE *) &pvk, &szPvk))
					{
						kprintf(L"  | PVK file  : %s - \'%s\' : ", keyContainerName, pvkName);
						if(CryptImportKey(hProv, (PBYTE) pvk + sizeof(PVK_FILE_HDR), pvk->cbPvk, 0, 0, &hKey))
							kprintf(L"OK\n");
						else PRINT_ERROR_AUTO(L"CryptImportKey (RSA)");
					}
				}
				if(isLive || hKey)
				{
					if(CryptImportKey(hProv, sessionKey, szSessionKey, hKey, 0, &hSessionKey))
					{
						if(CryptDecrypt(hSessionKey, 0, FALSE, 0, liveData, &szLiveData))
						{
							kprintf(L"  | Password  : %s\n", liveData + sizeof(DWORD) /*CRC32 ? Random ?*/);
						}
						else PRINT_ERROR_AUTO(L"CryptDecrypt");
						CryptDestroyKey(hSessionKey);
					}
					else PRINT_ERROR_AUTO(L"CryptImportKey (session)");
				}
				if(!isLive)
				{
					if(hKey)
						CryptDestroyKey(hKey);
					if(pvk)
						LocalFree(pvk);
				}
				CryptReleaseContext(hProv, 0);
			}
			else PRINT_ERROR_AUTO(L"CryptAcquireContext");
			LocalFree(liveData);
		}
	}
}
Beispiel #23
0
/**
 * Calculates the HMAC of the given message, hashtype, and hashkey.
 * dest must be at least the hash length.
 */
int create_hmac(int hashtype, const unsigned char *key, unsigned int keylen,
                const unsigned char *src, unsigned int srclen,
                unsigned char *dest, unsigned int *destlen)
{
    // TODO: right now we reimport the hmac key each time.  Test to see if this
    // is quick enough or if we need to cache an imported hmac key.
    HCRYPTKEY hmackey;
    HCRYPTHASH hash;
    char keyblob[BLOBLEN];
    BLOBHEADER *bheader;
    DWORD *keysize;
    BYTE *keydata;
    HMAC_INFO info;
    ALG_ID alg;
    int bloblen, hashlen, rval;
    DWORD _destlen;

    hashlen = get_hash_len(hashtype);
    alg = get_hash(hashtype);

    bheader = (BLOBHEADER *)keyblob;
    keysize = (DWORD *)(keyblob + sizeof(BLOBHEADER));
    keydata = (BYTE *)((char *)keysize + sizeof(DWORD));

    memset(keyblob, 0, sizeof(keyblob));
    bheader->bType = PLAINTEXTKEYBLOB;
    bheader->bVersion = CUR_BLOB_VERSION;
    bheader->aiKeyAlg = CALG_RC2;
    *keysize = keylen;
    memcpy(keydata, key, keylen);
    bloblen = sizeof(BLOBHEADER) + sizeof(DWORD) + hashlen;

    if (!CryptImportKey(base_prov, keyblob, bloblen, 0,
                        CRYPT_IPSEC_HMAC_KEY, &hmackey)) {
        mserror("CryptImportKey failed");
        return 0;
    }

    if (!CryptCreateHash(base_prov, CALG_HMAC, hmackey, 0, &hash)) {
        mserror("CryptCreateHash failed");
        rval = 0;
        goto end1;
    }
    memset(&info, 0, sizeof(info));
    info.HashAlgid = alg;
    if (!CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&info, 0)) {
        mserror("CryptSetHashParam failed");
        rval = 0;
        goto end2;
    }
    if (!CryptHashData(hash, src, srclen, 0)) {
        mserror("CryptHashData failed");
        rval = 0;
        goto end2;
    }
    _destlen = hashlen;
    if (!CryptGetHashParam(hash, HP_HASHVAL, dest, &_destlen, 0)) {
        mserror("CryptGetHashParam failed");
        rval = 0;
        goto end2;
    }
    *destlen = _destlen;
    rval = 1;

end2:
    if (!CryptDestroyHash(hash)) {
        mserror("CryptDestroyHash failed");
    }
end1:
    if (!CryptDestroyKey(hmackey)) {
        mserror("CryptDestroyKey failed");
    }
    return rval;
}
Beispiel #24
0
/**
 * Takes a block of data encrypted with a symmetric cypher and decrypts it.
 * The output buffer must be at least the size of source data.
 */
int decrypt_block(int keytype, const unsigned char *IV,
                  const unsigned char *key,
                  const unsigned char *src, unsigned int srclen,
                  unsigned char *dest, unsigned int *destlen)
{
    // TODO: right now we reimport the key each time.  Test to see if this
    // is quick enough or if we need to cache an imported key.
    HCRYPTKEY hckey;
    char keyblob[BLOBLEN];
    BLOBHEADER *bheader;
    DWORD *keysize;
    BYTE *keydata;
    int bloblen, keylen, ivlen, rval;
    ALG_ID alg;
    DWORD mode, _destlen;

    get_key_info(keytype, &keylen, &ivlen);
    alg = get_cipher(keytype);

    bheader = (BLOBHEADER *)keyblob;
    keysize = (DWORD *)(keyblob + sizeof(BLOBHEADER));
    keydata = (BYTE *)((char *)keysize + sizeof(DWORD));

    memset(keyblob, 0, sizeof(keyblob));
    bheader->bType = PLAINTEXTKEYBLOB;
    bheader->bVersion = CUR_BLOB_VERSION;
    bheader->aiKeyAlg = alg;
    *keysize = keylen;
    memcpy(keydata, key, keylen);
    bloblen = sizeof(BLOBHEADER) + sizeof(DWORD) + keylen;

    if (!CryptImportKey(base_prov, keyblob, bloblen, 0, 0, &hckey)) {
        mserror("CryptImportKey failed");
        return 0;
    }

    mode = CRYPT_MODE_CBC;
    if (!CryptSetKeyParam(hckey, KP_MODE, (BYTE *)&mode, 0)) {
        mserror("CryptSetKeyParam failed on KP_MODE");
        rval = 0;
        goto end;
    }
    if (!CryptSetKeyParam(hckey, KP_IV, IV, 0)) {
        mserror("CryptSetKeyParam failed on KP_IV");
        rval = 0;
        goto end;
    }
    memcpy(dest, src, srclen);
    _destlen = srclen;
    if (!CryptDecrypt(hckey, 0, 1, 0, dest, &_destlen)) {
        mserror("CryptDecrypt failed");
        rval = 0;
        goto end;
    }
    *destlen = _destlen;
    rval = 1;

end:
    if (!CryptDestroyKey(hckey)) {
        mserror("CryptDestroyKey failed");
    }
    return rval;
}
Beispiel #25
0
BOOL CCrypto::Initialize(CHAR* szKeyFile)
{			
	DWORD	dwResult;
	errno_t err;
	FILE* fp;

	m_cbBlob = file_length(szKeyFile);
	m_pbBlob = (BYTE*)malloc(m_cbBlob + 1);
	memset(m_pbBlob, 0, m_cbBlob + 1); 

	err = fopen_s(&fp, szKeyFile, "rb");
	if (err == 0) 
	{
		fread(m_pbBlob, 1, m_cbBlob, fp);
		fclose(fp);
	} 
	else 
	{
		free(m_pbBlob);
		m_pbBlob = NULL;
	}

	if (!CryptAcquireContext(&m_hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, 0))
	{
		dwResult = GetLastError();
		if (dwResult == NTE_BAD_KEYSET)
		{
			if (!CryptAcquireContext(&m_hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
			{
				dwResult = GetLastError();
				//MessageBox(_T("Error [0x%x]: CryptAcquireContext() failed."), _T("Information"), MB_OK);
				return FALSE;
			}
		} else {
			dwResult = GetLastError();
			return FALSE;
		}
	}

	if (m_pbBlob)
	{
		if (!CryptImportKey(m_hProv, m_pbBlob, m_cbBlob, 0, 0, &m_hSessionKey))
		{
			dwResult = GetLastError();
			//MessageBox(_T("Error [0x%x]: CryptImportKey() failed."), "Information", MB_OK);
			return FALSE;
		}
	} 
	else 
	{ 
		if (!CryptImportKey(m_hProv, PrivateKeyWithExponentOfOne, sizeof(PrivateKeyWithExponentOfOne), 0, 0, &m_hKey))
		{
			dwResult = GetLastError();
			//MessageBox(_T("Error CryptImportKey() failed."), _T("Information"), MB_OK);
			return FALSE;
		}

		if (!CryptGenKey(m_hProv, CALG_RC4, CRYPT_EXPORTABLE, &m_hSessionKey))
		{
			dwResult = GetLastError();
			//MessageBox(_T("Error CryptGenKey() failed."), _T("Information"), MB_OK);
			return FALSE;
		}	
	}

	return TRUE;
}
Beispiel #26
0
int CSteamProto::RsaEncrypt(const char *pszModulus, const char *data, BYTE *encryptedData, DWORD &encryptedSize)
{
	DWORD cchModulus = (DWORD)mir_strlen(pszModulus);
	int result = 0;
	BYTE *pbBuffer = 0;
	BYTE *pKeyBlob = 0;
	HCRYPTKEY phKey = 0;
	HCRYPTPROV hCSP = 0;

	// convert hex string to byte array
	DWORD cbLen = 0, dwSkip = 0, dwFlags = 0;
	if (!CryptStringToBinaryA(pszModulus, cchModulus, CRYPT_STRING_HEX, NULL, &cbLen, &dwSkip, &dwFlags))
	{
		result = GetLastError();
		goto exit;
	}

	// allocate a new buffer.
	pbBuffer = (BYTE*)malloc(cbLen);
	if (!CryptStringToBinaryA(pszModulus, cchModulus, CRYPT_STRING_HEX, pbBuffer, &cbLen, &dwSkip, &dwFlags))
	{
		result = GetLastError();
		goto exit;
	}

	// reverse byte array, because of microsoft
	for (int i = 0; i < (int)(cbLen / 2); ++i)
	{
		BYTE temp = pbBuffer[cbLen - i - 1];
		pbBuffer[cbLen - i - 1] = pbBuffer[i];
		pbBuffer[i] = temp;
	}
	
	if (!CryptAcquireContext(&hCSP, NULL, NULL, PROV_RSA_AES, CRYPT_SILENT) &&
		!CryptAcquireContext(&hCSP, NULL, NULL, PROV_RSA_AES, CRYPT_SILENT | CRYPT_NEWKEYSET))
	{
		result = GetLastError();
		goto exit;
	}

	// Move the key into the key container.
	DWORD cbKeyBlob = sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) + cbLen;
	pKeyBlob = (BYTE*)malloc(cbKeyBlob);

	// Fill in the data.
	PUBLICKEYSTRUC *pPublicKey = (PUBLICKEYSTRUC*)pKeyBlob;
	pPublicKey->bType = PUBLICKEYBLOB; 
	pPublicKey->bVersion = CUR_BLOB_VERSION;  // Always use this value.
	pPublicKey->reserved = 0;                 // Must be zero.
	pPublicKey->aiKeyAlg = CALG_RSA_KEYX;     // RSA public-key key exchange. 

	// The next block of data is the RSAPUBKEY structure.
	RSAPUBKEY *pRsaPubKey = (RSAPUBKEY*)(pKeyBlob + sizeof(PUBLICKEYSTRUC));
	pRsaPubKey->magic = 0x31415352; // RSA1 // Use public key
	pRsaPubKey->bitlen = cbLen * 8;  // Number of bits in the modulus.
	pRsaPubKey->pubexp = 0x10001; // "010001" // Exponent.

	// Copy the modulus into the blob. Put the modulus directly after the
	// RSAPUBKEY structure in the blob.
	BYTE *pKey = (BYTE*)(((BYTE *)pRsaPubKey) + sizeof(RSAPUBKEY));
	//pKeyBlob + sizeof(BLOBHEADER)+ sizeof(RSAPUBKEY); 
	memcpy(pKey, pbBuffer, cbLen);

	// Now import public key	
	if (!CryptImportKey(hCSP, pKeyBlob, cbKeyBlob, 0, 0, &phKey))
	{
		result = GetLastError();
		goto exit;
	}

	DWORD dataSize = (DWORD)mir_strlen(data);

	// if data is not allocated just renurn size
	if (encryptedData == NULL)
	{
		// get length of encrypted data
		if (!CryptEncrypt(phKey, 0, TRUE, 0, NULL, &encryptedSize, dataSize))
			result = GetLastError();
		goto exit;
	}

	// encrypt password
	memcpy(encryptedData, data, dataSize);
	if (!CryptEncrypt(phKey, 0, TRUE, 0, encryptedData, &dataSize, encryptedSize))
	{
		result = GetLastError();
		goto exit;
	}

	// reverse byte array again
	for (int i = 0; i < (int)(encryptedSize / 2); ++i)
	{
		BYTE temp = encryptedData[encryptedSize - i - 1];
		encryptedData[encryptedSize - i - 1] = encryptedData[i];
		encryptedData[i] = temp;
	}

exit:
	if (pKeyBlob)
		free(pKeyBlob);
	if (phKey)
		CryptDestroyKey(phKey);
	
	if (pbBuffer)
		free(pbBuffer);
	if (hCSP)
		CryptReleaseContext(hCSP, 0);

	return 0;
}
Beispiel #27
0
static void testAcquireSecurityContext(void)
{
    BOOL has_schannel = FALSE;
    SecPkgInfoA *package_info;
    ULONG i;
    SECURITY_STATUS st;
    CredHandle cred;
    SecPkgCredentials_NamesA names;
    TimeStamp exp;
    SCHANNEL_CRED schanCred;
    PCCERT_CONTEXT certs[2];
    HCRYPTPROV csp;
    WCHAR ms_def_prov_w[MAX_PATH];
    BOOL ret;
    HCRYPTKEY key;
    CRYPT_KEY_PROV_INFO keyProvInfo;

    if (!pAcquireCredentialsHandleA ||
        !pEnumerateSecurityPackagesA || !pFreeContextBuffer ||
        !pFreeCredentialsHandle)
    {
        win_skip("Needed functions are not available\n");
        return;
    }

    if (SUCCEEDED(pEnumerateSecurityPackagesA(&i, &package_info)))
    {
        while(i--)
        {
            if (!strcmp(package_info[i].Name, unisp_name_a))
            {
                has_schannel = TRUE;
                break;
            }
        }
        pFreeContextBuffer(package_info);
    }
    if (!has_schannel)
    {
        skip("Schannel not available\n");
        return;
    }

    lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W);

    keyProvInfo.pwszContainerName = cspNameW;
    keyProvInfo.pwszProvName = ms_def_prov_w;
    keyProvInfo.dwProvType = PROV_RSA_FULL;
    keyProvInfo.dwFlags = 0;
    keyProvInfo.cProvParam = 0;
    keyProvInfo.rgProvParam = NULL;
    keyProvInfo.dwKeySpec = AT_SIGNATURE;

    certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
    certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert, sizeof(selfSignedCert));

    SetLastError(0xdeadbeef);
    ret = CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
     CRYPT_DELETEKEYSET);
    if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
    {
        /* WinMe would crash on some tests */
        win_skip("CryptAcquireContextW is not implemented\n");
        return;
    }

    st = pAcquireCredentialsHandleA(NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL,
     NULL);
    ok(st == SEC_E_SECPKG_NOT_FOUND,
     "Expected SEC_E_SECPKG_NOT_FOUND, got %08x\n", st);
    if (0)
    {
        /* Crashes on Win2K */
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, 0, NULL, NULL, NULL,
         NULL, NULL, NULL);
        ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);

        /* Crashes on WinNT */
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_BOTH, NULL,
         NULL, NULL, NULL, NULL, NULL);
        ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);

        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
         NULL, NULL, NULL, NULL, NULL, NULL);
        ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);

        /* Crashes */
        pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
         NULL, NULL, NULL, NULL, NULL, NULL);
    }
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
     NULL, NULL, NULL, NULL, &cred, NULL);
    ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
    if(st == SEC_E_OK)
        pFreeCredentialsHandle(&cred);
    memset(&cred, 0, sizeof(cred));
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
     NULL, NULL, NULL, NULL, &cred, &exp);
    ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
    /* expriy is indeterminate in win2k3 */
    trace("expiry: %08x%08x\n", exp.HighPart, exp.LowPart);

    st = pQueryCredentialsAttributesA(&cred, SECPKG_CRED_ATTR_NAMES, &names);
    ok(st == SEC_E_NO_CREDENTIALS || st == SEC_E_UNSUPPORTED_FUNCTION /* before Vista */, "expected SEC_E_NO_CREDENTIALS, got %08x\n", st);

    pFreeCredentialsHandle(&cred);

    /* Bad version in SCHANNEL_CRED */
    memset(&schanCred, 0, sizeof(schanCred));
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
     NULL, &schanCred, NULL, NULL, NULL, NULL);
    ok(st == SEC_E_INTERNAL_ERROR ||
       st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */ ||
       st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
     NULL, &schanCred, NULL, NULL, NULL, NULL);
    ok(st == SEC_E_INTERNAL_ERROR ||
       st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */ ||
       st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);

    /* No cert in SCHANNEL_CRED succeeds for outbound.. */
    schanCred.dwVersion = SCHANNEL_CRED_VERSION;
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
     NULL, &schanCred, NULL, NULL, &cred, NULL);
    ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
    pFreeCredentialsHandle(&cred);
    /* but fails for inbound. */
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
     NULL, &schanCred, NULL, NULL, &cred, NULL);
    ok(st == SEC_E_NO_CREDENTIALS ||
       st == SEC_E_OK /* Vista/win2k8 */,
       "Expected SEC_E_NO_CREDENTIALS or SEC_E_OK, got %08x\n", st);

    if (0)
    {
        /* Crashes with bad paCred pointer */
        schanCred.cCreds = 1;
        pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
         NULL, &schanCred, NULL, NULL, NULL, NULL);
    }

    /* Bogus cert in SCHANNEL_CRED. Windows fails with
     * SEC_E_UNKNOWN_CREDENTIALS, but I'll accept SEC_E_NO_CREDENTIALS too.
     */
    schanCred.cCreds = 1;
    schanCred.paCred = &certs[0];
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
     NULL, &schanCred, NULL, NULL, NULL, NULL);
    ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
       st == SEC_E_NO_CREDENTIALS ||
       st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
     NULL, &schanCred, NULL, NULL, NULL, NULL);
    ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
       st == SEC_E_NO_CREDENTIALS ||
       st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);

    /* Good cert, but missing private key. Windows fails with
     * SEC_E_NO_CREDENTIALS, but I'll accept SEC_E_UNKNOWN_CREDENTIALS too.
     */
    schanCred.cCreds = 1;
    schanCred.paCred = &certs[1];
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
     NULL, &schanCred, NULL, NULL, &cred, NULL);
    ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_NO_CREDENTIALS ||
       st == SEC_E_INTERNAL_ERROR, /* win2k */
     "Expected SEC_E_UNKNOWN_CREDENTIALS, SEC_E_NO_CREDENTIALS "
     "or SEC_E_INTERNAL_ERROR, got %08x\n", st);
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
     NULL, &schanCred, NULL, NULL, NULL, NULL);
    ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_NO_CREDENTIALS ||
       st == SEC_E_INTERNAL_ERROR, /* win2k */
     "Expected SEC_E_UNKNOWN_CREDENTIALS, SEC_E_NO_CREDENTIALS "
     "or SEC_E_INTERNAL_ERROR, got %08x\n", st);

    /* Good cert, with CRYPT_KEY_PROV_INFO set before it's had a key loaded. */
    ret = CertSetCertificateContextProperty(certs[1],
          CERT_KEY_PROV_INFO_PROP_ID, 0, &keyProvInfo);
    schanCred.dwVersion = SCH_CRED_V3;
    ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError());
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
        NULL, &schanCred, NULL, NULL, &cred, NULL);
    ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_INTERNAL_ERROR /* WinNT */,
       "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_INTERNAL_ERROR, got %08x\n", st);
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
        NULL, &schanCred, NULL, NULL, &cred, NULL);
    ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_INTERNAL_ERROR /* WinNT */,
        "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_INTERNAL_ERROR, got %08x\n", st);

    ret = CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
     CRYPT_NEWKEYSET);
    ok(ret, "CryptAcquireContextW failed: %08x\n", GetLastError());
    ret = 0;

    ret = CryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
    ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
    if (ret)
    {
        PCCERT_CONTEXT tmp;

        if (0)
        {
            /* Crashes */
            pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
             NULL, &schanCred, NULL, NULL, NULL, NULL);

            /* Crashes on WinNT */
            /* Good cert with private key, bogus version */
            schanCred.dwVersion = SCH_CRED_V1;
            st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
                NULL, &schanCred, NULL, NULL, &cred, NULL);
            ok(st == SEC_E_INTERNAL_ERROR ||
                st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
                "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
            st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
                NULL, &schanCred, NULL, NULL, &cred, NULL);
            ok(st == SEC_E_INTERNAL_ERROR ||
                st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
                "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
            schanCred.dwVersion = SCH_CRED_V2;
            st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
                NULL, &schanCred, NULL, NULL, &cred, NULL);
            ok(st == SEC_E_INTERNAL_ERROR ||
                st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
                "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
            st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
                NULL, &schanCred, NULL, NULL, &cred, NULL);
            ok(st == SEC_E_INTERNAL_ERROR ||
                st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
                "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
        }

        /* Succeeds on V3 or higher */
        schanCred.dwVersion = SCH_CRED_V3;
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
         NULL, &schanCred, NULL, NULL, &cred, NULL);
        ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
        pFreeCredentialsHandle(&cred);
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
         NULL, &schanCred, NULL, NULL, &cred, NULL);
        ok(st == SEC_E_OK ||
           st == SEC_E_UNKNOWN_CREDENTIALS, /* win2k3 */
           "AcquireCredentialsHandleA failed: %08x\n", st);
        pFreeCredentialsHandle(&cred);
        schanCred.dwVersion = SCHANNEL_CRED_VERSION;
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
         NULL, &schanCred, NULL, NULL, &cred, NULL);
        ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
        pFreeCredentialsHandle(&cred);
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
         NULL, &schanCred, NULL, NULL, &cred, NULL);
        ok(st == SEC_E_OK ||
           st == SEC_E_UNKNOWN_CREDENTIALS, /* win2k3 */
           "AcquireCredentialsHandleA failed: %08x\n", st);
        if (st == SEC_E_OK) test_strength(&cred);
        pFreeCredentialsHandle(&cred);

        /* How about more than one cert? */
        schanCred.cCreds = 2;
        schanCred.paCred = certs;
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
         NULL, &schanCred, NULL, NULL, &cred, NULL);
        ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
           st == SEC_E_NO_CREDENTIALS /* Vista/win2k8 */ ||
           st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
         NULL, &schanCred, NULL, NULL, &cred, NULL);
        ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
           st == SEC_E_NO_CREDENTIALS ||
           st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
        tmp = certs[0];
        certs[0] = certs[1];
        certs[1] = tmp;
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
         NULL, &schanCred, NULL, NULL, &cred, NULL);
        ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
           st == SEC_E_NO_CREDENTIALS ||
           st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
         NULL, &schanCred, NULL, NULL, &cred, NULL);
        ok(st == SEC_E_UNKNOWN_CREDENTIALS,
         "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
        /* FIXME: what about two valid certs? */

        CryptDestroyKey(key);
    }

    CryptReleaseContext(csp, 0);
    CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_DELETEKEYSET);

    CertFreeCertificateContext(certs[0]);
    CertFreeCertificateContext(certs[1]);
}
Beispiel #28
0
bool vmsSecurity::VerifySign(LPCTSTR ptszFile, LPCTSTR ptszPubKey)
{
	HCRYPTPROV hProv = NULL;
	BOOL bOK = CryptAcquireContext (&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);	
	if (!bOK)
		return false;
	
	BYTE abKey [1000];
	DWORD dwKeySize;
	
	HANDLE h = CreateFile (ptszPubKey, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (h == INVALID_HANDLE_VALUE)
		return false;
	ReadFile (h, abKey, sizeof (abKey), &dwKeySize, NULL);
	CloseHandle (h);
	
	HCRYPTKEY hKey;
	if (FALSE == CryptImportKey (hProv, abKey, dwKeySize, NULL, 0, &hKey))
		return false;
	
	LPBYTE pbData;
	DWORD dwDataSize;
	
	h = CreateFile (ptszFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (h == INVALID_HANDLE_VALUE)
		return FALSE;
	dwDataSize = GetFileSize (h, NULL);
	if (dwDataSize < strlen (FdmCryptSignatureMarker))
	{
		CloseHandle (h);
		return false;
	}
	pbData = new BYTE [dwDataSize];
	DWORD dw;
	ReadFile (h, pbData, dwDataSize, &dw, NULL);
	CloseHandle (h);
	
	int nSigLen = strlen (FdmCryptSignatureMarker);
	LPBYTE pbSig = pbData + dwDataSize - nSigLen;
	while (pbSig != pbData && strncmp ((char*)pbSig, FdmCryptSignatureMarker, nSigLen) != 0)
		pbSig--;
	if (pbData == pbSig)
	{
		delete [] pbData;
		return false;
	}
	
	HCRYPTHASH hHash;
	if (FALSE == CryptCreateHash (hProv, CALG_MD5, 0, 0, &hHash))
		return false;
	
	if (FALSE == CryptHashData (hHash, pbData, pbSig - pbData, 0))
		return false;
	
	BOOL bResult = CryptVerifySignature (hHash, pbSig + nSigLen,
		pbData + dwDataSize - pbSig - nSigLen, hKey, NULL, 0);
		
	CryptDestroyHash (hHash);
	
	delete [] pbData;
	
	CryptDestroyKey (hKey);
	
	CryptReleaseContext (hProv, 0);
	
	return bResult != FALSE;
}
DWORD aes_Decrypt(LPBYTE key, DWORD SizeKey, LPBYTE iv, LPBYTE Data, LPDWORD SizeData)
{
    HCRYPTPROV provider = NULL;
    HCRYPTKEY hKey = NULL;
    DWORD Result = -1;

    do {
        if (!OpenCryptContext(&provider)) {
            xstrerror("CryptAcquireContext()");
            break;
        }

        // 创建 Key
        struct keyBlob {
            BLOBHEADER hdr;
            DWORD cbKeySize;
            BYTE rgbKeyData[32];                // FOR AES-256 = 32
        } keyBlob;
        keyBlob.hdr.bType = PLAINTEXTKEYBLOB;
        keyBlob.hdr.bVersion = CUR_BLOB_VERSION;
        keyBlob.hdr.reserved = 0;
        keyBlob.hdr.aiKeyAlg = CALG_AES_256;    // FOR AES-256 = CALG_AES_256
        keyBlob.cbKeySize = 32;                    // FOR AES-256 = 32
        CopyMemory(keyBlob.rgbKeyData, key, keyBlob.cbKeySize);

        if (!CryptImportKey(provider, (BYTE*)(&keyBlob), sizeof(keyBlob), NULL, 0, &hKey)) {
            break;
        }

        DWORD dwMode = CRYPT_MODE_CBC, dwPadding = PKCS5_PADDING;

        if (!CryptSetKeyParam(hKey, KP_IV, (BYTE*)iv, 0)) {
            break;
        }

        if (!CryptSetKeyParam(hKey, KP_MODE, reinterpret_cast<BYTE*>(&dwMode), 0)) {
            break;
        }

        if (!CryptSetKeyParam(hKey, KP_PADDING, reinterpret_cast<BYTE*>(&dwPadding), 0)) {
            break;
        }

        if (!CryptDecrypt(hKey, NULL, TRUE, 0, Data, SizeData)) {
            xstrerror("CryptDecrypt()");
            break;
        }

        Result = *SizeData; // Set return value to the decrypted data size
    } while (0);

    if (hKey != NULL) {
        CryptDestroyKey(hKey);
    }

    if (provider != NULL)   {
        CryptReleaseContext(provider, 0);
    }

    return Result;
}
DWORD aes_Encrypt(LPBYTE key, DWORD SizeKey, LPBYTE iv, LPBYTE InData, DWORD SizeInData, LPBYTE *OutData)
{
    HCRYPTPROV provider = NULL;
    HCRYPTKEY hKey = NULL;
    DWORD SizeData = SizeInData;
    DWORD SizeBuffer = 0;
    DWORD Result = -1;

    do {
        if (!OpenCryptContext(&provider)) {
            xstrerror("CryptAcquireContext()");
            break;
        }

        // 创建 Key
        struct keyBlob {
            BLOBHEADER hdr;
            DWORD cbKeySize;
            BYTE rgbKeyData[32];                // FOR AES-256 = 32
        } keyBlob;
        keyBlob.hdr.bType = PLAINTEXTKEYBLOB;
        keyBlob.hdr.bVersion = CUR_BLOB_VERSION;
        keyBlob.hdr.reserved = 0;
        keyBlob.hdr.aiKeyAlg = CALG_AES_256;    // FOR AES-256 = CALG_AES_256
        keyBlob.cbKeySize = 32;                    // FOR AES-256 = 32
        CopyMemory(keyBlob.rgbKeyData, key, keyBlob.cbKeySize);

        if (!CryptImportKey(provider, (BYTE*)(&keyBlob), sizeof(keyBlob), NULL, 0, &hKey)) {
            break;
        }

        DWORD dwMode = CRYPT_MODE_CBC, dwPadding = PKCS5_PADDING;

        if (!CryptSetKeyParam(hKey, KP_IV, (BYTE*)iv, 0)) {
            break;
        }

        if (!CryptSetKeyParam(hKey, KP_MODE, reinterpret_cast<BYTE*>(&dwMode), 0)) {
            break;
        }

        if (!CryptSetKeyParam(hKey, KP_PADDING, reinterpret_cast<BYTE*>(&dwPadding), 0)) {
            break;
        }

        DWORD block_size = GetCipherBlockSize(hKey);
        DWORD data_len = SizeInData;
        SizeBuffer = data_len + block_size;
        *OutData = (LPBYTE)xmalloc(SizeBuffer);

        if (*OutData == NULL)
            break;

        memcpy(*OutData, InData, SizeInData);

        if (!CryptEncrypt(hKey, NULL, TRUE, 0, *OutData, &SizeData, SizeBuffer)) {
            xstrerror("CryptEncrypt()");
            break;
        }

        Result = SizeData;
    } while (0);

    if (hKey != NULL) {
        CryptDestroyKey(hKey);
    }

    if (provider != NULL)   {
        CryptReleaseContext(provider, 0);
    }

    if (OutData != NULL && !Result)
        xfree(*OutData);

    return Result;
}