Example program

As you have noticed, the previous two sections (AES-NI and SSE) were left without proper examples. The reason is that the best way to demonstrate the abilities of both extensions would be to mix them in a single program. In this section, we will implement a simple AES-128 encryption algorithm with the help of the two. AES encryption is one the classic examples of an algorithm that would definitely benefit from parallel processing of data offered by SSE.

We will use the templates we prepared in the beginning of this chapter, thus, all we have to do is write the following code in place of this comment:

;
; Put your code here
;

The code runs equally well on both Windows and Linux, so no other preparations required:

 ; First of all we have to expand the key
; into AES key schedule.
lea esi, [k]
movups xmm1, [esi]
lea edi, [s]

; Copy initial key to schedule
mov ecx, 4
rep movsd
; Expand the key
call aes_set_encrypt_key

; Actually encrypt data
lea esi, [s] ; ESI points to key schedule
lea edi, [r] ; EDI points to result buffer
lea eax, [d] ; EAX points to data we want
; to encrypt
movups xmm0, [eax] ; Load this data to XMM0

; Call the AES128 encryption procedure
call aes_encrypt

; Nicely terminate the process
push 0
call [exitProcess]


; AES128 encryption procedure
aes_encrypt: ; esi points to key schedule
; edi points to output buffer
; xmm0 contains data to be encrypted
mov ecx, 9
movups xmm1, [esi]
add esi, 0x10
pxor xmm0, xmm1 ; Add the first round key

.encryption_loop:
movups xmm1, [esi] ; Load next round key
add esi, 0x10
aesenc xmm0, xmm1 ; Perform encryption round
loop .encryption_loop

movups xmm1, [esi] ; Load last round key
aesenclast xmm0, xmm1 ; Perform the last encryption round

lea edi, [r]
movups [edi], xmm0 ; Store encrypted data
ret

; AES128 key setup procedures
; This procedure creates full
; AES128 encryption key schedule
aes_set_encrypt_key: ; xmm1 contains the key
; edi points to key schedule
aeskeygenassist xmm2, xmm1, 1
call key_expand
aeskeygenassist xmm2, xmm1, 2
call key_expand
aeskeygenassist xmm2, xmm1, 4
call key_expand
aeskeygenassist xmm2, xmm1, 8
call key_expand
aeskeygenassist xmm2, xmm1, 0x10
call key_expand
aeskeygenassist xmm2, xmm1, 0x20
call key_expand
aeskeygenassist xmm2, xmm1, 0x40
call key_expand
aeskeygenassist xmm2, xmm1, 0x80
call key_expand
aeskeygenassist xmm2, xmm1, 0x1b
call key_expand
aeskeygenassist xmm2, xmm1, 0x36
call key_expand
ret

key_expand: ; xmm2 contains key portion
; edi points to place in schedule
; where this portion should
; be stored at
pshufd xmm2, xmm2, 0xff ; Set all elements to 4th element
vpslldq xmm3, xmm1, 0x04 ; Shift XMM1 4 bytes left
; store result to XMM3
pxor xmm1, xmm3
vpslldq xmm3, xmm1, 0x04
pxor xmm1, xmm3
vpslldq xmm3, xmm1, 0x04
pxor xmm1, xmm3
pxor xmm1, xmm2
movups [edi], xmm1
add edi, 0x10
ret

The following should be placed in the data section/segment:

 ; Data to be encrypted
d db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa,0xb, 0xc, 0xd, 0xe, 0xf

; Encryption key
k db 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1

; AES key schedule (11 round keys, 16 bytes each)
s rb 16 * 11

; Result will be placed here
r rb 16
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset