1/*
2 * aesVect.c - generate NIST-compatible test vectors for various AES implementations.
3 *
4 * Written by Doug Mitchell.
5 */
6
7#include <stdlib.h>
8#include <stdio.h>
9#include <time.h>
10#include "enDecrypt.h"
11#include "rijndael-alg-ref.h"
12#include <strings.h>
13
14static void usage(char **argv)
15{
16	printf("usage: %s r|t|c vectorStyle [options]\n", argv[0]);
17	printf("r=reference  t=testImple  c=CSP\n");
18	printf("vectorStyle:\n");
19	printf("   k   Variable key KAT\n");
20	printf("   p   Variable plaintext KAT\n");
21	printf("options:\n");
22	printf("   k=keySizeInBits (default = 128)\n");
23	printf("   i=max value of i (default = max per context)\n");
24	printf("   h(elp)\n");
25	exit(1);
26}
27
28static void setBit(
29	unsigned char *val,
30	unsigned valBytes,
31	unsigned i)
32{
33	unsigned whichByte;
34	unsigned whichBit;
35
36	i--;
37	whichByte = i / 8;
38	whichBit = 7 - (i % 8);
39	memset(val, 0, valBytes);
40	val[whichByte] = 1 << whichBit;
41}
42
43static void printBigNum(
44	const char *name,
45	unsigned char *val,
46	unsigned valBytes)
47{
48	unsigned i;
49	printf("%s=", name);
50	for(i=0; i<valBytes; i++) {
51		unsigned iNum = val[i] & 0xff;
52		printf("%02X", iNum);
53	}
54	printf("\n");
55}
56
57static void varKeyKAT(
58	encrDecrFcn		encrDecr,			// encryptDecryptRef, encryptDecryptTest
59	unsigned		keySizeInBits,
60	unsigned		maxI)
61{
62	unsigned i;
63	unsigned char key[MAX_AES_KEY_BYTES];
64	unsigned char ptext[MIN_AES_BLOCK_BYTES];
65	unsigned char ctext[MIN_AES_BLOCK_BYTES];
66	unsigned keyBytes = keySizeInBits / 8;
67
68	memset(ptext, 0, MIN_AES_BLOCK_BYTES);
69	if(maxI == 0) {
70		maxI = keySizeInBits;
71	}
72
73	printf("KEYSIZE=%d\n\n", keySizeInBits);
74	printf("PT=00000000000000000000000000000000\n\n");
75
76	for(i=1; i<=maxI; i++) {
77		setBit(key, keyBytes, i);
78		encrDecr(CSSM_TRUE,
79			keySizeInBits,
80			MIN_AES_BLOCK_BITS,
81			key,
82			ptext,
83			MIN_AES_BLOCK_BYTES,
84			ctext);
85		printf("I=%d\n", i);
86		printBigNum("KEY", key, keyBytes);
87		printBigNum("CT", ctext, MIN_AES_BLOCK_BYTES);
88		printf("\n");
89	}
90}
91
92static void varPtextKAT(
93	encrDecrFcn		encrDecr,			// encryptDecryptRef, encryptDecryptTest
94	unsigned		keySizeInBits,
95	unsigned		maxI)
96{
97	unsigned i;
98	unsigned char key[MAX_AES_KEY_BYTES];
99	unsigned char ptext[MIN_AES_BLOCK_BYTES];
100	unsigned char ctext[MIN_AES_BLOCK_BYTES];
101	unsigned keyBytes = keySizeInBits / 8;
102
103	memset(key, 0, MAX_AES_KEY_BYTES);
104	if(maxI == 0) {
105		maxI = MIN_AES_BLOCK_BITS;
106	}
107
108	printf("KEYSIZE=%d\n\n", keySizeInBits);
109	printBigNum("KEY", key, keyBytes);
110	printf("\n");
111
112	for(i=1; i<=maxI; i++) {
113		setBit(ptext, MIN_AES_BLOCK_BYTES, i);
114		encrDecr(CSSM_TRUE,
115			keySizeInBits,
116			MIN_AES_BLOCK_BITS,
117			key,
118			ptext,
119			MIN_AES_BLOCK_BYTES,
120			ctext);
121		printf("I=%d\n", i);
122		printBigNum("PT", ptext, MIN_AES_BLOCK_BYTES);
123		printBigNum("CT", ctext, MIN_AES_BLOCK_BYTES);
124		printf("\n");
125	}
126}
127
128int main(int argc, char **argv)
129{
130	int			arg;
131	char		*argp;
132
133	unsigned	keySizeInBits = MIN_AES_KEY_BITS;
134	unsigned	maxI = 0;
135	encrDecrFcn	encrDecr;
136
137	if(argc < 3) {
138		usage(argv);
139	}
140	switch(argv[1][0]) {
141		case 'r':
142			encrDecr = encryptDecryptRef;
143			break;
144		case 't':
145			encrDecr = encryptDecryptTest;
146			break;
147		case 'c':
148			encrDecr = encryptDecryptCsp;
149			break;
150		default:
151			usage(argv);
152	}
153	for(arg=3; arg<argc; arg++) {
154		argp = argv[arg];
155		switch(argp[0]) {
156		    case 'k':
157				keySizeInBits = atoi(&argp[2]);
158				break;
159		    case 'i':
160				maxI = atoi(&argp[2]);
161				break;
162		    case 'h':
163		    default:
164				usage(argv);
165		}
166	}
167	switch(argv[2][0]) {
168		case 'k':
169			varKeyKAT(encrDecr, keySizeInBits, maxI);
170			break;
171		case 'p':
172			varPtextKAT(encrDecr, keySizeInBits, maxI);
173			exit(1);
174		default:
175			usage(argv);
176
177	}
178	return 0;
179}
180