summaryrefslogtreecommitdiffstats
path: root/src/spdk/intel-ipsec-mb/LibTestApp/cmac_test.c
blob: 9365af76157fc57811609be68a43bb305358e73a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
/*****************************************************************************
 Copyright (c) 2018, Intel Corporation

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:

     * Redistributions of source code must retain the above copyright notice,
       this list of conditions and the following disclaimer.
     * Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.
     * Neither the name of Intel Corporation nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <intel-ipsec-mb.h>
#include "gcm_ctr_vectors_test.h"
#include "utils.h"

enum cmac_type {
        CMAC = 0,
        CMAC_BITLEN,
};

int cmac_test(const enum arch_type arch, struct MB_MGR *mb_mgr);

/*
 * Test vectors from https://tools.ietf.org/html/rfc4493
 */

/*
 *  Subkey Generation
 *  K              2b7e1516 28aed2a6 abf71588 09cf4f3c
 *  AES-128(key,0) 7df76b0c 1ab899b3 3e42f047 b91b546f
 *  K1             fbeed618 35713366 7c85e08f 7236a8de
 *  K2             f7ddac30 6ae266cc f90bc11e e46d513b
 */
static const uint8_t key[16] = {
        0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
        0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
};
static const uint8_t sub_key1[16] = {
        0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
        0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
};
static const uint8_t sub_key2[16] = {
        0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
        0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
};

/*
 *  Example 1: len = 0
 *  M              <empty string>
 *  AES-CMAC       bb1d6929 e9593728 7fa37d12 9b756746
 */
static const uint8_t T_1[16] = {
        0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
        0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
};

/*
 *  Example 2: len = 16
 *  M              6bc1bee2 2e409f96 e93d7e11 7393172a
 *  AES-CMAC       070a16b4 6b4d4144 f79bdd9d d04a287c
 */
static const uint8_t T_2[16] = {
        0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
        0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
};

/*
 *  Example 3: len = 40
 *  M              6bc1bee2 2e409f96 e93d7e11 7393172a
 *                 ae2d8a57 1e03ac9c 9eb76fac 45af8e51
 *                 30c81c46 a35ce411
 *  AES-CMAC       dfa66747 de9ae630 30ca3261 1497c827
 */
static const uint8_t T_3[16] = {
        0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
        0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27
};

/*
 *  Example 4: len = 64
 *  M              6bc1bee2 2e409f96 e93d7e11 7393172a
 *                 ae2d8a57 1e03ac9c 9eb76fac 45af8e51
 *                 30c81c46 a35ce411 e5fbc119 1a0a52ef
 *                 f69f2445 df4f9b17 ad2b417b e66c3710
 *  AES-CMAC       51f0bebf 7e3b9d92 fc497417 79363cfe
 */
static const uint8_t T_4[16] = {
        0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
        0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
};

/*
 *  Custom Vector
 *
 *  Example 5: len = 8
 *  M              6bc1bee2 2e409f96
 *  AES-CMAC       dc87cdcf 77a2f182 9e012c4d 31af2f8b
 */
static const uint8_t T_5[16] = {
        0xdc, 0x87, 0xcd, 0xcf, 0x77, 0xa2, 0xf1, 0x82,
        0x9e, 0x01, 0x2c, 0x4d, 0x31, 0xaf, 0x2f, 0x8b
};

static const uint8_t M[64] = {
        0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
        0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
        0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
        0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
        0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
        0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
        0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
        0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
};

/*
 * 3GPP 33.401 C.2.1 Test Case 1
 *
 * CMAC(K,M):
 *   K         = (hex) 2bd6459f 82c5b300 952c4910 4881ff48
 *   Mlen      = 122 (bits)
 *   M         = (hex) 38a6f056 c0000000 33323462 63393840
 *
 * Subkey generation:
 *   K1        = (hex) dc84c270 b5bf83f9 6f90be18 8d3f6418
 *   K2        = (hex) b90984e1 6b7f07f2 df217c31 1a7ec8b7
 *
 * MAC generation:
 *   C1        = (hex) 118c6eb8 b775144b 0b831110 54c96eb6
 *   MACT      = (hex) 118c6eb8
 */
static const uint8_t EIA2_128_K_1[16] = {
        0x2b, 0xd6, 0x45, 0x9f, 0x82, 0xc5, 0xb3, 0x00,
        0x95, 0x2c, 0x49, 0x10, 0x48, 0x81, 0xff, 0x48
};

static const uint8_t EIA2_128_SK1_1[16] = {
        0xdc, 0x84, 0xc2, 0x70, 0xb5, 0xbf, 0x83, 0xf9,
        0x6f, 0x90, 0xbe, 0x18, 0x8d, 0x3f, 0x64, 0x18
};

static const uint8_t EIA2_128_SK2_1[16] = {
        0xb9, 0x09, 0x84, 0xe1, 0x6b, 0x7f, 0x07, 0xf2,
        0xdf, 0x21, 0x7c, 0x31, 0x1a, 0x7e, 0xc8, 0xb7
};

static const uint8_t EIA2_128_T_1[4] = {
        0x11, 0x8c, 0x6e, 0xb8
};

static const uint8_t EIA2_128_M_1[16] = {
        0x38, 0xa6, 0xf0, 0x56, 0xc0, 0x00, 0x00, 0x00,
        0x33, 0x32, 0x34, 0x62, 0x63, 0x39, 0x38, 0x40 /* 0x40 = 0100 0000 */
};

/*
 * 3GPP 33.401 C.2.1 Test Case 2
 *
 * CMAC(K, M):
 *   K         = d3c5d592 327fb11c 4035c668 0af8c6d1
 *   Mlen      = 128
 *   M         = 398a59b4 d4000000 484583d5 afe082ae
 *
 * Subkey Generation:
 *   L         = 9b71f299 132915d3 605211b5 e5df8632
 *   K1        = 36e3e532 26522ba6 c0a4236b cbbf0ce3
 *   K2        = 6dc7ca64 4ca4574d 814846d7 977e19c6
 *
 * MAC generation:
 *   C1        = b93787e6 493ff113 ad73d3e0 1e826d73
 *   MACT      = b93787e6
 */
static const uint8_t EIA2_128_K_2[16] = {
        0xd3, 0xc5, 0xd5, 0x92, 0x32, 0x7f, 0xb1, 0x1c,
        0x40, 0x35, 0xc6, 0x68, 0x0a, 0xf8, 0xc6, 0xd1
};

static const uint8_t EIA2_128_SK1_2[16] = {
        0x36, 0xe3, 0xe5, 0x32, 0x26, 0x52, 0x2b, 0xa6,
        0xc0, 0xa4, 0x23, 0x6b, 0xcb, 0xbf, 0x0c, 0xe3
};

static const uint8_t EIA2_128_SK2_2[16] = {
        0x6d, 0xc7, 0xca, 0x64, 0x4c, 0xa4, 0x57, 0x4d,
        0x81, 0x48, 0x46, 0xd7, 0x97, 0x7e, 0x19, 0xc6
};

static const uint8_t EIA2_128_T_2[4] = {
        0xb9, 0x37, 0x87, 0xe6
};

static const uint8_t EIA2_128_M_2[16] = {
        0x39, 0x8a, 0x59, 0xb4, 0xd4, 0x00, 0x00, 0x00,
        0x48, 0x45, 0x83, 0xd5, 0xaf, 0xe0, 0x82, 0xae
};

/*
 * 3GPP 33.401 C.2.1 Test Case 3
 *
 * CMAC(K, M):
 *   K         = 7e5e9443 1e11d738 28d739cc 6ced4573
 *   Mlen      = 318
 *   M         = 36af6144 c4000000 b3d3c917 0a4e1632 f60f8610 13d22d84 b726b6a2
 *               78d802d1 eeaf1321 ba5929dc
 *
 * Subkey Generation:
 *   L         = d78b4628 35781e79 d2255f8d 309a60ef
 *   K1        = af168c50 6af03cf3 a44abf1a 6134c159
 *   K2        = 5e2d18a0 d5e079e7 48957e34 c2698235
 *
 * MAC generation:
 *   C3        = 1f60b01d e05aa666 3bda32c6 1771e70b
 *   MACT      = 1f60b01d
 */
static const uint8_t EIA2_128_K_3[16] = {
        0x7e, 0x5e, 0x94, 0x43, 0x1e, 0x11, 0xd7, 0x38,
        0x28, 0xd7, 0x39, 0xcc, 0x6c, 0xed, 0x45, 0x73
};

static const uint8_t EIA2_128_SK1_3[16] = {
        0xaf, 0x16, 0x8c, 0x50, 0x6a, 0xf0, 0x3c, 0xf3,
        0xa4, 0x4a, 0xbf, 0x1a, 0x61, 0x34, 0xc1, 0x59
};

static const uint8_t EIA2_128_SK2_3[16] = {
        0x5e, 0x2d, 0x18, 0xa0, 0xd5, 0xe0, 0x79, 0xe7,
        0x48, 0x95, 0x7e, 0x34, 0xc2, 0x69, 0x82, 0x35
};

static const uint8_t EIA2_128_T_3[4] = {
        0x1f, 0x60, 0xb0, 0x1d
};

static const uint8_t EIA2_128_M_3[40] = {
        0x36, 0xaf, 0x61, 0x44, 0xc4, 0x00, 0x00, 0x00,
        0xb3, 0xd3, 0xc9, 0x17, 0x0a, 0x4e, 0x16, 0x32,
        0xf6, 0x0f, 0x86, 0x10, 0x13, 0xd2, 0x2d, 0x84,
        0xb7, 0x26, 0xb6, 0xa2, 0x78, 0xd8, 0x02, 0xd1,
        0xee, 0xaf, 0x13, 0x21, 0xba, 0x59, 0x29, 0xdc
};

/*
 * 3GPP 33.401 C.2.1 Test Case 4
 *
 * CMAC(K, M):
 *   K         = d3419be8 21087acd 02123a92 48033359
 *   Mlen      = 575
 *   M         = c7590ea9 b8000000 bbb05703 8809496b
 *               cff86d6f bc8ce5b1 35a06b16 6054f2d5
 *               65be8ace 75dc851e 0bcdd8f0 7141c495
 *               872fb5d8 c0c66a8b 6da55666 3e4e4612
 *               05d84580 bee5bc7e
 *
 * Subkey Generation:
 *   L         = 054dd008 2d9ecd21 a3f32b0a a7369be4
 *   K1        = 0a9ba010 5b3d9a43 47e65615 4e6d37c8
 *   K2        = 15374020 b67b3486 8fccac2a 9cda6f90
 *
 * MAC generation:
 *   C5        = 6846a2f0 a0b6be7a 4fb26a15 7e914c53
 *   MACT      = 6846a2f0
 */
static const uint8_t EIA2_128_K_4[16] = {
        0xd3, 0x41, 0x9b, 0xe8, 0x21, 0x08, 0x7a, 0xcd,
        0x02, 0x12, 0x3a, 0x92, 0x48, 0x03, 0x33, 0x59
};

static const uint8_t EIA2_128_SK1_4[16] = {
        0x0a, 0x9b, 0xa0, 0x10, 0x5b, 0x3d, 0x9a, 0x43,
        0x47, 0xe6, 0x56, 0x15, 0x4e, 0x6d, 0x37, 0xc8
};

static const uint8_t EIA2_128_SK2_4[16] = {
        0x15, 0x37, 0x40, 0x20, 0xb6, 0x7b, 0x34, 0x86,
        0x8f, 0xcc, 0xac, 0x2a, 0x9c, 0xda, 0x6f, 0x90
};

static const uint8_t EIA2_128_T_4[4] = {
        0x68, 0x46, 0xa2, 0xf0
};

static const uint8_t EIA2_128_M_4[72] = {
        0xc7, 0x59, 0x0e, 0xa9, 0xb8, 0x00, 0x00, 0x00,
        0xbb, 0xb0, 0x57, 0x03, 0x88, 0x09, 0x49, 0x6b,
        0xcf, 0xf8, 0x6d, 0x6f, 0xbc, 0x8c, 0xe5, 0xb1,
        0x35, 0xa0, 0x6b, 0x16, 0x60, 0x54, 0xf2, 0xd5,
        0x65, 0xbe, 0x8a, 0xce, 0x75, 0xdc, 0x85, 0x1e,
        0x0b, 0xcd, 0xd8, 0xf0, 0x71, 0x41, 0xc4, 0x95,
        0x87, 0x2f, 0xb5, 0xd8, 0xc0, 0xc6, 0x6a, 0x8b,
        0x6d, 0xa5, 0x56, 0x66, 0x3e, 0x4e, 0x46, 0x12,
        0x05, 0xd8, 0x45, 0x80, 0xbe, 0xe5, 0xbc, 0x7e
};

/*
 * 3GPP 33.401 C.2.1 Test Case 5
 *
 * CMAC(K, M):
 *   K         = 83fd23a2 44a74cf3 58da3019 f1722635
 *   Mlen      = 832
 *   M         = 36af6144 7c000000 35c68716 633c66fb
 *               750c2668 65d53c11 ea05b1e9 fa49c839
 *               8d48e1ef a5909d39 47902837 f5ae96d5
 *               a05bc8d6 1ca8dbef 1b13a4b4 abfe4fb1
 *               006045b6 74bb5472 9304c382 be53a5af
 *               05556176 f6eaa2ef 1d05e4b0 83181ee6
 *               74cda5a4 85f74d7a
 *
 * Subkey Generation:
 *   L         = 9df61c57 3c86acac 704db9d5 b0dea444
 *   K1        = 3bec38ae 790d5958 e09b73ab 61bd480f
 *   K2        = 77d8715c f21ab2b1 c136e756 c37a901e
 *
 * MAC generation:
 *   C7        = e657e182 5298f2fa ee2ca1e0 7373bc7e
 *   MACT      = e657e182
 */
static const uint8_t EIA2_128_K_5[16] = {
        0x83, 0xfd, 0x23, 0xa2, 0x44, 0xa7, 0x4c, 0xf3,
        0x58, 0xda, 0x30, 0x19, 0xf1, 0x72, 0x26, 0x35
};

static const uint8_t EIA2_128_SK1_5[16] = {
        0x3b, 0xec, 0x38, 0xae, 0x79, 0x0d, 0x59, 0x58,
        0xe0, 0x9b, 0x73, 0xab, 0x61, 0xbd, 0x48, 0x0f
};

static const uint8_t EIA2_128_SK2_5[16] = {
        0x77, 0xd8, 0x71, 0x5c, 0xf2, 0x1a, 0xb2, 0xb1,
        0xc1, 0x36, 0xe7, 0x56, 0xc3, 0x7a, 0x90, 0x1e
};

static const uint8_t EIA2_128_T_5[4] = {
        0xe6, 0x57, 0xe1, 0x82
};

static const uint8_t EIA2_128_M_5[104] = {
        0x36, 0xaf, 0x61, 0x44, 0x7c, 0x00, 0x00, 0x00,
        0x35, 0xc6, 0x87, 0x16, 0x63, 0x3c, 0x66, 0xfb,
        0x75, 0x0c, 0x26, 0x68, 0x65, 0xd5, 0x3c, 0x11,
        0xea, 0x05, 0xb1, 0xe9, 0xfa, 0x49, 0xc8, 0x39,
        0x8d, 0x48, 0xe1, 0xef, 0xa5, 0x90, 0x9d, 0x39,
        0x47, 0x90, 0x28, 0x37, 0xf5, 0xae, 0x96, 0xd5,
        0xa0, 0x5b, 0xc8, 0xd6, 0x1c, 0xa8, 0xdb, 0xef,
        0x1b, 0x13, 0xa4, 0xb4, 0xab, 0xfe, 0x4f, 0xb1,
        0x00, 0x60, 0x45, 0xb6, 0x74, 0xbb, 0x54, 0x72,
        0x93, 0x04, 0xc3, 0x82, 0xbe, 0x53, 0xa5, 0xaf,
        0x05, 0x55, 0x61, 0x76, 0xf6, 0xea, 0xa2, 0xef,
        0x1d, 0x05, 0xe4, 0xb0, 0x83, 0x18, 0x1e, 0xe6,
        0x74, 0xcd, 0xa5, 0xa4, 0x85, 0xf7, 0x4d, 0x7a
};

/*
 * 3GPP 33.401 C.2.1 Test Case 6
 *
 * CMAC(K, M):
 *   K         = 6832a65c ff447362 1ebdd4ba 26a921fe
 *   Mlen      = 447
 *   M         = 36af6144 c0000000 d3c53839 62682071
 *               77656676 20323837 63624098 1ba6824c
 *               1bfb1ab4 85472029 b71d808c e33e2cc3
 *               c0b5fc1f 3de8a6dc
 *
 * Subkey Generation:
 *   L         = e50123c3 87e13fd6 8d8bf0d0 a4581685
 *   K1        = ca024787 0fc27fad 1b17e1a1 48b02d8d
 *   K2        = 94048f0e 1f84ff5a 362fc342 91605b9d
 *
 * MAC generation:
 *   C4        = f0668c1e 4197300b 1243f834 25d06c25
 *   MACT      = f0668c1e
 */
static const uint8_t EIA2_128_K_6[16] = {
        0x68, 0x32, 0xa6, 0x5c, 0xff, 0x44, 0x73, 0x62,
        0x1e, 0xbd, 0xd4, 0xba, 0x26, 0xa9, 0x21, 0xfe
};

static const uint8_t EIA2_128_SK1_6[16] = {
        0xca, 0x02, 0x47, 0x87, 0x0f, 0xc2, 0x7f, 0xad,
        0x1b, 0x17, 0xe1, 0xa1, 0x48, 0xb0, 0x2d, 0x8d
};

static const uint8_t EIA2_128_SK2_6[16] = {
        0x94, 0x04, 0x8f, 0x0e, 0x1f, 0x84, 0xff, 0x5a,
        0x36, 0x2f, 0xc3, 0x42, 0x91, 0x60, 0x5b, 0x9d
};

static const uint8_t EIA2_128_T_6[4] = {
        0xf0, 0x66, 0x8c, 0x1e
};

static const uint8_t EIA2_128_M_6[56] = {
        0x36, 0xaf, 0x61, 0x44, 0xc0, 0x00, 0x00, 0x00,
        0xd3, 0xc5, 0x38, 0x39, 0x62, 0x68, 0x20, 0x71,
        0x77, 0x65, 0x66, 0x76, 0x20, 0x32, 0x38, 0x37,
        0x63, 0x62, 0x40, 0x98, 0x1b, 0xa6, 0x82, 0x4c,
        0x1b, 0xfb, 0x1a, 0xb4, 0x85, 0x47, 0x20, 0x29,
        0xb7, 0x1d, 0x80, 0x8c, 0xe3, 0x3e, 0x2c, 0xc3,
        0xc0, 0xb5, 0xfc, 0x1f, 0x3d, 0xe8, 0xa6, 0xdc
};

/*
 * 3GPP 33.401 C.2.1 Test Case 7
 *
 * CMAC(K, M):
 *   K         = 5d0a80d8 134ae196 77824b67 1e838af4
 *   Mlen      = 2622
 *   M         = 7827fab2 2c000000 70dedf2d c42c5cbd
 *               3a96f8a0 b11418b3 608d5733 604a2cd3
 *               6aabc70c e3193bb5 153be2d3 c06dfdb2
 *               d16e9c35 7158be6a 41d6b861 e491db3f
 *               bfeb518e fcf048d7 d5895373 0ff30c9e
 *               c470ffcd 663dc342 01c36add c0111c35
 *               b38afee7 cfdb582e 3731f8b4 baa8d1a8
 *               9c06e811 99a97162 27be344e fcb436dd
 *               d0f096c0 64c3b5e2 c399993f c77394f9
 *               e09720a8 11850ef2 3b2ee05d 9e617360
 *               9d86e1c0 c18ea51a 012a00bb 413b9cb8
 *               188a703c d6bae31c c67b34b1 b00019e6
 *               a2b2a690 f02671fe 7c9ef8de c0094e53
 *               3763478d 58d2c5f5 b827a014 8c5948a9
 *               6931acf8 4f465a64 e62ce740 07e991e3
 *               7ea823fa 0fb21923 b79905b7 33b631e6
 *               c7d6860a 3831ac35 1a9c730c 52ff72d9
 *               d308eedb ab21fde1 43a0ea17 e23edc1f
 *               74cbb363 8a2033aa a15464ea a733385d
 *               bbeb6fd7 3509b857 e6a419dc a1d8907a
 *               f977fbac 4dfa35ec
 *
 * Subkey Generation:
 *   L         = 9832e229 fbb93970 bcf7b282 3ee4fe5d
 *   K1        = 3065c453 f77272e1 79ef6504 7dc9fc3d
 *   K2        = 60cb88a7 eee4e5c2 f3deca08 fb93f87a
 *
 * MAC generation:
 *   C21       = f4cc8fa3 59e6e2e7 6e09c45d 6ea5e0de
 *   MACT      = f4cc8fa3
 */
static const uint8_t EIA2_128_K_7[16] = {
        0x5d, 0x0a, 0x80, 0xd8, 0x13, 0x4a, 0xe1, 0x96,
        0x77, 0x82, 0x4b, 0x67, 0x1e, 0x83, 0x8a, 0xf4
};

static const uint8_t EIA2_128_SK1_7[16] = {
        0x30, 0x65, 0xc4, 0x53, 0xf7, 0x72, 0x72, 0xe1,
        0x79, 0xef, 0x65, 0x04, 0x7d, 0xc9, 0xfc, 0x3d
};

static const uint8_t EIA2_128_SK2_7[16] = {
        0x60, 0xcb, 0x88, 0xa7, 0xee, 0xe4, 0xe5, 0xc2,
        0xf3, 0xde, 0xca, 0x08, 0xfb, 0x93, 0xf8, 0x7a
};

static const uint8_t EIA2_128_T_7[4] = {
        0xf4, 0xcc, 0x8f, 0xa3
};

static const uint8_t EIA2_128_M_7[328] = {
        0x78, 0x27, 0xfa, 0xb2, 0x2c, 0x00, 0x00, 0x00,
        0x70, 0xde, 0xdf, 0x2d, 0xc4, 0x2c, 0x5c, 0xbd,
        0x3a, 0x96, 0xf8, 0xa0, 0xb1, 0x14, 0x18, 0xb3,
        0x60, 0x8d, 0x57, 0x33, 0x60, 0x4a, 0x2c, 0xd3,
        0x6a, 0xab, 0xc7, 0x0c, 0xe3, 0x19, 0x3b, 0xb5,
        0x15, 0x3b, 0xe2, 0xd3, 0xc0, 0x6d, 0xfd, 0xb2,
        0xd1, 0x6e, 0x9c, 0x35, 0x71, 0x58, 0xbe, 0x6a,
        0x41, 0xd6, 0xb8, 0x61, 0xe4, 0x91, 0xdb, 0x3f,
        0xbf, 0xeb, 0x51, 0x8e, 0xfc, 0xf0, 0x48, 0xd7,
        0xd5, 0x89, 0x53, 0x73, 0x0f, 0xf3, 0x0c, 0x9e,
        0xc4, 0x70, 0xff, 0xcd, 0x66, 0x3d, 0xc3, 0x42,
        0x01, 0xc3, 0x6a, 0xdd, 0xc0, 0x11, 0x1c, 0x35,
        0xb3, 0x8a, 0xfe, 0xe7, 0xcf, 0xdb, 0x58, 0x2e,
        0x37, 0x31, 0xf8, 0xb4, 0xba, 0xa8, 0xd1, 0xa8,
        0x9c, 0x06, 0xe8, 0x11, 0x99, 0xa9, 0x71, 0x62,
        0x27, 0xbe, 0x34, 0x4e, 0xfc, 0xb4, 0x36, 0xdd,
        0xd0, 0xf0, 0x96, 0xc0, 0x64, 0xc3, 0xb5, 0xe2,
        0xc3, 0x99, 0x99, 0x3f, 0xc7, 0x73, 0x94, 0xf9,
        0xe0, 0x97, 0x20, 0xa8, 0x11, 0x85, 0x0e, 0xf2,
        0x3b, 0x2e, 0xe0, 0x5d, 0x9e, 0x61, 0x73, 0x60,
        0x9d, 0x86, 0xe1, 0xc0, 0xc1, 0x8e, 0xa5, 0x1a,
        0x01, 0x2a, 0x00, 0xbb, 0x41, 0x3b, 0x9c, 0xb8,
        0x18, 0x8a, 0x70, 0x3c, 0xd6, 0xba, 0xe3, 0x1c,
        0xc6, 0x7b, 0x34, 0xb1, 0xb0, 0x00, 0x19, 0xe6,
        0xa2, 0xb2, 0xa6, 0x90, 0xf0, 0x26, 0x71, 0xfe,
        0x7c, 0x9e, 0xf8, 0xde, 0xc0, 0x09, 0x4e, 0x53,
        0x37, 0x63, 0x47, 0x8d, 0x58, 0xd2, 0xc5, 0xf5,
        0xb8, 0x27, 0xa0, 0x14, 0x8c, 0x59, 0x48, 0xa9,
        0x69, 0x31, 0xac, 0xf8, 0x4f, 0x46, 0x5a, 0x64,
        0xe6, 0x2c, 0xe7, 0x40, 0x07, 0xe9, 0x91, 0xe3,
        0x7e, 0xa8, 0x23, 0xfa, 0x0f, 0xb2, 0x19, 0x23,
        0xb7, 0x99, 0x05, 0xb7, 0x33, 0xb6, 0x31, 0xe6,
        0xc7, 0xd6, 0x86, 0x0a, 0x38, 0x31, 0xac, 0x35,
        0x1a, 0x9c, 0x73, 0x0c, 0x52, 0xff, 0x72, 0xd9,
        0xd3, 0x08, 0xee, 0xdb, 0xab, 0x21, 0xfd, 0xe1,
        0x43, 0xa0, 0xea, 0x17, 0xe2, 0x3e, 0xdc, 0x1f,
        0x74, 0xcb, 0xb3, 0x63, 0x8a, 0x20, 0x33, 0xaa,
        0xa1, 0x54, 0x64, 0xea, 0xa7, 0x33, 0x38, 0x5d,
        0xbb, 0xeb, 0x6f, 0xd7, 0x35, 0x09, 0xb8, 0x57,
        0xe6, 0xa4, 0x19, 0xdc, 0xa1, 0xd8, 0x90, 0x7a,
        0xf9, 0x77, 0xfb, 0xac, 0x4d, 0xfa, 0x35, 0xec
};

/*
 * 3GPP 33.401 C.2.1 Test Case 8
 *
 * CMAC(K, M):
 *   K         = b3120ffd b2cf6af4 e73eaf2e f4ebec69
 *   Mlen      = 16512
 *   M         = 296f393c 5c000000 00000000 00000000
 *               01010101 01010101 e0958045 f3a0bba4
 *               e3968346 f0a3b8a7 c02a018a e6407652
 *               26b987c9 13e6cbf0 83570016 cf83efbc
 *               61c08251 3e21561a 427c009d 28c298ef
 *               ace78ed6 d56c2d45 05ad032e 9c04dc60
 *               e73a8169 6da665c6 c48603a5 7b45ab33
 *               221585e6 8ee31691 87fb0239 528632dd
 *               656c807e a3248b7b 46d002b2 b5c7458e
 *               b85b9ce9 5879e034 0859055e 3b0abbc3
 *               eace8719 caa80265 c97205d5 dc4bcc90
 *               2fe18396 29ed7132 8a0f0449 f588557e
 *               6898860e 042aecd8 4b2404c2 12c9222d
 *               a5bf8a89 ef679787 0cf50771 a60f66a2
 *               ee628536 57addf04 cdde07fa 414e11f1
 *               2b4d81b9 b4e8ac53 8ea30666 688d881f
 *               6c348421 992f31b9 4f8806ed 8fccff4c
 *               9123b896 42527ad6 13b109bf 75167485
 *               f1268bf8 84b4cd23 d29a0934 925703d6
 *               34098f77 67f1be74 91e708a8 bb949a38
 *               73708aef 4a36239e 50cc0823 5cd5ed6b
 *               be578668 a17b58c1 171d0b90 e813a9e4
 *               f58a89d7 19b11042 d6360b1b 0f52deb7
 *               30a58d58 faf46315 954b0a87 26914759
 *               77dc88c0 d733feff 54600a0c c1d0300a
 *               aaeb9457 2c6e95b0 1ae90de0 4f1dce47
 *               f87e8fa7 bebf77e1 dbc20d6b a85cb914
 *               3d518b28 5dfa04b6 98bf0cf7 819f20fa
 *               7a288eb0 703d995c 59940c7c 66de57a9
 *               b70f8237 9b70e203 1e450fcf d2181326
 *               fcd28d88 23baaa80 df6e0f44 35596475
 *               39fd8907 c0ffd9d7 9c130ed8 1c9afd9b
 *               7e848c9f ed38443d 5d380e53 fbdb8ac8
 *               c3d3f068 76054f12 2461107d e92fea09
 *               c6f6923a 188d53af e54a10f6 0e6e9d5a
 *               03d996b5 fbc820f8 a637116a 27ad04b4
 *               44a0932d d60fbd12 671c11e1 c0ec73e7
 *               89879faa 3d42c64d 20cd1252 742a3768
 *               c25a9015 85888ece e1e612d9 936b403b
 *               0775949a 66cdfd99 a29b1345 baa8d9d5
 *               400c9102 4b0a6073 63b013ce 5de9ae86
 *               9d3b8d95 b0570b3c 2d391422 d32450cb
 *               cfae9665 2286e96d ec1214a9 34652798
 *               0a8192ea c1c39a3a af6f1535 1da6be76
 *               4df89772 ec0407d0 6e4415be fae7c925
 *               80df9bf5 07497c8f 2995160d 4e218daa
 *               cb02944a bf83340c e8be1686 a960faf9
 *               0e2d90c5 5cc6475b abc3171a 80a36317
 *               4954955d 7101dab1 6ae81791 67e21444
 *               b443a9ea aa7c91de 36d118c3 9d389f8d
 *               d4469a84 6c9a262b f7fa1848 7a79e8de
 *               11699e0b 8fdf557c b48719d4 53ba7130
 *               56109b93 a218c896 75ac195f b4fb0663
 *               9b379714 4955b3c9 327d1aec 003d42ec
 *               d0ea98ab f19ffb4a f3561a67 e77c35bf
 *               15c59c24 12da881d b02b1bfb cebfac51
 *               52bc99bc 3f1d15f7 71001b70 29fedb02
 *               8f8b852b c4407eb8 3f891c9c a733254f
 *               dd1e9edb 56919ce9 fea21c17 4072521c
 *               18319a54 b5d4efbe bddf1d8b 69b1cbf2
 *               5f489fcc 98137254 7cf41d00 8ef0bca1
 *               926f934b 735e090b 3b251eb3 3a36f82e
 *               d9b29cf4 cb944188 fa0e1e38 dd778f7d
 *               1c9d987b 28d132df b9731fa4 f4b41693
 *               5be49de3 0516af35 78581f2f 13f561c0
 *               66336194 1eab249a 4bc123f8 d15cd711
 *               a956a1bf 20fe6eb7 8aea2373 361da042
 *               6c79a530 c3bb1de0 c99722ef 1fde39ac
 *               2b00a0a8 ee7c800a 08bc2264 f89f4eff
 *               e627ac2f 0531fb55 4f6d21d7 4c590a70
 *               adfaa390 bdfbb3d6 8e46215c ab187d23
 *               68d5a71f 5ebec081 cd3b20c0 82dbe4cd
 *               2faca287 73795d6b 0c10204b 659a939e
 *               f29bbe10 88243624 429927a7 eb576dd3
 *               a00ea5e0 1af5d475 83b2272c 0c161a80
 *               6521a16f f9b0a722 c0cf26b0 25d5836e
 *               2258a4f7 d4773ac8 01e4263b c294f43d
 *               ef7fa870 3f3a4197 46352588 7652b0b2
 *               a4a2a7cf 87f00914 871e2503 9113c7e1
 *               618da340 64b57a43 c463249f b8d05e0f
 *               26f4a6d8 4972e7a9 05482414 5f91295c
 *               dbe39a6f 920facc6 59712b46 a54ba295
 *               bbe6a901 54e91b33 985a2bcd 420ad5c6
 *               7ec9ad8e b7ac6864 db272a51 6bc94c28
 *               39b0a816 9a6bf58e 1a0c2ada 8c883b7b
 *               f497a491 71268ed1 5ddd2969 384e7ff4
 *               bf4aab2e c9ecc652 9cf629e2 df0f08a7
 *               7a65afa1 2aa9b505 df8b287e f6cc9149
 *               3d1caa39 076e28ef 1ea028f5 118de61a
 *               e02bb6ae fc3343a0 50292f19 9f401857
 *               b2bead5e 6ee2a1f1 91022f92 78016f04
 *               7791a9d1 8da7d2a6 d27f2e0e 51c2f6ea
 *               30e8ac49 a0604f4c 13542e85 b68381b9
 *               fdcfa0ce 4b2d3413 54852d36 0245c536
 *               b612af71 f3e77c90 95ae2dbd e504b265
 *               733dabfe 10a20fc7 d6d32c21 ccc72b8b
 *               3444ae66 3d65922d 17f82caa 2b865cd8
 *               8913d291 a6589902 6ea13284 39723c19
 *               8c36b0c3 c8d085bf af8a320f de334b4a
 *               4919b44c 2b95f6e8 ecf73393 f7f0d2a4
 *               0e60b1d4 06526b02 2ddc3318 10b1a5f7
 *               c347bd53 ed1f105d 6a0d30ab a477e178
 *               889ab2ec 55d558de ab263020 4336962b
 *               4db5b663 b6902b89 e85b31bc 6af50fc5
 *               0accb3fb 9b57b663 29703137 8db47896
 *               d7fbaf6c 600add2c 67f936db 037986db
 *               856eb49c f2db3f7d a6d23650 e438f188
 *               4041b013 119e4c2a e5af37cc cdfb6866
 *               0738b58b 3c59d1c0 24843747 2aba1f35
 *               ca1fb90c d714aa9f 635534f4 9e7c5bba
 *               81c2b6b3 6fdee21c a27e347f 793d2ce9
 *               44edb23c 8c9b914b e10335e3 50feb507
 *               0394b7a4 a15c0ca1 20283568 b7bfc254
 *               fe838b13 7a2147ce 7c113a3a 4d65499d
 *               9e86b87d bcc7f03b bd3a3ab1 aa243ece
 *               5ba9bcf2 5f82836c fe473b2d 83e7a720
 *               1cd0b96a 72451e86 3f6c3ba6 64a6d073
 *               d1f7b5ed 990865d9 78bd3815 d06094fc
 *               9a2aba52 21c22d5a b996389e 3721e3af
 *               5f05bedd c2875e0d faeb3902 1ee27a41
 *               187cbb45 ef40c3e7 3bc03989 f9a30d12
 *               c54ba7d2 141da8a8 75493e65 776ef35f
 *               97debc22 86cc4af9 b4623eee 902f840c
 *               52f1b8ad 658939ae f71f3f72 b9ec1de2
 *               1588bd35 484ea444 36343ff9 5ead6ab1
 *               d8afb1b2 a303df1b 71e53c4a ea6b2e3e
 *               9372be0d 1bc99798 b0ce3cc1 0d2a596d
 *               565dba82 f88ce4cf f3b33d5d 24e9c083
 *               1124bf1a d54b7925 32983dd6 c3a8b7d0
 *
 * Subkey Generation:
 *   L         = 2c645dcd 72114961 d8b9c864 7aac2c5b
 *   K1        = 58c8bb9a e42292c3 b17390c8 f55858b6
 *   K2        = b1917735 c8452587 62e72191 eab0b16c
 *
 * MAC generation:
 *   C129      = ebd5ccb0 b61ca905 29138303 f3377d22
 *   MACT      = ebd5ccb0
 */
static const uint8_t EIA2_128_K_8[16] = {
        0xb3, 0x12, 0x0f, 0xfd, 0xb2, 0xcf, 0x6a, 0xf4,
        0xe7, 0x3e, 0xaf, 0x2e, 0xf4, 0xeb, 0xec, 0x69
};

static const uint8_t EIA2_128_SK1_8[16] = {
        0x58, 0xc8, 0xbb, 0x9a, 0xe4, 0x22, 0x92, 0xc3,
        0xb1, 0x73, 0x90, 0xc8, 0xf5, 0x58, 0x58, 0xb6
};

static const uint8_t EIA2_128_SK2_8[16] = {
        0xb1, 0x91, 0x77, 0x35, 0xc8, 0x45, 0x25, 0x87,
        0x62, 0xe7, 0x21, 0x91, 0xea, 0xb0, 0xb1, 0x6c
};

static const uint8_t EIA2_128_T_8[4] = {
        0xeb, 0xd5, 0xcc, 0xb0
};

static const uint8_t EIA2_128_M_8[2064] = {
        0x29, 0x6f, 0x39, 0x3c, 0x5c, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
        0xe0, 0x95, 0x80, 0x45, 0xf3, 0xa0, 0xbb, 0xa4,
        0xe3, 0x96, 0x83, 0x46, 0xf0, 0xa3, 0xb8, 0xa7,
        0xc0, 0x2a, 0x01, 0x8a, 0xe6, 0x40, 0x76, 0x52,
        0x26, 0xb9, 0x87, 0xc9, 0x13, 0xe6, 0xcb, 0xf0,
        0x83, 0x57, 0x00, 0x16, 0xcf, 0x83, 0xef, 0xbc,
        0x61, 0xc0, 0x82, 0x51, 0x3e, 0x21, 0x56, 0x1a,
        0x42, 0x7c, 0x00, 0x9d, 0x28, 0xc2, 0x98, 0xef,
        0xac, 0xe7, 0x8e, 0xd6, 0xd5, 0x6c, 0x2d, 0x45,
        0x05, 0xad, 0x03, 0x2e, 0x9c, 0x04, 0xdc, 0x60,
        0xe7, 0x3a, 0x81, 0x69, 0x6d, 0xa6, 0x65, 0xc6,
        0xc4, 0x86, 0x03, 0xa5, 0x7b, 0x45, 0xab, 0x33,
        0x22, 0x15, 0x85, 0xe6, 0x8e, 0xe3, 0x16, 0x91,
        0x87, 0xfb, 0x02, 0x39, 0x52, 0x86, 0x32, 0xdd,
        0x65, 0x6c, 0x80, 0x7e, 0xa3, 0x24, 0x8b, 0x7b,
        0x46, 0xd0, 0x02, 0xb2, 0xb5, 0xc7, 0x45, 0x8e,
        0xb8, 0x5b, 0x9c, 0xe9, 0x58, 0x79, 0xe0, 0x34,
        0x08, 0x59, 0x05, 0x5e, 0x3b, 0x0a, 0xbb, 0xc3,
        0xea, 0xce, 0x87, 0x19, 0xca, 0xa8, 0x02, 0x65,
        0xc9, 0x72, 0x05, 0xd5, 0xdc, 0x4b, 0xcc, 0x90,
        0x2f, 0xe1, 0x83, 0x96, 0x29, 0xed, 0x71, 0x32,
        0x8a, 0x0f, 0x04, 0x49, 0xf5, 0x88, 0x55, 0x7e,
        0x68, 0x98, 0x86, 0x0e, 0x04, 0x2a, 0xec, 0xd8,
        0x4b, 0x24, 0x04, 0xc2, 0x12, 0xc9, 0x22, 0x2d,
        0xa5, 0xbf, 0x8a, 0x89, 0xef, 0x67, 0x97, 0x87,
        0x0c, 0xf5, 0x07, 0x71, 0xa6, 0x0f, 0x66, 0xa2,
        0xee, 0x62, 0x85, 0x36, 0x57, 0xad, 0xdf, 0x04,
        0xcd, 0xde, 0x07, 0xfa, 0x41, 0x4e, 0x11, 0xf1,
        0x2b, 0x4d, 0x81, 0xb9, 0xb4, 0xe8, 0xac, 0x53,
        0x8e, 0xa3, 0x06, 0x66, 0x68, 0x8d, 0x88, 0x1f,
        0x6c, 0x34, 0x84, 0x21, 0x99, 0x2f, 0x31, 0xb9,
        0x4f, 0x88, 0x06, 0xed, 0x8f, 0xcc, 0xff, 0x4c,
        0x91, 0x23, 0xb8, 0x96, 0x42, 0x52, 0x7a, 0xd6,
        0x13, 0xb1, 0x09, 0xbf, 0x75, 0x16, 0x74, 0x85,
        0xf1, 0x26, 0x8b, 0xf8, 0x84, 0xb4, 0xcd, 0x23,
        0xd2, 0x9a, 0x09, 0x34, 0x92, 0x57, 0x03, 0xd6,
        0x34, 0x09, 0x8f, 0x77, 0x67, 0xf1, 0xbe, 0x74,
        0x91, 0xe7, 0x08, 0xa8, 0xbb, 0x94, 0x9a, 0x38,
        0x73, 0x70, 0x8a, 0xef, 0x4a, 0x36, 0x23, 0x9e,
        0x50, 0xcc, 0x08, 0x23, 0x5c, 0xd5, 0xed, 0x6b,
        0xbe, 0x57, 0x86, 0x68, 0xa1, 0x7b, 0x58, 0xc1,
        0x17, 0x1d, 0x0b, 0x90, 0xe8, 0x13, 0xa9, 0xe4,
        0xf5, 0x8a, 0x89, 0xd7, 0x19, 0xb1, 0x10, 0x42,
        0xd6, 0x36, 0x0b, 0x1b, 0x0f, 0x52, 0xde, 0xb7,
        0x30, 0xa5, 0x8d, 0x58, 0xfa, 0xf4, 0x63, 0x15,
        0x95, 0x4b, 0x0a, 0x87, 0x26, 0x91, 0x47, 0x59,
        0x77, 0xdc, 0x88, 0xc0, 0xd7, 0x33, 0xfe, 0xff,
        0x54, 0x60, 0x0a, 0x0c, 0xc1, 0xd0, 0x30, 0x0a,
        0xaa, 0xeb, 0x94, 0x57, 0x2c, 0x6e, 0x95, 0xb0,
        0x1a, 0xe9, 0x0d, 0xe0, 0x4f, 0x1d, 0xce, 0x47,
        0xf8, 0x7e, 0x8f, 0xa7, 0xbe, 0xbf, 0x77, 0xe1,
        0xdb, 0xc2, 0x0d, 0x6b, 0xa8, 0x5c, 0xb9, 0x14,
        0x3d, 0x51, 0x8b, 0x28, 0x5d, 0xfa, 0x04, 0xb6,
        0x98, 0xbf, 0x0c, 0xf7, 0x81, 0x9f, 0x20, 0xfa,
        0x7a, 0x28, 0x8e, 0xb0, 0x70, 0x3d, 0x99, 0x5c,
        0x59, 0x94, 0x0c, 0x7c, 0x66, 0xde, 0x57, 0xa9,
        0xb7, 0x0f, 0x82, 0x37, 0x9b, 0x70, 0xe2, 0x03,
        0x1e, 0x45, 0x0f, 0xcf, 0xd2, 0x18, 0x13, 0x26,
        0xfc, 0xd2, 0x8d, 0x88, 0x23, 0xba, 0xaa, 0x80,
        0xdf, 0x6e, 0x0f, 0x44, 0x35, 0x59, 0x64, 0x75,
        0x39, 0xfd, 0x89, 0x07, 0xc0, 0xff, 0xd9, 0xd7,
        0x9c, 0x13, 0x0e, 0xd8, 0x1c, 0x9a, 0xfd, 0x9b,
        0x7e, 0x84, 0x8c, 0x9f, 0xed, 0x38, 0x44, 0x3d,
        0x5d, 0x38, 0x0e, 0x53, 0xfb, 0xdb, 0x8a, 0xc8,
        0xc3, 0xd3, 0xf0, 0x68, 0x76, 0x05, 0x4f, 0x12,
        0x24, 0x61, 0x10, 0x7d, 0xe9, 0x2f, 0xea, 0x09,
        0xc6, 0xf6, 0x92, 0x3a, 0x18, 0x8d, 0x53, 0xaf,
        0xe5, 0x4a, 0x10, 0xf6, 0x0e, 0x6e, 0x9d, 0x5a,
        0x03, 0xd9, 0x96, 0xb5, 0xfb, 0xc8, 0x20, 0xf8,
        0xa6, 0x37, 0x11, 0x6a, 0x27, 0xad, 0x04, 0xb4,
        0x44, 0xa0, 0x93, 0x2d, 0xd6, 0x0f, 0xbd, 0x12,
        0x67, 0x1c, 0x11, 0xe1, 0xc0, 0xec, 0x73, 0xe7,
        0x89, 0x87, 0x9f, 0xaa, 0x3d, 0x42, 0xc6, 0x4d,
        0x20, 0xcd, 0x12, 0x52, 0x74, 0x2a, 0x37, 0x68,
        0xc2, 0x5a, 0x90, 0x15, 0x85, 0x88, 0x8e, 0xce,
        0xe1, 0xe6, 0x12, 0xd9, 0x93, 0x6b, 0x40, 0x3b,
        0x07, 0x75, 0x94, 0x9a, 0x66, 0xcd, 0xfd, 0x99,
        0xa2, 0x9b, 0x13, 0x45, 0xba, 0xa8, 0xd9, 0xd5,
        0x40, 0x0c, 0x91, 0x02, 0x4b, 0x0a, 0x60, 0x73,
        0x63, 0xb0, 0x13, 0xce, 0x5d, 0xe9, 0xae, 0x86,
        0x9d, 0x3b, 0x8d, 0x95, 0xb0, 0x57, 0x0b, 0x3c,
        0x2d, 0x39, 0x14, 0x22, 0xd3, 0x24, 0x50, 0xcb,
        0xcf, 0xae, 0x96, 0x65, 0x22, 0x86, 0xe9, 0x6d,
        0xec, 0x12, 0x14, 0xa9, 0x34, 0x65, 0x27, 0x98,
        0x0a, 0x81, 0x92, 0xea, 0xc1, 0xc3, 0x9a, 0x3a,
        0xaf, 0x6f, 0x15, 0x35, 0x1d, 0xa6, 0xbe, 0x76,
        0x4d, 0xf8, 0x97, 0x72, 0xec, 0x04, 0x07, 0xd0,
        0x6e, 0x44, 0x15, 0xbe, 0xfa, 0xe7, 0xc9, 0x25,
        0x80, 0xdf, 0x9b, 0xf5, 0x07, 0x49, 0x7c, 0x8f,
        0x29, 0x95, 0x16, 0x0d, 0x4e, 0x21, 0x8d, 0xaa,
        0xcb, 0x02, 0x94, 0x4a, 0xbf, 0x83, 0x34, 0x0c,
        0xe8, 0xbe, 0x16, 0x86, 0xa9, 0x60, 0xfa, 0xf9,
        0x0e, 0x2d, 0x90, 0xc5, 0x5c, 0xc6, 0x47, 0x5b,
        0xab, 0xc3, 0x17, 0x1a, 0x80, 0xa3, 0x63, 0x17,
        0x49, 0x54, 0x95, 0x5d, 0x71, 0x01, 0xda, 0xb1,
        0x6a, 0xe8, 0x17, 0x91, 0x67, 0xe2, 0x14, 0x44,
        0xb4, 0x43, 0xa9, 0xea, 0xaa, 0x7c, 0x91, 0xde,
        0x36, 0xd1, 0x18, 0xc3, 0x9d, 0x38, 0x9f, 0x8d,
        0xd4, 0x46, 0x9a, 0x84, 0x6c, 0x9a, 0x26, 0x2b,
        0xf7, 0xfa, 0x18, 0x48, 0x7a, 0x79, 0xe8, 0xde,
        0x11, 0x69, 0x9e, 0x0b, 0x8f, 0xdf, 0x55, 0x7c,
        0xb4, 0x87, 0x19, 0xd4, 0x53, 0xba, 0x71, 0x30,
        0x56, 0x10, 0x9b, 0x93, 0xa2, 0x18, 0xc8, 0x96,
        0x75, 0xac, 0x19, 0x5f, 0xb4, 0xfb, 0x06, 0x63,
        0x9b, 0x37, 0x97, 0x14, 0x49, 0x55, 0xb3, 0xc9,
        0x32, 0x7d, 0x1a, 0xec, 0x00, 0x3d, 0x42, 0xec,
        0xd0, 0xea, 0x98, 0xab, 0xf1, 0x9f, 0xfb, 0x4a,
        0xf3, 0x56, 0x1a, 0x67, 0xe7, 0x7c, 0x35, 0xbf,
        0x15, 0xc5, 0x9c, 0x24, 0x12, 0xda, 0x88, 0x1d,
        0xb0, 0x2b, 0x1b, 0xfb, 0xce, 0xbf, 0xac, 0x51,
        0x52, 0xbc, 0x99, 0xbc, 0x3f, 0x1d, 0x15, 0xf7,
        0x71, 0x00, 0x1b, 0x70, 0x29, 0xfe, 0xdb, 0x02,
        0x8f, 0x8b, 0x85, 0x2b, 0xc4, 0x40, 0x7e, 0xb8,
        0x3f, 0x89, 0x1c, 0x9c, 0xa7, 0x33, 0x25, 0x4f,
        0xdd, 0x1e, 0x9e, 0xdb, 0x56, 0x91, 0x9c, 0xe9,
        0xfe, 0xa2, 0x1c, 0x17, 0x40, 0x72, 0x52, 0x1c,
        0x18, 0x31, 0x9a, 0x54, 0xb5, 0xd4, 0xef, 0xbe,
        0xbd, 0xdf, 0x1d, 0x8b, 0x69, 0xb1, 0xcb, 0xf2,
        0x5f, 0x48, 0x9f, 0xcc, 0x98, 0x13, 0x72, 0x54,
        0x7c, 0xf4, 0x1d, 0x00, 0x8e, 0xf0, 0xbc, 0xa1,
        0x92, 0x6f, 0x93, 0x4b, 0x73, 0x5e, 0x09, 0x0b,
        0x3b, 0x25, 0x1e, 0xb3, 0x3a, 0x36, 0xf8, 0x2e,
        0xd9, 0xb2, 0x9c, 0xf4, 0xcb, 0x94, 0x41, 0x88,
        0xfa, 0x0e, 0x1e, 0x38, 0xdd, 0x77, 0x8f, 0x7d,
        0x1c, 0x9d, 0x98, 0x7b, 0x28, 0xd1, 0x32, 0xdf,
        0xb9, 0x73, 0x1f, 0xa4, 0xf4, 0xb4, 0x16, 0x93,
        0x5b, 0xe4, 0x9d, 0xe3, 0x05, 0x16, 0xaf, 0x35,
        0x78, 0x58, 0x1f, 0x2f, 0x13, 0xf5, 0x61, 0xc0,
        0x66, 0x33, 0x61, 0x94, 0x1e, 0xab, 0x24, 0x9a,
        0x4b, 0xc1, 0x23, 0xf8, 0xd1, 0x5c, 0xd7, 0x11,
        0xa9, 0x56, 0xa1, 0xbf, 0x20, 0xfe, 0x6e, 0xb7,
        0x8a, 0xea, 0x23, 0x73, 0x36, 0x1d, 0xa0, 0x42,
        0x6c, 0x79, 0xa5, 0x30, 0xc3, 0xbb, 0x1d, 0xe0,
        0xc9, 0x97, 0x22, 0xef, 0x1f, 0xde, 0x39, 0xac,
        0x2b, 0x00, 0xa0, 0xa8, 0xee, 0x7c, 0x80, 0x0a,
        0x08, 0xbc, 0x22, 0x64, 0xf8, 0x9f, 0x4e, 0xff,
        0xe6, 0x27, 0xac, 0x2f, 0x05, 0x31, 0xfb, 0x55,
        0x4f, 0x6d, 0x21, 0xd7, 0x4c, 0x59, 0x0a, 0x70,
        0xad, 0xfa, 0xa3, 0x90, 0xbd, 0xfb, 0xb3, 0xd6,
        0x8e, 0x46, 0x21, 0x5c, 0xab, 0x18, 0x7d, 0x23,
        0x68, 0xd5, 0xa7, 0x1f, 0x5e, 0xbe, 0xc0, 0x81,
        0xcd, 0x3b, 0x20, 0xc0, 0x82, 0xdb, 0xe4, 0xcd,
        0x2f, 0xac, 0xa2, 0x87, 0x73, 0x79, 0x5d, 0x6b,
        0x0c, 0x10, 0x20, 0x4b, 0x65, 0x9a, 0x93, 0x9e,
        0xf2, 0x9b, 0xbe, 0x10, 0x88, 0x24, 0x36, 0x24,
        0x42, 0x99, 0x27, 0xa7, 0xeb, 0x57, 0x6d, 0xd3,
        0xa0, 0x0e, 0xa5, 0xe0, 0x1a, 0xf5, 0xd4, 0x75,
        0x83, 0xb2, 0x27, 0x2c, 0x0c, 0x16, 0x1a, 0x80,
        0x65, 0x21, 0xa1, 0x6f, 0xf9, 0xb0, 0xa7, 0x22,
        0xc0, 0xcf, 0x26, 0xb0, 0x25, 0xd5, 0x83, 0x6e,
        0x22, 0x58, 0xa4, 0xf7, 0xd4, 0x77, 0x3a, 0xc8,
        0x01, 0xe4, 0x26, 0x3b, 0xc2, 0x94, 0xf4, 0x3d,
        0xef, 0x7f, 0xa8, 0x70, 0x3f, 0x3a, 0x41, 0x97,
        0x46, 0x35, 0x25, 0x88, 0x76, 0x52, 0xb0, 0xb2,
        0xa4, 0xa2, 0xa7, 0xcf, 0x87, 0xf0, 0x09, 0x14,
        0x87, 0x1e, 0x25, 0x03, 0x91, 0x13, 0xc7, 0xe1,
        0x61, 0x8d, 0xa3, 0x40, 0x64, 0xb5, 0x7a, 0x43,
        0xc4, 0x63, 0x24, 0x9f, 0xb8, 0xd0, 0x5e, 0x0f,
        0x26, 0xf4, 0xa6, 0xd8, 0x49, 0x72, 0xe7, 0xa9,
        0x05, 0x48, 0x24, 0x14, 0x5f, 0x91, 0x29, 0x5c,
        0xdb, 0xe3, 0x9a, 0x6f, 0x92, 0x0f, 0xac, 0xc6,
        0x59, 0x71, 0x2b, 0x46, 0xa5, 0x4b, 0xa2, 0x95,
        0xbb, 0xe6, 0xa9, 0x01, 0x54, 0xe9, 0x1b, 0x33,
        0x98, 0x5a, 0x2b, 0xcd, 0x42, 0x0a, 0xd5, 0xc6,
        0x7e, 0xc9, 0xad, 0x8e, 0xb7, 0xac, 0x68, 0x64,
        0xdb, 0x27, 0x2a, 0x51, 0x6b, 0xc9, 0x4c, 0x28,
        0x39, 0xb0, 0xa8, 0x16, 0x9a, 0x6b, 0xf5, 0x8e,
        0x1a, 0x0c, 0x2a, 0xda, 0x8c, 0x88, 0x3b, 0x7b,
        0xf4, 0x97, 0xa4, 0x91, 0x71, 0x26, 0x8e, 0xd1,
        0x5d, 0xdd, 0x29, 0x69, 0x38, 0x4e, 0x7f, 0xf4,
        0xbf, 0x4a, 0xab, 0x2e, 0xc9, 0xec, 0xc6, 0x52,
        0x9c, 0xf6, 0x29, 0xe2, 0xdf, 0x0f, 0x08, 0xa7,
        0x7a, 0x65, 0xaf, 0xa1, 0x2a, 0xa9, 0xb5, 0x05,
        0xdf, 0x8b, 0x28, 0x7e, 0xf6, 0xcc, 0x91, 0x49,
        0x3d, 0x1c, 0xaa, 0x39, 0x07, 0x6e, 0x28, 0xef,
        0x1e, 0xa0, 0x28, 0xf5, 0x11, 0x8d, 0xe6, 0x1a,
        0xe0, 0x2b, 0xb6, 0xae, 0xfc, 0x33, 0x43, 0xa0,
        0x50, 0x29, 0x2f, 0x19, 0x9f, 0x40, 0x18, 0x57,
        0xb2, 0xbe, 0xad, 0x5e, 0x6e, 0xe2, 0xa1, 0xf1,
        0x91, 0x02, 0x2f, 0x92, 0x78, 0x01, 0x6f, 0x04,
        0x77, 0x91, 0xa9, 0xd1, 0x8d, 0xa7, 0xd2, 0xa6,
        0xd2, 0x7f, 0x2e, 0x0e, 0x51, 0xc2, 0xf6, 0xea,
        0x30, 0xe8, 0xac, 0x49, 0xa0, 0x60, 0x4f, 0x4c,
        0x13, 0x54, 0x2e, 0x85, 0xb6, 0x83, 0x81, 0xb9,
        0xfd, 0xcf, 0xa0, 0xce, 0x4b, 0x2d, 0x34, 0x13,
        0x54, 0x85, 0x2d, 0x36, 0x02, 0x45, 0xc5, 0x36,
        0xb6, 0x12, 0xaf, 0x71, 0xf3, 0xe7, 0x7c, 0x90,
        0x95, 0xae, 0x2d, 0xbd, 0xe5, 0x04, 0xb2, 0x65,
        0x73, 0x3d, 0xab, 0xfe, 0x10, 0xa2, 0x0f, 0xc7,
        0xd6, 0xd3, 0x2c, 0x21, 0xcc, 0xc7, 0x2b, 0x8b,
        0x34, 0x44, 0xae, 0x66, 0x3d, 0x65, 0x92, 0x2d,
        0x17, 0xf8, 0x2c, 0xaa, 0x2b, 0x86, 0x5c, 0xd8,
        0x89, 0x13, 0xd2, 0x91, 0xa6, 0x58, 0x99, 0x02,
        0x6e, 0xa1, 0x32, 0x84, 0x39, 0x72, 0x3c, 0x19,
        0x8c, 0x36, 0xb0, 0xc3, 0xc8, 0xd0, 0x85, 0xbf,
        0xaf, 0x8a, 0x32, 0x0f, 0xde, 0x33, 0x4b, 0x4a,
        0x49, 0x19, 0xb4, 0x4c, 0x2b, 0x95, 0xf6, 0xe8,
        0xec, 0xf7, 0x33, 0x93, 0xf7, 0xf0, 0xd2, 0xa4,
        0x0e, 0x60, 0xb1, 0xd4, 0x06, 0x52, 0x6b, 0x02,
        0x2d, 0xdc, 0x33, 0x18, 0x10, 0xb1, 0xa5, 0xf7,
        0xc3, 0x47, 0xbd, 0x53, 0xed, 0x1f, 0x10, 0x5d,
        0x6a, 0x0d, 0x30, 0xab, 0xa4, 0x77, 0xe1, 0x78,
        0x88, 0x9a, 0xb2, 0xec, 0x55, 0xd5, 0x58, 0xde,
        0xab, 0x26, 0x30, 0x20, 0x43, 0x36, 0x96, 0x2b,
        0x4d, 0xb5, 0xb6, 0x63, 0xb6, 0x90, 0x2b, 0x89,
        0xe8, 0x5b, 0x31, 0xbc, 0x6a, 0xf5, 0x0f, 0xc5,
        0x0a, 0xcc, 0xb3, 0xfb, 0x9b, 0x57, 0xb6, 0x63,
        0x29, 0x70, 0x31, 0x37, 0x8d, 0xb4, 0x78, 0x96,
        0xd7, 0xfb, 0xaf, 0x6c, 0x60, 0x0a, 0xdd, 0x2c,
        0x67, 0xf9, 0x36, 0xdb, 0x03, 0x79, 0x86, 0xdb,
        0x85, 0x6e, 0xb4, 0x9c, 0xf2, 0xdb, 0x3f, 0x7d,
        0xa6, 0xd2, 0x36, 0x50, 0xe4, 0x38, 0xf1, 0x88,
        0x40, 0x41, 0xb0, 0x13, 0x11, 0x9e, 0x4c, 0x2a,
        0xe5, 0xaf, 0x37, 0xcc, 0xcd, 0xfb, 0x68, 0x66,
        0x07, 0x38, 0xb5, 0x8b, 0x3c, 0x59, 0xd1, 0xc0,
        0x24, 0x84, 0x37, 0x47, 0x2a, 0xba, 0x1f, 0x35,
        0xca, 0x1f, 0xb9, 0x0c, 0xd7, 0x14, 0xaa, 0x9f,
        0x63, 0x55, 0x34, 0xf4, 0x9e, 0x7c, 0x5b, 0xba,
        0x81, 0xc2, 0xb6, 0xb3, 0x6f, 0xde, 0xe2, 0x1c,
        0xa2, 0x7e, 0x34, 0x7f, 0x79, 0x3d, 0x2c, 0xe9,
        0x44, 0xed, 0xb2, 0x3c, 0x8c, 0x9b, 0x91, 0x4b,
        0xe1, 0x03, 0x35, 0xe3, 0x50, 0xfe, 0xb5, 0x07,
        0x03, 0x94, 0xb7, 0xa4, 0xa1, 0x5c, 0x0c, 0xa1,
        0x20, 0x28, 0x35, 0x68, 0xb7, 0xbf, 0xc2, 0x54,
        0xfe, 0x83, 0x8b, 0x13, 0x7a, 0x21, 0x47, 0xce,
        0x7c, 0x11, 0x3a, 0x3a, 0x4d, 0x65, 0x49, 0x9d,
        0x9e, 0x86, 0xb8, 0x7d, 0xbc, 0xc7, 0xf0, 0x3b,
        0xbd, 0x3a, 0x3a, 0xb1, 0xaa, 0x24, 0x3e, 0xce,
        0x5b, 0xa9, 0xbc, 0xf2, 0x5f, 0x82, 0x83, 0x6c,
        0xfe, 0x47, 0x3b, 0x2d, 0x83, 0xe7, 0xa7, 0x20,
        0x1c, 0xd0, 0xb9, 0x6a, 0x72, 0x45, 0x1e, 0x86,
        0x3f, 0x6c, 0x3b, 0xa6, 0x64, 0xa6, 0xd0, 0x73,
        0xd1, 0xf7, 0xb5, 0xed, 0x99, 0x08, 0x65, 0xd9,
        0x78, 0xbd, 0x38, 0x15, 0xd0, 0x60, 0x94, 0xfc,
        0x9a, 0x2a, 0xba, 0x52, 0x21, 0xc2, 0x2d, 0x5a,
        0xb9, 0x96, 0x38, 0x9e, 0x37, 0x21, 0xe3, 0xaf,
        0x5f, 0x05, 0xbe, 0xdd, 0xc2, 0x87, 0x5e, 0x0d,
        0xfa, 0xeb, 0x39, 0x02, 0x1e, 0xe2, 0x7a, 0x41,
        0x18, 0x7c, 0xbb, 0x45, 0xef, 0x40, 0xc3, 0xe7,
        0x3b, 0xc0, 0x39, 0x89, 0xf9, 0xa3, 0x0d, 0x12,
        0xc5, 0x4b, 0xa7, 0xd2, 0x14, 0x1d, 0xa8, 0xa8,
        0x75, 0x49, 0x3e, 0x65, 0x77, 0x6e, 0xf3, 0x5f,
        0x97, 0xde, 0xbc, 0x22, 0x86, 0xcc, 0x4a, 0xf9,
        0xb4, 0x62, 0x3e, 0xee, 0x90, 0x2f, 0x84, 0x0c,
        0x52, 0xf1, 0xb8, 0xad, 0x65, 0x89, 0x39, 0xae,
        0xf7, 0x1f, 0x3f, 0x72, 0xb9, 0xec, 0x1d, 0xe2,
        0x15, 0x88, 0xbd, 0x35, 0x48, 0x4e, 0xa4, 0x44,
        0x36, 0x34, 0x3f, 0xf9, 0x5e, 0xad, 0x6a, 0xb1,
        0xd8, 0xaf, 0xb1, 0xb2, 0xa3, 0x03, 0xdf, 0x1b,
        0x71, 0xe5, 0x3c, 0x4a, 0xea, 0x6b, 0x2e, 0x3e,
        0x93, 0x72, 0xbe, 0x0d, 0x1b, 0xc9, 0x97, 0x98,
        0xb0, 0xce, 0x3c, 0xc1, 0x0d, 0x2a, 0x59, 0x6d,
        0x56, 0x5d, 0xba, 0x82, 0xf8, 0x8c, 0xe4, 0xcf,
        0xf3, 0xb3, 0x3d, 0x5d, 0x24, 0xe9, 0xc0, 0x83,
        0x11, 0x24, 0xbf, 0x1a, 0xd5, 0x4b, 0x79, 0x25,
        0x32, 0x98, 0x3d, 0xd6, 0xc3, 0xa8, 0xb7, 0xd0
};

static const struct cmac_rfc4493_vector {
        const uint8_t *key;
        const uint8_t *sub_key1;
        const uint8_t *sub_key2;
        const uint8_t *M;
        size_t len;
        const uint8_t *T;
        size_t T_len;
        enum cmac_type type; /* vector type - std or 3gpp */
} cmac_vectors[] = {
        { key, sub_key1, sub_key2, M, 0,  T_1, 16, CMAC },
        { key, sub_key1, sub_key2, M, 16, T_2, 16, CMAC },
        { key, sub_key1, sub_key2, M, 40, T_3, 16, CMAC },
        { key, sub_key1, sub_key2, M, 64, T_4, 16, CMAC },
        { key, sub_key1, sub_key2, M, 0,  T_1, 15, CMAC },
        { key, sub_key1, sub_key2, M, 16, T_2, 15, CMAC },
        { key, sub_key1, sub_key2, M, 40, T_3, 15, CMAC },
        { key, sub_key1, sub_key2, M, 64, T_4, 15, CMAC },
        { key, sub_key1, sub_key2, M, 0,  T_1, 12, CMAC },
        { key, sub_key1, sub_key2, M, 16, T_2, 12, CMAC },
        { key, sub_key1, sub_key2, M, 40, T_3, 12, CMAC },
        { key, sub_key1, sub_key2, M, 64, T_4, 12, CMAC },
        { key, sub_key1, sub_key2, M, 0,  T_1, 4, CMAC },
        { key, sub_key1, sub_key2, M, 16, T_2, 4, CMAC },
        { key, sub_key1, sub_key2, M, 40, T_3, 4, CMAC },
        { key, sub_key1, sub_key2, M, 64, T_4, 4, CMAC },
        { key, sub_key1, sub_key2, M, 8,  T_5, 16, CMAC },
};

static const struct cmac_rfc4493_vector cmac_3gpp_vectors[] = {
        { EIA2_128_K_1, EIA2_128_SK1_1, EIA2_128_SK2_1,
          EIA2_128_M_1, 122, EIA2_128_T_1, 4, CMAC_BITLEN },
        { EIA2_128_K_2, EIA2_128_SK1_2, EIA2_128_SK2_2,
          EIA2_128_M_2, 128, EIA2_128_T_2, 4, CMAC_BITLEN },
        { EIA2_128_K_3, EIA2_128_SK1_3, EIA2_128_SK2_3,
          EIA2_128_M_3, 318, EIA2_128_T_3, 4, CMAC_BITLEN },
        { EIA2_128_K_4, EIA2_128_SK1_4, EIA2_128_SK2_4,
          EIA2_128_M_4, 575, EIA2_128_T_4, 4, CMAC_BITLEN },
        { EIA2_128_K_5, EIA2_128_SK1_5, EIA2_128_SK2_5,
          EIA2_128_M_5, 832, EIA2_128_T_5, 4, CMAC_BITLEN },
        { EIA2_128_K_6, EIA2_128_SK1_6, EIA2_128_SK2_6,
          EIA2_128_M_6, 447, EIA2_128_T_6, 4, CMAC_BITLEN },
        { EIA2_128_K_7, EIA2_128_SK1_7, EIA2_128_SK2_7,
          EIA2_128_M_7, 2622, EIA2_128_T_7, 4, CMAC_BITLEN },
        { EIA2_128_K_8, EIA2_128_SK1_8, EIA2_128_SK2_8,
          EIA2_128_M_8, 16512, EIA2_128_T_8, 4, CMAC_BITLEN },
};

static int
cmac_job_ok(const struct cmac_rfc4493_vector *vec,
            const struct JOB_AES_HMAC *job,
            const uint8_t *auth,
            const uint8_t *padding,
            const size_t sizeof_padding)
{
        const size_t auth_len = job->auth_tag_output_len_in_bytes;

        if (job->status != STS_COMPLETED) {
                printf("%d Error status:%d", __LINE__, job->status);
                return 0;
        }

        /* hash checks */
        if (memcmp(padding, &auth[sizeof_padding + auth_len],
                   sizeof_padding)) {
                printf("hash overwrite tail\n");
                hexdump(stderr, "Target",
                        &auth[sizeof_padding + auth_len], sizeof_padding);
                return 0;
        }

        if (memcmp(padding, &auth[0], sizeof_padding)) {
                printf("hash overwrite head\n");
                hexdump(stderr, "Target", &auth[0], sizeof_padding);
                return 0;
        }

        if (memcmp(vec->T, &auth[sizeof_padding], auth_len)) {
                printf("hash mismatched\n");
                hexdump(stderr, "Received", &auth[sizeof_padding],
                        auth_len);
                hexdump(stderr, "Expected", vec->T,
                        auth_len);
                return 0;
        }
        return 1;
}

static int
test_cmac(struct MB_MGR *mb_mgr,
          const struct cmac_rfc4493_vector *vec,
          const int dir,
          const int num_jobs,
          const enum cmac_type type)
{
        DECLARE_ALIGNED(uint32_t expkey[4*15], 16);
        DECLARE_ALIGNED(uint32_t dust[4*15], 16);
        uint32_t skey1[4], skey2[4];
        struct JOB_AES_HMAC *job;
        uint8_t padding[16];
        uint8_t **auths = malloc(num_jobs * sizeof(void *));
        int i = 0, jobs_rx = 0, ret = -1;

        if (auths == NULL) {
		fprintf(stderr, "Can't allocate buffer memory\n");
		goto end2;
        }

        memset(padding, -1, sizeof(padding));
        memset(auths, 0, num_jobs * sizeof(void *));

        for (i = 0; i < num_jobs; i++) {
                auths[i] = malloc(16 + (sizeof(padding) * 2));
                if (auths[i] == NULL) {
                        fprintf(stderr, "Can't allocate buffer memory\n");
                        goto end;
                }

                memset(auths[i], -1, 16 + (sizeof(padding) * 2));
        }

        IMB_AES_KEYEXP_128(mb_mgr, vec->key, expkey, dust);
        IMB_AES_CMAC_SUBKEY_GEN_128(mb_mgr, expkey, skey1, skey2);

        if (memcmp(vec->sub_key1, skey1, sizeof(skey1))) {
                printf("sub-key1 mismatched\n");
                hexdump(stderr, "Received", &skey1[0], sizeof(skey1));
                hexdump(stderr, "Expected", vec->sub_key1, sizeof(skey1));
		goto end;
        }

        if (memcmp(vec->sub_key2, skey2, sizeof(skey2))) {
                printf("sub-key2 mismatched\n");
                hexdump(stderr, "Received", &skey2[0], sizeof(skey2));
                hexdump(stderr, "Expected", vec->sub_key2, sizeof(skey2));
		goto end;
        }

        while ((job = IMB_FLUSH_JOB(mb_mgr)) != NULL)
                ;

        /**
         * Submit all jobs then flush any outstanding jobs
         */
        for (i = 0; i < num_jobs; i++) {
                job = IMB_GET_NEXT_JOB(mb_mgr);
                job->cipher_direction = dir;
                job->chain_order = HASH_CIPHER;
                job->cipher_mode = NULL_CIPHER;

                if (type == CMAC) {
                        job->hash_alg = AES_CMAC;
                        job->msg_len_to_hash_in_bytes = vec->len;
                } else {
                        job->hash_alg = AES_CMAC_BITLEN;
                        /* check for std or 3gpp vectors
                           scale len if necessary */
                        if (vec->type == CMAC)
                                job->msg_len_to_hash_in_bits =
                                        vec->len * 8;
                        else
                                job->msg_len_to_hash_in_bits =
                                        vec->len;
                }
                job->u.CMAC._key_expanded = expkey;
                job->u.CMAC._skey1 = skey1;
                job->u.CMAC._skey2 = skey2;
                job->src = vec->M;
                job->hash_start_src_offset_in_bytes = 0;
                job->auth_tag_output = auths[i] + sizeof(padding);
                job->auth_tag_output_len_in_bytes = vec->T_len;

                job->user_data = auths[i];

                job = IMB_SUBMIT_JOB(mb_mgr);
                if (job) {
                        jobs_rx++;
                        if (num_jobs < 4) {
                                printf("%d Unexpected return from submit_job\n",
                                       __LINE__);
                                goto end;
                        }
                        if (!cmac_job_ok(vec, job, job->user_data, padding,
                                         sizeof(padding)))
                                goto end;
                }
        }

        while ((job = IMB_FLUSH_JOB(mb_mgr)) != NULL) {
                jobs_rx++;

                if (!cmac_job_ok(vec, job, job->user_data, padding,
                                 sizeof(padding)))
                        goto end;
        }

        if (jobs_rx != num_jobs) {
                printf("Expected %d jobs, received %d\n", num_jobs, jobs_rx);
                goto end;
        }

        /**
         * Submit each job and flush immediately
         */
        for (i = 0; i < num_jobs; i++) {
                struct JOB_AES_HMAC *first_job = NULL;

                job = IMB_GET_NEXT_JOB(mb_mgr);
                first_job = job;

                job->cipher_direction = dir;
                job->chain_order = HASH_CIPHER;
                job->cipher_mode = NULL_CIPHER;

                if (type == CMAC) {
                        job->hash_alg = AES_CMAC;
                        job->msg_len_to_hash_in_bytes = vec->len;
                } else {
                        job->hash_alg = AES_CMAC_BITLEN;
                        if (vec->type == CMAC)
                                job->msg_len_to_hash_in_bits = vec->len * 8;
                        else
                                job->msg_len_to_hash_in_bits = vec->len;
                }
                job->u.CMAC._key_expanded = expkey;
                job->u.CMAC._skey1 = skey1;
                job->u.CMAC._skey2 = skey2;
                job->src = vec->M;
                job->hash_start_src_offset_in_bytes = 0;
                job->auth_tag_output = auths[i] + sizeof(padding);
                job->auth_tag_output_len_in_bytes = vec->T_len;

                job->user_data = auths[i];

                job = IMB_SUBMIT_JOB(mb_mgr);
                if (job != NULL) {
                        printf("Received job, expected NULL\n");
                        goto end;
                }

                while ((job = IMB_FLUSH_JOB(mb_mgr)) != NULL) {
                        if (job != first_job) {
                                printf("Invalid return job received\n");
                                goto end;
                        }
                        if (!cmac_job_ok(vec, job, job->user_data, padding,
                                         sizeof(padding)))
                                goto end;
                }
        }

        ret = 0;

 end:
        while ((job = IMB_FLUSH_JOB(mb_mgr)) != NULL)
                ;

        for (i = 0; i < num_jobs; i++) {
                if (auths[i] != NULL)
                        free(auths[i]);
        }

 end2:
        if (auths != NULL)
                free(auths);

        return ret;
}

static int
test_cmac_std_vectors(struct MB_MGR *mb_mgr, const int num_jobs)
{
	const int vectors_cnt = sizeof(cmac_vectors) / sizeof(cmac_vectors[0]);
	int vect;
	int errors = 0;

	printf("AES-CMAC standard test vectors (N jobs = %d):\n", num_jobs);
	for (vect = 1; vect <= vectors_cnt; vect++) {
                const int idx = vect - 1;
#ifdef DEBUG
		printf("Standard vector [%d/%d] M len: %d, T len:%d\n",
                       vect, vectors_cnt,
                       (int) cmac_vectors[idx].len,
                       (int) cmac_vectors[idx].T_len);
#else
		printf(".");
#endif

                if (test_cmac(mb_mgr, &cmac_vectors[idx],
                              ENCRYPT, num_jobs, CMAC)) {
                        printf("error #%d encrypt\n", vect);
                        errors++;
                }

                if (test_cmac(mb_mgr, &cmac_vectors[idx],
                              DECRYPT, num_jobs, CMAC)) {
                        printf("error #%d decrypt\n", vect);
                        errors++;
                }

	}
	printf("\n");
        return errors;
}

static int
test_cmac_bitlen_std_vectors(struct MB_MGR *mb_mgr, const int num_jobs)
{
	const int vectors_cnt = sizeof(cmac_vectors) / sizeof(cmac_vectors[0]);
	int vect;
	int errors = 0;


        printf("AES-CMAC BITLEN standard test vectors "
               "(N jobs = %d):\n", num_jobs);
	for (vect = 1; vect <= vectors_cnt; vect++) {
                const int idx = vect - 1;
#ifdef DEBUG
		printf("Standard vector [%d/%d] M len: %d (bits), "
                       "T len:%d\n",
                       vect, vectors_cnt,
                       (int) cmac_vectors[idx].len * 8,
                       (int) cmac_vectors[idx].T_len);
#else
		printf(".");
#endif

                if (test_cmac(mb_mgr, &cmac_vectors[idx],
                              ENCRYPT, num_jobs, CMAC_BITLEN)) {
                        printf("error #%d encrypt\n", vect);
                        errors++;
                }

                if (test_cmac(mb_mgr, &cmac_vectors[idx],
                              DECRYPT, num_jobs, CMAC_BITLEN)) {
                        printf("error #%d decrypt\n", vect);
                        errors++;
                }

	}
        printf("\n");
        return errors;
}

static int
test_cmac_bitlen_3gpp_vectors(struct MB_MGR *mb_mgr, const int num_jobs)
{
	const int vectors_cnt =
                sizeof(cmac_3gpp_vectors) / sizeof(cmac_3gpp_vectors[0]);
	int vect;
	int errors = 0;

	printf("AES-CMAC BITLEN 3GPP test vectors (N jobs = %d):\n", num_jobs);
	for (vect = 1; vect <= vectors_cnt; vect++) {
                const int idx = vect - 1;
#ifdef DEBUG
		printf("3GPP vector [%d/%d] M len: %d (bits), "
                       "T len:%d (bytes)\n",
                       vect, vectors_cnt,
                       (int) cmac_3gpp_vectors[idx].len,
                       (int) cmac_3gpp_vectors[idx].T_len);
#else
		printf(".");
#endif

                if (test_cmac(mb_mgr, &cmac_3gpp_vectors[idx],
                              ENCRYPT, num_jobs, CMAC_BITLEN)) {
                        printf("error #%d encrypt\n", vect);
                        errors++;
                }

                if (test_cmac(mb_mgr, &cmac_3gpp_vectors[idx],
                              DECRYPT, num_jobs, CMAC_BITLEN)) {
                        printf("error #%d decrypt\n", vect);
                        errors++;
                }

	}
	printf("\n");
	return errors;
}

int
cmac_test(const enum arch_type arch,
          struct MB_MGR *mb_mgr)
{
        int i, errors = 0;

        (void) arch; /* unused */

        /* CMAC with standard vectors */
        for (i = 1; i < 10; i++)
                errors += test_cmac_std_vectors(mb_mgr, i);

        /* CMAC BITLEN with standard vectors */
        for (i = 1; i < 10; i++)
                errors += test_cmac_bitlen_std_vectors(mb_mgr, i);

        /* CMAC BITLEN with 3GPP vectors */
        for (i = 1; i < 10; i++)
                errors += test_cmac_bitlen_3gpp_vectors(mb_mgr, i);

	if (0 == errors)
		printf("...Pass\n");
	else
		printf("...Fail\n");

	return errors;
}