Cryptography 有没有一种快速的方法使IBM';VNS密码指令结果是否与Intels mm_aesdec_si128相同?

Cryptography 有没有一种快速的方法使IBM';VNS密码指令结果是否与Intels mm_aesdec_si128相同?,cryptography,aes,powerpc,aes-ni,Cryptography,Aes,Powerpc,Aes Ni,我正在移植一个应用程序,它使用AES加密和解密指令将一些数据从x86随机化到POWER8。我用_mm_aesdec_si128指令撞到了墙上,它似乎做了一些与等效的IBM内置加密不同的事情。 第52-54页的文件提到,它遵循FIPS 197。 位于第305页的IBM文档也说它遵循FIPS197,唯一的区别是InvMixColumns的顺序和带round键的xor被翻转,但这会改变结果吗 如果结果不同,他们怎么能说他们遵循规范 下面的C程序在x86中运行良好,但将在ppc64中为aesdec输出错

我正在移植一个应用程序,它使用AES加密和解密指令将一些数据从x86随机化到POWER8。我用_mm_aesdec_si128指令撞到了墙上,它似乎做了一些与等效的IBM内置加密不同的事情。 第52-54页的文件提到,它遵循FIPS 197。 位于第305页的IBM文档也说它遵循FIPS197,唯一的区别是InvMixColumns的顺序和带round键的xor被翻转,但这会改变结果吗

如果结果不同,他们怎么能说他们遵循规范

下面的C程序在x86中运行良好,但将在ppc64中为aesdec输出错误的结果。谢天谢地,ppc64中的aesenc按照预期工作

目前,我通过使用aesdec的软件实现解决了这个问题,但我想在硬件上完成所有工作

C程序:

//compile with "gcc -maes aestest.c -o aestest" in x86
//compile with "gcc -mcrypto -flax-vector-conversions aestest.c -o aestest" in power8

#include <stdio.h>
#include <stdint.h>
#include <string.h>

#ifdef __x86_64__
#include <x86intrin.h>
__m128i aesenc(__m128i d,__m128i k){
  return _mm_aesenc_si128(d,k);
}
__m128i aesdec(__m128i d,__m128i k){
  return _mm_aesdec_si128(d,k);
}
#endif

#ifdef __PPC64__
#include <endian.h>
#include <altivec.h>
#undef vector
#undef pixel
#undef bool
typedef __vector uint8_t __m128i;

//flip vector to BE order
__m128i vrev(__m128i v){
  #if __BYTE_ORDER == __BIG_ENDIAN
  return v;
  #else
  return vec_perm(v,(__m128i){0},(__m128i){15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0});
  #endif
}
__m128i aesenc(__m128i d,__m128i k){
  return vrev(__builtin_crypto_vcipher(vrev(d),vrev(k)));
}
__m128i aesdec(__m128i d,__m128i k){
  return vrev(__builtin_crypto_vncipher(vrev(d),vrev(k)));
}
#endif

void print_m128(char* msg,  __m128i v){
   uint8_t* t = (uint8_t*)&v;
   printf("%s: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",msg,t[0],t[1],t[2],t[3], t[4],t[5],t[6],t[7], t[8],t[9],t[10],t[11], t[12],t[13],t[14],t[15]) ;
}


int main(int argc,char* argv[]){
  uint8_t msg[] = "0123456789abcde"; 
  uint8_t key1[] = {255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255};
  uint8_t key2[] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
  uint8_t* c;
  __m128i xmm1 = (__m128i){0};
  __m128i xmm2 = (__m128i){0};
  __m128i encR = (__m128i){0};
  __m128i decR = (__m128i){0};
//zero test
  printf("zero test\n");
  print_m128("xmm1",xmm1);
  print_m128("xmm2",xmm2);
  encR = aesenc(xmm1,xmm2);
  decR = aesdec(xmm1,xmm2);
  print_m128("enc ",encR);
  print_m128("dec ",decR);
//zero key test
  printf("zero key test\n");
  c = (uint8_t*)&xmm1;
  memcpy(c,msg,16);
  print_m128("xmm1",xmm1);
  print_m128("xmm2",xmm2);
  encR = aesenc(xmm1,xmm2);
  decR = aesdec(xmm1,xmm2);
  print_m128("enc ",encR);
  print_m128("dec ",decR);
//ff key test
  printf("ff key test\n");
  c = (uint8_t*)&xmm1;
  memcpy(c,msg,16);
  c = (uint8_t*)&xmm2;
  memcpy(c,key1,16);
  print_m128("xmm1",xmm1);
  print_m128("xmm2",xmm2);
  encR = aesenc(xmm1,xmm2);
  decR = aesdec(xmm1,xmm2);
  print_m128("enc ",encR);
  print_m128("dec ",decR);
//key test
  printf("key test\n");
  c = (uint8_t*)&xmm1;
  memcpy(c,msg,16);
  c = (uint8_t*)&xmm2;
  memcpy(c,key2,16);
  print_m128("xmm1",xmm1);
  print_m128("xmm2",xmm2);
  encR = aesenc(xmm1,xmm2);
  decR = aesdec(xmm1,xmm2);
  print_m128("enc ",encR);
  print_m128("dec ",decR);
}

最后一次测试失败。

< P>解决方案是使用零键在中间返回标识中生成XOR步骤,然后在结束时用真正的键XORE。

__m128i aesd(__m128i d,__m128i k){
  __m128i out = vrev(__builtin_crypto_vncipher(vrev(d),(__m128i){0}));
  return vec_xor(out,k);
}

感谢特瓦多的建议
__m128i aesd(__m128i d,__m128i k){
  __m128i out = vrev(__builtin_crypto_vncipher(vrev(d),(__m128i){0}));
  return vec_xor(out,k);
}