xref: /isa-l_crypto/examples/saturation_test/aes_thread.c (revision d5b0e1659539e8c20d000c5beab2925273ca64e1)
1 
2 #include <pthread.h>
3 #include <sys/time.h>
4 #include <sys/types.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <stdbool.h>
8 #include <string.h>
9 #include <unistd.h>
10 
11 #include "isal_multithread_perf.h"
12 
13 struct aes_context {
14         int const bits;
15         int (*const preproc)(struct aes_context *pCtx);
16         void (*const processor)(struct aes_context *pCtx, char *plaintext, char *ciphertext,
17                                 uint64_t len);
18         void (*const postproc)(struct aes_context *pCtx);
19 };
20 
21 #define rounds_buf 2 /* first one is plain text, second is cipher text */
22 
23 static uint64_t
24 aes_thread_func(int32_t id, struct aes_context *pCtx)
25 {
26         uint32_t i = 0, j = 0;
27         char *aes_buf[rounds_buf] = { NULL };   /* aes buf is used to do checksum compute */
28         char *carry_buf[rounds_buf] = { NULL }; /* carry buf is used to do memory movement */
29         uint64_t round = -1;
30         struct timeval start_tv, stop_tv;
31         long long secs = run_secs;
32 
33         printfv("Thread %i is started\n", id);
34         /* memory allocate */
35         for (j = 0; j < rounds_buf; j++) {
36                 carry_buf[j] = (char *) calloc((size_t) buflen, 1);
37                 if (carry_buf[j] == NULL) {
38                         printf("calloc failed test aborted\n");
39                         goto out;
40                 }
41 
42                 aes_buf[j] = (char *) calloc((size_t) buflen, 1);
43                 if (aes_buf[j] == NULL) {
44                         printf("calloc failed test aborted\n");
45                         goto out;
46                 }
47 
48                 /* Create the random data */
49                 for (i = 0; i < buflen; i += 1024) {
50                         carry_buf[j][i] = i % 256;
51                         aes_buf[j][i] = i % 256;
52                 }
53         }
54 
55         if (pCtx->preproc(pCtx)) {
56                 printf("preproc failed test aborted\n");
57                 goto out;
58         }
59 
60         /* Thread sync */
61         pthread_mutex_lock(&count_lock);
62         count++;
63         if (count == num_threads) {
64                 pthread_cond_broadcast(&count_cond);
65         } else {
66                 pthread_cond_wait(&count_cond, &count_lock);
67         }
68         pthread_mutex_unlock(&count_lock);
69 
70         printfv("Thread %i is ready\n", id);
71         /* hash func starts to run */
72         round = 0;
73         gettimeofday(&start_tv, 0);
74         gettimeofday(&stop_tv, 0);
75         while (secs > (stop_tv.tv_sec - start_tv.tv_sec)) {
76                 /* Pre mem-operation */
77                 if (prememcpy)
78                         memcpy(aes_buf[0], carry_buf[0], buflen);
79 
80                 /* Calculate checksum */
81                 pCtx->processor(pCtx, aes_buf[0], aes_buf[1], buflen);
82 
83                 /* Post mem-operation */
84                 if (postmemcpy)
85                         memcpy(carry_buf[1], aes_buf[1], buflen);
86 
87                 round++;
88 
89                 gettimeofday(&stop_tv, 0);
90         }
91         printfv("thread %2i, aes_func rounds %ld\n", id, round);
92 
93 out:
94         pCtx->postproc(pCtx);
95 
96         for (j = 0; j < rounds_buf; j++) {
97                 free(carry_buf[j]);
98                 free(aes_buf[j]);
99         }
100 
101         return round;
102 }
103 
104 /*
105  * facilities for AES-CBC
106  */
107 static unsigned char const ic[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
108                                     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
109 
110 void
111 mk_rand_data(uint8_t *data, uint32_t size)
112 {
113         unsigned int i;
114         for (i = 0; i < size; i++) {
115                 *data++ = rand();
116         }
117 }
118 
119 /* thread functions for cbc dec */
120 struct cbc_context {
121         struct aes_context base;
122         uint8_t *iv;
123         uint8_t key[CBC_256_BITS];
124         struct cbc_key_data *key_data;
125 };
126 
127 static int
128 cbc_dec_pre(struct aes_context *p)
129 {
130         struct cbc_context *pCtx = (struct cbc_context *) p;
131         int ret;
132 
133         ret = posix_memalign((void **) &pCtx->iv, 16, (CBC_IV_DATA_LEN));
134         ret |= posix_memalign((void **) &pCtx->key_data, 16, (sizeof(*pCtx->key_data)));
135 
136         if ((0 != ret) || (NULL == pCtx->iv) || (NULL == pCtx->key_data))
137                 return 1;
138 
139         mk_rand_data(pCtx->key, sizeof(pCtx->key));
140         memcpy(pCtx->iv, ic, CBC_IV_DATA_LEN);
141         switch (pCtx->base.bits) {
142         case 128:
143                 isal_aes_keyexp_128(pCtx->key, pCtx->key_data->enc_keys, pCtx->key_data->dec_keys);
144                 break;
145         case 192:
146                 isal_aes_keyexp_192(pCtx->key, pCtx->key_data->enc_keys, pCtx->key_data->dec_keys);
147                 break;
148         case 256:
149                 isal_aes_keyexp_256(pCtx->key, pCtx->key_data->enc_keys, pCtx->key_data->dec_keys);
150                 break;
151         default:
152                 return 1;
153         }
154 
155         return 0;
156 }
157 
158 static void
159 cbc_dec_post(struct aes_context *p)
160 {
161         struct cbc_context *pCtx = (struct cbc_context *) p;
162 
163         free(pCtx->iv);
164         free(pCtx->key_data);
165 
166         return;
167 }
168 
169 static void
170 cbc_dec_proc(struct aes_context *p, char *plaintext, char *ciphertext, uint64_t len)
171 {
172         struct cbc_context *pCtx = (struct cbc_context *) p;
173 
174         if (pCtx->base.bits == 128)
175                 isal_aes_cbc_dec_128(ciphertext, pCtx->iv, pCtx->key_data->dec_keys, plaintext,
176                                      len);
177         else if (pCtx->base.bits == 192)
178                 isal_aes_cbc_dec_192(ciphertext, pCtx->iv, pCtx->key_data->dec_keys, plaintext,
179                                      len);
180         else if (pCtx->base.bits == 256)
181                 isal_aes_cbc_dec_256(ciphertext, pCtx->iv, pCtx->key_data->dec_keys, plaintext,
182                                      len);
183         else {
184                 printf("unsupported cbc encryption bits %d\n", pCtx->base.bits);
185                 exit(1);
186         }
187 
188         return;
189 }
190 
191 void *
192 cbc_128_dec_func(void *arg)
193 {
194         int32_t id = *((int *) arg);
195         uint64_t round = -1;
196 
197         struct cbc_context ctx = {
198                 { 128, cbc_dec_pre, cbc_dec_proc, cbc_dec_post }, NULL, { 0 }, NULL
199         };
200 
201         round = aes_thread_func(id, &ctx.base);
202 
203         pthread_exit((void *) round);
204 }
205 
206 void *
207 cbc_192_dec_func(void *arg)
208 {
209         int32_t id = *((int *) arg);
210         uint64_t round = -1;
211 
212         struct cbc_context ctx = {
213                 { 192, cbc_dec_pre, cbc_dec_proc, cbc_dec_post }, NULL, { 0 }, NULL
214         };
215 
216         round = aes_thread_func(id, &ctx.base);
217 
218         pthread_exit((void *) round);
219 }
220 
221 void *
222 cbc_256_dec_func(void *arg)
223 {
224         int32_t id = *((int *) arg);
225         uint64_t round = -1;
226 
227         struct cbc_context ctx = {
228                 { 256, cbc_dec_pre, cbc_dec_proc, cbc_dec_post }, NULL, { 0 }, NULL
229         };
230 
231         round = aes_thread_func(id, &ctx.base);
232 
233         pthread_exit((void *) round);
234 }
235 
236 /*
237  * thread functions for xts enc
238  */
239 struct xts_content {
240         struct aes_context base;
241         unsigned char key1[16 * 2];
242         unsigned char key2[16 * 2];
243         unsigned char tinit[16];
244 };
245 
246 static int
247 xts_enc_pre(struct aes_context *p)
248 {
249         struct xts_content *pCtx = (struct xts_content *) p;
250 
251         mk_rand_data(pCtx->key1, pCtx->base.bits / 8);
252         mk_rand_data(pCtx->key2, pCtx->base.bits / 8);
253         mk_rand_data(pCtx->tinit, sizeof(pCtx->tinit));
254 
255         return 0;
256 }
257 
258 static void
259 xts_enc_post(struct aes_context *p)
260 {
261         return;
262 }
263 
264 static void
265 xts_enc_proc(struct aes_context *p, char *plaintext, char *ciphertext, uint64_t len)
266 {
267         struct xts_content *pCtx = (struct xts_content *) p;
268 
269         if (pCtx->base.bits == 128)
270                 XTS_AES_128_enc(pCtx->key2, pCtx->key1, pCtx->tinit, len, plaintext, ciphertext);
271         else if (pCtx->base.bits == 256)
272                 XTS_AES_256_enc(pCtx->key2, pCtx->key1, pCtx->tinit, len, plaintext, ciphertext);
273         else {
274                 printf("unsupported xts encryption bits %d\n", pCtx->base.bits);
275                 exit(1);
276         }
277 
278         return;
279 }
280 
281 void *
282 xts_128_enc_func(void *arg)
283 {
284         int32_t id = *((int *) arg);
285         uint64_t round = -1;
286 
287         struct xts_content ctx = {
288                 { 128, xts_enc_pre, xts_enc_proc, xts_enc_post }, { 0 }, { 0 }, { 0 }
289         };
290 
291         round = aes_thread_func(id, &ctx.base);
292 
293         pthread_exit((void *) round);
294 }
295 
296 void *
297 xts_256_enc_func(void *arg)
298 {
299         int32_t id = *((int *) arg);
300         uint64_t round = -1;
301 
302         struct xts_content ctx = {
303                 { 256, xts_enc_pre, xts_enc_proc, xts_enc_post }, { 0 }, { 0 }, { 0 }
304         };
305 
306         round = aes_thread_func(id, &ctx.base);
307 
308         pthread_exit((void *) round);
309 }
310 
311 /*
312  * thread functions for gcm enc
313  */
314 struct gcm_context {
315         struct aes_context base;
316         uint8_t *key;
317         unsigned char *iv;
318         unsigned char *aad;
319         unsigned char *gcm_tag;
320         struct gcm_key_data gkey;
321         struct gcm_context_data gctx;
322 };
323 
324 static int
325 gcm_enc_pre(struct aes_context *p)
326 {
327         uint8_t const IVend[] = GCM_IV_END_MARK;
328 
329         struct gcm_context *pCtx = (struct gcm_context *) p;
330 
331         pCtx->key = malloc(pCtx->base.bits / 8);
332         pCtx->iv = malloc(GCM_IV_LEN);
333         pCtx->gcm_tag = malloc(MAX_TAG_LEN);
334         pCtx->aad = malloc(AAD_LENGTH);
335 
336         mk_rand_data(pCtx->aad, AAD_LENGTH);
337 
338         mk_rand_data(pCtx->iv, GCM_IV_LEN);
339         memcpy(&pCtx->iv[GCM_IV_END_START], IVend, sizeof(IVend));
340 
341         mk_rand_data(pCtx->key, pCtx->base.bits / 8);
342         if (pCtx->base.bits == 128)
343                 aes_gcm_pre_128(pCtx->key, &pCtx->gkey);
344         else
345                 aes_gcm_pre_256(pCtx->key, &pCtx->gkey);
346 
347         return 0;
348 }
349 
350 static void
351 gcm_enc_post(struct aes_context *p)
352 {
353         struct gcm_context *pCtx = (struct gcm_context *) p;
354 
355         free(pCtx->key);
356         free(pCtx->iv);
357         free(pCtx->gcm_tag);
358         free(pCtx->aad);
359 
360         return;
361 }
362 
363 static void
364 gcm_enc_proc(struct aes_context *p, char *plaintext, char *ciphertext, uint64_t len)
365 {
366         struct gcm_context *pCtx = (struct gcm_context *) p;
367 
368         if (pCtx->base.bits == 128)
369                 aes_gcm_enc_128(&pCtx->gkey, &pCtx->gctx, ciphertext, plaintext, len, pCtx->iv,
370                                 pCtx->aad, AAD_LENGTH, pCtx->gcm_tag, MAX_TAG_LEN);
371         else if (pCtx->base.bits == 256)
372                 aes_gcm_enc_256(&pCtx->gkey, &pCtx->gctx, ciphertext, plaintext, len, pCtx->iv,
373                                 pCtx->aad, AAD_LENGTH, pCtx->gcm_tag, MAX_TAG_LEN);
374         else {
375                 printf("unsupported gcm encryption bits %d\n", pCtx->base.bits);
376                 exit(1);
377         }
378 
379         return;
380 }
381 
382 void *
383 gcm_128_enc_func(void *arg)
384 {
385         int32_t id = *((int *) arg);
386         uint64_t round = -1;
387 
388         struct gcm_context ctx = {
389                 { 128, gcm_enc_pre, gcm_enc_proc, gcm_enc_post }, NULL, NULL, NULL, NULL, { 0 }
390         };
391 
392         round = aes_thread_func(id, &ctx.base);
393 
394         pthread_exit((void *) round);
395 }
396 
397 void *
398 gcm_256_enc_func(void *arg)
399 {
400         int32_t id = *((int *) arg);
401         uint64_t round = -1;
402 
403         struct gcm_context ctx = {
404                 { 256, gcm_enc_pre, gcm_enc_proc, gcm_enc_post }, NULL, NULL, NULL, NULL, { 0 }
405         };
406 
407         round = aes_thread_func(id, &ctx.base);
408 
409         pthread_exit((void *) round);
410 }
411