[C/C++] AES 256-Bit Ver-Entschlüsselung (DLL)&(NoDLL) [FiNAL]

Dieses Thema im Forum "Projekte / Codes" wurde erstellt von Golly, 8. Januar 2011 .

Schlagworte:
  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  1. Golly
    Golly Neu
    Stammnutzer
    #1 8. Januar 2011
    Zuletzt von einem Moderator bearbeitet: 14. April 2017
    AES 256-Bit Ver-Entschlüsselung (DLL)&(NoDLL) [FiNAL]

    Hi,
    habe aus langeweile den Advanced Encryption Standard (AES) "from-Scratch" in C geschrieben.
    Das ganze ist in einer DLL-Verpackt und über die 5 intuitiven Parameter "AESKey,encryption,OUTPUT,INPUT,sizeof(INPUT)" aufrufbar.

    Somit lässt sich auf einfache Weise Sicherheit in Form von Kryptographie in bereits bestehende Projekte integrieren oder hilft weiter den AES-Algorithmus zu verstehen.



    [ Download ]​



    Einbindungsbeispiel (DLL):
    Spoiler
    Code:
    //DLL-TESTER AES.dll
    #include <windows.h>
    
    typedef void (*pfunc1)(unsigned char*,unsigned char*,int,unsigned char*,int);
    pfunc1 AES_dll;
    
    int main()
    { 
     HINSTANCE hLib = LoadLibrary("AES.dll");
     if(hLib==NULL)
     {
     return 1;
     }
     char dllpath[70];
     GetModuleFileName((HMODULE)hLib,(LPTSTR)dllpath,70);
     AES_dll = (pfunc1)GetProcAddress((HMODULE)hLib, "AES");
     if((AES_dll==NULL)) 
     {
     FreeLibrary((HMODULE)hLib);
     return 1;
     }
     
     unsigned char K[] = {'\x00','\x01','\x02','\x03','\x04','\x05','\x06','\x07','\x08','\x09','\x0a','\x0b','\x0c','\x0d','\x0e','\x0f','\x10','\x11','\x12','\x13','\x14','\x15','\x16','\x17','\x18','\x19','\x1a','\x1b','\x1c','\x1d','\x1e','\x1f'};
     unsigned char input[] = "Ich bin geheim!";
     unsigned char temp[sizeof(input)+(16-sizeof(input)%16)];
     unsigned char output[sizeof(temp)];
     
     AES_dll(K,1,temp,input,sizeof(input)); //Ver-Schlüsseln
     AES_dll(K,0,output,temp,sizeof(temp)); //Ent-Schlüsseln
     
     printf("%s\n",output);
     
     FreeLibrary((HMODULE)hLib);
     system("PAUSE");
     return 0;
    }
    Einbindungsbeispiel(NoDLL)[~3x schneller]:
    Spoiler
    Code:
    #include <windows.h>
    #include "AES.h"
    
    int main()
    {
     unsigned char K[] = {'\x00','\x01','\x02','\x03','\x04','\x05','\x06','\x07','\x08','\x09','\x0a','\x0b','\x0c','\x0d','\x0e','\x0f','\x10','\x11','\x12','\x13','\x14','\x15','\x16','\x17','\x18','\x19','\x1a','\x1b','\x1c','\x1d','\x1e','\x1f'};
     unsigned char input[] = "Ich bin geheim!";
     unsigned char temp[sizeof(input)+(16-sizeof(input)%16)];
     unsigned char output[sizeof(temp)];
     
     AES(K,1,temp,input,sizeof(input)); //Ver-Schlüsseln
     AES(K,0,output,temp,sizeof(temp)); //Ent-Schlüsseln
     
     printf("%s\n",output);
    
     system("PAUSE");
     return 0; 
    }
    




    Einzige noch vorhandene Negativ-Punkte :
    -es wird nur die höchste Schlüssellänge von 256Bit angeboten (128 und 192 können auf Anfrage von mir nachintegriert werden, jedoch nicht umbedingt sinnvoll)

    Wenn Interesse am mathematischen Hintergrund bzgl. der MixColumns bzw. der InvMixColumns Operation besteht, kann der Code zur eigentlichen Berrechnung dieser von mir geuppt werden, da zZt. im aktuellen Code aus Performance-Gründen bereits vorgerechnete Tabellen verwendet werden.

    Habt erbarmen mit mir, das ist das erste mal, dass ich eine DLL geschrieben habe, das DLL-Gerüst ist aus irgent nem Tut gerippt und evtl teilweise redundant, kein Plan. Evtl. Fehler bitte posten, bin jetzt nicht allzu erfahren in C.


    *Bugs:
    -(Performance-Verbesserung) Shift_Mix_Add mit SubBytes zusammenfassen

    *Bugfixes:
    -Padding optimiert
    -Padding-Strip gefixt
     

  2. Anzeige
  3. razor90
    razor90 user nr. 1000
    Stammnutzer
    #2 8. Januar 2011
    AW: AES 256-Bit Ver-Entschlüsselung (DLL)

    Geh mal dem Tipp auf Wikipedia nach und fasse Sub, Shift und Mix mit Hilfe von 4 Arrays zu einer Funktion zusammen ;)
    Es sich selbst herzuleiten ist zwar schwer und man sieht am Ende nicht mehr, was der Code eigentlich macht, aber der Geschwindigkeitsgewinn ist groß.
    Bin damit auf ~600 mb/s mit einem i5-750 und 128-bit Key gekommen.

    mfg,
    r90
     
  4. Golly
    Golly Neu
    Stammnutzer
    #3 9. Januar 2011
    AW: AES 256-Bit Ver-Entschlüsselung (DLL)

    Habe es mir jetzt paar mal durchgelesen die Stelle, aber blicke nicht so ganz durch wie man die drei nochmals zusammenfassen könnte.

    Also vor allem wie man ShiftRows zu einer Tabelle machen will, da es ja nicht vom Input-Byte ansich sondern den anderen abhängt, da dort ja keine Rechenoperation sondern nur eine "Verschiebung"/"Umverdrahtung" geschieht.

    600Mb/s klingen aber schonmal sehr verlockend

    Habe meinen Code schon zig Verbesserungen bzgl. Performance nach bestem Wissen und Gewissen unterzogen, wüsste auch nicht was man da noch machen könnte ohne jetzt wo anders was abzukupfern.

    Ansonsten habe ich ja bereits vorgerechnete Tabellen, wobei ich sagen muss, dass ich mir selber einen Schulterklopfer geben musste, als ich gesehen habe, dass TrueCrypt die exakt gleichen Tabellen verwendet (jetzt bei MixColumn und InvMixColumn).

    //EDIT:

    Ich glaub ich weiß jetzt wies gemeint ist.
    Statt seperat ShiftRows zu machen, einfach anderen Offset in anderen Operationen verwenden.
    Werds nun ausprobieren und nachher Ergebnis posten.
     
  5. razor90
    razor90 user nr. 1000
    Stammnutzer
    #4 9. Januar 2011
    AW: AES 256-Bit Ver-Entschlüsselung (DLL)

    Exakt.
    Außerdem kann man SubBytes und MixColumns kombinieren und durch 4 Arrays (deren Herleitung absoluter Brain:mad: ist) in einem Schritt durchführen. Dazu noch das AddRoundKey reinhauen und man hat aus vier Funktionen eine gemacht ;)

    Bei mir siehts so aus:
    Code:
    void SubShiftMixAdd(const uint8 *in, uint8 *out, const uint8 *key)
    {
     unsigned int* pKey = (unsigned int*)&key[0];
     unsigned int* pIn = (unsigned int*)&in[0];
     unsigned int* pOut = (unsigned int*)&out[0];
    
     uint32 a1, a2, a3, a4;
    
     uint32 i1 = pIn[0];
     uint32 i2 = pIn[1];
     uint32 i3 = pIn[2];
     uint32 i4 = pIn[3];
    
     a1 = i1 & 0xFF;
     a2 = (i2 & 0xFF00) >> 8;
     a3 = (i3 & 0xFF0000) >> 16;
     a4 = (i4 & 0xFF000000) >> 24;
     *pOut++ = (SubMix1[a1] ^ SubMix2[a2] ^ SubMix3[a3] ^ SubMix4[a4]) ^ *pKey++;
    
     a1 = (i2 & 0xFF);
     a2 = (i3 & 0xFF00) >> 8;
     a3 = (i4 & 0xFF0000) >> 16;
     a4 = (i1 & 0xFF000000) >> 24;
     *pOut++ = (SubMix1[a1] ^ SubMix2[a2] ^ SubMix3[a3] ^ SubMix4[a4]) ^ *pKey++;
    
     a1 = (i3 & 0xFF);
     a2 = (i4 & 0xFF00) >> 8;
     a3 = (i1 & 0xFF0000) >> 16;
     a4 = (i2 & 0xFF000000) >> 24;
     *pOut++ = (SubMix1[a1] ^ SubMix2[a2] ^ SubMix3[a3] ^ SubMix4[a4]) ^ *pKey++;
    
     a1 = (i4 & 0xFF);
     a2 = (i1 & 0xFF00) >> 8;
     a3 = (i2 & 0xFF0000) >> 16;
     a4 = (i3 & 0xFF000000) >> 24;
     *pOut++ = (SubMix1[a1] ^ SubMix2[a2] ^ SubMix3[a3] ^ SubMix4[a4]) ^ *pKey++;
    }
    Nochmal zu der Geschwindigkeit:
    Hab's grad nochmal durchgetestet und gemerkt, dass die 600 mb/s nur bei 4 Threads, x64 und übertaktung erreicht werden ^^ Bei einem Thread und normaler Taktung sind es in-place bei x32 110mb/s und bei x64 160mb/s.
    x64 ist schneller, weil laut disasm die extra Register genutzt werden.
     
  6. Golly
    Golly Neu
    Stammnutzer
    #5 9. Januar 2011
    AW: AES 256-Bit Ver-Entschlüsselung (DLL)

    Verdammt bin ich gut :p

    Deinen Code schaue ich mir erstmal nicht an, mein Kopf tut so schon weh...
    Werde wie gesagt, zunächst das mit den verschobenem Offset probieren, dann guck ich mal wie ich den Rest noch zusammenfasse.

    Mit 110-160mb/s liegt man ja schon nahe an den Werten von meinem TrueCrypt Benchmark.
    Hatte mir den TrueCrypt-Code nicht weiter angeschaut, bis auf wie gesagt die gleichen Tabellen die mir sofort ins Auge gestochen sind.
    Da wird aber auch viel mit Assembler gearbeitet.
     
  7. razor90
    razor90 user nr. 1000
    Stammnutzer
    #6 9. Januar 2011
    AW: AES 256-Bit Ver-Entschlüsselung (DLL)

    Hehe, so ging es mir damals auch und jetzt wieder beim Anblick meines alten Codes^^
    Arbeite dich am besten Schritt für Schritt vor, dann kann man es sogar halbwegs verstehen ;)

    Hast du deinen Code eigentlich schon mit Test-Vektoren getestet?

    Jo, ist bei mir auch fast genau so schnell wie der TrueCrypt-Bench. Die letzten paar mb/s bekommt man nur noch mit ASM und evtl. SSE. Aber ob sich der Aufwand als Hobbyist lohnt?
    Ich habe z.B. nur die Verschlüsselung implementiert. Für die Entschlüsselung fehlte mir dann die Lust^^
     
  8. Golly
    Golly Neu
    Stammnutzer
    #7 9. Januar 2011
    AW: AES 256-Bit Ver-Entschlüsselung (DLL)

    Was meinst du mit Test-Vektoren ?

    Habe da paar Beispiel Inputs/Keys vom Rijndael-Inspektor und vom NIST-Paper, wenn du das meinst.

    Sehe ich auch so, man muss nicht übertreiben, zumal ich mit dem Algo von vornherein auch keine großen Dateien ver-/ent-schlüsseln wollte.
     
  9. razor90
    razor90 user nr. 1000
    Stammnutzer
    #8 9. Januar 2011
    AW: AES 256-Bit Ver-Entschlüsselung (DLL)

    Genau die meine ich :D
     
  10. Golly
    Golly Neu
    Stammnutzer
    #9 9. Januar 2011
    AW: AES 256-Bit Ver-Entschlüsselung (DLL)

    /////////////////////////////// UPDATE //////////////////////////////////////////

    -Ver-&Ent-Schlüsselung optimiert (nach Rat von razor90 und nach bestem Wissen und Gewissen - bis auf SubBytes ~.~)
    -CBC-Modus eingebaut
    -Aus Performance-Gründen (3x schneller) wird der Code in "eigenständige" Header-Datei (ohne Umweg über DLL) ausgelagert und zusätzlich angeboten.

    ///////////////////////////////////////////////////////////////////////////////////


    Das ganze sollte jetzt wie gewünscht laufen, wurde jedoch aus Zeitmangel noch nicht auf Herz und Nieren getestet.
     

  11. Videos zum Thema