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