xref: /isa-l_crypto/examples/saturation_test/aes_thread.c (revision 2a268c597b745b55509ea38d00753e5caa85e9ac)
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