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
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.
23 #include "cryptotest.h"
40 crypto_mech_type_t mech
;
41 crypto_session_id_t hsession
;
42 crypto_func_group_t fg
;
46 static const char CRYPTO_DEVICE
[] = "/dev/crypto";
49 kcf_do_ioctl(int opcode
, uint_t
*arg
, char *opstr
)
53 while ((ret
= ioctl(fd
, opcode
, arg
)) < 0) {
58 if (ret
< 0 || *arg
!= CRYPTO_SUCCESS
)
59 (void) fprintf(stderr
, "%s: Error = %d %d 0x%02x\n",
60 (opstr
== NULL
) ? "ioctl" : opstr
,
70 cryptotest_init(cryptotest_t
*arg
, crypto_func_group_t fg
)
72 crypto_op_t
*op
= malloc(sizeof (*op
));
77 while ((fd
= open(CRYPTO_DEVICE
, O_RDWR
)) < 0) {
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
;
99 op
->outlen
= op
->inlen
;
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
);
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",
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
;
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",
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
)
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
;
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
;
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
;
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
;
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"));