5869 Need AES CMAC support in KCF+PKCS11
[unleashed.git] / usr / src / test / crypto-tests / tests / common / cryptotest_kcf.c
blob260821dcac37232207c2137cb64b9b24207a0e3c
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.
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.
13 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
16 #include <fcntl.h>
17 #include <strings.h>
18 #include <unistd.h>
19 #include <errno.h>
20 #include <stdio.h>
21 #include <stdlib.h>
23 #include "cryptotest.h"
25 struct crypto_op {
26 char *in;
27 char *out;
28 char *key;
29 char *param;
31 size_t inlen;
32 size_t outlen;
33 size_t keylen;
34 size_t paramlen;
35 size_t updatelen;
37 char *mechname;
39 /* internal */
40 crypto_mech_type_t mech;
41 crypto_session_id_t hsession;
42 crypto_func_group_t fg;
45 static int fd;
46 static const char CRYPTO_DEVICE[] = "/dev/crypto";
48 int
49 kcf_do_ioctl(int opcode, uint_t *arg, char *opstr)
51 int ret;
53 while ((ret = ioctl(fd, opcode, arg)) < 0) {
54 if (errno != EINTR)
55 break;
58 if (ret < 0 || *arg != CRYPTO_SUCCESS)
59 (void) fprintf(stderr, "%s: Error = %d %d 0x%02x\n",
60 (opstr == NULL) ? "ioctl" : opstr,
61 ret, errno, *arg);
63 if (ret < 0)
64 return (errno);
66 return (*arg);
69 crypto_op_t *
70 cryptotest_init(cryptotest_t *arg, crypto_func_group_t fg)
72 crypto_op_t *op = malloc(sizeof (*op));
74 if (op == NULL)
75 return (NULL);
77 while ((fd = open(CRYPTO_DEVICE, O_RDWR)) < 0) {
78 if (errno != EINTR)
79 return (NULL);
82 op->in = (char *)arg->in;
83 op->out = (char *)arg->out;
84 op->key = (char *)arg->key;
85 op->param = (char *)arg->param;
87 op->inlen = arg->inlen;
88 op->outlen = arg->outlen;
89 op->keylen = arg->keylen * 8; /* kcf uses keylen in bits */
90 op->paramlen = arg->plen;
91 op->updatelen = arg->updatelen;
93 op->mechname = arg->mechname;
95 op->hsession = CRYPTO_INVALID_SESSION;
96 op->fg = fg;
98 if (op->out == NULL)
99 op->outlen = op->inlen;
100 return (op);
104 cryptotest_close_session(crypto_session_id_t session)
106 crypto_close_session_t cs;
108 cs.cs_session = session;
109 return (kcf_do_ioctl(CRYPTO_CLOSE_SESSION, (uint_t *)&cs, "session"));
113 cryptotest_close(crypto_op_t *op)
115 if (op->hsession != CRYPTO_INVALID_SESSION)
116 (void) cryptotest_close_session(op->hsession);
117 free(op);
118 if (fd >= 0)
119 return (close(fd));
120 return (0);
124 get_mech_info(crypto_op_t *op)
126 crypto_get_mechanism_number_t get_number;
128 bzero(&get_number, sizeof (get_number));
130 get_number.pn_mechanism_string = op->mechname;
131 get_number.pn_mechanism_len = strlen(op->mechname) + 1;
133 if (kcf_do_ioctl(CRYPTO_GET_MECHANISM_NUMBER,
134 (uint_t *)&get_number, "get_mech_info") != CRYPTO_SUCCESS) {
135 (void) fprintf(stderr, "failed to resolve mechanism name %s\n",
136 op->mechname);
137 (void) cryptotest_close(op);
138 return (CTEST_NAME_RESOLVE_FAILED);
140 op->mech = get_number.pn_internal_number;
141 return (CRYPTO_SUCCESS);
145 get_hsession_by_mech(crypto_op_t *op)
147 crypto_by_mech_t mech;
148 int rv;
150 mech.mech_keylen = op->keylen;
151 mech.mech_type = op->mech;
152 mech.mech_fg = op->fg;
154 rv = kcf_do_ioctl(CRYPTO_GET_PROVIDER_BY_MECH, (uint_t *)&mech,
155 "get_hsession_by_mech");
157 if (rv != 0 || mech.rv != CRYPTO_SUCCESS) {
158 (void) fprintf(stderr,
159 "could not find provider for mechanism %llu\n",
160 mech.mech_type);
161 (void) cryptotest_close(op);
162 return (CTEST_MECH_NO_PROVIDER);
165 op->hsession = mech.session_id;
167 return (CRYPTO_SUCCESS);
171 * CRYPTO_MAC_* functions
174 mac_init(crypto_op_t *op)
176 crypto_mac_init_t init;
178 bzero((void *)&init, sizeof (init));
180 init.mi_session = op->hsession;
182 init.mi_key.ck_data = op->key;
183 init.mi_key.ck_format = CRYPTO_KEY_RAW; /* must be this */
184 init.mi_key.ck_length = op->keylen;
186 init.mi_mech.cm_type = op->mech;
187 init.mi_mech.cm_param = NULL;
188 init.mi_mech.cm_param_len = 0;
190 return (kcf_do_ioctl(CRYPTO_MAC_INIT, (uint_t *)&init, "init"));
194 mac_single(crypto_op_t *op)
196 crypto_mac_t mac;
198 bzero(&mac, sizeof (mac));
199 mac.cm_session = op->hsession;
200 mac.cm_datalen = op->inlen;
201 mac.cm_databuf = op->in;
202 mac.cm_maclen = op->outlen;
203 mac.cm_macbuf = op->out;
205 return (kcf_do_ioctl(CRYPTO_MAC, (uint_t *)&mac, "single"));
209 mac_update(crypto_op_t *op, int offset)
211 crypto_mac_update_t update;
213 bzero((void *)&update, sizeof (update));
215 update.mu_session = op->hsession;
216 update.mu_databuf = op->in + offset;
217 update.mu_datalen = op->updatelen;
219 return (kcf_do_ioctl(CRYPTO_MAC_UPDATE, (uint_t *)&update, "update"));
223 mac_final(crypto_op_t *op)
225 crypto_mac_final_t final;
227 bzero((void *)&final, sizeof (final));
229 final.mf_session = op->hsession;
230 final.mf_maclen = op->outlen;
231 final.mf_macbuf = op->out;
233 return (kcf_do_ioctl(CRYPTO_MAC_FINAL, (uint_t *)&final, "final"));
238 * CRYPTO_ENCRYPT_* functions
242 encrypt_init(crypto_op_t *op)
244 crypto_encrypt_init_t init;
246 bzero((void *)&init, sizeof (init));
248 init.ei_session = op->hsession;
250 init.ei_key.ck_data = op->key;
251 init.ei_key.ck_format = CRYPTO_KEY_RAW; /* must be this */
252 init.ei_key.ck_length = op->keylen;
254 init.ei_mech.cm_type = op->mech;
255 init.ei_mech.cm_param = op->param;
256 init.ei_mech.cm_param_len = op->paramlen;
258 return (kcf_do_ioctl(CRYPTO_ENCRYPT_INIT, (uint_t *)&init, "init"));
262 encrypt_single(crypto_op_t *op)
264 crypto_encrypt_t encrypt;
266 bzero(&encrypt, sizeof (encrypt));
267 encrypt.ce_session = op->hsession;
268 encrypt.ce_datalen = op->inlen;
269 encrypt.ce_databuf = op->in;
270 encrypt.ce_encrlen = op->outlen;
271 encrypt.ce_encrbuf = op->out;
273 return (kcf_do_ioctl(CRYPTO_ENCRYPT, (uint_t *)&encrypt, "single"));
277 encrypt_update(crypto_op_t *op, int offset, size_t *encrlen)
279 crypto_encrypt_update_t update;
280 int ret;
281 bzero((void *)&update, sizeof (update));
283 update.eu_session = op->hsession;
284 update.eu_databuf = op->in + offset;
285 update.eu_datalen = op->updatelen;
286 update.eu_encrlen = op->outlen - *encrlen;
287 update.eu_encrbuf = op->out + *encrlen;
289 ret = kcf_do_ioctl(CRYPTO_ENCRYPT_UPDATE, (uint_t *)&update, "update");
290 *encrlen += update.eu_encrlen;
291 return (ret);
295 encrypt_final(crypto_op_t *op, size_t encrlen)
297 crypto_encrypt_final_t final;
299 bzero((void *)&final, sizeof (final));
301 final.ef_session = op->hsession;
302 final.ef_encrlen = op->outlen - encrlen;
303 final.ef_encrbuf = op->out + encrlen;
305 return (kcf_do_ioctl(CRYPTO_ENCRYPT_FINAL, (uint_t *)&final, "final"));
309 * CRYPTO_DECRYPT_* functions
313 decrypt_init(crypto_op_t *op)
315 crypto_decrypt_init_t init;
317 bzero((void *)&init, sizeof (init));
319 init.di_session = op->hsession;
321 init.di_key.ck_data = op->key;
322 init.di_key.ck_format = CRYPTO_KEY_RAW; /* must be this */
323 init.di_key.ck_length = op->keylen;
325 init.di_mech.cm_type = op->mech;
326 init.di_mech.cm_param = op->param;
327 init.di_mech.cm_param_len = op->paramlen;
329 return (kcf_do_ioctl(CRYPTO_DECRYPT_INIT, (uint_t *)&init, "init"));
333 decrypt_single(crypto_op_t *op)
335 crypto_decrypt_t decrypt;
337 bzero(&decrypt, sizeof (decrypt));
338 decrypt.cd_session = op->hsession;
339 decrypt.cd_datalen = op->outlen;
340 decrypt.cd_databuf = op->out;
341 decrypt.cd_encrlen = op->inlen;
342 decrypt.cd_encrbuf = op->in;
344 return (kcf_do_ioctl(CRYPTO_DECRYPT, (uint_t *)&decrypt, "single"));
348 decrypt_update(crypto_op_t *op, int offset, size_t *encrlen)
350 crypto_decrypt_update_t update;
351 int ret;
353 bzero((void *)&update, sizeof (update));
355 update.du_session = op->hsession;
356 update.du_databuf = op->out + *encrlen;
357 update.du_datalen = op->outlen - *encrlen;
358 update.du_encrlen = op->updatelen;
359 update.du_encrbuf = op->in + offset;
361 ret = kcf_do_ioctl(CRYPTO_DECRYPT_UPDATE, (uint_t *)&update, "update");
362 *encrlen += update.du_datalen;
363 return (ret);
367 decrypt_final(crypto_op_t *op, size_t encrlen)
369 crypto_decrypt_final_t final;
371 bzero((void *)&final, sizeof (final));
373 final.df_session = op->hsession;
374 final.df_datalen = op->outlen - encrlen;
375 final.df_databuf = op->out + encrlen;
377 return (kcf_do_ioctl(CRYPTO_DECRYPT_FINAL, (uint_t *)&final, "final"));