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