Add Original SDK
This commit is contained in:
@@ -0,0 +1,502 @@
|
||||
function dpsample
|
||||
%DPSAMPLE Example use of the Dinkey Pro/FD API in MATLAB.
|
||||
|
||||
% Copyright 2015 Microcosm Ltd.
|
||||
|
||||
% Load the correct library for this platform
|
||||
% !!!! If you rename the libraries as recommended in the user manual,
|
||||
% !!!! you need to modify the lines below to use the new names.
|
||||
switch computer()
|
||||
case 'PCWIN64' % 64-bit Windows
|
||||
loadlibrary('dpwin64.dll', @dinkeypro64proto, 'alias', 'dinkeypro');
|
||||
case 'PCWIN' % 32-bit Windows
|
||||
loadlibrary('dpwin32.dll', @dinkeyprowin32proto, 'alias', 'dinkeypro');
|
||||
case 'GLNXA64' % 64-bit Linux
|
||||
loadlibrary('dplin64.so', @dinkeypro64proto, 'alias', 'dinkeypro');
|
||||
case 'GLNX86' % 32-bit Linux
|
||||
loadlibrary('dplin32.so', @dinkeypro32proto, 'alias', 'dinkeypro');
|
||||
case 'MACI64' % 64-bit Mac OS X
|
||||
loadlibrary('dpmac64.dylib', @dinkeypro64proto, 'alias', 'dinkeypro');
|
||||
case 'MAC' % 32-bit Mac OS X
|
||||
loadlibrary('dpmac32.dylib', @dinkeypro32proto, 'alias', 'dinkeypro');
|
||||
otherwise
|
||||
disp('Error! Platform not supported!');
|
||||
return
|
||||
end
|
||||
|
||||
% Each of the functions below demonstrates different API functionality.
|
||||
% Uncomment the appropriate functions to execute the examples.
|
||||
% See the comments in each function for more details about the features
|
||||
% that they demonstrate.
|
||||
|
||||
protcheck('dinkeypro');
|
||||
%protcheckwithalg('dinkeypro');
|
||||
%writedataarea('dinkeypro');
|
||||
%readdataarea('dinkeypro');
|
||||
%encryptuserdata('dinkeypro');
|
||||
%protcheckenc('dinkeypro');
|
||||
%writedataareaenc('dinkeypro');
|
||||
%readdataareaenc('dinkeypro');
|
||||
|
||||
% Unload the library
|
||||
unloadlibrary('dinkeypro');
|
||||
end
|
||||
|
||||
|
||||
function protcheck(libName)
|
||||
% An example of a basic protection check
|
||||
|
||||
PROTECTION_CHECK = 1;
|
||||
DEC_ONE_EXEC = 1;
|
||||
START_NET_USER = 4;
|
||||
|
||||
% Initialise the DRIS
|
||||
dris.function = PROTECTION_CHECK;
|
||||
dris.flags = bitor(DEC_ONE_EXEC, START_NET_USER);
|
||||
|
||||
% Call the API
|
||||
[retCode, dris] = ddprotcheck(libName, dris);
|
||||
|
||||
% Check the return value
|
||||
if (retCode ~= 0)
|
||||
displayerror(retCode, dris.ext_err);
|
||||
return
|
||||
end
|
||||
|
||||
% ...
|
||||
|
||||
% You can check other values from the DRIS in other parts of your
|
||||
% program to improve security. For example:
|
||||
|
||||
% Check the SDSN
|
||||
% !!!! "10101" is the SDSN used by the demo SDK and demo dongles
|
||||
% !!!! If not using a demo, replace "10101" with your own SDSN here
|
||||
if (dris.sdsn ~= 10101)
|
||||
disp('Incorrect SDSN! Have you replaced "10101" with your SDSN in the sample code?');
|
||||
return
|
||||
end
|
||||
|
||||
% Check the product code
|
||||
% !!!! Replace "DEMO" with the product code you specify when adding
|
||||
% protection with DinkeyAdd
|
||||
if (~strcmp(dris.prodcode, 'DEMO'))
|
||||
disp('Incorrect product code! Have you replaced "DEMO" with your product code in the sample code?');
|
||||
return
|
||||
end
|
||||
|
||||
disp('Protection check successful');
|
||||
end
|
||||
|
||||
|
||||
function protcheckwithalg(libName)
|
||||
% An example of a protection check that also executes an algorithm stored
|
||||
% in the dongle.
|
||||
% The best way to use this feature is to identify lines of code in your
|
||||
% program that can be represented by algorithms stored in the dongle, and
|
||||
% replace these lines with calls to the API. Lite dongle users cannot
|
||||
% change the algorithm stored in the dongles, so should calculate the
|
||||
% algorithm in their own code and compare the result with the one returned
|
||||
% by the API, as in this example.
|
||||
|
||||
EXECUTE_ALGORITHM = 2;
|
||||
|
||||
% Initialise the DRIS
|
||||
dris.function = EXECUTE_ALGORITHM;
|
||||
dris.alg_vars = [1 2 3 4 5 6 7 8]; % The input variables to use in the algorithm
|
||||
dris.alg_number = 1; % The algorithm to execute. Lite dongles ignore this field, as they contain only 1 algorithm
|
||||
|
||||
% Call the API
|
||||
[retCode, dris] = ddprotcheck(libName, dris);
|
||||
|
||||
% Check the return value
|
||||
if (retCode ~= 0)
|
||||
displayerror(retCode, dris.ext_err);
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
% Check the algorithm result in another part of your program to improve
|
||||
% security. !!!! Ensure the myalgorithm() function matches the
|
||||
% algorithm that was executed by the protection check!
|
||||
if (dris.alg_answer ~= myalgorithm(dris.alg_vars))
|
||||
disp('Error! The algorithm result was not as expected.');
|
||||
return
|
||||
end
|
||||
|
||||
disp('Protection check with algorithm successful');
|
||||
end
|
||||
|
||||
|
||||
function writedataarea(libName)
|
||||
% An example of a protection check that also writes data to the dongle's
|
||||
% secure data area.
|
||||
% This feature is not supported by Lite dongles.
|
||||
% Make sure you specify a large enough data area size when adding
|
||||
% protection with DinkeyAdd!
|
||||
|
||||
WRITE_DATA_AREA = 3;
|
||||
|
||||
% Initialise the DRIS
|
||||
dris.function = WRITE_DATA_AREA;
|
||||
dris.rw_data = 'Hello, World!'; % Data to write
|
||||
dris.rw_offset = 0; % Index to start writing at. Note indices start at zero!
|
||||
|
||||
% Call the API
|
||||
[retCode, dris] = ddprotcheck(libName, dris);
|
||||
|
||||
% Check the return value
|
||||
if (retCode ~= 0)
|
||||
displayerror(retCode, dris.ext_err);
|
||||
return
|
||||
end
|
||||
|
||||
disp('Writing data successful');
|
||||
end
|
||||
|
||||
|
||||
function readdataarea(libName)
|
||||
% An example of a protection check that also reads data from the dongle's
|
||||
% secure data area.
|
||||
% This feature is not supported by Lite dongles.
|
||||
% Make sure you specify a large enough data area size when adding
|
||||
% protection with DinkeyAdd!
|
||||
|
||||
READ_DATA_AREA = 4;
|
||||
|
||||
% Initialise the DRIS
|
||||
dris.function = READ_DATA_AREA;
|
||||
dris.rw_offset = 0; % Index to start reading at. Note indices start at zero!
|
||||
dris.rw_length = 13; % How many bytes to read
|
||||
|
||||
% Call the API
|
||||
[retCode, dris] = ddprotcheck(libName, dris);
|
||||
|
||||
% Check the return value
|
||||
if (retCode ~= 0)
|
||||
displayerror(retCode, dris.ext_err);
|
||||
return
|
||||
end
|
||||
|
||||
disp(['Reading data successful: ' char(dris.rw_data)]);
|
||||
end
|
||||
|
||||
|
||||
function encryptuserdata(libName)
|
||||
% An example of protection checks that encrypt/decrypt your data.
|
||||
% This feature is not supported by Lite dongles.
|
||||
|
||||
ENCRYPT_USER_DATA = 5;
|
||||
DECRYPT_USER_DATA = 6;
|
||||
|
||||
originalData = uint8(255 * rand(1, 10));
|
||||
|
||||
% Initialise the DRIS
|
||||
dris.function = ENCRYPT_USER_DATA;
|
||||
dris.rw_data = originalData;
|
||||
dris.data_crypt_key_num = 1;
|
||||
|
||||
% Call the API
|
||||
[retCode, dris] = ddprotcheck(libName, dris);
|
||||
|
||||
% Check the return value
|
||||
if (retCode ~= 0)
|
||||
displayerror(retCode, dris.ext_err);
|
||||
return
|
||||
end
|
||||
|
||||
encryptedData = dris.rw_data;
|
||||
|
||||
% Initialise the DRIS
|
||||
dris.function = DECRYPT_USER_DATA;
|
||||
|
||||
% Call the API
|
||||
[retCode, dris] = ddprotcheck(libName, dris);
|
||||
|
||||
% Check the return value
|
||||
if (retCode ~= 0)
|
||||
displayerror(retCode, dris.ext_err);
|
||||
return
|
||||
end
|
||||
|
||||
decryptedData = dris.rw_data;
|
||||
|
||||
disp('Data encryption successful');
|
||||
disp('Original data:');
|
||||
disp(originalData);
|
||||
disp('Encrypted data:');
|
||||
disp(encryptedData);
|
||||
disp('Decrypted data:');
|
||||
disp(decryptedData);
|
||||
end
|
||||
|
||||
|
||||
function protcheckenc(libName)
|
||||
% An example of a protection check that uses DRIS encryption for extra
|
||||
% security.
|
||||
|
||||
PROTECTION_CHECK = 1;
|
||||
|
||||
% Initialise the DRIS
|
||||
dris.function = PROTECTION_CHECK;
|
||||
dris.seed1 = uint8(255 * rand(1, 4)); % 4 random bytes
|
||||
dris.seed2 = uint8(255 * rand(1, 4)); % 4 random bytes
|
||||
|
||||
% Call the API
|
||||
[retCode, dris] = ddprotcheck(libName, dris, @cryptdris);
|
||||
|
||||
% Check the return value
|
||||
if (retCode ~= 0)
|
||||
displayerror(retCode, dris.ext_err);
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
% You can check other values from the DRIS in other parts of your
|
||||
% program to improve security. For example:
|
||||
|
||||
% Check the SDSN
|
||||
% !!!! "10101" is the SDSN used by the demo SDK and demo dongles
|
||||
% !!!! If not using a demo, replace "10101" with your own SDSN here
|
||||
if (dris.sdsn ~= 10101)
|
||||
disp('Incorrect SDSN! Have you replaced "10101" with your SDSN in the sample code?');
|
||||
return
|
||||
end
|
||||
|
||||
% Check the product code
|
||||
% !!!! Replace "DEMO" with the product code you specify when adding
|
||||
% protection with DinkeyAdd
|
||||
if (~strcmp(dris.prodcode, 'DEMO'))
|
||||
disp('Incorrect product code! Have you replaced "DEMO" with your product code in the sample code?');
|
||||
return
|
||||
end
|
||||
|
||||
disp('Protection check successful');
|
||||
end
|
||||
|
||||
|
||||
function writedataareaenc(libName)
|
||||
% An example of a protection check that also writes data to the dongle's
|
||||
% secure data area.
|
||||
% This feature is not supported by Lite dongles.
|
||||
% Make sure you specify a large enough data area size when adding
|
||||
% protection with DinkeyAdd! This function also uses DRIS encryption and
|
||||
% encrypts the rw_data field for extra security. You must select these
|
||||
% options in DinkeyAdd for this function to work correctly!
|
||||
|
||||
WRITE_DATA_AREA = 3;
|
||||
|
||||
% Initialise the DRIS
|
||||
dris.function = WRITE_DATA_AREA;
|
||||
dris.rw_offset = 0;
|
||||
dris.seed1 = uint8(255 * rand(1, 4)); % 4 random bytes
|
||||
dris.seed2 = uint8(255 * rand(1, 4)); % 4 random bytes
|
||||
dris.alg_vars = randint(1 , 8, double([intmin intmax])); % 8 random signed 32-bit integers
|
||||
|
||||
rwAlgAnswer = myrwalgorithm(dris.alg_vars);
|
||||
|
||||
% Encrypt the data to be written to the dongle
|
||||
dataToWrite = uint8('ABCDEFGHIJKLMNOPQRSTUVWXYZ');
|
||||
dris.rw_data = cryptapidata(dataToWrite, dris.seed1, dris.seed2, rwAlgAnswer);
|
||||
|
||||
% Call the API
|
||||
[retCode, dris] = ddprotcheck(libName, dris, @cryptdris);
|
||||
|
||||
% Check the return value
|
||||
if (retCode ~= 0)
|
||||
displayerror(retCode, dris.ext_err);
|
||||
return
|
||||
end
|
||||
|
||||
disp('Writing data successful');
|
||||
end
|
||||
|
||||
|
||||
function readdataareaenc(libName)
|
||||
% An example of a protection check that also reads data from the dongle's
|
||||
% secure data area.
|
||||
% This feature is not supported by Lite dongles.
|
||||
% Make sure you specify a large enough data area size when adding
|
||||
% protection with DinkeyAdd! This function also uses DRIS encryption and
|
||||
% encrypts the rw_data field for extra security. You must select these
|
||||
% options in DinkeyAdd for this function to work correctly!
|
||||
|
||||
READ_DATA_AREA = 4;
|
||||
|
||||
% Initialise the DRIS
|
||||
dris.function = READ_DATA_AREA;
|
||||
dris.rw_offset = 0;
|
||||
dris.rw_length = 10;
|
||||
dris.seed1 = uint8(255 * rand(1, 4)); % 4 random bytes
|
||||
dris.seed2 = uint8(255 * rand(1, 4)); % 4 random bytes
|
||||
dris.alg_vars = randint(1 , 8, double([intmin intmax])); % 8 random signed 32-bit integers
|
||||
|
||||
% Call the API
|
||||
[retCode, dris] = ddprotcheck(libName, dris, @cryptdris);
|
||||
|
||||
% Check the return value
|
||||
if (retCode ~= 0)
|
||||
displayerror(retCode, dris.ext_err);
|
||||
return
|
||||
end
|
||||
|
||||
% Decrypt the data read from the dongle
|
||||
rwAlgAnswer = myrwalgorithm(dris.alg_vars);
|
||||
dataRead = cryptapidata(dris.rw_data, dris.seed1, dris.seed2, rwAlgAnswer);
|
||||
|
||||
disp(['Reading data successful: ' char(dataRead)]);
|
||||
end
|
||||
|
||||
|
||||
function ret = myalgorithm(algVars)
|
||||
% !!!! This function must match one stored in the dongle for
|
||||
% protcheckwithalg() to work correctly.
|
||||
% For Lite dongles, use DinkeyLook to see the algorithm pre-programmed
|
||||
% into the dongle. For Plus and Net dongles, ensure this algorithm matches
|
||||
% one you specified in DinkeyAdd when adding protection.
|
||||
ret = algVars(1) - algVars(2) - algVars(3) - algVars(4) - algVars(5) - algVars(6) - algVars(7);
|
||||
end
|
||||
|
||||
|
||||
function ret = myrwalgorithm(algVars)
|
||||
% !!!! This function must match the R/W algorithm stored in the dongle for
|
||||
% writedataareaenc() and readdataareaenc() to work correctly.
|
||||
ret = algVars(1) - algVars(2) - algVars(3) - algVars(4) - algVars(5) - algVars(6);
|
||||
end
|
||||
|
||||
|
||||
function dris = cryptdris(dris)
|
||||
% This function can be used to encrypt/decrypt the DRIS. If using DRIS
|
||||
% encryption in your own program, copy this function exactly. Modify only
|
||||
% the parts indicated by !!!!
|
||||
|
||||
% !!!! Overwrite the encryption parameters with those chosen in
|
||||
% DinkeyAdd. This example uses 123, 212, 97.
|
||||
DRIS_ENCRYPTION_PARAMETERS = [123 212 97];
|
||||
|
||||
S = 0:255;
|
||||
bigseed = zeros(256, 1);
|
||||
|
||||
for i = 1:8:256
|
||||
for j = 0:3
|
||||
bigseed(i+j) = dris(9+j);
|
||||
bigseed(i+j+4) = dris(13+j);
|
||||
end
|
||||
end
|
||||
|
||||
j = 0;
|
||||
for i = 0:255
|
||||
j = bitand((j + S(i+1) + bigseed(i+1) + DRIS_ENCRYPTION_PARAMETERS(1)), 255);
|
||||
temp = S(i+1);
|
||||
S(i+1) = S(j+1);
|
||||
S(j+1) = temp;
|
||||
end
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
for k = 17:length(dris)
|
||||
i = bitand((i + 1), 255);
|
||||
j = bitand((j + S(i+1) + DRIS_ENCRYPTION_PARAMETERS(2)), 255);
|
||||
temp = S(i+1);
|
||||
S(i+1) = S(j+1);
|
||||
S(j+1) = temp;
|
||||
t = bitand((S(i+1) + S(j+1) + DRIS_ENCRYPTION_PARAMETERS(3)), 255);
|
||||
dris(k) = bitxor(dris(k), S(t+1));
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function data = cryptapidata(data, seed1, seed2, algAnswer)
|
||||
% This function is used to encrypt/decrypt data passed in the rw_data DRIS
|
||||
% field (applies to Plus and Net dongles only). If using this feature in
|
||||
% your own program, copy this function exactly. Modify only the parts
|
||||
% indicated by !!!!
|
||||
|
||||
% !!!! If you are using constant encryption parameters, define them
|
||||
% like this:
|
||||
% DATA_ENCRYPTION_PARAMETERS = [X Y Z];
|
||||
|
||||
|
||||
% !!!! If you are using the R/W algorithm, derive the encryption
|
||||
% parameters from the algorithm result like this:
|
||||
|
||||
% 1. Convert algAnswer to uint32 without changing underlying data
|
||||
if (algAnswer < 0)
|
||||
algAnswer = uint32(double(algAnswer) + hex2dec('FFFFFFFF') + 1);
|
||||
else
|
||||
algAnswer = uint32(algAnswer);
|
||||
end
|
||||
|
||||
% 2. Now algAnswer is a uint32 we can use bitwise operations to derive
|
||||
% the encryption parameters
|
||||
DATA_ENCRYPTION_PARAMETERS = [bitand(algAnswer, 255), bitand(bitshift(algAnswer,-8), 255), bitand(bitshift(algAnswer,-16), 255)];
|
||||
|
||||
|
||||
% The rest of the function should not be modified!
|
||||
|
||||
S = 0:255;
|
||||
bigseed = zeros(256, 1);
|
||||
|
||||
for i = 1:8:256
|
||||
for j = 0:3
|
||||
bigseed(i+j) = seed1(j+1);
|
||||
bigseed(i+j+4) = seed2(j+1);
|
||||
end
|
||||
end
|
||||
|
||||
j = 0;
|
||||
for i = 0:255
|
||||
j = bitand((j + S(i+1) + bigseed(i+1) + DATA_ENCRYPTION_PARAMETERS(1)), 255);
|
||||
temp = S(i+1);
|
||||
S(i+1) = S(j+1);
|
||||
S(j+1) = temp;
|
||||
end
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
for k = 1:length(data)
|
||||
i = bitand((i + 1), 255);
|
||||
j = bitand((j + S(i+1) + DATA_ENCRYPTION_PARAMETERS(2)), 255);
|
||||
temp = S(i+1);
|
||||
S(i+1) = S(j+1);
|
||||
S(j+1) = temp;
|
||||
t = bitand((S(i+1) + S(j+1) + DATA_ENCRYPTION_PARAMETERS(3)), 255);
|
||||
data(k) = bitxor(data(k), S(t+1));
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
% An example of error reporting
|
||||
% Displays descriptions for some common error codes
|
||||
% IMPORTANT - THE MESSAGES DISPLAYED ARE TO HELP DEVELOPERS IMPLEMENT THE
|
||||
% DINKEY PRO/FD API. THEY ARE NOT SUITABLE FOR DISPLAYING TO USERS!
|
||||
function displayerror(retCode, extErr)
|
||||
switch retCode
|
||||
case 401
|
||||
disp('Error! No dongles detected!');
|
||||
case 403
|
||||
disp('Error! The dongle is a different type to the one specified in DinkeyAdd.');
|
||||
case 404
|
||||
disp('Error! The dongle is a different model to those specified in DinkeyAdd.');
|
||||
case 409
|
||||
disp('Error! The dongle has not been programmed by DinkeyAdd.');
|
||||
case 410
|
||||
disp('Error! The dongle has a different product code to the one specified in DinkeyAdd.');
|
||||
case 411
|
||||
disp('Error! This program''s licence was not found in the dongle.');
|
||||
case 413
|
||||
disp('Error! This program has not been locked by DinkeyAdd. For guidance please read the DinkeyAdd chapter of the user manual.');
|
||||
case 417
|
||||
disp('Error! One or more of the parameters set in the DRIS is incorrect.');
|
||||
disp('Check that you have defined the necessary input fields in the DRIS struct.');
|
||||
disp('Also check if you are encrypting the DRIS in your code but did not specify DRIS encryption in DinkeyAdd - or vice versa.');
|
||||
case 423
|
||||
disp('Error! The number of network users has been exceeded.');
|
||||
case 435
|
||||
disp('Error! DinkeyServer has not been detected on the network.');
|
||||
case 922
|
||||
disp('Error! The Software Key has expired.');
|
||||
otherwise
|
||||
str = sprintf('An error occurred checking the dongle. Error: %d, Extended Error: %d', retCode, extErr);
|
||||
disp(str);
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user