1/*
2 * Simple test:
3 *
4 *  -- generate a key
5 *  -- generate MAC
6 *  -- verify MAC
7 */
8#include <stdlib.h>
9#include <stdio.h>
10#include <time.h>
11#include <Security/cssm.h>
12#include "cspwrap.h"
13#include "common.h"
14#define DATA_SIZE_DEF	100
15#define LOOPS_DEF		10
16
17#define KEY_ALG_DEF		CSSM_ALGID_SHA1HMAC
18#define MAC_ALG_DEF		CSSM_ALGID_SHA1HMAC
19
20static void usage(char **argv)
21{
22	printf("usage: %s [options]\n", argv[0]);
23	printf("Options:\n");
24	printf("  d=dataSize (default = %d)\n", DATA_SIZE_DEF);
25	printf("  l=loops (0=forever)\n");
26	printf("  p=pauseInterval (default=0, no pause)\n");
27	printf("  m (HMACMD5; default is HMACSHA1)\n");
28	printf("  D (CSP/DL; default = bare CSP)\n");
29	printf("  q(uiet)\n");
30	printf("  v(erbose))\n");
31	exit(1);
32}
33
34int main(int argc, char **argv)
35{
36	int		 				arg;
37	char					*argp;
38	CSSM_CSP_HANDLE 		cspHand;
39	CSSM_CC_HANDLE			macHand;
40	CSSM_RETURN				crtn;
41	CSSM_DATA				randData;
42	CSSM_KEY_PTR			symmKey;
43	CSSM_DATA				macData = {0, NULL};
44	unsigned				loop;
45	int 					i;
46	unsigned 				dataSize = DATA_SIZE_DEF;
47	unsigned				pauseInterval = 0;
48	unsigned				loops = LOOPS_DEF;
49	CSSM_BOOL				quiet = CSSM_FALSE;
50	CSSM_BOOL				verbose = CSSM_FALSE;
51	CSSM_BOOL				bareCsp = CSSM_TRUE;
52	CSSM_ALGORITHMS			macAlg = MAC_ALG_DEF;
53	CSSM_ALGORITHMS			keyAlg = KEY_ALG_DEF;
54
55	for(arg=1; arg<argc; arg++) {
56		argp = argv[arg];
57	    switch(argv[arg][0]) {
58			case 'd':
59				dataSize = atoi(&argv[arg][2]);
60				break;
61		    case 'l':
62				loops = atoi(&argv[arg][2]);
63				break;
64		    case 'p':
65				pauseInterval = atoi(&argv[arg][2]);
66				break;
67			case 'm':
68				keyAlg = macAlg = CSSM_ALGID_MD5HMAC;
69				break;
70			case 'D':
71				bareCsp = CSSM_FALSE;
72				break;
73			case 'q':
74				quiet = CSSM_TRUE;
75				break;
76		    case 'v':
77		    	verbose = CSSM_TRUE;
78				break;
79			default:
80				usage(argv);
81		}
82	}
83	cspHand = cspDlDbStartup(bareCsp, NULL);
84	if(cspHand == 0) {
85		exit(1);
86	}
87	printf("Starting mactest; args: ");
88	for(i=1; i<argc; i++) {
89		printf("%s ", argv[i]);
90	}
91	printf("\n");
92	symmKey = cspGenSymKey(cspHand,
93		keyAlg,
94		"noLabel",
95		7,
96		CSSM_KEYUSE_SIGN | CSSM_KEYUSE_VERIFY,
97		CSP_KEY_SIZE_DEFAULT,
98		CSSM_TRUE);
99	if(symmKey == 0) {
100		printf("Error generating symmetric key; aborting.\n");
101		exit(1);
102	}
103	randData.Data = (uint8 *)CSSM_MALLOC(dataSize);
104	randData.Length = dataSize;
105	simpleGenData(&randData, dataSize, dataSize);
106	for(loop=1; ; loop++) {
107		if(!quiet) {
108			printf("...Loop %d\n", loop);
109		}
110		crtn = CSSM_CSP_CreateMacContext(cspHand,
111			macAlg,
112			symmKey,
113			&macHand);
114		if(crtn) {
115			printError("CSSM_CSP_CreateMacContext (1)", crtn);
116			exit(1);
117		}
118		crtn = CSSM_GenerateMac(macHand,
119			&randData,
120			1,
121			&macData);
122		if(crtn) {
123			printError("CSSM_GenerateMac error", crtn);
124			exit(1);
125		}
126		crtn = CSSM_DeleteContext(macHand);
127		if(crtn) {
128			printError("CSSM_DeleteContext", crtn);
129			exit(1);
130		}
131		crtn = CSSM_CSP_CreateMacContext(cspHand,
132			macAlg,
133			symmKey,
134			&macHand);
135		if(macHand == 0) {
136			printError("CSSM_CSP_CreateMacContext (2)", crtn);
137			exit(1);
138		}
139		crtn = CSSM_VerifyMac(macHand,
140			&randData,
141			1,
142			&macData);
143		if(crtn) {
144			printError("CSSM_VerifyMac", crtn);
145			exit(1);
146		}
147		crtn = CSSM_DeleteContext(macHand);
148		if(crtn) {
149			printError("CSSM_DeleteContext", crtn);
150			exit(1);
151		}
152		if(loops && (loop == loops)) {
153			break;
154		}
155		if(pauseInterval && ((loop % pauseInterval) == 0)) {
156			char inch;
157			fpurge(stdin);
158			printf("Hit CR to proceed or q to quit: ");
159			inch = getchar();
160			if(inch == 'q') {
161				break;
162			}
163		}
164	}
165	CSSM_FREE(randData.Data);
166	crtn = CSSM_ModuleDetach(cspHand);
167	if(crtn) {
168		printError("CSSM_CSP_Detach", crtn);
169		exit(1);
170	}
171	if(!quiet) {
172		printf("OK\n");
173	}
174	return 0;
175}
176