xref: /isa-l_crypto/examples/saturation_test/aes_thread.c (revision d452ca2cdda7caf40ebe483e38765692d4d5ca75)
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         aes_cbc_precomp(pCtx->key, pCtx->base.bits, pCtx->key_data);
142 
143         return 0;
144 }
145 
146 static void
147 cbc_dec_post(struct aes_context *p)
148 {
149         struct cbc_context *pCtx = (struct cbc_context *) p;
150 
151         free(pCtx->iv);
152         free(pCtx->key_data);
153 
154         return;
155 }
156 
157 static void
158 cbc_dec_proc(struct aes_context *p, char *plaintext, char *ciphertext, uint64_t len)
159 {
160         struct cbc_context *pCtx = (struct cbc_context *) p;
161 
162         if (pCtx->base.bits == 128)
163                 aes_cbc_dec_128(ciphertext, pCtx->iv, pCtx->key_data->dec_keys, plaintext, len);
164         else if (pCtx->base.bits == 192)
165                 aes_cbc_dec_192(ciphertext, pCtx->iv, pCtx->key_data->dec_keys, plaintext, len);
166         else if (pCtx->base.bits == 256)
167                 aes_cbc_dec_256(ciphertext, pCtx->iv, pCtx->key_data->dec_keys, plaintext, len);
168         else {
169                 printf("unsupported cbc encryption bits %d\n", pCtx->base.bits);
170                 exit(1);
171         }
172 
173         return;
174 }
175 
176 void *
177 cbc_128_dec_func(void *arg)
178 {
179         int32_t id = *((int *) arg);
180         uint64_t round = -1;
181 
182         struct cbc_context ctx = {
183                 { 128, cbc_dec_pre, cbc_dec_proc, cbc_dec_post }, NULL, { 0 }, NULL
184         };
185 
186         round = aes_thread_func(id, &ctx.base);
187 
188         pthread_exit((void *) round);
189 }
190 
191 void *
192 cbc_192_dec_func(void *arg)
193 {
194         int32_t id = *((int *) arg);
195         uint64_t round = -1;
196 
197         struct cbc_context ctx = {
198                 { 192, 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_256_dec_func(void *arg)
208 {
209         int32_t id = *((int *) arg);
210         uint64_t round = -1;
211 
212         struct cbc_context ctx = {
213                 { 256, 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 /*
222  * thread functions for xts enc
223  */
224 struct xts_content {
225         struct aes_context base;
226         unsigned char key1[16 * 2];
227         unsigned char key2[16 * 2];
228         unsigned char tinit[16];
229 };
230 
231 static int
232 xts_enc_pre(struct aes_context *p)
233 {
234         struct xts_content *pCtx = (struct xts_content *) p;
235 
236         mk_rand_data(pCtx->key1, pCtx->base.bits / 8);
237         mk_rand_data(pCtx->key2, pCtx->base.bits / 8);
238         mk_rand_data(pCtx->tinit, sizeof(pCtx->tinit));
239 
240         return 0;
241 }
242 
243 static void
244 xts_enc_post(struct aes_context *p)
245 {
246         return;
247 }
248 
249 static void
250 xts_enc_proc(struct aes_context *p, char *plaintext, char *ciphertext, uint64_t len)
251 {
252         struct xts_content *pCtx = (struct xts_content *) p;
253 
254         if (pCtx->base.bits == 128)
255                 XTS_AES_128_enc(pCtx->key2, pCtx->key1, pCtx->tinit, len, plaintext, ciphertext);
256         else if (pCtx->base.bits == 256)
257                 XTS_AES_256_enc(pCtx->key2, pCtx->key1, pCtx->tinit, len, plaintext, ciphertext);
258         else {
259                 printf("unsupported xts encryption bits %d\n", pCtx->base.bits);
260                 exit(1);
261         }
262 
263         return;
264 }
265 
266 void *
267 xts_128_enc_func(void *arg)
268 {
269         int32_t id = *((int *) arg);
270         uint64_t round = -1;
271 
272         struct xts_content ctx = {
273                 { 128, xts_enc_pre, xts_enc_proc, xts_enc_post }, { 0 }, { 0 }, { 0 }
274         };
275 
276         round = aes_thread_func(id, &ctx.base);
277 
278         pthread_exit((void *) round);
279 }
280 
281 void *
282 xts_256_enc_func(void *arg)
283 {
284         int32_t id = *((int *) arg);
285         uint64_t round = -1;
286 
287         struct xts_content ctx = {
288                 { 256, 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 /*
297  * thread functions for gcm enc
298  */
299 struct gcm_context {
300         struct aes_context base;
301         uint8_t *key;
302         unsigned char *iv;
303         unsigned char *aad;
304         unsigned char *gcm_tag;
305         struct gcm_key_data gkey;
306         struct gcm_context_data gctx;
307 };
308 
309 static int
310 gcm_enc_pre(struct aes_context *p)
311 {
312         uint8_t const IVend[] = GCM_IV_END_MARK;
313 
314         struct gcm_context *pCtx = (struct gcm_context *) p;
315 
316         pCtx->key = malloc(pCtx->base.bits / 8);
317         pCtx->iv = malloc(GCM_IV_LEN);
318         pCtx->gcm_tag = malloc(MAX_TAG_LEN);
319         pCtx->aad = malloc(AAD_LENGTH);
320 
321         mk_rand_data(pCtx->aad, AAD_LENGTH);
322 
323         mk_rand_data(pCtx->iv, GCM_IV_LEN);
324         memcpy(&pCtx->iv[GCM_IV_END_START], IVend, sizeof(IVend));
325 
326         mk_rand_data(pCtx->key, pCtx->base.bits / 8);
327         if (pCtx->base.bits == 128)
328                 aes_gcm_pre_128(pCtx->key, &pCtx->gkey);
329         else
330                 aes_gcm_pre_256(pCtx->key, &pCtx->gkey);
331 
332         return 0;
333 }
334 
335 static void
336 gcm_enc_post(struct aes_context *p)
337 {
338         struct gcm_context *pCtx = (struct gcm_context *) p;
339 
340         free(pCtx->key);
341         free(pCtx->iv);
342         free(pCtx->gcm_tag);
343         free(pCtx->aad);
344 
345         return;
346 }
347 
348 static void
349 gcm_enc_proc(struct aes_context *p, char *plaintext, char *ciphertext, uint64_t len)
350 {
351         struct gcm_context *pCtx = (struct gcm_context *) p;
352 
353         if (pCtx->base.bits == 128)
354                 aes_gcm_enc_128(&pCtx->gkey, &pCtx->gctx, ciphertext, plaintext, len, pCtx->iv,
355                                 pCtx->aad, AAD_LENGTH, pCtx->gcm_tag, MAX_TAG_LEN);
356         else if (pCtx->base.bits == 256)
357                 aes_gcm_enc_256(&pCtx->gkey, &pCtx->gctx, ciphertext, plaintext, len, pCtx->iv,
358                                 pCtx->aad, AAD_LENGTH, pCtx->gcm_tag, MAX_TAG_LEN);
359         else {
360                 printf("unsupported gcm encryption bits %d\n", pCtx->base.bits);
361                 exit(1);
362         }
363 
364         return;
365 }
366 
367 void *
368 gcm_128_enc_func(void *arg)
369 {
370         int32_t id = *((int *) arg);
371         uint64_t round = -1;
372 
373         struct gcm_context ctx = {
374                 { 128, gcm_enc_pre, gcm_enc_proc, gcm_enc_post }, NULL, NULL, NULL, NULL, { 0 }
375         };
376 
377         round = aes_thread_func(id, &ctx.base);
378 
379         pthread_exit((void *) round);
380 }
381 
382 void *
383 gcm_256_enc_func(void *arg)
384 {
385         int32_t id = *((int *) arg);
386         uint64_t round = -1;
387 
388         struct gcm_context ctx = {
389                 { 256, 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