Tests were made silent
[cryptodev-linux.git] / tests / hmac.c
blob1d9349ea557e4694d00db8285811fdcdeae21095
1 /*
2 * Demo on how to use /dev/crypto device for HMAC.
4 * Placed under public domain.
6 */
7 #include <stdio.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <fcntl.h>
11 #include <stdint.h>
13 #include <sys/ioctl.h>
14 #include <crypto/cryptodev.h>
16 static int debug = 0;
18 #define DATA_SIZE 4096
19 #define BLOCK_SIZE 16
20 #define KEY_SIZE 16
21 #define SHA1_HASH_LEN 20
23 static int
24 test_crypto(int cfd)
26 struct {
27 uint8_t in[DATA_SIZE],
28 encrypted[DATA_SIZE],
29 decrypted[DATA_SIZE],
30 iv[BLOCK_SIZE],
31 key[KEY_SIZE];
32 } data;
33 struct session_op sess;
34 #ifdef CIOCGSESSINFO
35 struct session_info_op siop;
36 #endif
37 struct crypt_op cryp;
38 uint8_t mac[AALG_MAX_RESULT_LEN];
39 uint8_t oldmac[AALG_MAX_RESULT_LEN];
40 uint8_t md5_hmac_out[] = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38";
41 uint8_t sha1_out[] = "\x8f\x82\x03\x94\xf9\x53\x35\x18\x20\x45\xda\x24\xf3\x4d\xe5\x2b\xf8\xbc\x34\x32";
42 int i;
44 memset(&sess, 0, sizeof(sess));
45 memset(&cryp, 0, sizeof(cryp));
47 /* Use the garbage that is on the stack :-) */
48 /* memset(&data, 0, sizeof(data)); */
50 /* SHA1 plain test */
51 memset(mac, 0, sizeof(mac));
53 sess.cipher = 0;
54 sess.mac = CRYPTO_SHA1;
55 if (ioctl(cfd, CIOCGSESSION, &sess)) {
56 perror("ioctl(CIOCGSESSION)");
57 return 1;
60 #ifdef CIOCGSESSINFO
61 siop.ses = sess.ses;
62 if (ioctl(cfd, CIOCGSESSINFO, &siop)) {
63 perror("ioctl(CIOCGSESSINFO)");
64 return 1;
66 if (debug) printf("requested mac CRYPTO_SHA1, got %s with driver %s\n",
67 siop.hash_info.cra_name, siop.hash_info.cra_driver_name);
68 #endif
70 cryp.ses = sess.ses;
71 cryp.len = sizeof("what do ya want for nothing?")-1;
72 cryp.src = "what do ya want for nothing?";
73 cryp.mac = mac;
74 cryp.op = COP_ENCRYPT;
75 if (ioctl(cfd, CIOCCRYPT, &cryp)) {
76 perror("ioctl(CIOCCRYPT)");
77 return 1;
80 if (memcmp(mac, sha1_out, 20)!=0) {
81 printf("mac: ");
82 for (i=0;i<SHA1_HASH_LEN;i++) {
83 printf("%.2x", (uint8_t)mac[i]);
85 puts("\n");
86 fprintf(stderr, "HASH test 1: failed\n");
87 } else {
88 if (debug) fprintf(stderr, "HASH test 1: passed\n");
91 /* MD5-HMAC test */
92 memset(mac, 0, sizeof(mac));
94 sess.cipher = 0;
95 sess.mackey = (uint8_t*)"Jefe";
96 sess.mackeylen = 4;
97 sess.mac = CRYPTO_MD5_HMAC;
98 if (ioctl(cfd, CIOCGSESSION, &sess)) {
99 perror("ioctl(CIOCGSESSION)");
100 return 1;
103 #ifdef CIOCGSESSINFO
104 siop.ses = sess.ses;
105 if (ioctl(cfd, CIOCGSESSINFO, &siop)) {
106 perror("ioctl(CIOCGSESSINFO)");
107 return 1;
109 if (debug)
110 printf("requested mac CRYPTO_MD5_HMAC, got %s with driver %s\n",
111 siop.hash_info.cra_name, siop.hash_info.cra_driver_name);
112 #endif
114 cryp.ses = sess.ses;
115 cryp.len = sizeof("what do ya want for nothing?")-1;
116 cryp.src = "what do ya want for nothing?";
117 cryp.mac = mac;
118 cryp.op = COP_ENCRYPT;
119 if (ioctl(cfd, CIOCCRYPT, &cryp)) {
120 perror("ioctl(CIOCCRYPT)");
121 return 1;
124 if (memcmp(mac, md5_hmac_out, 16)!=0) {
125 printf("mac: ");
126 for (i=0;i<SHA1_HASH_LEN;i++) {
127 printf("%.2x", (uint8_t)mac[i]);
129 puts("\n");
130 fprintf(stderr, "HMAC test 1: failed\n");
131 } else {
132 if (debug) fprintf(stderr, "HMAC test 1: passed\n");
135 /* Hash and encryption in one step test */
136 sess.cipher = CRYPTO_AES_CBC;
137 sess.mac = CRYPTO_SHA1_HMAC;
138 sess.keylen = KEY_SIZE;
139 sess.key = data.key;
140 sess.mackeylen = 16;
141 sess.mackey = (uint8_t*)"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
142 if (ioctl(cfd, CIOCGSESSION, &sess)) {
143 perror("ioctl(CIOCGSESSION)");
144 return 1;
147 #ifdef CIOCGSESSINFO
148 siop.ses = sess.ses;
149 if (ioctl(cfd, CIOCGSESSINFO, &siop)) {
150 perror("ioctl(CIOCGSESSINFO)");
151 return 1;
153 if (debug)
154 printf("requested cipher CRYPTO_AES_CBC and mac CRYPTO_SHA1_HMAC,"
155 " got cipher %s with driver %s and hash %s with driver %s\n",
156 siop.cipher_info.cra_name, siop.cipher_info.cra_driver_name,
157 siop.hash_info.cra_name, siop.hash_info.cra_driver_name);
158 #endif
160 /* Encrypt data.in to data.encrypted */
161 cryp.ses = sess.ses;
162 cryp.len = sizeof(data.in);
163 cryp.src = data.in;
164 cryp.dst = data.encrypted;
165 cryp.iv = data.iv;
166 cryp.mac = mac;
167 cryp.op = COP_ENCRYPT;
168 if (ioctl(cfd, CIOCCRYPT, &cryp)) {
169 perror("ioctl(CIOCCRYPT)");
170 return 1;
173 memcpy(oldmac, mac, sizeof(mac));
175 /* Decrypt data.encrypted to data.decrypted */
176 cryp.src = data.encrypted;
177 cryp.dst = data.decrypted;
178 cryp.op = COP_DECRYPT;
179 if (ioctl(cfd, CIOCCRYPT, &cryp)) {
180 perror("ioctl(CIOCCRYPT)");
181 return 1;
184 /* Verify the result */
185 if (memcmp(data.in, data.decrypted, sizeof(data.in)) != 0) {
186 fprintf(stderr,
187 "FAIL: Decrypted data are different from the input data.\n");
188 return 1;
189 } else if (debug) printf("Crypt Test: passed\n");
191 if (memcmp(mac, oldmac, 20) != 0) {
192 fprintf(stderr,
193 "FAIL: Hash in decrypted data different than in encrypted.\n");
194 return 1;
195 } else if (debug) printf("HMAC Test 2: passed\n");
197 /* Finish crypto session */
198 if (ioctl(cfd, CIOCFSESSION, &sess.ses)) {
199 perror("ioctl(CIOCFSESSION)");
200 return 1;
203 return 0;
206 static int
207 test_extras(int cfd)
209 struct session_op sess;
210 #ifdef CIOCGSESSINFO
211 struct session_info_op siop;
212 #endif
213 struct crypt_op cryp;
214 uint8_t mac[AALG_MAX_RESULT_LEN];
215 uint8_t oldmac[AALG_MAX_RESULT_LEN];
216 uint8_t md5_hmac_out[] = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38";
217 uint8_t sha1_out[] = "\x8f\x82\x03\x94\xf9\x53\x35\x18\x20\x45\xda\x24\xf3\x4d\xe5\x2b\xf8\xbc\x34\x32";
218 int i;
220 memset(&sess, 0, sizeof(sess));
221 memset(&cryp, 0, sizeof(cryp));
223 /* Use the garbage that is on the stack :-) */
224 /* memset(&data, 0, sizeof(data)); */
226 /* SHA1 plain test */
227 memset(mac, 0, sizeof(mac));
229 sess.cipher = 0;
230 sess.mac = CRYPTO_SHA1;
231 if (ioctl(cfd, CIOCGSESSION, &sess)) {
232 perror("ioctl(CIOCGSESSION)");
233 return 1;
236 #ifdef CIOCGSESSINFO
237 siop.ses = sess.ses;
238 if (ioctl(cfd, CIOCGSESSINFO, &siop)) {
239 perror("ioctl(CIOCGSESSINFO)");
240 return 1;
242 if (debug)
243 printf("requested mac CRYPTO_SHA1, got %s with driver %s\n",
244 siop.hash_info.cra_name, siop.hash_info.cra_driver_name);
245 #endif
247 cryp.ses = sess.ses;
248 cryp.len = sizeof("what do")-1;
249 cryp.src = "what do";
250 cryp.mac = mac;
251 cryp.op = COP_ENCRYPT;
252 cryp.flags = COP_FLAG_UPDATE;
253 if (ioctl(cfd, CIOCCRYPT, &cryp)) {
254 perror("ioctl(CIOCCRYPT)");
255 return 1;
258 cryp.ses = sess.ses;
259 cryp.len = sizeof(" ya want for nothing?")-1;
260 cryp.src = " ya want for nothing?";
261 cryp.mac = mac;
262 cryp.op = COP_ENCRYPT;
263 cryp.flags = COP_FLAG_FINAL;
264 if (ioctl(cfd, CIOCCRYPT, &cryp)) {
265 perror("ioctl(CIOCCRYPT)");
266 return 1;
269 if (memcmp(mac, sha1_out, 20)!=0) {
270 printf("mac: ");
271 for (i=0;i<SHA1_HASH_LEN;i++) {
272 printf("%.2x", (uint8_t)mac[i]);
274 puts("\n");
275 fprintf(stderr, "HASH test [update]: failed\n");
276 } else {
277 if (debug) fprintf(stderr, "HASH test [update]: passed\n");
280 memset(mac, 0, sizeof(mac));
282 /* Finish crypto session */
283 if (ioctl(cfd, CIOCFSESSION, &sess.ses)) {
284 perror("ioctl(CIOCFSESSION)");
285 return 1;
288 return 0;
293 main(int argc, char** argv)
295 int fd = -1, cfd = -1;
297 if (argc > 1) debug = 1;
299 /* Open the crypto device */
300 fd = open("/dev/crypto", O_RDWR, 0);
301 if (fd < 0) {
302 perror("open(/dev/crypto)");
303 return 1;
306 /* Clone file descriptor */
307 if (ioctl(fd, CRIOGET, &cfd)) {
308 perror("ioctl(CRIOGET)");
309 return 1;
312 /* Set close-on-exec (not really neede here) */
313 if (fcntl(cfd, F_SETFD, 1) == -1) {
314 perror("fcntl(F_SETFD)");
315 return 1;
318 /* Run the test itself */
319 if (test_crypto(cfd))
320 return 1;
322 if (test_extras(cfd))
323 return 1;
325 /* Close cloned descriptor */
326 if (close(cfd)) {
327 perror("close(cfd)");
328 return 1;
331 /* Close the original descriptor */
332 if (close(fd)) {
333 perror("close(fd)");
334 return 1;
337 return 0;