#ifndef CRYPT_H_INCLUDED
#define CRYPT_H_INCLUDED 1

/*
 * Copyright(C) 2000-2001 Проект ИОК
 *
 * Этот файл содержит информацию, являющуюся
 * собственностью компании Крипто Про.
 *
 * Любая часть этого файла не может быть скопирована,
 * исправлена, переведена на другие языки,
 * локализована или модифицирована любым способом,
 * откомпилирована, передана по сети с или на
 * любую компьютерную систему без предварительного
 * заключения соглашения с компанией Крипто Про.
 */

/*!
 * \file $RCSfile$
 * \version $Revision: 127051 $
 * \date $Date:: 2015-09-09 15:08:20 +0300#$
 * \author $Author: pav $
 *
 * \brief "СКЗИ КрипроПро CSP. Руководство программиста."
 */

#include "stdafx.h"
#include "CSP_WinCrypt.h"
#include "wincspc.h"
#include "reader/support.h"

#ifdef __cplusplus
extern "C" {
#endif

static inline DWORD CPCAPI
CPC2CryptAcquireContext(
		  /* [in] */ HCRYPTMODULE hCSP,
		  /* [out] */ HCRYPTPROV *phProv,
		  /* [string][in] */ CHAR *pszContainer,
		  /* [in] */ DWORD dwFlags,
		  /* [in] */ PVTABLEPROVSTRUC pVTable)
{
    UNUSED(hCSP);
    return CryptAcquireContextA(phProv, pszContainer, pVTable->pszProvName, pVTable->dwProvType, dwFlags)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptReleaseContext(
		  /* [in] */ HCRYPTMODULE hCSP,
		  /* [in] */ HCRYPTPROV hProv,
		  /* [in] */ DWORD dwFlags)
{
  UNUSED(hCSP);
  return CryptReleaseContext(hProv, dwFlags)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptGetProvParam(
		/* [in] */ HCRYPTMODULE hCSP,
		/* [in] */ HCRYPTPROV hProv,
		/* [in] */ DWORD dwParam,
		/* [size_is][out] */ BYTE *pbData,
		/* [out][in] */ DWORD *pdwDataLen,
		/* [in] */ DWORD dwFlags)
{
  UNUSED(hCSP);
  return CryptGetProvParam(hProv, dwParam, pbData, pdwDataLen, dwFlags)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptSetProvParam(
		/* [in] */ HCRYPTMODULE hCSP,
		/* [in] */ HCRYPTPROV hProv,
		/* [in] */ DWORD dwParam,
		/* [size_is][in] */ BYTE *pbData,
		/* [in] */ DWORD dwFlags)
{
  UNUSED(hCSP);
  return CryptSetProvParam(hProv, dwParam, pbData, dwFlags)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptGenKey(
	  /* [in] */ HCRYPTMODULE hCSP,
	  /* [in] */ HCRYPTPROV hProv,
	  /* [in] */ ALG_ID AlgId,
	  /* [in] */ DWORD dwFlags,
	  /* [out] */ HCRYPTKEY *phKey)
{
  UNUSED(hCSP);
  return CryptGenKey(hProv, AlgId, dwFlags, phKey)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptDestroyKey(
    /* [in] */ HCRYPTMODULE hCSP,
    /* [in] */ HCRYPTPROV hProv,
    /* [in] */ HCRYPTKEY hKey)
{
  UNUSED(hCSP); UNUSED(hProv);
  return CryptDestroyKey(hKey)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptCreateHash(
	      /* [in] */ HCRYPTMODULE hCSP,
	      /* [in] */ HCRYPTPROV hProv,
	      /* [in] */ ALG_ID AlgId,
	      /* [in] */ HCRYPTKEY hKey,
	      /* [in] */ DWORD dwFlags,
	      /* [out] */ HCRYPTHASH *phHash)
{
  UNUSED(hCSP);
  return CryptCreateHash(hProv, AlgId, hKey, dwFlags, phHash)?0:GetLastError();
}
                 
static inline DWORD CPCAPI
CPC2CryptDestroyHash(
	       /* [in] */ HCRYPTMODULE hCSP,
	       /* [in] */ HCRYPTPROV hProv,
	       /* [in] */ HCRYPTHASH hHash)
{
  UNUSED(hCSP); UNUSED(hProv);
  return CryptDestroyHash(hHash)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptEncrypt(
	   /* [in] */ HCRYPTMODULE hCSP,
	   /* [in] */ HCRYPTPROV hProv,
	   /* [in] */ HCRYPTKEY hKey,
	   /* [in] */ HCRYPTHASH hHash,
	   /* [in] */ BOOL Final,
	   /* [in] */ DWORD dwFlags,
	   /* [size_is][out][in] */ BYTE *pbData,
	   /* [out][in] */ DWORD *pdwDataLen,
	   /* [in] */ DWORD dwBufLen)
{
  UNUSED(hCSP); UNUSED(hProv);
  return CryptEncrypt(hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptDecrypt(
	   /* [in] */ HCRYPTMODULE hCSP,
	   /* [in] */ HCRYPTPROV hProv,
	   /* [in] */ HCRYPTKEY hKey,
	   /* [in] */ HCRYPTHASH hHash,
	   /* [in] */ BOOL Final,
	   /* [in] */ DWORD dwFlags,
	   /* [full][size_is][out][in] */ BYTE *pbData,
	   /* [out][in] */ DWORD *pdwDataLen)
{
  UNUSED(hCSP); UNUSED(hProv);
  return CryptDecrypt(hKey, hHash, Final, dwFlags, pbData, pdwDataLen)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptDeriveKey(
	     /* [in] */ HCRYPTMODULE hCSP,
	     /* [in] */ HCRYPTPROV hProv,
	     /* [in] */ ALG_ID AlgId,
	     /* [in] */ HCRYPTHASH hBaseData,
	     /* [in] */ DWORD dwFlags,
	     /* [out] */ HCRYPTKEY *phKey)
{
  UNUSED(hCSP);
  return CryptDeriveKey(hProv, AlgId, hBaseData, dwFlags, phKey)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptDuplicateKey(
		/* [in] */ HCRYPTMODULE hCSP,
		/* [in] */ HCRYPTPROV hProv,
		/* [in] */ HCRYPTKEY hKey,
		/* [full][in] */ DWORD *pdwReserved,
		/* [in] */ DWORD dwFlags,
		/* [out] */ HCRYPTKEY *phKey)
{
  UNUSED(hCSP); UNUSED(hProv);
  return CryptDuplicateKey(hKey, pdwReserved, dwFlags, phKey)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptDuplicateHash(
		 /* [in] */ HCRYPTMODULE hCSP,
		 /* [in] */ HCRYPTPROV hProv,
		 /* [in] */ HCRYPTHASH hHash,
		 /* [full][in] */ DWORD *pdwReserved,
		 /* [in] */ DWORD dwFlags,
		 /* [out] */ HCRYPTHASH *phHash)
{
  UNUSED(hCSP); UNUSED(hProv);
  return CryptDuplicateHash(hHash, pdwReserved, dwFlags, phHash)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptExportKey(
	     /* [in] */ HCRYPTMODULE hCSP,
	     /* [in] */ HCRYPTPROV hProv,
	     /* [in] */ HCRYPTKEY hKey,
	     /* [in] */ HCRYPTKEY hExpKey,
	     /* [in] */ DWORD dwBlobType,
	     /* [in] */ DWORD dwFlags,
	     /* [full][size_is][out][in] */ BYTE *pbData,
	     /* [out][in] */ DWORD *pdwDataLen)
{
  UNUSED(hCSP); UNUSED(hProv);
  return CryptExportKey(hKey, hExpKey, dwBlobType, dwFlags, pbData, pdwDataLen)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptGenRandom(
	     /* [in] */ HCRYPTMODULE hCSP,
	     /* [in] */ HCRYPTPROV hProv,
	     /* [in] */ DWORD dwLen,
	     /* [size_is][out][in] */ BYTE *pbBuffer)
{
  UNUSED(hCSP);
  return CryptGenRandom(hProv, dwLen, pbBuffer)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptGetHashParam(
		/* [in] */ HCRYPTMODULE hCSP,
		/* [in] */ HCRYPTPROV hProv,
		/* [in] */ HCRYPTHASH hHash,
		/* [in] */ DWORD dwParam,
		/* [full][size_is][out][in] */ BYTE *pbData,
		/* [out][in] */ DWORD *pdwDataLen,
		/* [in] */ DWORD dwFlags)
{
  UNUSED(hCSP); UNUSED(hProv);
  return CryptGetHashParam(hHash, dwParam, pbData, pdwDataLen, dwFlags)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptGetKeyParam(
	       /* [in] */ HCRYPTMODULE hCSP,
	       /* [in] */ HCRYPTPROV hProv,
	       /* [in] */ HCRYPTKEY hKey,
	       /* [in] */ DWORD dwParam,
	       /* [full][size_is][out][in] */ BYTE *pbData,
	       /* [out][in] */ DWORD *pdwDataLen,
	       /* [in] */ DWORD dwFlags)
{
  UNUSED(hCSP); UNUSED(hProv);
  return CryptGetKeyParam(hKey, dwParam, pbData, pdwDataLen, dwFlags)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptGetUserKey(
	      /* [in] */ HCRYPTMODULE hCSP,
	      /* [in] */ HCRYPTPROV hProv,
	      /* [in] */ DWORD dwKeySpec,
	      /* [out] */ HCRYPTKEY *phUserKey)
{
  UNUSED(hCSP);
  return CryptGetUserKey(hProv, dwKeySpec, phUserKey)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptHashData(
	    /* [in] */ HCRYPTMODULE hCSP,
	    /* [in] */ HCRYPTPROV hProv,
	    /* [in] */ HCRYPTHASH hHash,
	    /* [full][size_is][in] */ CONST BYTE *pbData,
	    /* [in] */ DWORD dwDataLen,
	    /* [in] */ DWORD dwFlags)
{
  UNUSED(hCSP); UNUSED(hProv);
  return CryptHashData(hHash, pbData, dwDataLen, dwFlags)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptHashSessionKey(
		  /* [in] */ HCRYPTMODULE hCSP,
		  /* [in] */ HCRYPTPROV hProv,
		  /* [in] */ HCRYPTHASH hHash,
		  /* [in] */ HCRYPTKEY hKey,
		  /* [in] */ DWORD dwFlags)
{
  UNUSED(hCSP); UNUSED(hProv);
  return CryptHashSessionKey(hHash, hKey, dwFlags)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptImportKey(
	     /* [in] */ HCRYPTMODULE hCSP,
	     /* [in] */ HCRYPTPROV hProv,
	     /* [full][size_is][in] */ CONST BYTE *pbData,
	     /* [in] */ DWORD dwDataLen,
	     /* [in] */ HCRYPTKEY hImpKey,
	     /* [in] */ DWORD dwFlags,
	     /* [out] */ HCRYPTKEY *phKey)
{
  UNUSED(hCSP);
  return CryptImportKey(hProv, pbData, dwDataLen, hImpKey, dwFlags, phKey)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptSetHashParam(
		/* [in] */ HCRYPTMODULE hCSP,
		/* [in] */ HCRYPTPROV hProv,
		/* [in] */ HCRYPTHASH hHash,
		/* [in] */ DWORD dwParam,
		/* [size_is][in] */ BYTE *pbData,
		/* [in] */ DWORD dwFlags)
{
  UNUSED(hCSP); UNUSED(hProv);
  return CryptSetHashParam(hHash, dwParam, pbData, dwFlags)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptSetKeyParam(
	       /* [in] */ HCRYPTMODULE hCSP,
	       /* [in] */ HCRYPTPROV hProv,
	       /* [in] */ HCRYPTKEY hKey,
	       /* [in] */ DWORD dwParam,
	       /* [size_is][in] */ BYTE *pbData,
	       /* [in] */ DWORD dwFlags)
{
  UNUSED(hCSP); UNUSED(hProv);
  return CryptSetKeyParam(hKey, dwParam, pbData, dwFlags)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptSignHash(
	    /* [in] */ HCRYPTMODULE hCSP,
	    /* [in] */ HCRYPTPROV hProv,
	    /* [in] */ HCRYPTHASH hHash,
	    /* [in] */ DWORD dwKeySpec,
	    /* [string][full][in] */ LPCWSTR sDescription,
	    /* [in] */ DWORD dwFlags,
	    /* [size_is][out][in] */ BYTE *pbSignature,
	    /* [out][in] */ DWORD *pdwSigLen)
{
  UNUSED(hCSP); UNUSED(hProv); UNUSED(sDescription);
  return CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, pbSignature, pdwSigLen)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptVerifySignature(
		   /* [in] */ HCRYPTMODULE hCSP,
		   /* [in] */ HCRYPTPROV hProv,
		   /* [in] */ HCRYPTHASH hHash,
		   /* [size_is][in] */ CONST BYTE *pbSignature,
		   /* [in] */ DWORD dwSigLen,
		   /* [in] */ HCRYPTKEY hPubKey,
		   /* [string][full][in] */ LPCWSTR sDescription,
		   /* [in] */ DWORD dwFlags)
{
  UNUSED(hCSP); UNUSED(hProv); UNUSED(sDescription);
  return CryptVerifySignature(hHash, pbSignature, dwSigLen, hPubKey, NULL, dwFlags)?0:GetLastError();
}

static inline DWORD CPCAPI
CPC2CryptDestroyProvider(
		   /* [in] */ HCRYPTMODULE hCSP)
{
  if(hCSP) free(hCSP);

  return 0;
}

static inline DWORD WINAPI
CPC2CryptCreateProvider(
    HCRYPTMODULE * phCSP,	/* [out] */
    LPCPC_CONFIG pConfig)
{
  UNUSED(pConfig);

  *phCSP=(HCRYPTMODULE)malloc(sizeof(CPC_FUNCTION_TABLE));
  if(!*phCSP) return (DWORD)NTE_NO_MEMORY;
  (*phCSP)->AcquireContext=CPC2CryptAcquireContext;
  (*phCSP)->ReleaseContext=CPC2CryptReleaseContext;
  (*phCSP)->GetProvParam=CPC2CryptGetProvParam;
  (*phCSP)->SetProvParam=CPC2CryptSetProvParam;
  (*phCSP)->GenKey=CPC2CryptGenKey;
  (*phCSP)->DestroyKey=CPC2CryptDestroyKey;
  (*phCSP)->CreateHash=CPC2CryptCreateHash;
  (*phCSP)->DestroyHash=CPC2CryptDestroyHash;
  (*phCSP)->Encrypt=CPC2CryptEncrypt;
  (*phCSP)->Decrypt=CPC2CryptDecrypt;
  (*phCSP)->DeriveKey=CPC2CryptDeriveKey;
  (*phCSP)->DuplicateKey=CPC2CryptDuplicateKey;
  (*phCSP)->DuplicateHash=CPC2CryptDuplicateHash;
  (*phCSP)->ExportKey=CPC2CryptExportKey;
  (*phCSP)->GenRandom=CPC2CryptGenRandom;
  (*phCSP)->GetHashParam=CPC2CryptGetHashParam;
  (*phCSP)->GetKeyParam=CPC2CryptGetKeyParam;
  (*phCSP)->GetUserKey=CPC2CryptGetUserKey;
  (*phCSP)->HashData=CPC2CryptHashData;
  (*phCSP)->HashSessionKey=CPC2CryptHashSessionKey;
  (*phCSP)->ImportKey=CPC2CryptImportKey;
  (*phCSP)->SetHashParam=CPC2CryptSetHashParam;
  (*phCSP)->SetKeyParam=CPC2CryptSetKeyParam;
  (*phCSP)->SignHash=CPC2CryptSignHash;
  (*phCSP)->VerifySignature=CPC2CryptVerifySignature;
  (*phCSP)->DestroyProvider=CPC2CryptDestroyProvider;

  return 0;
}

#ifdef __cplusplus
}
#endif

#endif /* CRYPT_H_INCLUDED */
