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[ISAL_CBC_256_BITS]; 124 struct isal_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, (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 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 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 * 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 * 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 * 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 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 259 xts_enc_post(struct aes_context *p) 260 { 261 return; 262 } 263 264 static void 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 * 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 * 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 gcm_key_data gkey; 323 struct gcm_context_data gctx; 324 }; 325 326 static int 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 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 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 * 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 * 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