00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 #ifndef __Random123_aes_dot_hpp__
00033 #define __Random123_aes_dot_hpp__
00034 
00035 #include "features/compilerfeatures.h"
00036 #include "array.h"
00037 
00038 
00039 
00040 #if R123_USE_AES_NI
00041 
00043 typedef struct r123array1xm128i aesni1xm128i_ctr_t;
00045 typedef struct r123array1xm128i aesni1xm128i_ukey_t;
00047 typedef struct r123array4x32 aesni4x32_ukey_t;
00049 enum r123_enum_aesni1xm128i { aesni1xm128i_rounds = 10 };
00050 
00052 R123_STATIC_INLINE __m128i AES_128_ASSIST (__m128i temp1, __m128i temp2) { 
00053     __m128i temp3; 
00054     temp2 = _mm_shuffle_epi32 (temp2 ,0xff); 
00055     temp3 = _mm_slli_si128 (temp1, 0x4);
00056     temp1 = _mm_xor_si128 (temp1, temp3);
00057     temp3 = _mm_slli_si128 (temp3, 0x4);
00058     temp1 = _mm_xor_si128 (temp1, temp3);
00059     temp3 = _mm_slli_si128 (temp3, 0x4);
00060     temp1 = _mm_xor_si128 (temp1, temp3);
00061     temp1 = _mm_xor_si128 (temp1, temp2); 
00062     return temp1; 
00063 }
00064 
00065 R123_STATIC_INLINE void aesni1xm128iexpand(aesni1xm128i_ukey_t uk, __m128i ret[11])
00066 {
00067     __m128i rkey = uk.v[0].m;
00068     __m128i tmp2;
00069 
00070     ret[0] = rkey;
00071     tmp2 = _mm_aeskeygenassist_si128(rkey, 0x1);
00072     rkey = AES_128_ASSIST(rkey, tmp2);
00073     ret[1] = rkey;
00074 
00075     tmp2 = _mm_aeskeygenassist_si128(rkey, 0x2);
00076     rkey = AES_128_ASSIST(rkey, tmp2);
00077     ret[2] = rkey;
00078 
00079     tmp2 = _mm_aeskeygenassist_si128(rkey, 0x4);
00080     rkey = AES_128_ASSIST(rkey, tmp2);
00081     ret[3] = rkey;
00082 
00083     tmp2 = _mm_aeskeygenassist_si128(rkey, 0x8);
00084     rkey = AES_128_ASSIST(rkey, tmp2);
00085     ret[4] = rkey;
00086 
00087     tmp2 = _mm_aeskeygenassist_si128(rkey, 0x10);
00088     rkey = AES_128_ASSIST(rkey, tmp2);
00089     ret[5] = rkey;
00090 
00091     tmp2 = _mm_aeskeygenassist_si128(rkey, 0x20);
00092     rkey = AES_128_ASSIST(rkey, tmp2);
00093     ret[6] = rkey;
00094 
00095     tmp2 = _mm_aeskeygenassist_si128(rkey, 0x40);
00096     rkey = AES_128_ASSIST(rkey, tmp2);
00097     ret[7] = rkey;
00098 
00099     tmp2 = _mm_aeskeygenassist_si128(rkey, 0x80);
00100     rkey = AES_128_ASSIST(rkey, tmp2);
00101     ret[8] = rkey;
00102 
00103     tmp2 = _mm_aeskeygenassist_si128(rkey, 0x1b);
00104     rkey = AES_128_ASSIST(rkey, tmp2);
00105     ret[9] = rkey;
00106 
00107     tmp2 = _mm_aeskeygenassist_si128(rkey, 0x36);
00108     rkey = AES_128_ASSIST(rkey, tmp2);
00109     ret[10] = rkey;
00110 }
00113 #ifdef __cplusplus
00114 
00115 struct aesni1xm128i_key_t{ 
00116     __m128i k[11]; 
00117     aesni1xm128i_key_t(){
00118         aesni1xm128i_ukey_t uk;
00119         uk.v[0].m = _mm_setzero_si128();
00120         aesni1xm128iexpand(uk, k);
00121     }
00122     aesni1xm128i_key_t(const aesni1xm128i_ukey_t& uk){
00123         aesni1xm128iexpand(uk, k);
00124     }
00125     aesni1xm128i_key_t(const aesni4x32_ukey_t& uk){
00126         aesni1xm128i_ukey_t uk128;
00127         uk128.v[0].m = _mm_set_epi32(uk.v[3], uk.v[2], uk.v[1], uk.v[0]);
00128         aesni1xm128iexpand(uk128, k);
00129     }
00130     aesni1xm128i_key_t& operator=(const aesni1xm128i_ukey_t& uk){
00131         aesni1xm128iexpand(uk, k);
00132         return *this;
00133     }
00134     aesni1xm128i_key_t& operator=(const aesni4x32_ukey_t& uk){
00135         aesni1xm128i_ukey_t uk128;
00136         uk128.v[0].m = _mm_set_epi32(uk.v[3], uk.v[2], uk.v[1], uk.v[0]);
00137         aesni1xm128iexpand(uk128, k);
00138         return *this;
00139     }
00140 };
00141 #else
00142 typedef struct { 
00143     __m128i k[11]; 
00144 }aesni1xm128i_key_t;
00145 
00147 R123_STATIC_INLINE aesni1xm128i_key_t aesni1xm128ikeyinit(aesni1xm128i_ukey_t uk){
00148     aesni1xm128i_key_t ret;
00149     aesni1xm128iexpand(uk, ret.k);
00150     return ret;
00151 }
00152 #endif
00153 
00155 R123_STATIC_INLINE aesni1xm128i_ctr_t aesni1xm128i(aesni1xm128i_ctr_t in, aesni1xm128i_key_t k) {
00156     __m128i x = _mm_xor_si128(k.k[0], in.v[0].m);
00157     x = _mm_aesenc_si128(x, k.k[1]);
00158     x = _mm_aesenc_si128(x, k.k[2]);
00159     x = _mm_aesenc_si128(x, k.k[3]);
00160     x = _mm_aesenc_si128(x, k.k[4]);
00161     x = _mm_aesenc_si128(x, k.k[5]);
00162     x = _mm_aesenc_si128(x, k.k[6]);
00163     x = _mm_aesenc_si128(x, k.k[7]);
00164     x = _mm_aesenc_si128(x, k.k[8]);
00165     x = _mm_aesenc_si128(x, k.k[9]);
00166     x = _mm_aesenclast_si128(x, k.k[10]);
00167     {
00168       aesni1xm128i_ctr_t ret;
00169       ret.v[0].m = x;
00170       return ret;
00171     }
00172 }
00173 
00175 R123_STATIC_INLINE aesni1xm128i_ctr_t aesni1xm128i_R(unsigned R, aesni1xm128i_ctr_t in, aesni1xm128i_key_t k){
00176     R123_ASSERT(R==10);
00177     return aesni1xm128i(in, k);
00178 }
00179 
00180 
00182 typedef struct r123array4x32 aesni4x32_ctr_t;
00184 typedef aesni1xm128i_key_t aesni4x32_key_t;
00186 enum r123_enum_aesni4x32 { aesni4x32_rounds = 10 };
00188 R123_STATIC_INLINE aesni4x32_key_t aesni4x32keyinit(aesni4x32_ukey_t uk){
00189     aesni1xm128i_ukey_t uk128;
00190     aesni4x32_key_t ret;
00191     uk128.v[0].m = _mm_set_epi32(uk.v[3], uk.v[2], uk.v[1], uk.v[0]);
00192     aesni1xm128iexpand(uk128, ret.k);
00193     return ret;
00194 }
00195 
00198 R123_STATIC_INLINE aesni4x32_ctr_t aesni4x32_R(unsigned int Nrounds, aesni4x32_ctr_t c, aesni4x32_key_t k){
00199     aesni1xm128i_ctr_t c128;
00200     c128.v[0].m = _mm_set_epi32(c.v[3], c.v[2], c.v[1], c.v[0]);
00201     c128 = aesni1xm128i_R(Nrounds, c128, k);
00202     _mm_storeu_si128((__m128i*)&c.v[0], c128.v[0].m);
00203     return c;
00204 }
00205 
00206 #define aesni4x32_rounds aesni1xm128i_rounds
00207 
00210 #define aesni4x32(c,k) aesni4x32_R(aesni4x32_rounds, c, k)
00211 
00212 #ifdef __cplusplus
00213 namespace r123{
00245 struct AESNI1xm128i{
00246     typedef aesni1xm128i_ctr_t ctr_type;
00247     typedef aesni1xm128i_ukey_t ukey_type;
00248     typedef aesni1xm128i_key_t key_type;
00249     static const unsigned int rounds=10;
00250     ctr_type operator()(ctr_type ctr, key_type key) const{
00251         return aesni1xm128i(ctr, key);
00252     }
00253 };
00254 
00255 
00256 struct AESNI4x32{
00257     typedef aesni4x32_ctr_t ctr_type;
00258     typedef aesni4x32_ukey_t ukey_type;
00259     typedef aesni4x32_key_t key_type;
00260     static const unsigned int rounds=10;
00261     ctr_type operator()(ctr_type ctr, key_type key) const{
00262         return aesni4x32(ctr, key);
00263     }
00264 };
00265 
00271 template <unsigned ROUNDS=10> 
00272 struct AESNI1xm128i_R : public AESNI1xm128i{
00273     R123_STATIC_ASSERT(ROUNDS==10, "AESNI1xm128i_R<R> is only valid with R=10");
00274 };
00275 
00277 template <unsigned ROUNDS=10> 
00278 struct AESNI4x32_R : public AESNI4x32{
00279     R123_STATIC_ASSERT(ROUNDS==10, "AESNI4x32_R<R> is only valid with R=10");
00280 };
00281 } 
00282 #endif 
00283 
00284 #endif 
00285 
00286 #if R123_USE_AES_OPENSSL
00287 #include <openssl/aes.h>
00288 typedef struct r123array16x8 aesopenssl16x8_ctr_t;
00289 typedef struct r123array16x8 aesopenssl16x8_ukey_t;
00290 #ifdef __cplusplus
00291 struct aesopenssl16x8_key_t{
00292     AES_KEY k;
00293     aesopenssl16x8_key_t(){
00294         aesopenssl16x8_ukey_t ukey={{}};
00295         AES_set_encrypt_key((const unsigned char *)&ukey.v[0], 128, &k);
00296     }
00297     aesopenssl16x8_key_t(const aesopenssl16x8_ukey_t& ukey){
00298         AES_set_encrypt_key((const unsigned char *)&ukey.v[0], 128, &k);
00299     }
00300     aesopenssl16x8_key_t& operator=(const aesopenssl16x8_ukey_t& ukey){
00301         AES_set_encrypt_key((const unsigned char *)&ukey.v[0], 128, &k);
00302         return *this;
00303     }
00304 };
00305 #else
00306 typedef struct aesopenssl16x8_key_t{
00307     AES_KEY k;
00308 }aesopenssl16x8_key_t;
00309 R123_STATIC_INLINE struct aesopenssl16x8_key_t aesopenssl16x8keyinit(aesopenssl16x8_ukey_t uk){
00310     aesopenssl16x8_key_t ret;
00311     AES_set_encrypt_key((const unsigned char *)&uk.v[0], 128, &ret.k);
00312     return ret;
00313 }
00314 #endif
00315 
00316 R123_STATIC_INLINE R123_FORCE_INLINE(aesopenssl16x8_ctr_t aesopenssl16x8_R(aesopenssl16x8_ctr_t ctr, aesopenssl16x8_key_t key));
00317 R123_STATIC_INLINE
00318 aesopenssl16x8_ctr_t aesopenssl16x8_R(aesopenssl16x8_ctr_t ctr, aesopenssl16x8_key_t key){
00319     aesopenssl16x8_ctr_t ret;
00320     AES_encrypt((const unsigned char*)&ctr.v[0], (unsigned char *)&ret.v[0], &key.k);
00321     return ret;
00322 }
00323 
00324 #define aesopenssl16x8_rounds aesni4x32_rounds
00325 #define aesopenssl16x8(c,k) aesopenssl16x8_R(aesopenssl16x8_rounds)
00326 
00327 #ifdef __cplusplus
00328 namespace r123{
00329 struct AESOpenSSL16x8{
00330     typedef aesopenssl16x8_ctr_t ctr_type;
00331     typedef aesopenssl16x8_key_t key_type;
00332     typedef aesopenssl16x8_ukey_t ukey_type;
00333     static const unsigned int rounds=10;
00334     ctr_type operator()(const ctr_type& in, const key_type& k){
00335         ctr_type out;
00336         AES_encrypt((const unsigned char *)&in[0], (unsigned char *)&out[0], &k.k);
00337         return out;
00338     }
00339 };
00340 } 
00341 #endif 
00342 #endif 
00343 
00344 #endif