Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.

AES Cryptography Primitive Malfunctioning?

ckentitt
Beginner
676 Views
When I use the 256 bit AES encryption primitives in OFB mode with the test vectors provided by NIST (http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf), I do not get the right encrypted or decrypted results.

According to the document using:

Key = 60 3d eb 10 15 ca 71 be 2b 73 ae f0 85 7d 77 81 1f 35 2c 07 3b 61 08 d7 2d 98 10 a3 09 14 df f4

IV = 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f

Plain Text = 6b c1 be e2 2e 40 9f 96 e9 3d 7e 11 73 93 17 2a

I should obtain:

Cipher Text = dc 7e 84 bf da 79 16 4b 7e cd 84 86 98 5d 38 60

I have confirmed that I get these results with both the Java cryptography library, and the open source Crypto++ C++ library, yet the Intel one does not produce these results.
[cpp]#include 
#include "aes.h"
#include "ippcp.h"
using namespace std;

int main()
{
	Ipp8u i_key[32] = {0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73,
					   0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07,
					   0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14,
					   0xdf, 0xf4};

	Ipp8u i_iv[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
					  0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};

	Ipp8u i_data[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d,
						0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

	Ipp8u i_enc_data[16];
	Ipp8u i_dec_data[16];

	int context_size;
	ippsRijndael256GetSize(&context_size);
	IppsRijndael256Spec* aes_spec = (IppsRijndael256Spec*)(new Ipp8u[context_size]);
	ippsRijndael256Init(i_key, IppsRijndaelKey256, aes_spec);
	ippsRijndael256EncryptOFB(i_data, i_enc_data, 16, 1, aes_spec, i_iv);
	ippsRijndael256DecryptOFB(i_enc_data, i_dec_data, 16, 1, aes_spec, i_iv);

	cout << "Encrypted: ";
	for (int i = 0; i < 16; ++i)
		printf("%x ", i_enc_data);
	cout << endl << "Decrypted: ";
	for (int i = 0; i < 16; ++i)
		printf("%x ", i_dec_data);
	cout << endl;

	return 0;
}
[/cpp]
Any thoughts?
Thanks,
Chris
0 Kudos
1 Solution
achrzesz2
New Contributor I
676 Views
Hello Chris
In the example from sp800-38a.pdf you are intersted
the plain-text
cipher-text
initial vector
have 128-bits (no 256-bits)

Only the key is 256-bit long

THAT IS AES 256-BIT ENCRYPTION

A quote from FIPS 197:

This standard specifies the Rijndael algorithm ([3] and [4]),
a symmetric block cipher that can
process data blocks of 128 bits,
using cipher keys with lengths of 128, 192, and 256 bits.
Rijndael was designed to handle additional block sizes and key lengths,
however they are not adopted in this standard.

View solution in original post

0 Kudos
7 Replies
achrzesz2
New Contributor I
676 Views
Hello Chris
Tray this way:




#include
#include
#include
#include "ippcp.h"
using namespace std;

int main()
{
Ipp8u i_key[32] = {0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73,
0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07,
0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14,
0xdf, 0xf4};

Ipp8u i_iv0[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
Ipp8u i_iv[16];
memcpy(i_iv,i_iv0,sizeof(i_iv0));

Ipp8u i_data[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d,
0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

Ipp8u i_enc_data[16];
Ipp8u i_dec_data[16];

int context_size;
ippsRijndael128GetSize(&context_size);
IppsRijndael128Spec* aes_spec = (IppsRijndael128Spec*)(new Ipp8u[context_size]);
ippsRijndael128Init(i_key, IppsRijndaelKey256, aes_spec);
ippsRijndael128EncryptOFB(i_data, i_enc_data, 16, 16, aes_spec, i_iv0);
ippsRijndael128DecryptOFB(i_enc_data, i_dec_data, 16, 16, aes_spec, i_iv);

cout << "Encrypted: ";
for (int i = 0; i < 16; ++i)
printf("%x ", i_enc_data);
cout << endl << "Decrypted: ";
for (int i = 0; i < 16; ++i)
printf("%x ", i_dec_data);
cout << endl;

return 0;
}



1) AES=Rijndael128
2)Note: IppsRijndaelKey256
3)IV shold be copied

Andrzej Ch
0 Kudos
ckentitt
Beginner
676 Views
Thanks for the reply.
So I see you've copied the IV, which I'm guessing is because the IV is updated to the next one after running encrypt and I need the same IV to decrypt. That's fine but that would only explain a problem in the decryption stage, not the encryption, and the encryption results do not match the official results.
You've also changed from 256 bit AES to 128. I do not want 128 bit, nor should that be a factor in why the 256 bit version is not working.
Finally, I see you changed the OFB block size to 16 instead of 1, I have tried both and neither produce a correct result.
Or am I missing something in your post?
-Chris
0 Kudos
achrzesz2
New Contributor I
676 Views
Hello Chris
The modifieded code gives right encrryption dc 7e 84 bf da 79 16 4b 7e cd 84 86 98 5d 38 60
I can repeat that in standard AES only Rijndael128 algorithm can be used
The 256 means key-length not block length

Andrzej Ch
0 Kudos
ckentitt
Beginner
676 Views
I'm aware that the 256 is the key-length, that is what I want! I want 256 bit encryption, not 128. The fact that 128 works, does not change my question as to why 256 does not.
0 Kudos
achrzesz2
New Contributor I
677 Views
Hello Chris
In the example from sp800-38a.pdf you are intersted
the plain-text
cipher-text
initial vector
have 128-bits (no 256-bits)

Only the key is 256-bit long

THAT IS AES 256-BIT ENCRYPTION

A quote from FIPS 197:

This standard specifies the Rijndael algorithm ([3] and [4]),
a symmetric block cipher that can
process data blocks of 128 bits,
using cipher keys with lengths of 128, 192, and 256 bits.
Rijndael was designed to handle additional block sizes and key lengths,
however they are not adopted in this standard.
0 Kudos
ckentitt
Beginner
676 Views
Ah!!!
I get it - the 256 in the primitive I was using is the block size, not the key length. That's odd, I would've thought it the other way around. Sorry for the confusion! Thanks for your help.
-Chris
0 Kudos
Ying_H_Intel
Employee
676 Views

Hi Chris, Andrzej,

Thanks for the good discussion. Exactly, the IPPRigndael256 is the data block size and AES256 means the 256 key size.

In general, AES uses only and only 16 bytes (128 bits) data block size - pieces of plane- or cipher text. AES std does not define AES for other data block size.

According to std and practice AES-128, AES-192 and AES-256 means 128-bit cipher (AES) but with different size of key (128, 192 and 256 bit correspondingly).


While IPP Rigndael256 means implementation of general Rijndael algorithm with 256 bit data block size.

So the result are different. And Andrzej's modification is exactly right.

Thanks
Ying

0 Kudos
Reply