Reputation: 7613
I'm trying to implement AES cryptography using the AES machine instructions (basing it on Intel's white paper) available on my Sandy Bridge. Unfortunately, I've come to a halt in the phase of generating the round keys for decryption. Specifically, the instruction aesimc
(applying the Inverse Mix Columns operation) returns an incorrect result.
In their paper they have an example:
So with input:
48 69 28 53 68 61 79 29 5B 47 75 65 72 6F 6E 5D
I get the following using _mm_aesimc_si128()
:
2D BF F9 31 99 CD 3A 37 B7 C7 81 FD 7D E0 3D 8E
It should have returned:
62 7A 6F 66 44 B1 09 C8 2B 18 33 0A 81 C3 B3 E5
Not the same result. Why is this the case?
If you want to reproduce it, I tested it with the code below (remember the arguments -maes -msse4
when compiling):
#include <wmmintrin.h>
#include <iostream>
using namespace std;
void print_m128i(__m128i data) {
unsigned char *ptr = (unsigned char*) &data;
for (int i = 0; i < 16; i++) {
int val = (int) ptr[i];
if (val < 0xF) {
cout << "0";
}
cout << uppercase << hex << val << " ";
}
cout << endl;
}
int main() {
unsigned char *data = (unsigned char*)
"\x48\x69\x28\x53\x68\x61\x79\x29\x5B\x47\x75\x65\x72\x6F\x6E\x5D";
__m128i num = _mm_loadu_si128((__m128i*) data);
__m128i num2 = _mm_aesimc_si128(num);
print_m128i(num2);
return 0;
}
EDIT: The example in Intel's white paper was wrong. As Hans suggested, my chip is little-endian so byte-swapping is necessary - to and fro.
Upvotes: 2
Views: 576
Reputation: 941208
The bytes are backwards. You want 0x5d to be the least significant byte, it has to come first. This is a little-endian chip. In VS, use Debug + Windows + Registers, right-click + tick SSE to see the register values.
Upvotes: 2