1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
14  */
15 
16 #define	__EXTENSIONS__
17 #include <strings.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include "cryptotest.h"
21 
22 
23 
24 test_fg_t cryptotest_decr_fg = {test_decrypt_single, test_decrypt};
25 test_fg_t cryptotest_encr_fg = {test_encrypt_single, test_encrypt};
26 test_fg_t cryptotest_mac_fg = {test_mac_single, test_mac};
27 
28 /*
29  * Utils
30  */
31 
32 void
33 printbuf(uint8_t *buf, char *name, size_t size)
34 {
35 	size_t i;
36 
37 	flockfile(stderr);
38 	(void) fprintf(stderr, "%s%s", name, (size > 0) ? " " : "");
39 	for (i = 0; i < size; i++)
40 		(void) fprintf(stderr, "%02x", buf[i]);
41 	(void) fputc('\n', stderr);
42 	funlockfile(stderr);
43 }
44 
45 int
46 bufcmp(uint8_t *auth, uint8_t *cmp, size_t size)
47 {
48 	if (memcmp(cmp, auth, size) != 0) {
49 		(void) fprintf(stderr, "mismatched result\n\n");
50 		printbuf(cmp, "calc", size);
51 		printbuf(auth, "orig", size);
52 		return (1);
53 	} else {
54 		(void) fprintf(stderr, "result matches\n\n");
55 		return (0);
56 	}
57 }
58 
59 /*
60  * Wrapper functions
61  */
62 
63 int
64 run_test(cryptotest_t *args, uint8_t *cmp, size_t cmplen,
65     test_fg_t *funcs)
66 {
67 	int ret, errs = 0;
68 	static int i = 0;
69 
70 	(void) fprintf(stderr, "%s: run %d\n", args->mechname, ++i);
71 	bzero(args->out, args->outlen);
72 	ret = funcs->update(args);
73 	if (ret > 0) {
74 		(void) fprintf(stderr, "failure %x\n", ret);
75 		errs += 1;
76 	} else if (ret < 0) {
77 		(void) fprintf(stderr, "fatal error %d\n", ret);
78 		exit(1);
79 	} else
80 		errs += bufcmp(cmp, args->out, cmplen);
81 
82 	bzero(args->out, args->outlen);
83 	ret = funcs->single(args);
84 	if (ret > 0) {
85 		(void) fprintf(stderr, "failure %x\n", ret);
86 		errs += 1;
87 	} else if (ret < 0) {
88 		(void) fprintf(stderr, "fatal error %d\n", ret);
89 		exit(2);
90 	} else
91 		errs += bufcmp(cmp, args->out, cmplen);
92 
93 	return (errs);
94 }
95 
96 static int
97 test_mac_common(cryptotest_t *args, boolean_t AIO)
98 {
99 	int ret, i;
100 	crypto_op_t *crypto_op;
101 
102 	if (args->in == NULL || args->key == NULL)
103 		return (CRYPTO_FAILED);
104 
105 	if ((crypto_op = cryptotest_init(args, CRYPTO_FG_MAC)) == NULL) {
106 		(void) fprintf(stderr, "Error occured during initialization\n");
107 		(void) cryptotest_close(NULL);
108 		return (CTEST_INIT_FAILED);
109 	}
110 
111 	if ((ret = get_mech_info(crypto_op)) != CRYPTO_SUCCESS)
112 		goto out;
113 
114 	if ((ret = get_hsession_by_mech(crypto_op)) != CRYPTO_SUCCESS)
115 		goto out;
116 
117 	if ((ret = mac_init(crypto_op)) != CRYPTO_SUCCESS)
118 		goto out;
119 
120 	if (AIO) {
121 		if ((ret = mac_single(crypto_op)) != CRYPTO_SUCCESS)
122 			goto out;
123 	} else {
124 		for (i = 0; i < args->inlen; i += args->updatelen) {
125 
126 			if ((ret = mac_update(crypto_op, i)) != CRYPTO_SUCCESS)
127 				goto out;
128 		}
129 
130 		if ((ret = mac_final(crypto_op)) != CRYPTO_SUCCESS)
131 			goto out;
132 
133 	}
134 
135 out:
136 	(void) cryptotest_close(crypto_op);
137 	return (ret);
138 }
139 
140 int
141 test_mac_single(cryptotest_t *args)
142 {
143 	return (test_mac_common(args, B_TRUE));
144 }
145 
146 int
147 test_mac(cryptotest_t *args)
148 {
149 	return (test_mac_common(args, B_FALSE));
150 }
151 
152 static int
153 test_encrypt_common(cryptotest_t *args, boolean_t AIO)
154 {
155 	int ret, i;
156 	size_t encrlen = 0;
157 	crypto_op_t *crypto_op;
158 
159 	if (args->key == NULL)
160 		return (CRYPTO_FAILED);
161 
162 	if ((crypto_op = cryptotest_init(args, CRYPTO_FG_ENCRYPT)) == NULL) {
163 		(void) fprintf(stderr, "Error occured during initialization\n");
164 		(void) cryptotest_close(NULL);
165 		return (CTEST_INIT_FAILED);
166 	}
167 
168 	if ((ret = get_mech_info(crypto_op)) != CRYPTO_SUCCESS)
169 		goto out;
170 
171 	if ((ret = get_hsession_by_mech(crypto_op)) != CRYPTO_SUCCESS)
172 		goto out;
173 
174 	if ((ret = encrypt_init(crypto_op)) != CRYPTO_SUCCESS)
175 		goto out;
176 
177 	if (AIO) {
178 		if ((ret = encrypt_single(crypto_op)) != CRYPTO_SUCCESS)
179 			goto out;
180 	} else {
181 		for (i = 0; i < args->inlen; i += args->updatelen) {
182 
183 			if ((ret = encrypt_update(crypto_op, i,
184 			    &encrlen)) != CRYPTO_SUCCESS)
185 				goto out;
186 		}
187 
188 		if ((ret = encrypt_final(crypto_op, encrlen)) != CRYPTO_SUCCESS)
189 			goto out;
190 
191 	}
192 
193 out:
194 	(void) cryptotest_close(crypto_op);
195 	return (ret);
196 }
197 
198 int
199 test_encrypt_single(cryptotest_t *args)
200 {
201 	return (test_encrypt_common(args, B_TRUE));
202 }
203 
204 
205 int
206 test_encrypt(cryptotest_t *args)
207 {
208 	return (test_encrypt_common(args, B_FALSE));
209 }
210 
211 static int
212 test_decrypt_common(cryptotest_t *args, boolean_t AIO)
213 {
214 	int ret, i;
215 	size_t encrlen = 0;
216 	crypto_op_t *crypto_op;
217 
218 	if (args->key == NULL)
219 		return (CRYPTO_FAILED);
220 
221 	if ((crypto_op = cryptotest_init(args, CRYPTO_FG_DECRYPT)) == NULL) {
222 		(void) fprintf(stderr, "Error occured during initialization\n");
223 		(void) cryptotest_close(NULL);
224 		return (CTEST_INIT_FAILED);
225 	}
226 
227 	if ((ret = get_mech_info(crypto_op)) != CRYPTO_SUCCESS)
228 		goto out;
229 
230 	if ((ret = get_hsession_by_mech(crypto_op)) != CRYPTO_SUCCESS)
231 		goto out;
232 
233 	if ((ret = decrypt_init(crypto_op)) != CRYPTO_SUCCESS)
234 		goto out;
235 
236 	if (AIO) {
237 		if ((ret = decrypt_single(crypto_op)) != CRYPTO_SUCCESS)
238 			goto out;
239 	} else {
240 		for (i = 0; i < args->inlen; i += args->updatelen) {
241 
242 			if ((ret = decrypt_update(crypto_op, i,
243 			    &encrlen)) != CRYPTO_SUCCESS)
244 				goto out;
245 		}
246 
247 		if ((ret = decrypt_final(crypto_op, encrlen)) != CRYPTO_SUCCESS)
248 			goto out;
249 
250 	}
251 
252 out:
253 	(void) cryptotest_close(crypto_op);
254 	return (ret);
255 }
256 
257 int
258 test_decrypt_single(cryptotest_t *args)
259 {
260 	return (test_decrypt_common(args, B_TRUE));
261 }
262 
263 
264 int
265 test_decrypt(cryptotest_t *args)
266 {
267 	return (test_decrypt_common(args, B_FALSE));
268 }
269