Bladeren bron

Add new AES and AES-NI implementation from pycrypto. Implement small

wrapper for it and default to AES software implementation for now.
tags/v1.0
Bernhard Fröhlich 5 jaren geleden
bovenliggende
commit
08a9b3cc8a
6 gewijzigde bestanden met toevoegingen van 1792 en 1300 verwijderingen
  1. 1456
    0
      AES.c
  2. 282
    0
      AESNI.c
  3. 3
    3
      Makefile
  4. 0
    1238
      aes.c
  5. 22
    41
      aes.h
  6. 29
    18
      drmdecrypt.c

+ 1456
- 0
AES.c
Diff onderdrukt omdat het te groot bestand
Bestand weergeven


+ 282
- 0
AESNI.c Bestand weergeven

@@ -0,0 +1,282 @@
1
+/*
2
+ *  AESNI.c: AES using AES-NI instructions
3
+ *
4
+ * Written in 2013 by Sebastian Ramacher <sebastian@ramacher.at>
5
+ *
6
+ * ===================================================================
7
+ * The contents of this file are dedicated to the public domain.  To
8
+ * the extent that dedication to the public domain is not available,
9
+ * everyone is granted a worldwide, perpetual, royalty-free,
10
+ * non-exclusive license to exercise all rights associated with the
11
+ * contents of this file for any purpose whatsoever.
12
+ * No rights are reserved.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
18
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ * ===================================================================
23
+ */
24
+
25
+#define HAVE_POSIX_MEMALIGN
26
+
27
+#include <wmmintrin.h>
28
+#include <stdlib.h>
29
+#include <string.h>
30
+#include <errno.h>
31
+#if defined(HAVE__ALIGNED_MALLOC)
32
+#include <malloc.h>
33
+#endif
34
+
35
+#define MODULE_NAME _AESNI
36
+#define BLOCK_SIZE 16
37
+#define KEY_SIZE 0
38
+
39
+#define MAXKC (256/32)
40
+#define MAXKB (256/8)
41
+#define MAXNR 14
42
+
43
+typedef unsigned char u8;
44
+
45
+typedef struct {
46
+    __m128i* ek;
47
+    __m128i* dk;
48
+    int rounds;
49
+} block_state;
50
+
51
+/* Wrapper functions for malloc and free with memory alignment */
52
+#if defined(HAVE_ALIGNED_ALLOC) /* aligned_alloc is defined by C11 */
53
+# define aligned_malloc_wrapper aligned_alloc
54
+# define aligned_free_wrapper free
55
+#elif defined(HAVE_POSIX_MEMALIGN) /* posix_memalign is defined by POSIX */
56
+static void* aligned_malloc_wrapper(size_t alignment, size_t size)
57
+{
58
+    void* tmp = NULL;
59
+    int err = posix_memalign(&tmp, alignment, size);
60
+    if (err != 0) {
61
+        /* posix_memalign does NOT set errno on failure; the error is returned */
62
+        errno = err;
63
+        return NULL;
64
+    }
65
+    return tmp;
66
+}
67
+# define aligned_free_wrapper free
68
+#elif defined(HAVE__ALIGNED_MALLOC) /* _aligned_malloc is available on Windows */
69
+static void* aligned_malloc_wrapper(size_t alignment, size_t size)
70
+{
71
+    /* NB: _aligned_malloc takes its args in the opposite order from aligned_alloc */
72
+    return _aligned_malloc(size, alignment);
73
+}
74
+# define aligned_free_wrapper _aligned_free
75
+#else
76
+# error "No function to allocate/free aligned memory is available."
77
+#endif
78
+
79
+/* Helper functions to expand keys */
80
+
81
+static __m128i aes128_keyexpand(__m128i key)
82
+{
83
+    key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
84
+    key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
85
+    return _mm_xor_si128(key, _mm_slli_si128(key, 4));
86
+}
87
+
88
+static __m128i aes192_keyexpand_2(__m128i key, __m128i key2)
89
+{
90
+    key = _mm_shuffle_epi32(key, 0xff);
91
+    key2 = _mm_xor_si128(key2, _mm_slli_si128(key2, 4));
92
+    return _mm_xor_si128(key, key2);
93
+}
94
+
95
+#define KEYEXP128_H(K1, K2, I, S) _mm_xor_si128(aes128_keyexpand(K1), \
96
+    _mm_shuffle_epi32(_mm_aeskeygenassist_si128(K2, I), S))
97
+
98
+#define KEYEXP128(K, I) KEYEXP128_H(K, K, I, 0xff)
99
+#define KEYEXP192(K1, K2, I) KEYEXP128_H(K1, K2, I, 0x55)
100
+#define KEYEXP192_2(K1, K2) aes192_keyexpand_2(K1, K2)
101
+#define KEYEXP256(K1, K2, I)  KEYEXP128_H(K1, K2, I, 0xff)
102
+#define KEYEXP256_2(K1, K2) KEYEXP128_H(K1, K2, 0x00, 0xaa)
103
+
104
+/* Encryption key setup */
105
+static void aes_key_setup_enc(__m128i rk[], const u8* cipherKey, int keylen)
106
+{
107
+    switch (keylen) {
108
+        case 16:
109
+        {
110
+            /* 128 bit key setup */
111
+            rk[0] = _mm_loadu_si128((const __m128i*) cipherKey);
112
+            rk[1] = KEYEXP128(rk[0], 0x01);
113
+            rk[2] = KEYEXP128(rk[1], 0x02);
114
+            rk[3] = KEYEXP128(rk[2], 0x04);
115
+            rk[4] = KEYEXP128(rk[3], 0x08);
116
+            rk[5] = KEYEXP128(rk[4], 0x10);
117
+            rk[6] = KEYEXP128(rk[5], 0x20);
118
+            rk[7] = KEYEXP128(rk[6], 0x40);
119
+            rk[8] = KEYEXP128(rk[7], 0x80);
120
+            rk[9] = KEYEXP128(rk[8], 0x1B);
121
+            rk[10] = KEYEXP128(rk[9], 0x36);
122
+            break;
123
+        }
124
+        case 24:
125
+        {
126
+            /* 192 bit key setup */
127
+            __m128i temp[2];
128
+            rk[0] = _mm_loadu_si128((const __m128i*) cipherKey);
129
+            rk[1] = _mm_loadu_si128((const __m128i*) (cipherKey+16));
130
+            temp[0] = KEYEXP192(rk[0], rk[1], 0x01);
131
+            temp[1] = KEYEXP192_2(temp[0], rk[1]);
132
+            rk[1] = (__m128i)_mm_shuffle_pd((__m128d)rk[1], (__m128d)temp[0], 0);
133
+            rk[2] = (__m128i)_mm_shuffle_pd((__m128d)temp[0], (__m128d)temp[1], 1);
134
+            rk[3] = KEYEXP192(temp[0], temp[1], 0x02);
135
+            rk[4] = KEYEXP192_2(rk[3], temp[1]);
136
+            temp[0] = KEYEXP192(rk[3], rk[4], 0x04);
137
+            temp[1] = KEYEXP192_2(temp[0], rk[4]);
138
+            rk[4] = (__m128i)_mm_shuffle_pd((__m128d)rk[4], (__m128d)temp[0], 0);
139
+            rk[5] = (__m128i)_mm_shuffle_pd((__m128d)temp[0], (__m128d)temp[1], 1);
140
+            rk[6] = KEYEXP192(temp[0], temp[1], 0x08);
141
+            rk[7] = KEYEXP192_2(rk[6], temp[1]);
142
+            temp[0] = KEYEXP192(rk[6], rk[7], 0x10);
143
+            temp[1] = KEYEXP192_2(temp[0], rk[7]);
144
+            rk[7] = (__m128i)_mm_shuffle_pd((__m128d)rk[7], (__m128d)temp[0], 0);
145
+            rk[8] = (__m128i)_mm_shuffle_pd((__m128d)temp[0], (__m128d)temp[1], 1);
146
+            rk[9] = KEYEXP192(temp[0], temp[1], 0x20);
147
+            rk[10] = KEYEXP192_2(rk[9], temp[1]);
148
+            temp[0] = KEYEXP192(rk[9], rk[10], 0x40);
149
+            temp[1] = KEYEXP192_2(temp[0], rk[10]);
150
+            rk[10] = (__m128i)_mm_shuffle_pd((__m128d)rk[10], (__m128d) temp[0], 0);
151
+            rk[11] = (__m128i)_mm_shuffle_pd((__m128d)temp[0],(__m128d) temp[1], 1);
152
+            rk[12] = KEYEXP192(temp[0], temp[1], 0x80);
153
+            break;
154
+        }
155
+        case 32:
156
+        {
157
+            /* 256 bit key setup */
158
+            rk[0] = _mm_loadu_si128((const __m128i*) cipherKey);
159
+            rk[1] = _mm_loadu_si128((const __m128i*) (cipherKey+16));
160
+            rk[2] = KEYEXP256(rk[0], rk[1], 0x01);
161
+            rk[3] = KEYEXP256_2(rk[1], rk[2]);
162
+            rk[4] = KEYEXP256(rk[2], rk[3], 0x02);
163
+            rk[5] = KEYEXP256_2(rk[3], rk[4]);
164
+            rk[6] = KEYEXP256(rk[4], rk[5], 0x04);
165
+            rk[7] = KEYEXP256_2(rk[5], rk[6]);
166
+            rk[8] = KEYEXP256(rk[6], rk[7], 0x08);
167
+            rk[9] = KEYEXP256_2(rk[7], rk[8]);
168
+            rk[10] = KEYEXP256(rk[8], rk[9], 0x10);
169
+            rk[11] = KEYEXP256_2(rk[9], rk[10]);
170
+            rk[12] = KEYEXP256(rk[10], rk[11], 0x20);
171
+            rk[13] = KEYEXP256_2(rk[11], rk[12]);
172
+            rk[14] = KEYEXP256(rk[12], rk[13], 0x40);
173
+            break;
174
+        }
175
+    }
176
+}
177
+
178
+/* Decryption key setup */
179
+static void aes_key_setup_dec(__m128i dk[], const __m128i ek[], int rounds)
180
+{
181
+	int i;
182
+    dk[rounds] = ek[0];
183
+    for (i = 1; i < rounds; ++i) {
184
+        dk[rounds - i] = _mm_aesimc_si128(ek[i]);
185
+    }
186
+    dk[0] = ek[rounds];
187
+}
188
+
189
+void block_init_aesni(block_state* self, unsigned char* key, int keylen)
190
+{
191
+    int nr = 0;
192
+    switch (keylen) {
193
+        case 16: nr = 10; break;
194
+        case 24: nr = 12; break;
195
+        case 32: nr = 14; break;
196
+        default:
197
+            return;
198
+    }
199
+
200
+    /* ensure that self->ek and self->dk are aligned to 16 byte boundaries */
201
+    void* tek = aligned_malloc_wrapper(16, (nr + 1) * sizeof(__m128i));
202
+    void* tdk = aligned_malloc_wrapper(16, (nr + 1) * sizeof(__m128i));
203
+    if (!tek || !tdk) {
204
+        aligned_free_wrapper(tek);
205
+        aligned_free_wrapper(tdk);
206
+        return;
207
+    }
208
+
209
+    self->ek = tek;
210
+    self->dk = tdk;
211
+
212
+    self->rounds = nr;
213
+    aes_key_setup_enc(self->ek, key, keylen);
214
+    aes_key_setup_dec(self->dk, self->ek, nr);
215
+}
216
+
217
+void block_finalize_aesni(block_state* self)
218
+{
219
+    /* overwrite contents of ek and dk */
220
+    memset(self->ek, 0, (self->rounds + 1) * sizeof(__m128i));
221
+    memset(self->dk, 0, (self->rounds + 1) * sizeof(__m128i));
222
+
223
+    aligned_free_wrapper(self->ek);
224
+    aligned_free_wrapper(self->dk);
225
+}
226
+
227
+void block_encrypt_aesni(block_state* self, const u8* in, u8* out)
228
+{
229
+    __m128i m = _mm_loadu_si128((const __m128i*) in);
230
+    /* first 9 rounds */
231
+    m = _mm_xor_si128(m, self->ek[0]);
232
+    m = _mm_aesenc_si128(m, self->ek[1]);
233
+    m = _mm_aesenc_si128(m, self->ek[2]);
234
+    m = _mm_aesenc_si128(m, self->ek[3]);
235
+    m = _mm_aesenc_si128(m, self->ek[4]);
236
+    m = _mm_aesenc_si128(m, self->ek[5]);
237
+    m = _mm_aesenc_si128(m, self->ek[6]);
238
+    m = _mm_aesenc_si128(m, self->ek[7]);
239
+    m = _mm_aesenc_si128(m, self->ek[8]);
240
+    m = _mm_aesenc_si128(m, self->ek[9]);
241
+    if (self->rounds != 10) {
242
+        /* two additional rounds for AES-192/256 */
243
+        m = _mm_aesenc_si128(m, self->ek[10]);
244
+        m = _mm_aesenc_si128(m, self->ek[11]);
245
+        if (self->rounds == 14) {
246
+            /* another two additional rounds for AES-256 */
247
+            m = _mm_aesenc_si128(m, self->ek[12]);
248
+            m = _mm_aesenc_si128(m, self->ek[13]);
249
+        }
250
+    }
251
+    m = _mm_aesenclast_si128(m, self->ek[self->rounds]);
252
+    _mm_storeu_si128((__m128i*) out, m);
253
+}
254
+
255
+void block_decrypt_aesni(block_state* self, const u8* in, u8* out)
256
+{
257
+    __m128i m = _mm_loadu_si128((const __m128i*) in);
258
+    /* first 9 rounds */
259
+    m = _mm_xor_si128(m, self->dk[0]);
260
+    m = _mm_aesdec_si128(m, self->dk[1]);
261
+    m = _mm_aesdec_si128(m, self->dk[2]);
262
+    m = _mm_aesdec_si128(m, self->dk[3]);
263
+    m = _mm_aesdec_si128(m, self->dk[4]);
264
+    m = _mm_aesdec_si128(m, self->dk[5]);
265
+    m = _mm_aesdec_si128(m, self->dk[6]);
266
+    m = _mm_aesdec_si128(m, self->dk[7]);
267
+    m = _mm_aesdec_si128(m, self->dk[8]);
268
+    m = _mm_aesdec_si128(m, self->dk[9]);
269
+    if (self->rounds != 10) {
270
+        /* two additional rounds for AES-192/256 */
271
+        m = _mm_aesdec_si128(m, self->dk[10]);
272
+        m = _mm_aesdec_si128(m, self->dk[11]);
273
+        if (self->rounds == 14) {
274
+            /* another two additional rounds for AES-256 */
275
+            m = _mm_aesdec_si128(m, self->dk[12]);
276
+            m = _mm_aesdec_si128(m, self->dk[13]);
277
+        }
278
+    }
279
+    m = _mm_aesdeclast_si128(m, self->dk[self->rounds]);
280
+    _mm_storeu_si128((__m128i*) out, m);
281
+}
282
+

+ 3
- 3
Makefile Bestand weergeven

@@ -3,7 +3,7 @@
3 3
 #
4 4
 
5 5
 CC	?= cc
6
-CFLAGS	+= -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
6
+CFLAGS	+= -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -maes
7 7
 
8 8
 INSTALL	= install -c
9 9
 STRIP	= strip
@@ -25,8 +25,8 @@ endif
25 25
 
26 26
 ##########################
27 27
 
28
-SRC	= aes.c drmdecrypt.c
29
-OBJS	= aes.o drmdecrypt.o
28
+SRC	= AES.c AESNI.c drmdecrypt.c
29
+OBJS	= AES.o AESNI.o drmdecrypt.o
30 30
 
31 31
 all:	drmdecrypt
32 32
 

+ 0
- 1238
aes.c
Diff onderdrukt omdat het te groot bestand
Bestand weergeven


+ 22
- 41
aes.h Bestand weergeven

@@ -1,54 +1,35 @@
1
-#include <stdio.h>
2
-#include <string.h>
3
-/**
4
- * rijndael-alg-fst.h
5
- *
6
- * @version 3.0 (December 2000)
7
- *
8
- * Optimised ANSI C code for the Rijndael cipher (now AES)
9
- *
10
- * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
11
- * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
12
- * @author Paulo Barreto <paulo.barreto@terra.com.br>
13
- *
14
- * This code is hereby placed in the public domain.
15
- *
16
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
17
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
20
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
- */
28
-#ifndef __RIJNDAEL_ALG_FST_H
29
-#define __RIJNDAEL_ALG_FST_H
1
+
2
+#ifndef __AES_H
3
+#define __AES_H
30 4
 
31 5
 #define MAXKC	(256/32)
32 6
 #define MAXKB	(256/8)
33 7
 #define MAXNR	14
34 8
 
9
+#define BLOCK_SIZE	16
10
+
35 11
 typedef unsigned char	u8;	
36 12
 typedef unsigned short	u16;	
37 13
 typedef unsigned int	u32;
38 14
 
39
-int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits);
40
-int rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits);
41
-void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]);
42
-void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 pt[16]);
15
+typedef struct {
16
+   u32 ek[ 4*(MAXNR+1) ];
17
+   u32 dk[ 4*(MAXNR+1) ];
18
+   int rounds;
19
+} block_state;
20
+
43 21
 
44
-#ifdef INTERMEDIATE_VALUE_KAT
45
-void rijndaelEncryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds);
46
-void rijndaelDecryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds);
47
-#endif /* INTERMEDIATE_VALUE_KAT */
22
+/* AES */
23
+extern void block_init_aes(block_state *state, unsigned char *key, int keylen);
24
+extern void block_finalize_aes(block_state* self);
25
+extern void block_encrypt_aes(block_state *self, u8 *in, u8 *out);
26
+extern void block_decrypt_aes(block_state *self, u8 *in, u8 *out);
48 27
 
49
-void AES_128(unsigned char *key, unsigned char *plainText, unsigned char *cipherText);
50
-void aes_decrypt_128(unsigned char *plainText, unsigned char *cipherText, unsigned char *key);
51
-void aes_encrypt_128(unsigned char *plainText, unsigned char *cipherText, unsigned char *key);
28
+/* AES-NI */
29
+extern void block_init_aesni(block_state *state, unsigned char *key, int keylen);
30
+extern void block_finalize_aesni(block_state* self);
31
+extern void block_encrypt_aesni(block_state *self, u8 *in, u8 *out);
32
+extern void block_decrypt_aesni(block_state *self, u8 *in, u8 *out);
52 33
 
53
-#endif /* __RIJNDAEL_ALG_FST_H */
34
+#endif /* __AES_H */
54 35
 

+ 29
- 18
drmdecrypt.c Bestand weergeven

@@ -9,6 +9,7 @@
9 9
 
10 10
 #include <stdlib.h>
11 11
 #include <stdio.h>
12
+#include <string.h>
12 13
 #include <libgen.h>
13 14
 #include <limits.h>
14 15
 #include <unistd.h>
@@ -110,6 +111,33 @@ int genoutfilename(char *outfile, char *inffile)
110 111
    return 0;
111 112
 }
112 113
 
114
+int decrypt_aes128cbc(char *key, unsigned char *pin, int len, unsigned char *pout)
115
+{
116
+   unsigned char IV[BLOCK_SIZE];
117
+   block_state state;
118
+   int i, j;
119
+
120
+   memset(IV, 0, BLOCK_SIZE);
121
+   memset(&state, 0, sizeof(block_state));
122
+
123
+   state.rounds = 10;
124
+   block_init_aes(&state, key, BLOCK_SIZE);
125
+
126
+   for(i=0; i < len; i+=BLOCK_SIZE)
127
+   {
128
+      for(j=0; j < BLOCK_SIZE; j++)
129
+      {
130
+         pout[i+j] ^= IV[j];
131
+         IV[j] = pin[i+j];
132
+      }
133
+
134
+      block_decrypt_aes(&state, pin + i, pout + i);
135
+   }
136
+
137
+   return 0;
138
+}
139
+
140
+
113 141
 /*
114 142
  * Decode a MPEG packet
115 143
  *
@@ -161,9 +189,7 @@ int genoutfilename(char *outfile, char *inffile)
161 189
 int decode_packet(unsigned char *data, unsigned char *outdata)
162 190
 {
163 191
    unsigned char iv[0x10];
164
-   unsigned char *inbuf;
165 192
    unsigned int i, n;
166
-   unsigned char *outbuf;
167 193
    int offset, rounds;
168 194
    int scrambling, adaptation;
169 195
 
@@ -206,22 +232,7 @@ int decode_packet(unsigned char *data, unsigned char *outdata)
206 232
    /* remove scrambling bits */
207 233
    outdata[3] &= 0x3f;
208 234
 
209
-   inbuf  = data + offset;
210
-   outbuf = outdata + offset;
211
-		
212
-   rounds = (188 - offset) / 0x10;
213
-   /* AES CBC */
214
-   memset(iv, 0, 16);
215
-   for (i = 0; i < rounds; i++)
216
-   {
217
-      unsigned char *out = outbuf + i * 0x10;
218
-
219
-      for(n = 0; n < 16; n++)
220
-         out[n] ^= iv[n];
221
-
222
-      aes_decrypt_128(inbuf + i * 0x10, outbuf + i * 0x10, drmkey);
223
-      memcpy(iv, inbuf + i * 0x10, 16);
224
-   }
235
+   decrypt_aes128cbc(drmkey, data + offset, 188 - offset, outdata + offset);
225 236
 
226 237
    return 1;		
227 238
 }

Laden…
Annuleren
Opslaan