unit GRDDongle;
{
free
}
interface
{$IFDEF FPC}
{ Free Pascal }
uses
SysUtils, GRDDelphi in 'GrdDelphi.pas';
{$ELSE}
{$IF CompilerVersion < 23}
{ Delphi 6 to Delphi XE }
uses
SysUtils, Windows, Classes, GRDDelphi in 'GrdDelphi.pas';
{$ELSE}
{ Delphi XE2 and above }
uses
System.SysUtils, Winapi.Windows, System.Classes, GRDDelphi;
// in 'GrdDelphi.pas';
{$IFEND}
{$ENDIF}
{$DEFINE DEBUGGRD_INFO}
// DEBUGGRD_INFO вывод сообщений
const
CryptPU: DWORD = $8566783; { Random value for access codes security }
CryptRD: DWORD = $17D49C84; { Random value for access codes security }
CryptWR: DWORD = $9843DE24; { Random value for access codes security }
CryptMS: DWORD = $47832845; { Random value for access codes security }
MAJ_VER = 1; // Major version nr.
MIN_VER = 0; // Minor version nr.
REL_VER = 0; // Release nr.
BLD_VER = 1; // Build nr.
type
TGRDDongle = class;
TErrorHandling = procedure(Sender: TObject;
StatusStr, StatusMessageStr: string; StatusCode, ErrCode: Integer)
of object;
TGRDDongle = class(TObject)
private
m_hMutex: HANDLE; // next ver
m_ErrorHandling: TErrorHandling;
function DoStartup: Integer;
procedure DoCleanup;
function GetVersionNr: Integer;
function GetVersion: string;
protected
{$IFDEF WIN32}
m_lGrdDongleClassCounter: Integer;
{$ELSE}
m_lGrdDongleClassCounter: DWORD;
{$ENDIF WIN32} // _WIN32
m_bGrdDongleStartup: Boolean;
m_abyGrdContainer: array [0 .. GrdContainerSize] of Byte;
m_hGrd: HANDLE;
m_dwRemoteMode: DWORD;
{ Local and/or remote (GrdSMF_Local + GrdSMF_Remote) }
// parameters for call SetFindMode()
m_dwFlags: DWORD; // Combination of GrdFM_XXXXX flags
m_dwProg: DWORD;
m_dwID: DWORD;
m_dwSN: DWORD;
m_dwVer: DWORD;
m_dwMask: DWORD;
m_dwType: DWORD;
m_dwModels: DWORD; // Possible dongle model bits. See GrdFMM_GSX definition
m_dwInterfaces: DWORD;
// Possible dongle interface bits. See GrdFMI_XXX definition
m_dwStartupFlags: DWORD; // See GrdRCS_XXXXX definition
m_dwDongleModel: DWORD; // dongle model after login
m_szNetworkClientIniPath: PChar;
m_useNotificationApi: Boolean;
// procedure CMBiDiModeChanged(var Message: TMessage); message CM_BIDIMODECHANGED;
m_GrdDC_NVK: DWORD; // = // public code }
m_GrdDC_RDO: DWORD; // = // private read code }
m_GrdDC_PRF: DWORD; // = // private write code }
m_GrdDC_MST: DWORD; // = // private master code }
Function GetInfo(dwInfoCode: DWORD;
// Code of requested information. See GrdGIX_XXXXX
pInfoData: pointer; // Pointer to buffer for return data
dwInfoSize: DWORD): Integer; overload; // Number of bytes for returning
Function Read(dwAddr, // Starting address in dongle memory to be read
dwLng: DWORD; // Length of data to be read
pData: pointer): Integer; // Buffer for data to be read
Function Write(dwAddr,
// Starting address in dongle memory to be written
dwLng: DWORD; // Length of data to be written
const pData: pointer): Integer; // Buffer for data to be written
published
constructor Create(
// parameters for call GrdStartup() & GrdSetFindMode
dwRemoteMode: DWORD = GrdFMR_Local + GrdFMR_Remote;
// parameters for call SetFindMode()
dwFlags: DWORD = 0; // Combination of GrdFM_XXXXX flags
dwProg: DWORD = 0; dwID: DWORD = 0; dwSN: DWORD = 0; dwVer: DWORD = 0;
dwMask: DWORD = 0; dwType: DWORD = 0; dwModels: DWORD = GrdFMM_ALL;
// Possible dongle model bits. See GrdFMM_GSX definition
dwInterfaces: DWORD = GrdFMI_ALL;
// Possible dongle interface bits. See GrdFMI_XXX definition
dwStartupFlags: DWORD = GrdRCS_UserDefined; // See GrdRCS_XXXXX definition
const szNetworkClientIniPath: string = '';
useNotificationApi: Boolean = false);
{ Must be encoded }
destructor Destroy; override;
function HandleError(nRet: Integer): Integer;
procedure PrintResult(nStatusStr: String; nErrorCode: Integer);
Function Open(
// parameters for call SetWorkMode()
dwFlagsWork: DWORD = GrdWM_UAM; // combination of GrdWM_XXX flags
dwFlagsMode: DWORD = GrdWMFM_DriverAuto): Integer;
// combination of GrdWMFM_XXX flags}
Function Unlock: Integer;
Function Lock(dwTimeoutWaitForUnlock: DWORD = 10000;
// Max GrdAPI unlock waiting time. -1 == infinity. 0 == no waiting
dwTimeoutAutoUnlock: DWORD = 10000;
// Max dongle locking time in ms. -1 == infinity. 0 == 10000 ms (10 sec)
dwMode: DWORD = GrdLM_Nothing): Integer;
function Check: Integer;
Function DecGP: Integer;
Function Seek(dwSeek: DWORD): Integer;
Function GetLastError: Integer;
Function FormatErrMessage(nLanguage: Integer = GrdLng_RUS): string;
Function FormatErrMessagenErrorCode(nErrorCode: Integer;
// Guardant error code
nLanguage: Integer = GrdLng_RUS): string; // Guardant language ID
Function GetInfo(dwInfoCode: DWORD;
// Code of requested information. See GrdGIX_XXXXX
var ptData: DWORD): Integer; overload;
// Pointer to variable to be returned
Function GetDongleModel: DWORD;
Function SetAccessCodes(dwPublic, // Must be already specified
dwPrivateRD: DWORD; // Must be already specified
dwPrivateWR: DWORD = 0; // == 0 if not needed
dwPrivateMST: DWORD = 0): Integer; // == 0 if not needed
Function SetWorkMode(dwFlagsWork: DWORD = GrdWM_UAM;
// combination of GrdWM_XXX flags
dwFlagsMode: DWORD = GrdWMFM_DriverAuto): Integer;
// combination of GrdWMFM_XXX flags
Function SetFindMode(dwRemoteMode: DWORD = GrdFMR_Local + GrdFMR_Remote;
// Local and/or remote (GrdFMR_Local + GrdFMR_Remote)
dwFlags: DWORD = 0; // Combination of GrdFM_XXXXX flags
dwProg: DWORD = 0; dwID: DWORD = 0; dwSN: DWORD = 0; dwVer: DWORD = 0;
dwMask: DWORD = 0; dwType: DWORD = 0; dwModels: DWORD = GrdFMM_ALL;
// Possible dongle model bits. See GrdFMM_GSX definition
dwInterfaces: DWORD = GrdFMI_ALL): Integer;
Function GetFindMode(dwRemoteMode,
// Local and/or remote (GrdFMR_Local + GrdFMR_Remote)
dwFlags, // Combination of GrdFM_XXXXX flags
dwProg, dwID, dwSN, dwVer, dwMask, dwType, dwModels,
// Possible dongle model bits. See GrdFMM_GSX definition
dwInterfaces: DWORD): Integer;
Function Find(dwMode: DWORD; // GrdF_First or GrdF_Next
var pdwID: DWORD; // Pointer to variable for return dongle ID
var FindInfo: TGrdFindInfo): Integer;
// Place for return dongle info or NULL for ignore it in other languages
Function Login(dwModuleLMS: DWORD = DWORD(-1);
// module number or -1 if License Management System functions are not used
dwLoginFlags: DWORD = GrdLM_PerStation): Integer;
// Login flags (GrdLLM_PerStation or GrdLLM_PerHandle)
Function Logout: Integer;
Function Protect(dwWrProt,
// address of first BYTES which can by write in SAM
dwRdProt, // address of first BYTES which can by read in SAM
dwNumFunc: DWORD;
// Number of hardware-implemented algorithms in the dongle
dwTableLMS: DWORD = 0;
// For Net II: SAM address of the first byte of LMS Table in 2-byte words; For Net III: number of protected item that contains LMS Table
dwGlobalFlags: DWORD = 0): Integer; // Reserved, must be 0
Function Transform(dwAlgoNum, dwLng: DWORD; pData: pointer;
dwMethod: DWORD = 0;
// GrdAM_ECB + GrdAM_Encrypt,// if Stealth I or Fidus it must be 0. Otherwise - combination of GrdAM_XXX flags
pIV: pointer = nil): Integer;
Function TransformEx(dwAlgoNum, dwLng: DWORD; pData: pointer;
dwMethod: DWORD = 0;
// GrdAM_ECB + GrdAM_Encrypt,// if Stealth I or Fidus it must be 0. Otherwise - combination of GrdAM_XXX flags
dwIVLng: DWORD = 0; pIV: pointer = nil): Integer;
Function Crypt(dwAlgo,
// Number of hardware- or software-implemented algorithm
dwDataLng: DWORD; // Data length
pData: pointer; // Data for Encryption/Decryption
dwMethod: DWORD = 0;
// Encrypt/Decrypt, First/Next/Last, block chaining modes (ECB/OFB/...)
pIV: pointer = nil; // Initialization Vector
const pKeyBuf: pointer = nil;
// Encryption/decryption secret key for software-implemented algorithm (nil if not used)
pContext: pointer = nil): Integer;
Function CryptEx(dwAlgo,
// Number of hardware- or software-implemented algorithm
dwDataLng: DWORD; // Data length
pData: pointer; // Data for Encryption/Decryption
dwMethod: DWORD = 0;
// Encrypt/Decrypt, First/Next/Last, block chaining modes (ECB/OFB/...)
dwIVLng: DWORD = 0; pIV: pointer = nil; // Initialization Vector
const pKeyBuf: pointer = nil;
// Encryption/decryption secret key for software-implemented algorithm (nil if not used)
pContext: pointer = nil): Integer;
Function Hash(dwSoftHash,
// Number of hardware- or software-implemented algorithm
dwDataLng: DWORD; // Data length
const pData: pointer; // Data for hash calculation
dwMethod: DWORD; // GrdSC_First/GrdSC_Next/GrdSC_Last
pDigest: pointer;
// Pointer to memory allocated for hash on GrdSC_Last step
const pKeyBuf: pointer = nil;
// Hash calculation secret key for software-implemented algorithm (nil if not used)
pContext: pointer = nil): Integer;
// property VertScrollBar: TControlScrollBar read FVertScrollBar write SetVertScrollBar;
Function HashEx(dwSoftHash,
// Number of hardware- or software-implemented algorithm
dwDataLng: DWORD; // Data length
const pData: pointer; // Data for hash calculation
dwMethod: DWORD; // GrdSC_First/GrdSC_Next/GrdSC_Last
dwDigestLng: DWORD; // Digest length
pDigest: pointer;
// Pointer to memory allocated for hash on GrdSC_Last step
dwKeyBufLng: DWORD; // Not used, must be 0
const pKeyBuf: pointer;
// Hash calculation secret key for software-implemented algorithm (nil if not used)
dwContextLng: DWORD; // Context length
pContext: pointer): Integer;
Function CRC(const pData: pointer; dwLng: DWORD;
dwPrevCRC: DWORD = Grd_StartCRC): DWORD;
Function PI_Activate(dwItemNum: DWORD;
// Algorithm or Protected Item number to be activated
dwActivatePsw: DWORD = 0): Integer;
// Optional password. If not used, must be 0
Function PI_Deactivate(dwItemNum: DWORD;
// Algorithm or Protected Item number to be deactivated
dwDeactivatePsw: DWORD = 0): Integer;
// Optional password. If not used, must be 0
Function PI_Read(dwItemNum,
// Algorithm or Protected Item number to be read
dwAddr, // Offset in Algorithm or Protected Item data
dwLng: DWORD; // Number of bytes for reading
pData: pointer; // Pointer to buffer for read data
dwReadPsw: DWORD = 0): Integer;
// Optional password. If not used, must be 0
Function PI_Update(dwItemNum,
// Algorithm or Protected Item number to be updated
dwAddr, // Offset in Algorithm or Protected Item data
dwLng: DWORD; // Number of bytes for updating
const pData: pointer; // Pointer to buffer with data to be written
dwUpdatePsw: DWORD = 0; // Optional password. If not used, must be 0
dwMethod: DWORD = GrdUM_MOV): Integer;
Function TRU_SetKey(const pGSII64_Key128: pointer): Integer;
// Unique
Function TRU_GenerateQuestion(pQuestion: pointer;
// Pointer to Question 8 bytes (64 bit)
pdwID, // Pointer to ID 4 bytes
pdwPublic: DWORD; // Pointer to Dongle Public Code 4 bytes
pHash: pointer): Integer;
Function TRU_GenerateQuestionTime(pQuestion: pointer;
// Pointer to Question 8 bytes (64 bit)
pdwID, // Pointer to ID 4 bytes
pdwPublic, // Pointer to Dongle Public Code 4 bytes
pqwDongleTime, // Pointer to Dongle Time (encrypted) 8 bytes
dwDeadTimesSize, pqwDeadTimes, pdwDeadTimesNumbers: DWORD;
pHash: pointer): Integer;
Function TRU_DecryptQuestion(dwAlgoNum_GSII64,
// Dongle GSII64 algorithm number with same key as in remote dongle
dwAlgoNum_HashS3: DWORD;
// Dongle HASH algorithm number with same key as in remote dongle
pQuestion: pointer;
// Pointer to Question 8 bytes (64 bit)
dwID, // ID 4 bytes
dwPublic: DWORD; // Public Code 4 bytes
const pHash: pointer): Integer;
Function TRU_DecryptQuestionTime(
// GSII64 algorithm with the same key as in remote dongle
dwAlgoNum_GSII64,
// Dongle GSII64 algorithm number with same key as in remote dongle
dwAlgoNum_HashS3: DWORD;
// Dongle HASH64 algorithm number with same key as in remote dongle
pQuestion: pointer;
// Pointer to Question 8 bytes (64 bit)
dwID, // ID 4 bytes
dwPublic: DWORD; // Public Code 4 bytes
pqwDongleTime, // Pointer to Dongle Time (encrypted) 8 bytes
pqwDeadTimes: QWORD; dwDeadTimesNumbers: DWORD;
const pHash: pointer): Integer;
Function TRU_SetAnswerProperties(dwTRU_Flags,
// Use Init & Protect or not
dwReserved, // Reserved, must be 0
dwWrProt, // remote GrdProtect parameters, SAM addres of the first byte available for writing in bytes
dwRdProt, // remote GrdProtect parameters, SAM addres of the first byte available for reading in bytes
dwNumFunc: DWORD;
// remote GrdProtect parameters, Number of hardware-implemented algorithms in the dongle including all protected items and LMS table of Net III
dwTableLMS: DWORD = 0;
// remote GrdProtect parameters, Net II: SAM address of the first byte of LMS Table in 2-byte words;
// Net III: number of protected item that contains LMS Table
dwGlobalFlags: DWORD = 0): Integer;
Function TRU_EncryptAnswer(dwAddr,
// Starting address for writing in dongle
dwLng: DWORD; // Size of data to be written
const pData: pointer; // Buffer for data to be written
const pQuestion: pointer;
// Pointer to decrypted Question 8 bytes (64 bit)
dwAlgoNum_GSII64,
// Dongle GSII64 algorithm number with the same key as in remote dongle
dwAlgoNum_HashS3: DWORD;
// Dongle HASH algorithm number with the same key as in remote dongle
pAnswer: pointer; // Pointer to the buffer for Answer data
pdwAnswerSize: DWORD): Integer;
Function TRU_ApplyAnswer(const pAnswer: pointer;
// Answer data update buffer prepared and encrypted by GrdTRU_EncryptAnswer
dwAnswerSize: DWORD): Integer;
Function Sign(dwAlgoNum,
// Number of hardware implemented ECC algorithm
dwDataLng: DWORD; // Data for sign length (20 bytes for ECC160)
const pData: pointer; // Data for sign
dwSignResultLng: DWORD; // ECC sign length (40 bytes for ECC160)
pSignResult: pointer): Integer;
Function VerifySign(dwAlgoType,
// Type of asymmetric cryptoalgorithm. See GrdVSC_XXXXX definition
dwPublicKeyLng: DWORD; // Public ECC key length
const pPublicKey: pointer; // Public ECC key
dwDataLng: DWORD; // Data for sign length (20 bytes for ECC160)
const pData: pointer; // Data for sign
dwSignLng: DWORD; // ECC sign length (40 bytes for ECC160)
const pSign: pointer): Integer;
Function SetTime(const pGrdSystemTime: TGrdSystemTime): Integer;
Function GetTime(pGrdSystemTime: TGrdSystemTime): Integer;
Function PI_GetTimeLimit(dwItemNum: DWORD;
// Algorithm or Protected Item number
pGrdSystemTime: TGrdSystemTime): Integer;
Function PI_GetCounter(dwItemNum: DWORD;
// Algorithm or Protected Item number
pdwCounter: DWORD): Integer;
Function CodeGetInfo(dwAlgoName: DWORD;
// Algorithm numerical name to be loaded
grdCodeInfo: TGrdCodeInfo): Integer;
Function CodeLoad(dwAlgoName,
// Algorithm numerical name to be loaded
dwFileSize: DWORD; // Buffer size for GCEXE-file
const pFileBuf: pointer): Integer;
Function CodeRun(dwAlgoName: DWORD;
// Algorithm numerical name to be loaded
dwP1, // Parameter (subfunction code) for loadable code
pdwRet, // result := code of loadable code
dwDataFromDongleLng: DWORD;
// The amount of data to be received from the dongle
pDataFromDongle: pointer;
// Pointer to a buffer for data to be received from the dongle
dwDataToDongleLng: DWORD; // The amount of data to be sent to the dongle
const pDataToDongle: pointer): Integer;
Function SetDriverMode(dwMode: DWORD): Integer;
Function InitializeNotificationAPI: Integer;
Function RegisterDongleNotification(pCallBack
: TGrdDongleNotifyCallBack): Integer;
Function UnRegisterDongleNotification(): Integer;
public
Function ReadVariable(dwAddr: DWORD;
// Starting address in dongle memory to be read
ptData: pointer): Integer; overload; // Pointer to variable to be read
Function ReadBlock(dwLng: DWORD; // Length of data to be read
pData: pointer): Integer; // Buffer for data to be read
Function ReadVariable(ptData: pointer): Integer; overload;
Function WriteVariable(dwAddr: DWORD;
// Starting address in dongle memory to be written
const ptData: pointer): Integer; overload;
// Pointer to variable to be written
Function WriteBlock(dwLng: DWORD; // Length of data to be written
const pData: pointer): Integer; // Buffer for data to be written
Function WriteVariable(const ptData: pointer): Integer; overload;
Function Init: Integer;
property PublicCode: DWORD read m_GrdDC_NVK write m_GrdDC_NVK;
// default GrdDC_DEMONVK;
property PrivateReadCode: DWORD read m_GrdDC_RDO write m_GrdDC_RDO;
// default GrdDC_DEMORDO;
property PrivateWriteCode: DWORD read m_GrdDC_PRF write m_GrdDC_PRF;
// default GrdDC_DEMOPRF;
property PrivateMasterCode: DWORD read m_GrdDC_MST write m_GrdDC_MST;
// default GrdDC_DEMOMST;
property OnErrorHandling: TErrorHandling read m_ErrorHandling
write m_ErrorHandling;
property Version: string read GetVersion;
end;
implementation
{ TGrdDongle }
/// Constructor
constructor TGRDDongle.Create(
// parameters for call GrdStartup() & GrdSetFindMode
dwRemoteMode: DWORD = GrdFMR_Local + GrdFMR_Remote;
// parameters for call SetFindMode()
dwFlags: DWORD = 0; // Combination of GrdFM_XXXXX flags
dwProg: DWORD = 0; dwID: DWORD = 0; dwSN: DWORD = 0; dwVer: DWORD = 0;
dwMask: DWORD = 0; dwType: DWORD = 0; dwModels: DWORD = GrdFMM_ALL;
// Possible dongle model bits. See GrdFMM_GSX definition
dwInterfaces: DWORD = GrdFMI_ALL;
// Possible dongle interface bits. See GrdFMI_XXX definition
dwStartupFlags: DWORD = GrdRCS_UserDefined; // See GrdRCS_XXXXX definition
const szNetworkClientIniPath: string = '';
useNotificationApi: Boolean = false);
var
nRet: Integer;
begin
m_lGrdDongleClassCounter := 0;
m_dwRemoteMode := dwRemoteMode;
m_dwFlags := dwFlags; // Combination of GrdFM_XXXXX flags
m_dwProg := dwProg;
m_dwID := dwID;
m_dwSN := dwSN;
m_dwVer := dwVer;
m_dwMask := dwMask;
m_dwType := dwType;
m_dwModels := dwModels;
// Possible dongle model bits. See GrdFMM_GSX definition
m_dwInterfaces := dwInterfaces;
// Possible dongle interface bits. See GrdFMI_XXX definition
m_dwStartupFlags := dwStartupFlags; // See GrdRCS_XXXXX definition
m_dwDongleModel := DWORD(-1);
// dongle model after login
m_szNetworkClientIniPath := PChar(szNetworkClientIniPath);
m_useNotificationApi := useNotificationApi;
inc(m_lGrdDongleClassCounter);
// Open(dwPublic, dwPrivRD, 0, 0);
HandleError(nRet);
inherited Create;
end;
// destructor
destructor TGRDDongle.Destroy;
var
nRet: Integer;
begin
if m_hGrd <> nil then
begin
nRet := GrdCloseHandle(m_hGrd);
if (nRet <> GrdE_OK) Then
m_hGrd := nil;
end;
DoCleanup;
inherited Destroy;
end;
function TGRDDongle.GetVersion: string;
var
vn: Integer;
begin
vn := GetVersionNr;
Result := inttostr(Hi(HiWord(vn))) + '.' + inttostr(Lo(HiWord(vn))) + '.' +
inttostr(Hi(LoWord(vn))) + '.' + inttostr(Lo(LoWord(vn)));
end;
function TGRDDongle.GetVersionNr: Integer;
begin
Result := makelong(MakeWord(BLD_VER, REL_VER), MakeWord(MIN_VER, MAJ_VER));
end;
{ --------------------------------------------------------------------------- }
procedure TGRDDongle.PrintResult(nStatusStr: String; nErrorCode: Integer);
begin
// Translate error code to text message
if Assigned(OnErrorHandling) then
OnErrorHandling(Self, Format(nStatusStr, []),
FormatErrMessagenErrorCode(nErrorCode), 0, nErrorCode);
end;
{ --------------------------------------------------------------------------- }
function TGRDDongle.HandleError(nRet: Integer): Integer;
begin
if (nRet <> GrdE_OK) Then
begin
if (m_hGrd <> nil) Then
// Perform some cleanup operations if hGrd handle exists
begin
// Close hGrd handle, log out from dongle/server, free allocated memory
PrintResult('- Closing handle: ', nRet);
nRet := GrdCloseHandle(m_hGrd);
PrintResult('', nRet);
end;
// Deinitialize this copy of GrdAPI. GrdCleanup() must be called after last GrdAPI call before program termination
PrintResult('-- Deinitializing this copy of GrdAPI: ', nRet);
nRet := GrdCleanup();
PrintResult('', nRet);
end
else
PrintResult('+ Result: ', nRet);
Result := nRet;
end;
/// Create class object. It call GrdStartup, GrdCreateHandle, GrdSetAccessCodes, GrdSetWorkMode, GrdSetFindMode
/// and must by call after constructor and before any first other member function calls
Function TGRDDongle.Open(dwFlagsWork: DWORD = GrdWM_UAM;
// combination of GrdWM_XXX flags
dwFlagsMode: DWORD = GrdWMFM_DriverAuto): Integer;
// combination of GrdWMFM_XXX flags
var
nRet: Integer;
begin
nRet := DoStartup();
if (nRet <> GrdE_OK) then
begin
HandleError(nRet);
exit(nRet);
end;
if (m_hGrd = nil) then
begin
// Create Grd protected object
m_hGrd := GrdCreateHandle(@m_abyGrdContainer, GrdCHM_MultiThread, nil);
if (m_hGrd = nil) then
Result := GrdE_Internal;
HandleError(nRet);
end;
// Store dongle codes in Guardant protected container
nRet := GrdSetAccessCodes(m_hGrd, m_GrdDC_NVK + CryptPU,
m_GrdDC_RDO + CryptRD, m_GrdDC_PRF + CryptWR, m_GrdDC_MST + CryptMS);
if (nRet <> GrdE_OK) then
begin
HandleError(nRet);
exit(nRet);
end;
// Set System Address Mode (SAM) as default mode
nRet := GrdSetWorkMode(m_hGrd, dwFlagsWork, dwFlagsMode);
if (nRet <> GrdE_OK) then
begin
HandleError(nRet);
exit(nRet);
end;
// Set dongle search parameters
Result := GrdSetFindMode(m_hGrd, m_dwRemoteMode, m_dwFlags, m_dwProg, m_dwID,
m_dwSN, m_dwVer, m_dwMask, m_dwType, m_dwModels, m_dwInterfaces);
HandleError(Result);
end;
/// Get last error information from protected container with specified handle
/// The last error code is maintained on a per-handle basis
/// Multiple handles do not overwrite each other's last-error code
Function TGRDDongle.GetLastError: Integer;
begin
Result := GrdGetLastError(m_hGrd, nil);
end;
/// Convert error code to text message string
Function TGRDDongle.FormatErrMessagenErrorCode(nErrorCode: Integer;
// Guardant error code
nLanguage: Integer = GrdLng_RUS): string; // Guardant language ID
var
szBuf: array [0 .. 1023] of ansichar; { buffer for error string }
begin
GrdFormatMessage(m_hGrd, nErrorCode, nLanguage, @szBuf[0],
sizeof(szBuf), nil);
Result := szBuf;
// MessageBox(0,@szBuf, 'Ошибка',0);
end;
/// Convert last error code (stored in handle) to text message string
Function TGRDDongle.FormatErrMessage(nLanguage: Integer = GrdLng_RUS): string;
// Guardant language ID
var
szBuf: array [0 .. 1023] of ansichar; { buffer for error string }
begin
GrdFormatMessage(m_hGrd, 0, nLanguage, @szBuf[0], sizeof(szBuf), nil);
Result := szBuf;
end;
/// Get requested information
Function TGRDDongle.GetInfo(dwInfoCode: DWORD;
// Code of requested information. See GrdGIX_XXXXX
pInfoData: pointer; // Pointer to buffer for return data
dwInfoSize: DWORD): Integer; // Number of bytes for returning
begin
Result := GrdGetInfo(m_hGrd, dwInfoCode, pInfoData, dwInfoSize);
{$IFDEF DEBUGGRD_INFO}
PrintResult('GetInfo', Result);
{$ENDIF}
end;
/// template for get requested information of different types
// template<class Type>
Function TGRDDongle.GetInfo(dwInfoCode: DWORD;
// Code of requested information. See GrdGIX_XXXXX
var ptData: DWORD): Integer; // Pointer to variable to be returned
begin
Result := GetInfo(dwInfoCode, @ptData, sizeof(ptData));
{$IFDEF DEBUGGRD_INFO}
PrintResult('GetInfo', Result);
{$ENDIF}
end;
Function TGRDDongle.GetDongleModel: DWORD;
begin
if (m_dwDongleModel <> $FFFFFFFF) then
exit(m_dwDongleModel);
if (GetInfo(GrdGIL_Model, @m_dwDongleModel, sizeof(m_dwDongleModel)) <>
GrdE_OK) then
exit($FFFFFFFF);
case m_dwDongleModel of
GrdDM_FidusUSB, GrdDM_FidusLPT:
m_dwDongleModel := GrdFMM_Fidus;
GrdDM_Stealth1LPT, GrdDM_Stealth1USB:
m_dwDongleModel := GrdFMM_Stealth1;
GrdDM_Stealth2LPT, GrdDM_Stealth2USB:
m_dwDongleModel := GrdFMM_Stealth2;
GrdDM_Stealth3USB:
m_dwDongleModel := GrdFMM_Stealth3;
GrdDM_SignUSB:
m_dwDongleModel := GrdFMM_SignUSB;
GrdDM_Soft:
m_dwDongleModel := GrdFMM_Soft;
GrdDM_CodeUSB:
m_dwDongleModel := GrdFMM_CodeUSB;
else
m_dwDongleModel := $FFFFFFFF;
end;
Result := m_dwDongleModel;
end;
/// Store dongle codes in Guardant protected container
Function TGRDDongle.SetAccessCodes(dwPublic, // Must be already specified
dwPrivateRD: DWORD; // Must be already specified
dwPrivateWR: DWORD = 0; // == 0 if not needed
dwPrivateMST: DWORD = 0): Integer; // == 0 if not needed
begin
Result := GrdSetAccessCodes(m_hGrd, dwPublic, dwPrivateRD, dwPrivateWR,
dwPrivateMST);
{$IFDEF DEBUGGRD_INFO}
PrintResult('SetAccessCodes', Result);
{$ENDIF}
end;
/// Set dongle working mode to Guardant protected container
Function TGRDDongle.SetWorkMode(dwFlagsWork: DWORD = GrdWM_UAM;
// combination of GrdWM_XXX flags
dwFlagsMode: DWORD = GrdWMFM_DriverAuto): Integer;
// combination of GrdWMFM_XXX flags
begin
Result := GrdSetWorkMode(m_hGrd, dwFlagsWork, dwFlagsMode);
{$IFDEF DEBUGGRD_INFO}
PrintResult('SetWorkMode', Result);
{$ENDIF}
end;
/// Set dongle search conditions and operation modes to Guardant protected container
Function TGRDDongle.SetFindMode(dwRemoteMode: DWORD = GrdFMR_Local +
GrdFMR_Remote; // Local and/or remote (GrdFMR_Local + GrdFMR_Remote)
dwFlags: DWORD = 0; // Combination of GrdFM_XXXXX flags
dwProg: DWORD = 0; dwID: DWORD = 0; dwSN: DWORD = 0; dwVer: DWORD = 0;
dwMask: DWORD = 0; dwType: DWORD = 0; dwModels: DWORD = GrdFMM_ALL;
// Possible dongle model bits. See GrdFMM_GSX definition
dwInterfaces: DWORD = GrdFMI_ALL): Integer;
// Possible dongle interface bits. See GrdFMI_XXX definition
begin
Result := GrdSetFindMode(m_hGrd, dwRemoteMode, dwFlags, dwProg, dwID, dwSN,
dwVer, dwMask, dwType, dwModels, dwInterfaces);
{$IFDEF DEBUGGRD_INFO}
PrintResult('SetFindMode', Result);
{$ENDIF}
end;
Function TGRDDongle.GetFindMode(dwRemoteMode,
// Local and/or remote (GrdFMR_Local + GrdFMR_Remote)
dwFlags, // Combination of GrdFM_XXXXX flags
dwProg, dwID, dwSN, dwVer, dwMask, dwType, dwModels,
// Possible dongle model bits. See GrdFMM_GSX definition
dwInterfaces: DWORD): Integer;
// Possible dongle interface bits. See GrdFMI_XXX definition
var
nRet: Integer;
begin
nRet := GrdGetInfo(m_hGrd, GrdGIF_Remote, @dwRemoteMode,
sizeof(dwRemoteMode));
if (GrdE_OK <> nRet) then
exit(nRet);;
nRet := GrdGetInfo(m_hGrd, GrdGIF_Flags, @dwFlags, sizeof(dwFlags));
if (GrdE_OK <> nRet) then
exit(nRet);;
nRet := GrdGetInfo(m_hGrd, GrdGIF_Model, @dwModels, sizeof(dwModels));
if (GrdE_OK <> nRet) then
exit(nRet);;
nRet := GrdGetInfo(m_hGrd, GrdGIF_Interface, @dwInterfaces,
sizeof(dwInterfaces));
if (GrdE_OK <> nRet) then
exit(nRet);;
nRet := GrdGetInfo(m_hGrd, GrdGIF_Ver, @dwVer, sizeof(dwVer));
if (GrdE_OK <> nRet) then
exit(nRet);;
nRet := GrdGetInfo(m_hGrd, GrdGIF_Prog, @dwProg, sizeof(dwProg));
if (GrdE_OK <> nRet) then
exit(nRet);;
nRet := GrdGetInfo(m_hGrd, GrdGIF_SN, @dwSN, sizeof(dwSN));
if (GrdE_OK <> nRet) then
exit(nRet);;
nRet := GrdGetInfo(m_hGrd, GrdGIF_ID, @dwID, sizeof(dwID));
if (GrdE_OK <> nRet) then
exit(nRet);;
nRet := GrdGetInfo(m_hGrd, GrdGIF_Type, @dwType, sizeof(dwType));
if (GrdE_OK <> nRet) then
exit(nRet);;
Result := GrdGetInfo(m_hGrd, GrdGIF_Mask, @dwMask, sizeof(dwMask));
{$IFDEF DEBUGGRD_INFO}
PrintResult('GetFindMode', Result);
{$ENDIF}
end;
/// Obtain the ID and other dongle info of the first or next dongle found
Function TGRDDongle.Find(dwMode: DWORD; // GrdF_First or GrdF_Next
var pdwID: DWORD; // Pointer to variable for return dongle ID
var FindInfo: TGrdFindInfo): Integer;
// Place for return dongle info or NULL for ignore it in other languages
begin
Result := GrdFind(m_hGrd, dwMode, @pdwID, @FindInfo);
{$IFDEF DEBUGGRD_INFO}
PrintResult('Find', Result);
{$ENDIF}
end;
/// Login to Guardant dongle
Function TGRDDongle.Login(dwModuleLMS: DWORD = DWORD(-1);
// module number or -1 if License Management System functions are not used
dwLoginFlags: DWORD = GrdLM_PerStation): Integer;
// Login flags (GrdLLM_PerStation or GrdLLM_PerHandle)
begin
Result := GrdLogin(m_hGrd, dwModuleLMS, dwLoginFlags);
{$IFDEF DEBUGGRD_INFO}
PrintResult('Login', Result);
{$ENDIF}
end;
/// Log out from Guardant dongle
Function TGRDDongle.Logout: Integer;
begin
Result := GrdLogout(m_hGrd, 0);
{$IFDEF DEBUGGRD_INFO}
PrintResult('Logout', Result);
{$ENDIF}
end;
/// startup stuff
Function TGRDDongle.DoStartup: Integer;
var
// lock:CGrdMutex;
nRet: Integer;
begin
if not m_bGrdDongleStartup then
begin
nRet := GrdStartupEx(m_dwRemoteMode, m_szNetworkClientIniPath,
m_dwStartupFlags);
if (nRet <> GrdE_OK) then
begin
HandleError(nRet);
exit(nRet);
end;
{$IFDEF WIN32}
if m_useNotificationApi then
begin
nRet := GrdInitializeNotificationAPI;
if (nRet <> GrdE_OK) then
begin
GrdCleanup();
// result := nRet;
HandleError(nRet);
exit(nRet);
end;
end;
{$ENDIF WIN32} // _WIN32
m_bGrdDongleStartup := true;
end;
Result := GrdE_OK;
end;
/// cleanup stuff
procedure TGRDDongle.DoCleanup;
begin
// CGrdMutex lock;
dec(m_lGrdDongleClassCounter);
if (m_lGrdDongleClassCounter = 0) and (m_bGrdDongleStartup) then
begin
{$IFDEF WIN32}
if m_useNotificationApi then
GrdUnInitializeNotificationAPI();
{$ENDIF WIN32} // _WIN32
GrdCleanup;
m_bGrdDongleStartup := false;
end;
end;
/// Increment lock counter of specified dongle
Function TGRDDongle.Lock(dwTimeoutWaitForUnlock: DWORD = 10000;
// Max GrdAPI unlock waiting time. -1 == infinity. 0 == no waiting
dwTimeoutAutoUnlock: DWORD = 10000;
// Max dongle locking time in ms. -1 == infinity. 0 == 10000 ms (10 sec)
dwMode: DWORD = GrdLM_Nothing): Integer;
// in default works like critical section
begin
Result := GrdLock(m_hGrd, dwTimeoutWaitForUnlock,
dwTimeoutAutoUnlock, dwMode);
{$IFDEF DEBUGGRD_INFO}
PrintResult('Lock', Result);
{$ENDIF}
end;
/// Unlock specified dongle
Function TGRDDongle.Unlock: Integer;
begin
Result := GrdUnlock(m_hGrd);
{$IFDEF DEBUGGRD_INFO}
PrintResult('Unlock', Result);
{$ENDIF}
end;
/// Check for dongle availability
Function TGRDDongle.Check: Integer;
begin
Result := GrdCheck(m_hGrd);
{$IFDEF DEBUGGRD_INFO}
PrintResult('Check', Result);
{$ENDIF}
end;
/// Check for dongle availability and decrement GP executions counter
/// Requires Private write code to be specified in SetAccessCodes
Function TGRDDongle.DecGP: Integer;
begin
Result := GrdDecGP(m_hGrd);
{$IFDEF DEBUGGRD_INFO}
PrintResult('DecGP', Result);
{$ENDIF}
end;
/// GrdDongle fSeek analog
/// Moves the dongle memory pointer (if any) associated with handle to a new location
Function TGRDDongle.Seek(dwSeek: DWORD): Integer;
begin
Result := GrdSeek(m_hGrd, dwSeek);
{$IFDEF DEBUGGRD_INFO}
PrintResult('Seek', Result);
{$ENDIF}
end;
/// Read a block of bytes from the dongle's memory
Function TGRDDongle.Read(dwAddr, // Starting address in dongle memory to be read
dwLng: DWORD; // Length of data to be read
pData: pointer): Integer; // Buffer for data to be read
begin
Result := GrdRead(m_hGrd, dwAddr, dwLng, pData, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('Read', Result);
{$ENDIF}
end;
/// Read a variable from the dongle's memory
Function TGRDDongle.ReadVariable(dwAddr: DWORD;
// Starting address in dongle memory to be read
ptData: pointer): Integer; // Pointer to variable to be read
begin
Result := Read(dwAddr, sizeof(ptData), ptData);
{$IFDEF DEBUGGRD_INFO}
PrintResult('ReadVariable', Result);
{$ENDIF}
end;
/// Read a block of bytes from the dongle's memory
Function TGRDDongle.ReadBlock(dwLng: DWORD; // Length of data to be read
pData: pointer): Integer; // Buffer for data to be read
begin
Result := Read(GrdSeekCur, dwLng, pData);
{$IFDEF DEBUGGRD_INFO}
PrintResult('ReadBlock', Result);
{$ENDIF}
end;
/// Read a variable from the dongle's memory
Function TGRDDongle.ReadVariable(ptData: pointer): Integer;
// Pointer to variable to be read
begin
Result := Read(GrdSeekCur, sizeof(ptData), ptData);
{$IFDEF DEBUGGRD_INFO}
PrintResult('ReadVariable', Result);
{$ENDIF}
end;
/// Write a block of bytes into the dongle's memory
/// Requires Private write code to be specified in SetAccessCodes
Function TGRDDongle.Write(dwAddr,
// Starting address in dongle memory to be written
dwLng: DWORD; // Length of data to be written
const pData: pointer): Integer; // Buffer for data to be written
begin
Result := GrdWrite(m_hGrd, dwAddr, dwLng, pData, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('Write', Result);
{$ENDIF}
end;
/// write a variable into the dongle's memory
Function TGRDDongle.WriteVariable(dwAddr: DWORD;
// Starting address in dongle memory to be written
const ptData: pointer): Integer; // Pointer to variable to be written
begin
Result := Write(dwAddr, sizeof(ptData), ptData);
{$IFDEF DEBUGGRD_INFO}
PrintResult('WriteVariable', Result);
{$ENDIF}
end;
/// Write a block of bytes into the dongle's memory
/// Requires Private write code to be specified in SetAccessCodes
Function TGRDDongle.WriteBlock(dwLng: DWORD; // Length of data to be written
const pData: pointer): Integer; // Buffer for data to be written
begin
Result := Write(GrdSeekCur, dwLng, pData);
{$IFDEF DEBUGGRD_INFO}
PrintResult('WriteBlock', Result);
{$ENDIF}
end;
/// write a variable into the dongle's memory
Function TGRDDongle.WriteVariable(const ptData: pointer): Integer;
// Pointer to variable to be written
begin
Result := Write(GrdSeekCur, sizeof(ptData), ptData);
{$IFDEF DEBUGGRD_INFO}
PrintResult('WriteVariable', Result);
{$ENDIF}
end;
/// Initialize the dongle's memory
/// Requires Private master code to be specified in SetAccessCodes
Function TGRDDongle.Init: Integer;
begin
Result := GrdInit(m_hGrd);
{$IFDEF DEBUGGRD_INFO}
PrintResult('Init', Result);
{$ENDIF}
end;
/// Implement locks / Specify the number of hardware algorithms
/// and LMS table address
/// Requires Private master code to be specified in SetAccessCodes
Function TGRDDongle.Protect(dwWrProt,
// address of first BYTES which can by write in SAM
dwRdProt, // address of first BYTES which can by read in SAM
dwNumFunc: DWORD; // Number of hardware-implemented algorithms in the dongle
dwTableLMS: DWORD = 0;
// For Net II: SAM address of the first byte of LMS Table in 2-byte words; For Net III: number of protected item that contains LMS Table
dwGlobalFlags: DWORD = 0): Integer; // Reserved, must be 0
begin
Result := GrdProtect(m_hGrd, dwWrProt, dwRdProt, dwNumFunc, dwTableLMS,
dwGlobalFlags, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('Protect', Result);
{$ENDIF}
end;
/// --- Cryptographic functions
/// Transform a block of bytes using dongle's hardware-implemented algorithm (including GSII64)
Function TGRDDongle.Transform(dwAlgoNum, dwLng: DWORD; pData: pointer;
dwMethod: DWORD = 0;
// GrdAM_ECB + GrdAM_Encrypt,// if Stealth I or Fidus it must be 0. Otherwise - combination of GrdAM_XXX flags
pIV: pointer = nil): Integer;
// if Stealth I or Fidus it must be NULL. Otherwise - 8-bytes initialization vector
begin
Result := GrdTransform(m_hGrd, dwAlgoNum, dwLng, pData, dwMethod, pIV);
{$IFDEF DEBUGGRD_INFO}
PrintResult('Transform', Result);
{$ENDIF}
end;
/// Transform a block of bytes using dongle's hardware-implemented algorithm (including GSII64)
Function TGRDDongle.TransformEx(dwAlgoNum, dwLng: DWORD; pData: pointer;
dwMethod: DWORD = 0;
// GrdAM_ECB + GrdAM_Encrypt,// if Stealth I or Fidus it must be 0. Otherwise - combination of GrdAM_XXX flags
dwIVLng: DWORD = 0; pIV: pointer = nil): Integer;
// if Stealth I or Fidus it must be NULL. Otherwise - n-bytes initialization vector
begin
Result := GrdTransformEx(m_hGrd, dwAlgoNum, dwLng, pData, dwMethod, dwIVLng,
pIV, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('TransformEx', Result);
{$ENDIF}
end;
/// Encrypt/decrypt a block of bytes using encryption algorithm
Function TGRDDongle.Crypt(dwAlgo,
// Number of hardware- or software-implemented algorithm
dwDataLng: DWORD; // Data length
pData: pointer; // Data for Encryption/Decryption
dwMethod: DWORD = 0;
// Encrypt/Decrypt, First/Next/Last, block chaining modes (ECB/OFB/...)
pIV: pointer = nil; // Initialization Vector
const pKeyBuf: pointer = nil;
// Encryption/decryption secret key for software-implemented algorithm (nil if not used)
pContext: pointer = nil): Integer;
// Context for multiple-buffer encryption. Must be corresponded GrdXXXXXX_CONTEXT_SIZE bytes size
begin
Result := GrdCrypt(m_hGrd, dwAlgo, dwDataLng, pData, dwMethod, pIV, pKeyBuf,
pContext);
{$IFDEF DEBUGGRD_INFO}
PrintResult('Crypt', Result);
{$ENDIF}
end;
/// Encrypt/decrypt a block of bytes using encryption algorithm
Function TGRDDongle.CryptEx(dwAlgo,
// Number of hardware- or software-implemented algorithm
dwDataLng: DWORD; // Data length
pData: pointer; // Data for Encryption/Decryption
dwMethod: DWORD = 0;
// Encrypt/Decrypt, First/Next/Last, block chaining modes (ECB/OFB/...)
dwIVLng: DWORD = 0; pIV: pointer = nil; // Initialization Vector
const pKeyBuf: pointer = nil;
// Encryption/decryption secret key for software-implemented algorithm (nil if not used)
pContext: pointer = nil): Integer;
// Context for multiple-buffer encryption. Must be corresponded GrdXXXXXX_CONTEXT_SIZE bytes size
begin
Result := GrdCryptEx(m_hGrd, dwAlgo, dwDataLng, pData, dwMethod, dwIVLng, pIV,
pKeyBuf, pContext, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('CryptEx', Result);
{$ENDIF}
end;
/// Hash calculation of a block of bytes
Function TGRDDongle.Hash(dwSoftHash,
// Number of hardware- or software-implemented algorithm
dwDataLng: DWORD; // Data length
const pData: pointer; // Data for hash calculation
dwMethod: DWORD; // GrdSC_First/GrdSC_Next/GrdSC_Last
pDigest: pointer; // Pointer to memory allocated for hash on GrdSC_Last step
const pKeyBuf: pointer = nil;
// Hash calculation secret key for software-implemented algorithm (nil if not used)
pContext: pointer = nil): Integer;
// Context for multiple buffer calculation. Must be corresponded GrdXXXXXX_CONTEXT_SIZE bytes size
begin
Result := GrdHash(m_hGrd, dwSoftHash, dwDataLng, pData, dwMethod, pDigest,
pKeyBuf, pContext);
{$IFDEF DEBUGGRD_INFO}
PrintResult('Hash', Result);
{$ENDIF}
end;
/// Hash calculation of a block of bytes
Function TGRDDongle.HashEx(dwSoftHash,
// Number of hardware- or software-implemented algorithm
dwDataLng: DWORD; // Data length
const pData: pointer; // Data for hash calculation
dwMethod: DWORD; // GrdSC_First/GrdSC_Next/GrdSC_Last
dwDigestLng: DWORD; // Digest length
pDigest: pointer; // Pointer to memory allocated for hash on GrdSC_Last step
dwKeyBufLng: DWORD; // Not used, must be 0
const pKeyBuf: pointer;
// Hash calculation secret key for software-implemented algorithm (nil if not used)
dwContextLng: DWORD; // Context length
pContext: pointer): Integer;
// Context for multiple buffer calculation. Must be corresponded GrdXXXXXX_CONTEXT_SIZE bytes size
begin
Result := GrdHashEx(m_hGrd, dwSoftHash, dwDataLng, pData, dwMethod,
dwDigestLng, pDigest, dwKeyBufLng, pKeyBuf, dwContextLng, pContext, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('HashEx', Result);
{$ENDIF}
end;
/// Calculate 32-bit CRC of a memory block
Function TGRDDongle.CRC(const pData: pointer; dwLng: DWORD;
dwPrevCRC: DWORD = Grd_StartCRC): DWORD;
begin
Result := GrdCRC(pData, dwLng, dwPrevCRC);
{$IFDEF DEBUGGRD_INFO}
PrintResult('CRC', Result);
{$ENDIF}
end;
/// --- Protected Item functions
/// Activate dongle Algorithm or Protected Item
Function TGRDDongle.PI_Activate(dwItemNum: DWORD;
// Algorithm or Protected Item number to be activated
dwActivatePsw: DWORD = 0): Integer;
// Optional password. If not used, must be 0
begin
Result := GrdPI_Activate(m_hGrd, dwItemNum, dwActivatePsw);
{$IFDEF DEBUGGRD_INFO}
PrintResult('PI_Activate', Result);
{$ENDIF}
end;
/// Deactivate dongle Algorithm or Protected Item
Function TGRDDongle.PI_Deactivate(dwItemNum: DWORD;
// Algorithm or Protected Item number to be deactivated
dwDeactivatePsw: DWORD = 0): Integer;
// Optional password. If not used, must be 0
begin
Result := GrdPI_Deactivate(m_hGrd, dwItemNum, dwDeactivatePsw);
{$IFDEF DEBUGGRD_INFO}
PrintResult('PI_Deactivate', Result);
{$ENDIF}
end;
/// Read data from dongle Protected Item
Function TGRDDongle.PI_Read(dwItemNum,
// Algorithm or Protected Item number to be read
dwAddr, // Offset in Algorithm or Protected Item data
dwLng: DWORD; // Number of bytes for reading
pData: pointer; // Pointer to buffer for read data
dwReadPsw: DWORD = 0): Integer; // Optional password. If not used, must be 0
begin
Result := GrdPI_Read(m_hGrd, dwItemNum, dwAddr, dwLng, pData, dwReadPsw, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('PI_Read', Result);
{$ENDIF}
end;
/// Update data in dongle Protected Item
Function TGRDDongle.PI_Update(dwItemNum,
// Algorithm or Protected Item number to be updated
dwAddr, // Offset in Algorithm or Protected Item data
dwLng: DWORD; // Number of bytes for updating
const pData: pointer; // Pointer to buffer with data to be written
dwUpdatePsw: DWORD = 0; // Optional password. If not used, must be 0
dwMethod: DWORD = GrdUM_MOV): Integer;
// Update method. See GrdUM_XXX definitions
begin
Result := GrdPI_Update(m_hGrd, dwItemNum, dwAddr, dwLng, pData, dwUpdatePsw,
dwMethod, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('PI_Update', Result);
{$ENDIF}
end;
/// --- Guardant Trusted Remote Update API
/// Write secret GSII64 remote update key for Guardant Secured Remote Update to the dongle
/// Requires Private master code to be specified in SetAccessCodes
Function TGRDDongle.TRU_SetKey(const pGSII64_Key128: pointer): Integer;
// Unique Trusted Remote Update GSII64 128-bit secret key
begin
Result := GrdTRU_SetKey(m_hGrd, pGSII64_Key128);
{$IFDEF DEBUGGRD_INFO}
PrintResult('TRU_SetKey', Result);
{$ENDIF}
end;
/// Generate encrypted question and initialize remote update procedure
Function TGRDDongle.TRU_GenerateQuestion(pQuestion: pointer;
// Pointer to Question 8 bytes (64 bit)
pdwID, // Pointer to ID 4 bytes
pdwPublic: DWORD; // Pointer to Dongle Public Code 4 bytes
pHash: pointer): Integer; // Pointer to Hash of previous 16 bytes 8 bytes
begin
Result := GrdTRU_GenerateQuestion(m_hGrd, pQuestion, @pdwID,
@pdwPublic, pHash);
{$IFDEF DEBUGGRD_INFO}
PrintResult('TRU_GenerateQuestion', Result);
{$ENDIF}
end;
/// Generate encrypted question and initialize remote update procedure
Function TGRDDongle.TRU_GenerateQuestionTime(pQuestion: pointer;
// Pointer to Question 8 bytes (64 bit)
pdwID, // Pointer to ID 4 bytes
pdwPublic, // Pointer to Dongle Public Code 4 bytes
pqwDongleTime, // Pointer to Dongle Time (encrypted) 8 bytes
dwDeadTimesSize, pqwDeadTimes, pdwDeadTimesNumbers: DWORD; pHash: pointer)
: Integer; // Pointer to Hash of previous data
begin
Result := GrdTRU_GenerateQuestionTime(m_hGrd, pQuestion, @pdwID, @pdwPublic,
@pqwDongleTime, dwDeadTimesSize, @pqwDeadTimes, @pdwDeadTimesNumbers,
pHash, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('TRU_GenerateQuestionTime', Result);
{$ENDIF}
end;
/// Decrypt and validate question
Function TGRDDongle.TRU_DecryptQuestion(dwAlgoNum_GSII64,
// Dongle GSII64 algorithm number with same key as in remote dongle
dwAlgoNum_HashS3: DWORD;
// Dongle HASH algorithm number with same key as in remote dongle
pQuestion: pointer; // Pointer to Question 8 bytes (64 bit)
dwID, // ID 4 bytes
dwPublic: DWORD; // Public Code 4 bytes
const pHash: pointer): Integer;
// Pointer to Hash of previous 16 bytes 8 bytes
begin
Result := GrdTRU_DecryptQuestion(m_hGrd, dwAlgoNum_GSII64, dwAlgoNum_HashS3,
pQuestion, dwID, dwPublic, pHash);
{$IFDEF DEBUGGRD_INFO}
PrintResult('TRU_DecryptQuestion', Result);
{$ENDIF}
end;
/// Decrypt and validate question
Function TGRDDongle.TRU_DecryptQuestionTime(
// GSII64 algorithm with the same key as in remote dongle
dwAlgoNum_GSII64,
// Dongle GSII64 algorithm number with same key as in remote dongle
dwAlgoNum_HashS3: DWORD;
// Dongle HASH64 algorithm number with same key as in remote dongle
pQuestion: pointer; // Pointer to Question 8 bytes (64 bit)
dwID, // ID 4 bytes
dwPublic: DWORD; // Public Code 4 bytes
pqwDongleTime, // Pointer to Dongle Time (encrypted) 8 bytes
pqwDeadTimes: QWORD; dwDeadTimesNumbers: DWORD; const pHash: pointer)
: Integer;
// Pointer to Hash of previous 16 bytes 8 bytes
begin
Result := GrdTRU_DecryptQuestionTime(m_hGrd, dwAlgoNum_GSII64,
dwAlgoNum_HashS3, pQuestion, dwID, dwPublic, @pqwDongleTime, @pqwDeadTimes,
dwDeadTimesNumbers, pHash);
{$IFDEF DEBUGGRD_INFO}
PrintResult('TRU_DecryptQuestionTime', Result);
{$ENDIF}
end;
/// Set Init & Protect parameters for Trusted Remote Update
/// This function must be called after GrdTRU_DecryptQuestion and before GrdTRU_EncryptAnswer functions
/// only if Init & Protect operations will be executed during remote update (call GrdTRU_ApplyAnswer) procedure on remote PC
Function TGRDDongle.TRU_SetAnswerProperties(dwTRU_Flags,
// Use Init & Protect or not
dwReserved, // Reserved, must be 0
dwWrProt, // remote GrdProtect parameters, SAM addres of the first byte available for writing in bytes
dwRdProt, // remote GrdProtect parameters, SAM addres of the first byte available for reading in bytes
dwNumFunc: DWORD;
// remote GrdProtect parameters, Number of hardware-implemented algorithms in the dongle including all protected items and LMS table of Net III
dwTableLMS: DWORD = 0;
// remote GrdProtect parameters, Net II: SAM address of the first byte of LMS Table in 2-byte words;
// Net III: number of protected item that contains LMS Table
dwGlobalFlags: DWORD = 0): Integer;
// remote GrdProtect parameters, Reserved, must be 0
begin
Result := GrdTRU_SetAnswerProperties(m_hGrd, dwTRU_Flags, dwReserved,
dwWrProt, dwRdProt, dwNumFunc, dwTableLMS, dwGlobalFlags, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('TRU_SetAnswerProperties', Result);
{$ENDIF}
end;
/// Prepare data for Trusted Remote Update
Function TGRDDongle.TRU_EncryptAnswer(dwAddr,
// Starting address for writing in dongle
dwLng: DWORD; // Size of data to be written
const pData: pointer; // Buffer for data to be written
const pQuestion: pointer;
// Pointer to decrypted Question 8 bytes (64 bit)
dwAlgoNum_GSII64,
// Dongle GSII64 algorithm number with the same key as in remote dongle
dwAlgoNum_HashS3: DWORD;
// Dongle HASH algorithm number with the same key as in remote dongle
pAnswer: pointer; // Pointer to the buffer for Answer data
pdwAnswerSize: DWORD): Integer;
// IN: Maximum buffer size for Answer data, OUT: Size of pAnswer buffer
begin
Result := GrdTRU_EncryptAnswer(m_hGrd, dwAddr, dwLng, pData, pQuestion,
dwAlgoNum_GSII64, dwAlgoNum_HashS3, pAnswer, @pdwAnswerSize);
{$IFDEF DEBUGGRD_INFO}
PrintResult('TRU_EncryptAnswer', Result);
{$ENDIF}
end;
/// Write data from secured buffer received via remote update procedure
Function TGRDDongle.TRU_ApplyAnswer(const pAnswer: pointer;
// Answer data update buffer prepared and encrypted by GrdTRU_EncryptAnswer
dwAnswerSize: DWORD): Integer; // Size of pAnswer buffer
begin
Result := GrdTRU_ApplyAnswer(m_hGrd, pAnswer, dwAnswerSize);
{$IFDEF DEBUGGRD_INFO}
PrintResult('TRU_ApplyAnswer', Result);
{$ENDIF}
end;
/// Digitally sign a block of bytes by using dongle hardware implemented ECC algorithm
Function TGRDDongle.Sign(dwAlgoNum,
// Number of hardware implemented ECC algorithm
dwDataLng: DWORD; // Data for sign length (20 bytes for ECC160)
const pData: pointer; // Data for sign
dwSignResultLng: DWORD; // ECC sign length (40 bytes for ECC160)
pSignResult: pointer): Integer; // ECC sign
begin
Result := GrdSign(m_hGrd, dwAlgoNum, dwDataLng, pData, dwSignResultLng,
pSignResult, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('Sign', Result);
{$ENDIF}
end;
/// ECC algorithm digest verifying. Full software implemented
Function TGRDDongle.VerifySign(dwAlgoType,
// Type of asymmetric cryptoalgorithm. See GrdVSC_XXXXX definition
dwPublicKeyLng: DWORD; // Public ECC key length
const pPublicKey: pointer; // Public ECC key
dwDataLng: DWORD; // Data for sign length (20 bytes for ECC160)
const pData: pointer; // Data for sign
dwSignLng: DWORD; // ECC sign length (40 bytes for ECC160)
const pSign: pointer): Integer; // ECC sign
begin
Result := GrdVerifySign(m_hGrd, dwAlgoType, dwPublicKeyLng, pPublicKey,
dwDataLng, pData, dwSignLng, pSign, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('VerifySign', Result);
{$ENDIF}
end;
/// Set dongle system time
Function TGRDDongle.SetTime(const pGrdSystemTime: TGrdSystemTime): Integer;
// Pointer to TGrdSystemTime
begin
Result := GrdSetTime(m_hGrd, @pGrdSystemTime, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('SetTime', Result);
{$ENDIF}
end;
/// Get dongle system time
Function TGRDDongle.GetTime(pGrdSystemTime: TGrdSystemTime): Integer;
// Pointer to TGrdSystemTime
begin
Result := GrdGetTime(m_hGrd, @pGrdSystemTime, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('GetTime', Result);
{$ENDIF}
end;
/// Get time limit for specified item
Function TGRDDongle.PI_GetTimeLimit(dwItemNum: DWORD;
// Algorithm or Protected Item number
pGrdSystemTime: TGrdSystemTime): Integer; // Pointer to TGrdSystemTime
begin
Result := GrdPI_GetTimeLimit(m_hGrd, dwItemNum, @pGrdSystemTime, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('PI_GetTimeLimit', Result);
{$ENDIF}
end;
/// Get counter for specified item
Function TGRDDongle.PI_GetCounter(dwItemNum: DWORD;
// Algorithm or Protected Item number
pdwCounter: DWORD): Integer; // Pointer to counter value
begin
Result := GrdPI_GetCounter(m_hGrd, dwItemNum, @pdwCounter, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('PI_GetCounter', Result);
{$ENDIF}
end;
/// Get information from user-defined loadable code descriptor
Function TGRDDongle.CodeGetInfo(dwAlgoName: DWORD;
// Algorithm numerical name to be loaded
grdCodeInfo: TGrdCodeInfo): Integer;
begin
Result := GrdCodeGetInfo(m_hGrd, dwAlgoName, sizeof(TGrdCodeInfo),
@grdCodeInfo, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('CodeGetInfo', Result);
{$ENDIF}
end;
/// Load GCEXE file to the dongle
Function TGRDDongle.CodeLoad(dwAlgoName,
// Algorithm numerical name to be loaded
dwFileSize: DWORD; // Buffer size for GCEXE-file
const pFileBuf: pointer): Integer; // Pointer to the buffer for GCEXE-file
begin
Result := GrdCodeLoad(m_hGrd, dwAlgoName, dwFileSize, pFileBuf, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('CodeLoad', Result);
{$ENDIF}
end;
/// Run user-defined loadable code
Function TGRDDongle.CodeRun(dwAlgoName: DWORD;
// Algorithm numerical name to be loaded
dwP1, // Parameter (subfunction code) for loadable code
pdwRet, // result := code of loadable code
dwDataFromDongleLng: DWORD;
// The amount of data to be received from the dongle
pDataFromDongle: pointer;
// Pointer to a buffer for data to be received from the dongle
dwDataToDongleLng: DWORD; // The amount of data to be sent to the dongle
const pDataToDongle: pointer): Integer;
// Pointer to a buffer for data to be sent to the dongle
begin
Result := GrdCodeRun(m_hGrd, dwAlgoName, dwP1, @pdwRet, dwDataFromDongleLng,
pDataFromDongle, dwDataToDongleLng, pDataToDongle, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('CodeRun', Result);
{$ENDIF}
end;
/// Switching driver type of USB-dongle
Function TGRDDongle.SetDriverMode(dwMode: DWORD): Integer;
// New Guardant dongle USB driver mode. See GrdDM_XXX definitions
begin
Result := GrdSetDriverMode(m_hGrd, dwMode, nil);
{$IFDEF DEBUGGRD_INFO}
PrintResult('SetDriverMode', Result);
{$ENDIF}
end;
// manual InitializeNotificationAPI
Function TGRDDongle.InitializeNotificationAPI: Integer;
begin
m_useNotificationApi := true;
Result := GrdInitializeNotificationAPI;
{$IFDEF DEBUGGRD_INFO}
PrintResult('InitializeNotificationAPI', Result);
{$ENDIF}
end;
/// Register dongle notification for specified handle
Function TGRDDongle.RegisterDongleNotification
(pCallBack: TGrdDongleNotifyCallBack): Integer;
// Pointer to Dongle Notification CallBack routine
begin
if (m_useNotificationApi) then
Result := GrdRegisterDongleNotification(m_hGrd, pCallBack);
{$IFDEF DEBUGGRD_INFO}
PrintResult('RegisterDongleNotification', Result);
{$ENDIF};
Result := GrdE_OK;
end;
/// Unregister dongle notification for specified handle
Function TGRDDongle.UnRegisterDongleNotification(): Integer;
begin
if (m_useNotificationApi) then
Result := GrdUnRegisterDongleNotification(m_hGrd);
{$IFDEF DEBUGGRD_INFO}
PrintResult('UnRegisterDongleNotification', Result);
{$ENDIF};
Result := GrdE_OK;
end;
end.