xref: /isa-l_crypto/examples/saturation_test/aes_thread.c (revision 5e6526ee40a69b90ccddc657a303f853af79de4d)
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
aes_thread_func(int32_t id,struct aes_context * pCtx)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
mk_rand_data(uint8_t * data,uint32_t size)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[ISAL_CBC_256_BITS];
124         struct isal_cbc_key_data *key_data;
125 };
126 
127 static int
cbc_dec_pre(struct aes_context * p)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, (ISAL_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, ISAL_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
cbc_dec_post(struct aes_context * p)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
cbc_dec_proc(struct aes_context * p,char * plaintext,char * ciphertext,uint64_t len)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 *
cbc_128_dec_func(void * arg)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 *
cbc_192_dec_func(void * arg)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 *
cbc_256_dec_func(void * arg)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
xts_enc_pre(struct aes_context * p)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
xts_enc_post(struct aes_context * p)259 xts_enc_post(struct aes_context *p)
260 {
261         return;
262 }
263 
264 static void
xts_enc_proc(struct aes_context * p,char * plaintext,char * ciphertext,uint64_t len)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                 isal_aes_xts_enc_128(pCtx->key2, pCtx->key1, pCtx->tinit, len, plaintext,
271                                      ciphertext);
272         else if (pCtx->base.bits == 256)
273                 isal_aes_xts_enc_256(pCtx->key2, pCtx->key1, pCtx->tinit, len, plaintext,
274                                      ciphertext);
275         else {
276                 printf("unsupported xts encryption bits %d\n", pCtx->base.bits);
277                 exit(1);
278         }
279 
280         return;
281 }
282 
283 void *
xts_128_enc_func(void * arg)284 xts_128_enc_func(void *arg)
285 {
286         int32_t id = *((int *) arg);
287         uint64_t round = -1;
288 
289         struct xts_content ctx = {
290                 { 128, xts_enc_pre, xts_enc_proc, xts_enc_post }, { 0 }, { 0 }, { 0 }
291         };
292 
293         round = aes_thread_func(id, &ctx.base);
294 
295         pthread_exit((void *) round);
296 }
297 
298 void *
xts_256_enc_func(void * arg)299 xts_256_enc_func(void *arg)
300 {
301         int32_t id = *((int *) arg);
302         uint64_t round = -1;
303 
304         struct xts_content ctx = {
305                 { 256, xts_enc_pre, xts_enc_proc, xts_enc_post }, { 0 }, { 0 }, { 0 }
306         };
307 
308         round = aes_thread_func(id, &ctx.base);
309 
310         pthread_exit((void *) round);
311 }
312 
313 /*
314  * thread functions for gcm enc
315  */
316 struct gcm_context {
317         struct aes_context base;
318         uint8_t *key;
319         unsigned char *iv;
320         unsigned char *aad;
321         unsigned char *gcm_tag;
322         struct isal_gcm_key_data gkey;
323         struct isal_gcm_context_data gctx;
324 };
325 
326 static int
gcm_enc_pre(struct aes_context * p)327 gcm_enc_pre(struct aes_context *p)
328 {
329         struct gcm_context *pCtx = (struct gcm_context *) p;
330 
331         pCtx->key = malloc(pCtx->base.bits / 8);
332         pCtx->iv = malloc(ISAL_GCM_IV_LEN);
333         pCtx->gcm_tag = malloc(ISAL_GCM_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, ISAL_GCM_IV_LEN);
339 
340         mk_rand_data(pCtx->key, pCtx->base.bits / 8);
341         if (pCtx->base.bits == 128)
342                 isal_aes_gcm_pre_128(pCtx->key, &pCtx->gkey);
343         else
344                 isal_aes_gcm_pre_256(pCtx->key, &pCtx->gkey);
345 
346         return 0;
347 }
348 
349 static void
gcm_enc_post(struct aes_context * p)350 gcm_enc_post(struct aes_context *p)
351 {
352         struct gcm_context *pCtx = (struct gcm_context *) p;
353 
354         free(pCtx->key);
355         free(pCtx->iv);
356         free(pCtx->gcm_tag);
357         free(pCtx->aad);
358 
359         return;
360 }
361 
362 static void
gcm_enc_proc(struct aes_context * p,char * plaintext,char * ciphertext,uint64_t len)363 gcm_enc_proc(struct aes_context *p, char *plaintext, char *ciphertext, uint64_t len)
364 {
365         struct gcm_context *pCtx = (struct gcm_context *) p;
366 
367         if (pCtx->base.bits == 128)
368                 isal_aes_gcm_enc_128(&pCtx->gkey, &pCtx->gctx, ciphertext, plaintext, len, pCtx->iv,
369                                      pCtx->aad, AAD_LENGTH, pCtx->gcm_tag, ISAL_GCM_MAX_TAG_LEN);
370         else if (pCtx->base.bits == 256)
371                 isal_aes_gcm_enc_256(&pCtx->gkey, &pCtx->gctx, ciphertext, plaintext, len, pCtx->iv,
372                                      pCtx->aad, AAD_LENGTH, pCtx->gcm_tag, ISAL_GCM_MAX_TAG_LEN);
373         else {
374                 printf("unsupported gcm encryption bits %d\n", pCtx->base.bits);
375                 exit(1);
376         }
377 
378         return;
379 }
380 
381 void *
gcm_128_enc_func(void * arg)382 gcm_128_enc_func(void *arg)
383 {
384         int32_t id = *((int *) arg);
385         uint64_t round = -1;
386 
387         struct gcm_context ctx = {
388                 { 128, gcm_enc_pre, gcm_enc_proc, gcm_enc_post }, NULL, NULL, NULL, NULL, { 0 }
389         };
390 
391         round = aes_thread_func(id, &ctx.base);
392 
393         pthread_exit((void *) round);
394 }
395 
396 void *
gcm_256_enc_func(void * arg)397 gcm_256_enc_func(void *arg)
398 {
399         int32_t id = *((int *) arg);
400         uint64_t round = -1;
401 
402         struct gcm_context ctx = {
403                 { 256, gcm_enc_pre, gcm_enc_proc, gcm_enc_post }, NULL, NULL, NULL, NULL, { 0 }
404         };
405 
406         round = aes_thread_func(id, &ctx.base);
407 
408         pthread_exit((void *) round);
409 }
410