Removed the guards against empty PT and empty AAD. It's an edge case that -- while...
[cryptodev-linux.git] / tests / hmac_comp.c
blob451bedbbef6ed47d0657e57338c297a627a156e4
1 /*
2 * Compare HMAC results with ones from openssl.
4 * Placed under public domain.
6 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <fcntl.h>
12 #include <stdint.h>
14 #include <sys/ioctl.h>
15 #include <crypto/cryptodev.h>
17 #include "openssl_wrapper.h"
19 #define BLOCK_SIZE 16
20 #define KEY_SIZE 16
21 #define MACKEY_SIZE 20
22 #define MAX_DATALEN (64 * 1024)
24 static void printhex(unsigned char *buf, int buflen)
26 while (buflen-- > 0) {
27 printf("\\x%.2x", *(buf++));
29 printf("\n");
32 static int
33 test_crypto(int cfd, struct session_op *sess, int datalen)
35 unsigned char *data, *encrypted;
36 unsigned char *encrypted_comp;
38 unsigned char iv[BLOCK_SIZE];
39 unsigned char mac[AALG_MAX_RESULT_LEN];
41 unsigned char mac_comp[AALG_MAX_RESULT_LEN];
43 struct crypt_op cryp;
45 int ret = 0;
47 data = malloc(datalen);
48 encrypted = malloc(datalen);
49 encrypted_comp = malloc(datalen);
50 memset(data, datalen & 0xff, datalen);
51 memset(encrypted, 0x27, datalen);
52 memset(encrypted_comp, 0x27, datalen);
54 memset(iv, 0x23, sizeof(iv));
55 memset(mac, 0, sizeof(mac));
56 memset(mac_comp, 0, sizeof(mac_comp));
58 memset(&cryp, 0, sizeof(cryp));
60 /* Encrypt data.in to data.encrypted */
61 cryp.ses = sess->ses;
62 cryp.len = datalen;
63 cryp.src = data;
64 cryp.dst = encrypted;
65 cryp.iv = iv;
66 cryp.mac = mac;
67 cryp.op = COP_ENCRYPT;
68 if ((ret = ioctl(cfd, CIOCCRYPT, &cryp))) {
69 perror("ioctl(CIOCCRYPT)");
70 goto out;
73 cryp.dst = encrypted_comp;
74 cryp.mac = mac_comp;
76 if ((ret = openssl_cioccrypt(sess, &cryp))) {
77 fprintf(stderr, "openssl_cioccrypt() failed!\n");
78 goto out;
81 if ((ret = memcmp(encrypted, encrypted_comp, cryp.len))) {
82 printf("fail for datalen %d, cipher texts do not match!\n", datalen);
84 if ((ret = memcmp(mac, mac_comp, AALG_MAX_RESULT_LEN))) {
85 printf("fail for datalen 0x%x, MACs do not match!\n", datalen);
86 printf("wrong mac: ");
87 printhex(mac, 20);
88 printf("right mac: ");
89 printhex(mac_comp, 20);
93 out:
94 free(data);
95 free(encrypted);
96 free(encrypted_comp);
97 return ret;
100 #define max(a, b) ((a) > (b) ? (a) : (b))
101 #define min(a, b) ((a) < (b) ? (a) : (b))
104 main(int argc, char **argv)
106 int fd;
107 struct session_op sess;
108 unsigned char key[KEY_SIZE], mackey[MACKEY_SIZE];
109 int datalen = BLOCK_SIZE;
110 int datalen_end = MAX_DATALEN;
111 int i;
113 if (argc > 1) {
114 datalen = min(max(atoi(argv[1]), BLOCK_SIZE), MAX_DATALEN);
115 datalen_end = datalen;
117 if (argc > 2) {
118 datalen_end = min(atoi(argv[2]), MAX_DATALEN);
119 if (datalen_end < datalen)
120 datalen_end = datalen;
123 /* Open the crypto device */
124 fd = open("/dev/crypto", O_RDWR, 0);
125 if (fd < 0) {
126 perror("open(/dev/crypto)");
127 return 1;
130 for (i = 0; i < KEY_SIZE; i++)
131 key[i] = i & 0xff;
132 for (i = 0; i < MACKEY_SIZE; i++)
133 mackey[i] = i & 0xff;
135 memset(&sess, 0, sizeof(sess));
137 /* Hash and encryption in one step test */
138 sess.cipher = CRYPTO_AES_CBC;
139 sess.mac = CRYPTO_SHA1_HMAC;
140 sess.keylen = KEY_SIZE;
141 sess.key = key;
142 sess.mackeylen = MACKEY_SIZE;
143 sess.mackey = mackey;
144 if (ioctl(fd, CIOCGSESSION, &sess)) {
145 perror("ioctl(CIOCGSESSION)");
146 return 1;
149 #ifdef CIOCGSESSINFO
151 struct session_info_op siop = {
152 .ses = sess.ses,
155 if (ioctl(fd, CIOCGSESSINFO, &siop)) {
156 perror("ioctl(CIOCGSESSINFO)");
157 } else {
158 printf("requested cipher CRYPTO_AES_CBC and mac CRYPTO_SHA1_HMAC,"
159 " got cipher %s with driver %s and hash %s with driver %s\n",
160 siop.cipher_info.cra_name, siop.cipher_info.cra_driver_name,
161 siop.hash_info.cra_name, siop.hash_info.cra_driver_name);
164 #endif
166 for (; datalen <= datalen_end; datalen += BLOCK_SIZE) {
167 if (test_crypto(fd, &sess, datalen)) {
168 printf("test_crypto() failed for datalen of %d\n", datalen);
169 return 1;
173 /* Finish crypto session */
174 if (ioctl(fd, CIOCFSESSION, &sess.ses)) {
175 perror("ioctl(CIOCFSESSION)");
178 close(fd);
179 return 0;