Advanced Encryption Standard AES - Rijndael - Assembler optimiert
Zum Code
In diesem Projekt habe ich meine eigene Implementierung von AES (Rijndael) verwirklicht. AES ist der Nachfolger vom alten Verschlüsselungsstandard DES (bzw. später Triple-DES). Wer mehr über AES erfahren möchte, kann sich bei Wikipedia informieren: http://de.wikipedia.org/wiki/AES

Die korrekte Ausführung des Algorithmus wird mittels einem einfachem Testmodul überprüft. Dennoch kann ich keine Fehlerlosigkeit garantieren, korrigiere aber gerne jeden Fehler den jemand findet. Für eine weitergehende sicherheitsrelevante Anwendung ist die Implementierung nicht ausreichend abgeschirmt, da weder Variablen gelöscht werden noch sonstige Daten abgeschirmt sind. Zusätzlich zum Testmodul existiert ein Speedtest-Modul, mit welchem die Ausführungszeit für einen Durchlauf gemessen werden kann. Hieraus wird zudem der theoretische Datendurchsatz errechnet.

Die Referenzimplementierung ist in reinem VB abgehandelt und kommentiert. Die Kommentare setzen allerdings Kenntnis von der Materie voraus. Theoretisch dürfte der Referenzcode mit allen vorgesehenen Bitlängen (128/196/256 Bit sowohl für Blöcke als auch Schlüssel) zurecht kommen. Zwecks verbesserter Performanz habe ich die Verschlüsselungsroutine ebenfalls in Assembler zur Verfügung gestellt. Diese Variante ist jedoch auf 128 Bit für die Blöcke und die Schlüssel begrenzt. Der beiliegende Assemblercode ist für MASM vorgesehen. Auf meinem Athlon XP2200+ erreicht die optimierte Variante einen theoretischen Datendurchsatz von ~72 Mb/s.

History
24.09.2004 Hinzugefügt
16.10.2004 Entschlüsselung nun auch in Assembler vorhanden

Autor: Dominik Auras <Dominik_auf_vbInside.de>

Code aus SpeedTest.bas
Option Explicit

Private Declare Function QueryPerformanceCounter Lib "kernel32" _
(lpPerformanceCount As Currency) As Long
Private Declare Function QueryPerformanceFrequency Lib "kernel32" _
(lpFrequency As Currency) As Long

Public CPU_Takt As Currency, Overhead As Currency

Private Const k_msec As Currency = 1000
Private Const k_usec As Currency = 1000000
Private Const k_nsec As Currency = 1000000000

Public Sub Speed_Test()
Dim block1(3, 3) As Byte, i As Long, n As Long, block2(3, 3) As Byte
Dim c As Long, key(15) As Byte, l As Long, y As Currency, c1 As _
Currency
Dim c2 As Currency, clk As New cCpuClk

Randomize Timer

Init_Speedtest

For i = 0 To UBound(key)
key(c) = Int(Rnd * 255)
Next i
KeyExpansion key, (UBound(block1, 1) + 1) * 32

Set_Random block1
Copy_Block block1, block2

y = 0
Rijndael_EncryptBlock block1
For i = 1 To 1000
clk.CpuClk c1
Rijndael_EncryptBlock block1
clk.CpuClk c2
y = y + (c2 - c1 - Overhead)
Next i
y = y / 1000

Log "Benötigte Zeit: " & CStr(usec(y)) & " µs (Verschlüsselung)"
Log "Durchsatz: " & Format$(CStr(Round(16 / sec(y), 2)), _
"###,###,###.00") & " B/s"

y = 0
Rijndael_DecryptBlock block1
For i = 1 To 1000
clk.CpuClk c1
Rijndael_DecryptBlock block1
clk.CpuClk c2
y = y + (c2 - c1 - Overhead)
Next i
y = y / 1000
Check_Block block1, block2

Log "Benötigte Zeit: " & CStr(usec(y)) & " µs (Entschlüsselung)"
Log "Durchsatz: " & Format$(CStr(Round(16 / sec(y), 2)), _
"###,###,###.00") & " B/s"
End Sub

Public Sub Init_Speedtest()
Dim cCycles As Currency, cStart As Currency, cStop As Currency, _
cNow As Currency
Dim c1 As Currency, c2 As Currency, clk As New cCpuClk, Factor _
As Currency, i As Long

For i = 1 To 1000
clk.CpuClk c1
clk.CpuClk c2
Next i
Overhead = c2 - c1

Call QueryPerformanceFrequency(cCycles)

Call clk.CpuClk(c1)
Call QueryPerformanceCounter(cStart)
cStop = cStart + cCycles

Do
Call QueryPerformanceCounter(cNow)
Loop Until (cNow >= cStop)
Call clk.CpuClk(c2)
c2 = c2 - c1 - Overhead
Factor = (cNow - cStart) / cCycles
CPU_Takt = c2 / Factor
End Sub

Public Function sec(ByVal zeit As Currency) As Double
sec = zeit / CPU_Takt
End Function

Public Function msec(ByVal zeit As Currency) As Double
msec = zeit / CPU_Takt * k_msec
End Function

Public Function usec(ByVal zeit As Currency) As Double
usec = zeit / CPU_Takt * k_usec
End Function

Public Function nsec(ByVal zeit As Currency) As Double
nsec = zeit / CPU_Takt * k_nsec
End Function

Private Sub Set_Random(block() As Byte)
Dim i As Long, n As Long

For i = 0 To 3
For n = 0 To 3
block(i, n) = Int(Rnd * 255)
Next n
Next i
End Sub

Private Sub Copy_Block(block() As Byte, block2() As Byte)
Dim i As Long, n As Long

For i = 0 To 3
For n = 0 To 3
block2(i, n) = block(i, n)
Next n
Next i
End Sub

Private Sub Check_Block(block() As Byte, block2() As Byte)
Dim i As Long, n As Long

For i = 0 To 3
For n = 0 To 3
If block(i, n) <> block2(i, n) Then
Log "Fehler aufgetreten: Speed_Test"
PrintBlock block
PrintBlock block2
End If
Next n
Next i
End Sub