Advanced Encryption Standard (AES) è uno dei più usati e sicuri algoritmi di crittografia disponibili ad oggi. L’algoritmo è basato su diverse sostituzioni, permutazioni e trasformazioni lineari, ognuno eseguito su blocchi di dati da 16 byte da qui il termine cifrario a blocchi. Ad oggi, non esiste un attacco praticabile contro AES, quindi rimane lo standard di crittografia preferita per governi, banche e sistemi di alta sicurezza in tutto il mondo.
Questo blocco funzione esegue la crittatura con l’algoritmo AES, è protetto per utilizzarlo occorre richiedere il codice di protezione, vedi protezione funzioni e blocchi funzione. E’ comunque possibile utilizzarlo liberamente in modo test per 15 Min.
Attivando Enable i dati in formato Ascii o Hexadecimal presenti nel buffer definito in IData per la lunghezza definita in IDLength sono crittati utilizzando la chiave definita in CKey. E’ possibile eseguire crittatura di un intero file in tal caso definire il file in IData e settare IDLength a 0.
I dati crittati in uscita sono espressi in Base64 e vengono trasferiti nel buffer definito in OData per la dimensione definita in ODSize. E’ possibile memorizzare i dati in un file in tal caso definire il file in OData e settare ODSize a 0.
Come dimensionare ODSize
L’operazione di crittatura genera una stringa in uscita in Base64, con una dimensione maggiore della stringa da crittare, in questo report diamo una indicazione della dimensione e dei tempi di crittatura su di un sistema Cortex M7.
+---------------------+-------------------+----------------------+------------------+ | Stringa in ingresso | Stringa in uscita | Variazione lunghezza | Tempo esecuzione | +---------------------+-------------------+----------------------+------------------+ | 8 (Bytes) | 24 (Bytes) | 2.6 | 4 (mS) | | 16 (Bytes) | 44 (Bytes) | 2.6 | 17 (mS) | | 32 (Bytes) | 64 (Bytes) | 1.9 | 33 (mS) | | 128 (Bytes) | 192 (Bytes) | 1.5 | 26 (mS) | | 256 (Bytes) | 364 (Bytes) | 1.4 | 49 (mS) | | 512 (Bytes) | 704 (Bytes) | 1.4 | 97 (mS) | | 1024 (Bytes) | 1388 (Bytes) | 1.4 | 190 (mS) | | 2048 (Bytes) | 2752 (Bytes) | 1.4 | 377 (mS) | | 4096 (Bytes) | 5484 (Bytes) | 1.4 | 751 (mS) | +---------------------+-------------------+----------------------+------------------+
Descrizione
Enable (BOOL) Abilitazione crittatura.
SpyOn (BOOL) Se attivo permette di spiare il funzionamento del FB (Vedi articolo).
CKey (@STRING) Puntatore a CIPHER key, chiave di crittazione dati.
IData (PVOID) Puntatore ai dati da crittare (Ascii). Se IDLength:=0 viene considerato come definizione a file.
IDLength (UDINT) Lunghezza dati da crittare. Se 0 viene eseguita crittazione del file definito in IData.
OData (PVOID) Puntatore a buffer dati crittati (Base64). Se ODSize:=0 viene considerato definizione a file.
ODSize (UDINT) Lunghezza buffer dati crittati. Se 0 i dati vengono trasferiti nel file definito in OData.
Done (BOOL) Attivo a fine esecuzione.
Fault (BOOL) Si attiva per un loop se errore esecuzione.
Encrypted (BOOL) Si attiva se crittatura eseguita correttamente.
ODLength (UDINT) Ritorna la lunghezza dei dati crittati.

Spionaggio funzionamento
Se SpyOn attivo è possibile utilizzare utilizzare la console di spionaggio per verificare il funzionamento della FB. Sono previsti vari livelli di triggers.
Trigger di spionaggio
16#00000001 | Kt: Visualizzo key table. |
16#00000002 | St: Visualizzo state table. |
16#00000004 | Cr: Visualizzo passaggi di crittazione. |
16#10000000 | Lg: Messaggi di log funzionamento. |
16#40000000 | Er: Errori di esecuzione. |
Esempi
Come utilizzare gli esempi
ST_AESCryptOnMemory: Attivando da debug la variabile Start viene eseguita la crittazione e la successiva decrittazione del messaggio definito. Nella console di spionaggio viene visualizzato il risultato delle operazioni.
ST_AESCryptOnDisk: Attivando da debug la variabile Start viene eseguita la crittazione e la successiva decrittazione del contenuto del file indicato.
LogicLab (ST_AESCryptOnMemory)
PROGRAM ST_AESCryptOnMemory
VAR
Start : BOOL; (* Start command *)
CaseNr : USINT; (* Program case *)
CString : STRING[ 128 ]; (* Cripted string *)
DString : STRING[ 128 ]; (* Output string decrypted *)
IString : STRING[ 128 ]; (* Input string to crypt *)
AESDecrypt : AESDecryption; (* AES decryption *)
AESEncrypt : AESEncryption; (* AES encryption *)
END_VAR
// *****************************************************************************
// PROGRAM "ST_AESCryptOnMemory"
// *****************************************************************************
// The program encrypts a string using the AES128 algorithm, and decrypts it.
// -----------------------------------------------------------------------------
// -------------------------------------------------------------------------
// PROGRAM INITIALIZATION
// -------------------------------------------------------------------------
// Initialize FB.
IF (SysFirstLoop) THEN
CaseNr:=0; //Program case
IString:='Two One Nine Two'; //Input string to crypt
AESEncrypt.SpyOn:=FALSE; //Spy On
AESEncrypt.CKey:=ADR('Thats my Kung Fu'); //Crypt key
AESEncrypt.IData:=ADR(IString); //Input data pointer
AESEncrypt.OData:=ADR(CString); //Output data pointer
AESEncrypt.ODSize:=SIZEOF(CString); //Output data buffer size
AESDecrypt.SpyOn:=FALSE; //Spy On
AESDecrypt.CKey:=ADR('Thats my Kung Fu'); //Crypt key
AESDecrypt.IData:=ADR(CString); //Input data pointer
AESDecrypt.OData:=ADR(DString); //Output data pointer
AESDecrypt.ODSize:=SIZEOF(DString); //Output data buffer size
END_IF;
// -------------------------------------------------------------------------
// ENCRYPT AND DECRYPT FBS
// -------------------------------------------------------------------------
// Execute encrypt and decrypt FBs.
AESEncrypt(); //AES encryption
AESDecrypt(); //AES decryption
// -------------------------------------------------------------------------
// PROGRAM LOOP
// -------------------------------------------------------------------------
// Manage program cases.
CASE (CaseNr) OF
// ---------------------------------------------------------------------
// Wait start, set "Start" variable by debug.
0:
IF NOT(Start) THEN RETURN; END_IF;
Start:=FALSE; //Start command
CaseNr:=10; //Program case
// ---------------------------------------------------------------------
// Encrypt a string using defined key.
10:
AESEncrypt.IDLength:=Sysstrlen(AESEncrypt.IData); //Input data length
AESEncrypt.Enable:=TRUE; //Encrypt enable
CaseNr:=CaseNr+1; //Program case
// ---------------------------------------------------------------------
// Wait execution done.
11:
IF NOT(AESEncrypt.Done) THEN RETURN; END_IF;
AESEncrypt.Enable:=FALSE; //Encrypt enable
// Report the encrypted string. The Base64 crypted string is:
// KcNQX1cUIPZAIpmzGgLXOrPkbxG6jSuXwYdpRJqJ6Gg=
eTO_JUNK(SysWrSpyData(SPY_ASCII, 0, 16#FFFFFFFF, ADR('Encrypted string'), ADR(CString)));
CaseNr:=20; //Program case
// ---------------------------------------------------------------------
// Decrypt a string using defined key.
20:
AESDecrypt.IDLength:=AESEncrypt.ODLength; //Input data length
AESDecrypt.Enable:=TRUE; //Decrypt enable
CaseNr:=CaseNr+1; //Program case
// ---------------------------------------------------------------------
// Wait execution done.
21:
IF NOT(AESDecrypt.Done) THEN RETURN; END_IF;
AESDecrypt.Enable:=FALSE; //Decrypt enable
// Report the decrypted data.
eTO_JUNK(SysWrSpyData(SPY_ASCHEX, 64, 16#FFFFFFFF, ADR('Decrypted string'), ADR(DString)));
CaseNr:=0; //Program case
END_CASE;
// [End of file]
LogicLab (ST_AESCryptOnDisk)
PROGRAM ST_AESCryptOnDisk
VAR
Start : BOOL; (* Start command *)
i : UDINT; (* Auxiliary variable *)
CaseNr : USINT; (* Program case *)
TimeBf : UDINT; (* Time buffer (uS) *)
Time : ARRAY[0..1] OF REAL; (* Execution time (S) *)
AESEncrypt : AESEncryption; (* AES encryption *)
AESDecrypt : AESDecryption; (* AES decryption *)
END_VAR
// *****************************************************************************
// PROGRAM "ST_AESCryptOnDisk"
// *****************************************************************************
// The program encrypts a file using the AES128 algorithm, and decrypts it.
// To encrypt a 10Kb file it requires about 2 (S), and 2 (S) to write on disk.
// To decrypt a 13Kb file it requires about 8 (S), and 2 (S) to write on disk.
// -----------------------------------------------------------------------------
// -------------------------------------------------------------------------
// PROGRAM INITIALIZATION
// -------------------------------------------------------------------------
// Initialize FB.
IF (SysFirstLoop) THEN
CaseNr:=0; //Program case
AESEncrypt.SpyOn:=FALSE; //Spy On
AESEncrypt.CKey:=ADR('Thats my Kung Fu'); //Crypt key
AESEncrypt.IData:=ADR('D:/ToCrypt.txt'); //Input data pointer
AESEncrypt.IDLength:=0; //Input data length
AESEncrypt.OData:=ADR('D:/Crypted.txt'); //Output data pointer
AESEncrypt.ODSize:=0; //Output data buffer size
AESDecrypt.SpyOn:=FALSE; //Spy On
AESDecrypt.CKey:=ADR('Thats my Kung Fu'); //Crypt key
AESDecrypt.IData:=ADR('D:/Crypted.txt'); //Input data pointer
AESDecrypt.IDLength:=0; //Input data length
AESDecrypt.OData:=ADR('D:/Decrypted.txt'); //Output data pointer
AESDecrypt.ODSize:=0; //Output data buffer size
END_IF;
// -------------------------------------------------------------------------
// ENCRYPT AND DECRYPT FBS
// -------------------------------------------------------------------------
// Execute encrypt and decrypt FBs.
AESEncrypt(); //AES encryption
AESDecrypt(); //AES decryption
// -------------------------------------------------------------------------
// PROGRAM LOOP
// -------------------------------------------------------------------------
// Manage program cases.
CASE (CaseNr) OF
// ---------------------------------------------------------------------
// Wait start, set "Start" variable by debug.
0:
IF NOT(Start) THEN RETURN; END_IF;
Start:=FALSE; //Start command
CaseNr:=10; //Program case
// ---------------------------------------------------------------------
// AES crypt file using defined key.
10:
TimeBf:=SysGetSysTime(TRUE); //Time buffer (uS)
AESEncrypt.Enable:=TRUE; //Encrypt enable
CaseNr:=CaseNr+1; //Program case
// ---------------------------------------------------------------------
// Wait execution done.
11:
IF NOT(AESEncrypt.Done) THEN RETURN; END_IF;
AESEncrypt.Enable:=FALSE; //Crypt enable
Time[0]:=TO_REAL(SysGetSysTime(TRUE)-TimeBf)/1000000.0; //Execution time (S)
CaseNr:=20; //Program case
// ---------------------------------------------------------------------
// AES decrypt file using defined key.
20:
TimeBf:=SysGetSysTime(TRUE); //Time buffer (uS)
AESDecrypt.Enable:=TRUE; //Decrypt enable
CaseNr:=CaseNr+1; //Program case
// ---------------------------------------------------------------------
// Wait execution done.
21:
IF NOT(AESDecrypt.Done) THEN RETURN; END_IF;
AESDecrypt.Enable:=FALSE; //Decrypt enable
Time[1]:=TO_REAL(SysGetSysTime(TRUE)-TimeBf)/1000000.0; //Execution time (S)
CaseNr:=0; //Program case
END_CASE;
// [End of file]