MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / char / mxhwenp / test / test_mxhw.c
blobc389806dab745b852a8f09635d19bd9240134163
1 #include <fcntl.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <mxhw_crypto_userio.h>
5 #include <mxhw_crypto_wrapper.h>
6 #include <cipher.h>
7 #include <test_ssl.h>
9 static u_char iv_sw[64], input_sw[MAX_BUF], output_sw[MAX_BUF];
10 static u_char iv_hw[64], input_hw[MAX_BUF], output_hw[MAX_BUF];
12 static u_char IV[64];
14 static void
15 hexit(char *msg, u_char *d, int len)
17 int i;
18 usleep(10000);
19 printf("[%4d] %s ",len, msg);
20 len = len>80? 40:len;
21 #if 1
22 for (i=0;i<len;i++,d++)
24 printf("%02x",*d);
25 if (i%4==3) printf(" ");
27 #else
28 for(;len >=4; d+=4,len-=4)
29 printf("%08x ",*(u_int*) d);
31 if (len>0)
33 d+=3;
34 for (i=0;i<len;i++,d--)
35 printf("%02x",*d);
37 #endif
38 printf("\n");
39 usleep(10000);
42 TESTHW TestHW[]=
44 {MXCIPHER_ALGO_DES, MXCIPHER_MODE_ECB, "DES/ECB", 8,8,0, test_DES_ecb_encrypt},
45 {MXCIPHER_ALGO_DES, MXCIPHER_MODE_CBC, "DES/CBC", 8,8,0, test_DES_cbc_encrypt},
46 {MXCIPHER_ALGO_3DES, MXCIPHER_MODE_ECB, "3DES/ECB", 8,24,0, test_DES_ecb3_encrypt},
47 {MXCIPHER_ALGO_3DES, MXCIPHER_MODE_CBC, "3DES/CBC", 8,24,0, test_DES_ede3_cbc_encrypt},
48 #ifdef CPE_ENGINE
49 {MXCIPHER_ALGO_DES, MXCIPHER_MODE_OFB, "DES/OFB", 8,8,0, test_DES_ofb_encrypt},
50 {MXCIPHER_ALGO_DES, MXCIPHER_MODE_CFB, "DES/CFB", 8,8,0, test_DES_cfb_encrypt},
51 {MXCIPHER_ALGO_3DES, MXCIPHER_MODE_OFB, "3DES/OFB", 8,24,0, test_DES_ede3_ofb64_encrypt},
52 {MXCIPHER_ALGO_3DES, MXCIPHER_MODE_CFB, "3DES/CFB", 8,24,0, test_DES_ede3_cfb64_encrypt},
53 #endif
55 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
56 {MXCIPHER_ALGO_AES128, MXCIPHER_MODE_ECB, "AES128/ECB", 16,16,1, test_AES_ecb_encrypt},
57 {MXCIPHER_ALGO_AES192, MXCIPHER_MODE_ECB, "AES192/ECB", 16,24,1, test_AES_ecb_encrypt},
58 {MXCIPHER_ALGO_AES256, MXCIPHER_MODE_ECB, "AES256/ECB", 16,32,1, test_AES_ecb_encrypt},
59 {MXCIPHER_ALGO_AES128, MXCIPHER_MODE_CBC, "AES128/CBC", 16,16,1, test_AES_cbc_encrypt},
60 {MXCIPHER_ALGO_AES192, MXCIPHER_MODE_CBC, "AES192/CBC", 16,24,1, test_AES_cbc_encrypt},
61 {MXCIPHER_ALGO_AES256, MXCIPHER_MODE_CBC, "AES256/CBC", 16,32,1, test_AES_cbc_encrypt},
62 {MXCIPHER_ALGO_AES128, MXCIPHER_MODE_CTR, "AES128/CTR", 16,16,0, test_AES_ctr_encrypt},
63 {MXCIPHER_ALGO_AES192, MXCIPHER_MODE_CTR, "AES192/CTR", 16,24,0, test_AES_ctr_encrypt},
64 {MXCIPHER_ALGO_AES256, MXCIPHER_MODE_CTR, "AES256/CTR", 16,32,0, test_AES_ctr_encrypt},
65 #ifdef CPE_ENGINE
66 {MXCIPHER_ALGO_AES128, MXCIPHER_MODE_CFB, "AES128/CFB", 16,16,0, test_AES_cfb_encrypt},
67 {MXCIPHER_ALGO_AES192, MXCIPHER_MODE_CFB, "AES192/CFB", 16,24,0, test_AES_cfb_encrypt},
68 {MXCIPHER_ALGO_AES256, MXCIPHER_MODE_CFB, "AES256/CFB", 16,32,0, test_AES_cfb_encrypt},
69 {MXCIPHER_ALGO_AES128, MXCIPHER_MODE_OFB, "AES128/OFB", 16,16,0, test_AES_ofb_encrypt},
70 {MXCIPHER_ALGO_AES192, MXCIPHER_MODE_OFB, "AES192/OFB", 16,24,0, test_AES_ofb_encrypt},
71 {MXCIPHER_ALGO_AES256, MXCIPHER_MODE_OFB, "AES256/OFB", 16,32,0, test_AES_ofb_encrypt},
72 #if 0
73 {MXCIPHER_ALGO_DES, MXCIPHER_MODE_CFB, "DES/CFB64", 8,8,1, test_DES_cfb64_encrypt},
74 {MXCIPHER_ALGO_AES128, MXCIPHER_MODE_CFB, "AES128/CFB128", 16,16,1, test_AES_cfb128_encrypt},
75 #endif
76 #endif //0x00907000L
77 #endif
80 u_int TestHWSizes=sizeof(TestHW)/sizeof(TestHW[0]);
82 TESTHW*
83 test_find(char *name)
85 TESTHW *t;
86 int m;
88 for (m=0; m < TestHWSizes; m++)
90 t = &TestHW[m];
91 if (t->do_cipher==NULL || strcmp(t->name, name))
92 continue;
93 return t;
95 return NULL;
98 static void
99 test_inside(TESTHW *t, u_int pktLen, int performance, int idx)
101 u_int i, num;
103 if (performance==0)
104 num=1;
105 else
106 num=performance;
108 fill_data (IV, t->blen); /* for CTR */
110 pktLen=fill_data (input_sw, pktLen);
112 memcpy(input_hw, input_sw, pktLen);
113 memcpy(iv_sw, IV, t->blen);
114 memcpy(iv_hw, IV, t->blen);
116 mxcrypto_set_software(ISHW);
117 timeit(ISHW, idx, TSTART, 0);
118 for (i=0; i < num; i++)
119 t->do_cipher(input_hw, output_hw, pktLen, t->key1,t->key2,t->key3,
120 t->mode!=MXCIPHER_MODE_ECB? iv_hw:NULL, DES_ENCRYPT);
121 timeit(ISHW, idx, TEND, 0);
123 mxcrypto_set_software(ISSW);
124 timeit(ISSW, idx, TSTART, 0);
125 for (i=0; i < num; i++)
126 t->do_cipher(input_sw, output_sw, pktLen, t->key1,t->key2,t->key3,
127 t->mode!=MXCIPHER_MODE_ECB? iv_sw:NULL, DES_ENCRYPT);
128 timeit(ISSW, idx, TEND, 0);
130 if (!performance)
132 /* compare the results */
133 if (memcmp(output_hw,output_sw, pktLen))
135 hexit("USERHW ENCRYPT TO:", output_hw, pktLen);
136 hexit("USERSW ENCRYPT TO:", output_sw, pktLen);
138 if(t->mode!=MXCIPHER_MODE_ECB && (memcmp(iv_hw,iv_sw, t->blen)))
140 hexit("USERHW ENCRYPT IV:", iv_hw, t->blen);
141 hexit("USERSW ENCRYPT IV:", iv_sw, t->blen);
144 if(t->mode==MXCIPHER_MODE_CTR)
146 memcpy(iv_sw, IV, t->blen);
147 memcpy(iv_hw, IV, t->blen);
150 mxcrypto_set_software(ISHW);
151 timeit(ISHW, idx, TSTART, 0);
152 for (i=0; i < num; i++)
153 t->do_cipher(output_hw, input_hw, pktLen, t->key1,t->key2,t->key3,
154 t->mode!=MXCIPHER_MODE_ECB? iv_hw:NULL, DES_DECRYPT);
155 timeit(ISHW, idx, TEND, 1);
157 mxcrypto_set_software(ISSW);
158 timeit(ISSW, idx, TSTART, 0);
159 for (i=0; i < num; i++)
160 t->do_cipher(output_sw, input_sw, pktLen, t->key1,t->key2,t->key3,
161 t->mode!=MXCIPHER_MODE_ECB? iv_sw:NULL, DES_DECRYPT);
162 timeit(ISSW, idx, TEND, 1);
164 if (!performance)
166 /* compare the results */
167 if (memcmp(input_hw,input_sw, pktLen))
169 hexit("USERHW DECRYPT TO:", input_hw, pktLen);
170 hexit("USERSW DECRYPT TO:", input_sw, pktLen);
172 if(t->mode!=MXCIPHER_MODE_ECB && (memcmp(iv_hw,iv_sw, t->blen)))
174 hexit("USERHW DECRYPT IV:", iv_hw, t->blen);
175 hexit("USERSW DECRYPT IV:", iv_sw, t->blen);
180 void
181 test_correctness(u_int numTimes)
183 TESTHW *t;
184 u_int i,m, is_aes,size;
185 u_char keys[32];
187 printf("--------------correctness tests--------------------\n");
188 printf("If you see any hex string, then there is something wrong with the tests\n\n");
189 for (m=0; m < TestHWSizes; m++)
191 t = &TestHW[m];
192 if (t->do_cipher==NULL)
193 continue;
195 size = 0;
196 printf("<--- operate [%s] ", t->name);
197 is_aes = (t->algo>=MXCIPHER_ALGO_AES128)? 1:0;
199 fill_data (keys, 32);
200 test_set_keys(t, keys, is_aes);
201 for (i=0; i < numTimes; i++) test_inside(t, 0, 0, 0);
203 size+=mxcrypto_close(t->key1);
204 if (t->aes_dec)
205 size+=mxcrypto_close(t->key2);
206 printf("in %ld packets\n", size);
210 static void
211 test_performance(u_int *pktSizes,u_int numPktSizes,u_int numPkts, u_int w)
213 TESTHW *t;
214 u_int i,m, is_aes, size=0;
215 u_char keys[32];
217 printf("--------------performance tests--------------------\n");
219 for (m=0; m < TestHWSizes; m++)
221 t = &TestHW[m];
222 if (t->do_cipher==NULL)
223 continue;
224 is_aes = (t->algo>=MXCIPHER_ALGO_AES128)? 1:0;
225 times_reset();
226 fill_data (keys, 32);
227 test_set_keys(t, keys, is_aes);
228 for (i=0; i < numPktSizes; i++)
229 test_inside(t, pktSizes[i], numPkts, i);
231 size=0;
232 size+=mxcrypto_close(t->key1);
233 if (t->aes_dec) size+=mxcrypto_close(t->key2);
234 timereport(t->name, pktSizes, numPktSizes, numPkts, size);
238 #ifndef CPE_ENGINE
239 #define swap(a,b)
240 #else
241 #if 1
242 #define SWAP32(v) ((v>>24)|((v&0x00ff0000)>>8)|((v&0x0000ff00)<<8)|(v<<24))
243 #else
244 #define SWAP32(v) v
245 #endif
246 void
247 swap(u_char *data, u_int len)
249 u_int i, v;
251 i = len%4;
252 if (i>0)
253 len += (4-i);
255 for (i=0; i < len; i+=4)
257 v = *(u_int*) (data+i);
258 *(u_int*)(data+i) = SWAP32(v);
261 #endif
263 static void
264 test_hardware_data(TESTHW *t, int type)
266 u_char input[256], output[256], keys[32], ivec[16], ovec[16], cipher[256];
267 u_char *ckey, *cive, *text, *ciph;
268 u_int size=0,dlen,is_aes=(t->algo>=MXCIPHER_ALGO_AES128)? 1:0;;
270 printf("<---- operate %s %s", t->name, type? "encryption":"decryption");
272 memset(input, 0, 256);
273 memset(output, 0, 256);
274 if (t->algo==MXCIPHER_ALGO_DES)
276 dlen = sizeof(DES_TEXT[t->mode]);
277 ckey = (u_char*) DES_KEYS[t->mode];
278 cive = (u_char*) DES_IVEC[t->mode];
279 text = (u_char*) DES_TEXT[t->mode];
280 ciph = (u_char*) DES_CIPHER[t->mode];
282 else if (t->algo==MXCIPHER_ALGO_3DES)
284 dlen = sizeof(DES3_TEXT[t->mode]);
285 ckey = (u_char*) DES3_KEYS[t->mode];
286 cive = (u_char*) DES3_IVEC[t->mode];
287 text = (u_char*) DES3_TEXT[t->mode];
288 ciph = (u_char*) DES3_CIPHER[t->mode];
290 else
292 int algo = t->algo-MXCIPHER_ALGO_AES128;
294 dlen = sizeof(AES_TEXT);
295 ckey = (u_char*) AES_KEYS[algo%3];
296 cive = (u_char*) (t->mode==MXCIPHER_MODE_CTR? AES_CTR_IVEC:AES_IVEC);
297 text = (u_char*) AES_TEXT;
298 ciph = (u_char*) AES_CIPHER[t->mode*3+algo];
301 if (type==DES_DECRYPT)
303 u_char *tmp = ciph;
305 ciph = text;
306 text = tmp;
309 memcpy(keys, ckey, t->klen);
310 memcpy(ivec, cive, t->blen);
311 memcpy(ovec, cive, t->blen);
312 memcpy(input, text, dlen);
313 memcpy(cipher,ciph, dlen);
315 /* little endian converted to big endian */
316 swap(keys, t->klen);
317 swap(ivec, t->blen);
318 swap(ovec, t->blen);
319 swap(input, dlen);
320 swap(cipher, dlen);
322 if (t->mode==MXCIPHER_MODE_CFB)
324 if (t->algo==MXCIPHER_ALGO_DES)
325 dlen = 10;
326 else if (t->algo==MXCIPHER_ALGO_3DES)
327 dlen = 8;
328 else
329 dlen = 18;
332 test_set_keys(t, keys, (t->algo>=MXCIPHER_ALGO_AES128));
334 mxcrypto_set_software(ISHW);
335 t->do_cipher(input, output, dlen, t->key1,t->key2,t->key3,
336 (t->mode!=MXCIPHER_MODE_ECB)? ivec:NULL, type);
338 if (memcmp(cipher, output, dlen)!=0)
340 hexit("PLAINKEYS:", keys, t->klen);
341 if (t->mode != MXCIPHER_MODE_ECB)
343 hexit("PLAINIVEC:", ovec, t->blen);
344 hexit("CIPHEIVEC:", ivec, t->blen);
346 // hexit("PLAINTEXT:", input, dlen);
347 hexit("CIPHERTXT:", (u_char*)cipher, dlen);
348 if (type==DES_ENCRYPT)
349 hexit("ENCRYPTXX:", output, dlen);
350 else
351 hexit("DECRYPTXX:", output, dlen);
352 printf("\n");
354 size+=mxcrypto_close(t->key1);
355 if (is_aes && t->mode!=MXCIPHER_MODE_CTR && t->mode!=MXCIPHER_MODE_OFB)
356 size+=mxcrypto_close(t->key2);
357 printf (" %ld packets\n", size);
360 static int
361 test_gloden_pattern()
363 u_int i;
364 TESTHW *t;
366 printf("--------------NIST gloden pattern tests--------------------\n");
367 for (i=0; i < TestHWSizes; i++)
369 t = &TestHW[i];
370 if (t->do_cipher==NULL)
371 continue;
373 test_hardware_data(t, DES_ENCRYPT);
374 test_hardware_data(t, DES_DECRYPT);
376 return 0;
379 #ifdef OVERFLOW_TEST
380 int mxcrypto_uio_write(int ctxId, const u_char *input, u_long len, u_char *ivec, int ilen);
381 int mxcrypto_uio_read(int ctxId, u_char *output, u_long len, u_char *ivec, int ilen);
382 int mxcrypto_uio_queue(int ctxId);
384 static void
385 test_buffer_overflow(int max)
387 TESTHW *t;
388 u_int pktLen=1024, i,j;
389 int encId;
391 t = &TestHW[1];
392 if (t->do_cipher==NULL)
393 return;
395 encId = mxcrypto_uio_register(t->algo, t->mode, cipherKey, TYPE_ENCRYPT);
396 if (encId<0)
397 return;
398 printf("operate [%s] %d packets with each in size of %d at file %d\n", t->name, max, pktLen, encId);
400 fcntl(encId, F_SETFL, O_NONBLOCK);
401 for (j=0; j<max; j++)
403 printf("write %d\n", mxcrypto_uio_queue(encId));
404 if (mxcrypto_uio_write(encId, input_hw, pktLen, iv_hw, t->blen)<0)
406 printf("error in write at %d\n", j);
407 break;
410 sleep(2);
411 for (i=0; i<j; i++)
413 printf("read %d\n", mxcrypto_uio_queue(encId));
414 if (mxcrypto_uio_read(encId, input_hw, pktLen, iv_hw, t->blen)<0)
416 printf("error in read at %d\n", i);
417 break;
420 mxcrypto_uio_close(encId);
423 static void
424 test_iocaller_overflow(int max)
426 TESTHW *t;
427 int i,j,k;
428 int encId[128];
430 t = &TestHW[1];
431 if (t->do_cipher==NULL)
432 return;
433 for (k=0; k < max; k++)
435 for (i=0; i<64; i++)
437 encId[i] = mxcrypto_uio_register(t->algo, t->mode, cipherKey, TYPE_ENCRYPT);
438 if (encId[i]<0)
439 break;
440 printf("[%d] register at file %d\n", i, encId[i]);
442 for (j=i-1; j>=0; j--)
444 printf("[%d] close at file %d\n", j, encId[j]);
445 mxcrypto_uio_close(encId[j]);
449 #endif
451 void
452 usage(char *pn)
454 printf("Usage:\n");
455 printf("\t** correctness (compared with libcrypto.so) **\n\n");
456 printf("\t\t> %s [<0>] [<# of packets>:1]\n\n", pn);
457 printf("\t** correctness (NIST standard) **\n\n");
458 printf("\t\t> %s <1>\n\n", pn);
459 printf("\t** performance **\n\n");
460 printf("\t\t> %s <2> [<# of packets>:5000] [<1 for hw, 2 for sw, 0 for both>:both]\n\n", pn);
464 main(int argc, char *argv[])
466 unsigned int pktSizes[]={128, 256, 384, 512, 640, 768, 896, 1024, 1152, 1280};
467 // unsigned int pktSizes[]={16, 32, 64, 80, 96, 112, 128, 144};
468 unsigned int numTimes, i=0;
470 if (argc>1) i = atoi(argv[1]);
472 if (i==0) /* [<0>] [<# of runs>] */
474 test_correctness((argc>2)? atoi(argv[2]):1);
476 else if (i==1)
478 test_gloden_pattern();
480 else if (i==2) /* <2> [<# of packets>] [hw/sw] */
482 numTimes = sizeof(pktSizes)/sizeof(pktSizes[0]);
484 test_performance(pktSizes,numTimes,(argc>2)? atoi(argv[2]):5000,(argc>3)? atoi(argv[3]):0);
486 #ifdef OVERFLOW_TEST
487 else if (i==3) /* <3> */
489 test_buffer_overflow(64);
491 else
493 test_iocaller_overflow(64);
495 #endif
496 else
497 usage(argv[0]);
498 return 0;