aes.c revision 4558:36be0ae50c2d
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#pragma ident	"%Z%%M%	%I%	%E% SMI"
27
28/*
29 * AES provider for the Kernel Cryptographic Framework (KCF)
30 */
31
32#include <sys/types.h>
33#include <sys/systm.h>
34#include <sys/modctl.h>
35#include <sys/cmn_err.h>
36#include <sys/ddi.h>
37#include <sys/crypto/common.h>
38#include <sys/crypto/spi.h>
39#include <sys/sysmacros.h>
40#include <sys/strsun.h>
41#include <aes_impl.h>
42#include <aes_cbc_crypt.h>
43
44extern struct mod_ops mod_cryptoops;
45
46/*
47 * Module linkage information for the kernel.
48 */
49static struct modlcrypto modlcrypto = {
50	&mod_cryptoops,
51	"AES Kernel SW Provider %I%"
52};
53
54static struct modlinkage modlinkage = {
55	MODREV_1,
56	(void *)&modlcrypto,
57	NULL
58};
59
60/*
61 * CSPI information (entry points, provider info, etc.)
62 */
63typedef enum aes_mech_type {
64	AES_ECB_MECH_INFO_TYPE,		/* SUN_CKM_AES_ECB */
65	AES_CBC_MECH_INFO_TYPE,		/* SUN_CKM_AES_CBC */
66	AES_CBC_PAD_MECH_INFO_TYPE,	/* SUN_CKM_AES_CBC_PAD */
67	AES_CTR_MECH_INFO_TYPE,		/* SUN_CKM_AES_CTR */
68	AES_CCM_MECH_INFO_TYPE		/* SUN_CKM_AES_CCM */
69} aes_mech_type_t;
70
71/*
72 * The following definitions are to keep EXPORT_SRC happy.
73 */
74#ifndef AES_MIN_KEY_BYTES
75#define	AES_MIN_KEY_BYTES		0
76#endif
77
78#ifndef AES_MAX_KEY_BYTES
79#define	AES_MAX_KEY_BYTES		0
80#endif
81
82/*
83 * Mechanism info structure passed to KCF during registration.
84 */
85static crypto_mech_info_t aes_mech_info_tab[] = {
86	/* AES_ECB */
87	{SUN_CKM_AES_ECB, AES_ECB_MECH_INFO_TYPE,
88	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
89	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
90	    AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
91	/* AES_CBC */
92	{SUN_CKM_AES_CBC, AES_CBC_MECH_INFO_TYPE,
93	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
94	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
95	    AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
96	/* AES_CTR */
97	{SUN_CKM_AES_CTR, AES_CTR_MECH_INFO_TYPE,
98	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
99	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
100	    AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
101	/* AES_CCM */
102	{SUN_CKM_AES_CCM, AES_CCM_MECH_INFO_TYPE,
103	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
104	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
105	    AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES}
106};
107
108/* operations are in-place if the output buffer is NULL */
109#define	AES_ARG_INPLACE(input, output)				\
110	if ((output) == NULL)					\
111		(output) = (input);
112
113static void aes_provider_status(crypto_provider_handle_t, uint_t *);
114
115static crypto_control_ops_t aes_control_ops = {
116	aes_provider_status
117};
118
119static int aes_encrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
120    crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
121static int aes_decrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
122    crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
123static int aes_common_init(crypto_ctx_t *, crypto_mechanism_t *,
124    crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t, boolean_t);
125static int aes_common_init_ctx(aes_ctx_t *, crypto_spi_ctx_template_t *,
126    crypto_mechanism_t *, crypto_key_t *, int, boolean_t);
127static int aes_encrypt_final(crypto_ctx_t *, crypto_data_t *,
128    crypto_req_handle_t);
129static int aes_decrypt_final(crypto_ctx_t *, crypto_data_t *,
130    crypto_req_handle_t);
131
132static int aes_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
133    crypto_req_handle_t);
134static int aes_encrypt_update(crypto_ctx_t *, crypto_data_t *,
135    crypto_data_t *, crypto_req_handle_t);
136static int aes_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
137    crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
138    crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
139
140static int aes_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
141    crypto_req_handle_t);
142static int aes_decrypt_update(crypto_ctx_t *, crypto_data_t *,
143    crypto_data_t *, crypto_req_handle_t);
144static int aes_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
145    crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
146    crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
147
148static crypto_cipher_ops_t aes_cipher_ops = {
149	aes_encrypt_init,
150	aes_encrypt,
151	aes_encrypt_update,
152	aes_encrypt_final,
153	aes_encrypt_atomic,
154	aes_decrypt_init,
155	aes_decrypt,
156	aes_decrypt_update,
157	aes_decrypt_final,
158	aes_decrypt_atomic
159};
160
161static int aes_create_ctx_template(crypto_provider_handle_t,
162    crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
163    size_t *, crypto_req_handle_t);
164static int aes_free_context(crypto_ctx_t *);
165
166static crypto_ctx_ops_t aes_ctx_ops = {
167	aes_create_ctx_template,
168	aes_free_context
169};
170
171static crypto_ops_t aes_crypto_ops = {
172	&aes_control_ops,
173	NULL,
174	&aes_cipher_ops,
175	NULL,
176	NULL,
177	NULL,
178	NULL,
179	NULL,
180	NULL,
181	NULL,
182	NULL,
183	NULL,
184	NULL,
185	&aes_ctx_ops
186};
187
188static crypto_provider_info_t aes_prov_info = {
189	CRYPTO_SPI_VERSION_1,
190	"AES Software Provider",
191	CRYPTO_SW_PROVIDER,
192	{&modlinkage},
193	NULL,
194	&aes_crypto_ops,
195	sizeof (aes_mech_info_tab)/sizeof (crypto_mech_info_t),
196	aes_mech_info_tab
197};
198
199static crypto_kcf_provider_handle_t aes_prov_handle = NULL;
200
201int
202_init(void)
203{
204	int ret;
205
206	/*
207	 * Register with KCF. If the registration fails, return error.
208	 */
209	if ((ret = crypto_register_provider(&aes_prov_info,
210	    &aes_prov_handle)) != CRYPTO_SUCCESS) {
211		cmn_err(CE_WARN, "%s _init: crypto_register_provider()"
212		    "failed (0x%x)", CRYPTO_PROVIDER_NAME, ret);
213		return (EACCES);
214	}
215
216	if ((ret = mod_install(&modlinkage)) != 0) {
217		int rv;
218
219		ASSERT(aes_prov_handle != NULL);
220		/* We should not return if the unregister returns busy. */
221		while ((rv = crypto_unregister_provider(aes_prov_handle))
222		    == CRYPTO_BUSY) {
223			cmn_err(CE_WARN,
224			    "%s _init: crypto_unregister_provider() "
225			    "failed (0x%x). Retrying.",
226			    CRYPTO_PROVIDER_NAME, rv);
227			/* wait 10 seconds and try again. */
228			delay(10 * drv_usectohz(1000000));
229		}
230	}
231
232	return (ret);
233}
234
235int
236_fini(void)
237{
238	int ret;
239
240	/*
241	 * Unregister from KCF if previous registration succeeded.
242	 */
243	if (aes_prov_handle != NULL) {
244		if ((ret = crypto_unregister_provider(aes_prov_handle)) !=
245		    CRYPTO_SUCCESS) {
246			cmn_err(CE_WARN,
247			    "%s _fini: crypto_unregister_provider() "
248			    "failed (0x%x)", CRYPTO_PROVIDER_NAME, ret);
249			return (EBUSY);
250		}
251		aes_prov_handle = NULL;
252	}
253
254	return (mod_remove(&modlinkage));
255}
256
257int
258_info(struct modinfo *modinfop)
259{
260	return (mod_info(&modlinkage, modinfop));
261}
262
263
264static int
265aes_check_mech_param(crypto_mechanism_t *mechanism)
266{
267	int rv = CRYPTO_SUCCESS;
268
269	switch (mechanism->cm_type) {
270	case AES_ECB_MECH_INFO_TYPE:
271		/* no parameter */
272		break;
273	case AES_CBC_MECH_INFO_TYPE:
274		if (mechanism->cm_param != NULL &&
275		    mechanism->cm_param_len != AES_BLOCK_LEN)
276			rv = CRYPTO_MECHANISM_PARAM_INVALID;
277		break;
278	case AES_CTR_MECH_INFO_TYPE:
279		if (mechanism->cm_param != NULL &&
280		    mechanism->cm_param_len != sizeof (CK_AES_CTR_PARAMS))
281			rv = CRYPTO_MECHANISM_PARAM_INVALID;
282		break;
283	case AES_CCM_MECH_INFO_TYPE:
284		if (mechanism->cm_param != NULL &&
285		    mechanism->cm_param_len != sizeof (CK_AES_CCM_PARAMS))
286			rv = CRYPTO_MECHANISM_PARAM_INVALID;
287		break;
288	default:
289		rv = CRYPTO_MECHANISM_INVALID;
290	}
291	return (rv);
292}
293
294/* EXPORT DELETE START */
295
296/*
297 * Initialize key schedules for AES
298 */
299static int
300init_keysched(crypto_key_t *key, void *newbie)
301{
302	/*
303	 * Only keys by value are supported by this module.
304	 */
305	switch (key->ck_format) {
306	case CRYPTO_KEY_RAW:
307		if (key->ck_length < AES_MINBITS ||
308		    key->ck_length > AES_MAXBITS) {
309			return (CRYPTO_KEY_SIZE_RANGE);
310		}
311
312		/* key length must be either 128, 192, or 256 */
313		if ((key->ck_length & 63) != 0)
314			return (CRYPTO_KEY_SIZE_RANGE);
315		break;
316	default:
317		return (CRYPTO_KEY_TYPE_INCONSISTENT);
318	}
319
320	aes_init_keysched(key->ck_data, key->ck_length, newbie);
321	return (CRYPTO_SUCCESS);
322}
323
324/* EXPORT DELETE END */
325
326/*
327 * KCF software provider control entry points.
328 */
329/* ARGSUSED */
330static void
331aes_provider_status(crypto_provider_handle_t provider, uint_t *status)
332{
333	*status = CRYPTO_PROVIDER_READY;
334}
335
336static int
337aes_encrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
338    crypto_key_t *key, crypto_spi_ctx_template_t template,
339    crypto_req_handle_t req) {
340	return (aes_common_init(ctx, mechanism, key, template, req, B_TRUE));
341}
342
343static int
344aes_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
345    crypto_key_t *key, crypto_spi_ctx_template_t template,
346    crypto_req_handle_t req) {
347	return (aes_common_init(ctx, mechanism, key, template, req, B_FALSE));
348}
349
350
351
352/*
353 * KCF software provider encrypt entry points.
354 */
355static int
356aes_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
357    crypto_key_t *key, crypto_spi_ctx_template_t template,
358    crypto_req_handle_t req, boolean_t is_encrypt_init)
359{
360
361/* EXPORT DELETE START */
362
363	aes_ctx_t *aes_ctx;
364	int rv;
365	int kmflag;
366
367	/*
368	 * Only keys by value are supported by this module.
369	 */
370	if (key->ck_format != CRYPTO_KEY_RAW) {
371		return (CRYPTO_KEY_TYPE_INCONSISTENT);
372	}
373
374	if ((rv = aes_check_mech_param(mechanism)) != CRYPTO_SUCCESS)
375		return (rv);
376
377	/*
378	 * Allocate an AES context.
379	 */
380	kmflag = crypto_kmflag(req);
381	if ((aes_ctx = kmem_zalloc(sizeof (aes_ctx_t), kmflag)) == NULL)
382		return (CRYPTO_HOST_MEMORY);
383
384	rv = aes_common_init_ctx(aes_ctx, template, mechanism, key, kmflag,
385	    is_encrypt_init);
386	if (rv != CRYPTO_SUCCESS) {
387		kmem_free(aes_ctx, sizeof (aes_ctx_t));
388		return (rv);
389	}
390
391	ctx->cc_provider_private = aes_ctx;
392
393/* EXPORT DELETE END */
394
395	return (CRYPTO_SUCCESS);
396}
397
398/*
399 * Helper AES encrypt update function for iov input data.
400 */
401static int
402aes_cipher_update_iov(aes_ctx_t *aes_ctx, crypto_data_t *input,
403    crypto_data_t *output, int (*cipher)(aes_ctx_t *, caddr_t, size_t,
404    crypto_data_t *))
405{
406	int rv;
407/* EXPORT DELETE START */
408
409	if (input->cd_miscdata != NULL) {
410		if (IS_P2ALIGNED(input->cd_miscdata, sizeof (uint64_t))) {
411			/* LINTED: pointer alignment */
412			aes_ctx->ac_iv[0] = *(uint64_t *)input->cd_miscdata;
413			/* LINTED: pointer alignment */
414			aes_ctx->ac_iv[1] = *(uint64_t *)&input->cd_miscdata[8];
415		} else {
416			uint8_t *miscdata8 = (uint8_t *)&input->cd_miscdata[0];
417			uint8_t *iv8 = (uint8_t *)&aes_ctx->ac_iv[0];
418
419			AES_COPY_BLOCK(miscdata8, iv8);
420		}
421	}
422
423	if (input->cd_raw.iov_len < input->cd_length)
424		return (CRYPTO_ARGUMENTS_BAD);
425
426	rv = (cipher)(aes_ctx, input->cd_raw.iov_base + input->cd_offset,
427	    input->cd_length, (input == output) ? NULL : output);
428
429/* EXPORT DELETE END */
430
431	return (rv);
432}
433
434/*
435 * Helper AES encrypt update function for uio input data.
436 */
437static int
438aes_cipher_update_uio(aes_ctx_t *aes_ctx, crypto_data_t *input,
439    crypto_data_t *output, int (*cipher)(aes_ctx_t *, caddr_t, size_t,
440    crypto_data_t *))
441{
442/* EXPORT DELETE START */
443	uio_t *uiop = input->cd_uio;
444	off_t offset = input->cd_offset;
445	size_t length = input->cd_length;
446	uint_t vec_idx;
447	size_t cur_len;
448
449	if (input->cd_miscdata != NULL) {
450		if (IS_P2ALIGNED(input->cd_miscdata, sizeof (uint64_t))) {
451			/* LINTED: pointer alignment */
452			aes_ctx->ac_iv[0] = *(uint64_t *)input->cd_miscdata;
453			/* LINTED: pointer alignment */
454			aes_ctx->ac_iv[1] = *(uint64_t *)&input->cd_miscdata[8];
455		} else {
456			uint8_t *miscdata8 = (uint8_t *)&input->cd_miscdata[0];
457			uint8_t *iv8 = (uint8_t *)&aes_ctx->ac_iv[0];
458
459			AES_COPY_BLOCK(miscdata8, iv8);
460		}
461	}
462
463	if (input->cd_uio->uio_segflg != UIO_SYSSPACE) {
464		return (CRYPTO_ARGUMENTS_BAD);
465	}
466
467	/*
468	 * Jump to the first iovec containing data to be
469	 * processed.
470	 */
471	for (vec_idx = 0; vec_idx < uiop->uio_iovcnt &&
472	    offset >= uiop->uio_iov[vec_idx].iov_len;
473	    offset -= uiop->uio_iov[vec_idx++].iov_len)
474		;
475	if (vec_idx == uiop->uio_iovcnt) {
476		/*
477		 * The caller specified an offset that is larger than the
478		 * total size of the buffers it provided.
479		 */
480		return (CRYPTO_DATA_LEN_RANGE);
481	}
482
483	/*
484	 * Now process the iovecs.
485	 */
486	while (vec_idx < uiop->uio_iovcnt && length > 0) {
487		cur_len = MIN(uiop->uio_iov[vec_idx].iov_len -
488		    offset, length);
489
490		(cipher)(aes_ctx, uiop->uio_iov[vec_idx].iov_base + offset,
491		    cur_len, (input == output) ? NULL : output);
492
493		length -= cur_len;
494		vec_idx++;
495		offset = 0;
496	}
497
498	if (vec_idx == uiop->uio_iovcnt && length > 0) {
499		/*
500		 * The end of the specified iovec's was reached but
501		 * the length requested could not be processed, i.e.
502		 * The caller requested to digest more data than it provided.
503		 */
504
505		return (CRYPTO_DATA_LEN_RANGE);
506	}
507
508/* EXPORT DELETE END */
509
510	return (CRYPTO_SUCCESS);
511}
512
513/*
514 * Helper AES encrypt update function for mblk input data.
515 */
516static int
517aes_cipher_update_mp(aes_ctx_t *aes_ctx, crypto_data_t *input,
518    crypto_data_t *output, int (*cipher)(aes_ctx_t *, caddr_t, size_t,
519    crypto_data_t *))
520{
521/* EXPORT DELETE START */
522	off_t offset = input->cd_offset;
523	size_t length = input->cd_length;
524	mblk_t *mp;
525	size_t cur_len;
526
527	if (input->cd_miscdata != NULL) {
528		if (IS_P2ALIGNED(input->cd_miscdata, sizeof (uint64_t))) {
529			/* LINTED: pointer alignment */
530			aes_ctx->ac_iv[0] = *(uint64_t *)input->cd_miscdata;
531			/* LINTED: pointer alignment */
532			aes_ctx->ac_iv[1] = *(uint64_t *)&input->cd_miscdata[8];
533		} else {
534			uint8_t *miscdata8 = (uint8_t *)&input->cd_miscdata[0];
535			uint8_t *iv8 = (uint8_t *)&aes_ctx->ac_iv[0];
536
537			AES_COPY_BLOCK(miscdata8, iv8);
538		}
539	}
540
541	/*
542	 * Jump to the first mblk_t containing data to be processed.
543	 */
544	for (mp = input->cd_mp; mp != NULL && offset >= MBLKL(mp);
545	    offset -= MBLKL(mp), mp = mp->b_cont)
546		;
547	if (mp == NULL) {
548		/*
549		 * The caller specified an offset that is larger than the
550		 * total size of the buffers it provided.
551		 */
552		return (CRYPTO_DATA_LEN_RANGE);
553	}
554
555	/*
556	 * Now do the processing on the mblk chain.
557	 */
558	while (mp != NULL && length > 0) {
559		cur_len = MIN(MBLKL(mp) - offset, length);
560		(cipher)(aes_ctx, (char *)(mp->b_rptr + offset), cur_len,
561		    (input == output) ? NULL : output);
562
563		length -= cur_len;
564		offset = 0;
565		mp = mp->b_cont;
566	}
567
568	if (mp == NULL && length > 0) {
569		/*
570		 * The end of the mblk was reached but the length requested
571		 * could not be processed, i.e. The caller requested
572		 * to digest more data than it provided.
573		 */
574		return (CRYPTO_DATA_LEN_RANGE);
575	}
576
577/* EXPORT DELETE END */
578
579	return (CRYPTO_SUCCESS);
580}
581
582/* ARGSUSED */
583static int
584aes_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
585    crypto_data_t *ciphertext, crypto_req_handle_t req)
586{
587	int ret = CRYPTO_FAILED;
588
589/* EXPORT DELETE START */
590
591	aes_ctx_t *aes_ctx;
592	size_t saved_length, saved_offset, length_needed;
593
594	ASSERT(ctx->cc_provider_private != NULL);
595	aes_ctx = ctx->cc_provider_private;
596
597	/*
598	 * For block ciphers, plaintext must be a multiple of AES block size.
599	 * This test is only valid for ciphers whose blocksize is a power of 2.
600	 * Even though AES CCM mode is a block cipher, it does not
601	 * require the plaintext to be a multiple of AES block size.
602	 * The length requirement for AES CCM mode has already been checked
603	 * at init time
604	 */
605	if (((aes_ctx->ac_flags & AES_CTR_MODE) == 0) &&
606	    ((aes_ctx->ac_flags & AES_CCM_MODE) == 0) &&
607	    (plaintext->cd_length & (AES_BLOCK_LEN - 1)) != 0)
608		return (CRYPTO_DATA_LEN_RANGE);
609
610	AES_ARG_INPLACE(plaintext, ciphertext);
611
612	/*
613	 * We need to just return the length needed to store the output.
614	 * We should not destroy the context for the following case.
615	 */
616	if (aes_ctx->ac_flags & AES_CCM_MODE) {
617		length_needed = plaintext->cd_length + aes_ctx->ac_ccm_mac_len;
618	} else {
619		length_needed = plaintext->cd_length;
620	}
621
622	if (ciphertext->cd_length < length_needed) {
623		ciphertext->cd_length = length_needed;
624		return (CRYPTO_BUFFER_TOO_SMALL);
625	}
626
627	saved_length = ciphertext->cd_length;
628	saved_offset = ciphertext->cd_offset;
629
630	/*
631	 * Do an update on the specified input data.
632	 */
633	ret = aes_encrypt_update(ctx, plaintext, ciphertext, req);
634	if (ret != CRYPTO_SUCCESS) {
635		return (ret);
636	}
637
638	/*
639	 * For CCM mode, aes_ccm_encrypt_final() will take care of any
640	 * left-over unprocessed data, and compute the MAC
641	 */
642	if (aes_ctx->ac_flags & AES_CCM_MODE) {
643		/*
644		 * aes_ccm_encrypt_final() will compute the MAC and append
645		 * it to existing ciphertext. So, need to adjust the left over
646		 * length value accordingly
647		 */
648
649		/* order of following 2 lines MUST not be reversed */
650		ciphertext->cd_offset = ciphertext->cd_length;
651		ciphertext->cd_length = saved_length - ciphertext->cd_length;
652		ret = aes_ccm_encrypt_final(aes_ctx, ciphertext);
653		if (ret != CRYPTO_SUCCESS) {
654			return (ret);
655		}
656
657		if (plaintext != ciphertext) {
658			ciphertext->cd_length =
659			    ciphertext->cd_offset - saved_offset;
660		}
661		ciphertext->cd_offset = saved_offset;
662	}
663
664	ASSERT(aes_ctx->ac_remainder_len == 0);
665	(void) aes_free_context(ctx);
666
667/* EXPORT DELETE END */
668
669	/* LINTED */
670	return (ret);
671}
672
673/* ARGSUSED */
674static int
675aes_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
676    crypto_data_t *plaintext, crypto_req_handle_t req)
677{
678	int ret = CRYPTO_FAILED;
679
680/* EXPORT DELETE START */
681
682	aes_ctx_t *aes_ctx;
683	off_t saved_offset;
684	size_t saved_length;
685
686	ASSERT(ctx->cc_provider_private != NULL);
687	aes_ctx = ctx->cc_provider_private;
688
689	/*
690	 * For block ciphers, plaintext must be a multiple of AES block size.
691	 * This test is only valid for ciphers whose blocksize is a power of 2.
692	 * Even though AES CCM mode is a block cipher, it does not
693	 * require the plaintext to be a multiple of AES block size.
694	 * The length requirement for AES CCM mode has already been checked
695	 * at init time
696	 */
697	if (((aes_ctx->ac_flags & AES_CTR_MODE) == 0) &&
698	    ((aes_ctx->ac_flags & AES_CCM_MODE) == 0) &&
699	    (ciphertext->cd_length & (AES_BLOCK_LEN - 1)) != 0) {
700		return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
701	}
702
703	AES_ARG_INPLACE(ciphertext, plaintext);
704
705	/*
706	 * We need to just return the length needed to store the output.
707	 * We should not destroy the context for the following case.
708	 *
709	 * For AES CCM mode, size of the plaintext will be MAC_SIZE
710	 * smaller than size of the cipher text.
711	 */
712	if (aes_ctx->ac_flags & AES_CCM_MODE) {
713		if (plaintext->cd_length < aes_ctx->ac_ccm_data_len) {
714			plaintext->cd_length = aes_ctx->ac_ccm_data_len;
715			return (CRYPTO_BUFFER_TOO_SMALL);
716		}
717		saved_offset = plaintext->cd_offset;
718		saved_length = plaintext->cd_length;
719	} else if (plaintext->cd_length < ciphertext->cd_length) {
720		plaintext->cd_length = ciphertext->cd_length;
721		return (CRYPTO_BUFFER_TOO_SMALL);
722	}
723
724	/*
725	 * Do an update on the specified input data.
726	 */
727	ret = aes_decrypt_update(ctx, ciphertext, plaintext, req);
728	if (ret != CRYPTO_SUCCESS) {
729		goto cleanup;
730	}
731
732	if (aes_ctx->ac_flags & AES_CCM_MODE) {
733		ASSERT(aes_ctx->ac_ccm_processed_data_len
734		    == aes_ctx->ac_ccm_data_len);
735		ASSERT(aes_ctx->ac_ccm_processed_mac_len
736		    == aes_ctx->ac_ccm_mac_len);
737
738		/* order of following 2 lines MUST not be reversed */
739		plaintext->cd_offset = plaintext->cd_length;
740		plaintext->cd_length = saved_length - plaintext->cd_length;
741
742		ret = aes_ccm_decrypt_final(aes_ctx, plaintext);
743		if (ret == CRYPTO_SUCCESS) {
744			if (plaintext != ciphertext) {
745				plaintext->cd_length =
746				    plaintext->cd_offset - saved_offset;
747			}
748		} else {
749			plaintext->cd_length = saved_length;
750		}
751
752		plaintext->cd_offset = saved_offset;
753	}
754
755	ASSERT(aes_ctx->ac_remainder_len == 0);
756
757cleanup:
758	if (aes_ctx->ac_ccm_pt_buf) {
759		kmem_free(aes_ctx->ac_ccm_pt_buf, aes_ctx->ac_ccm_data_len);
760	}
761	(void) aes_free_context(ctx);
762
763/* EXPORT DELETE END */
764
765	/* LINTED */
766	return (ret);
767}
768
769/* ARGSUSED */
770static int
771aes_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
772    crypto_data_t *ciphertext, crypto_req_handle_t req)
773{
774	off_t saved_offset;
775	size_t saved_length, out_len;
776	int ret = CRYPTO_SUCCESS;
777	aes_ctx_t *aes_ctx;
778
779	ASSERT(ctx->cc_provider_private != NULL);
780
781	AES_ARG_INPLACE(plaintext, ciphertext);
782
783	/* compute number of bytes that will hold the ciphertext */
784	out_len = ((aes_ctx_t *)ctx->cc_provider_private)->ac_remainder_len;
785	out_len += plaintext->cd_length;
786	out_len &= ~(AES_BLOCK_LEN - 1);
787
788	/* return length needed to store the output */
789	if (ciphertext->cd_length < out_len) {
790		ciphertext->cd_length = out_len;
791		return (CRYPTO_BUFFER_TOO_SMALL);
792	}
793
794	saved_offset = ciphertext->cd_offset;
795	saved_length = ciphertext->cd_length;
796
797
798	/*
799	 * Do the AES update on the specified input data.
800	 */
801	switch (plaintext->cd_format) {
802	case CRYPTO_DATA_RAW:
803		ret = aes_cipher_update_iov(ctx->cc_provider_private,
804		    plaintext, ciphertext, aes_encrypt_contiguous_blocks);
805		break;
806	case CRYPTO_DATA_UIO:
807		ret = aes_cipher_update_uio(ctx->cc_provider_private,
808		    plaintext, ciphertext, aes_encrypt_contiguous_blocks);
809		break;
810	case CRYPTO_DATA_MBLK:
811		ret = aes_cipher_update_mp(ctx->cc_provider_private,
812		    plaintext, ciphertext, aes_encrypt_contiguous_blocks);
813		break;
814	default:
815		ret = CRYPTO_ARGUMENTS_BAD;
816	}
817
818	/*
819	 * Since AES counter mode is a stream cipher, we call
820	 * aes_counter_final() to pick up any remaining bytes.
821	 * It is an internal function that does not destroy
822	 * the context like *normal* final routines.
823	 */
824	aes_ctx = ctx->cc_provider_private;
825	if ((aes_ctx->ac_flags & AES_CTR_MODE) &&
826	    (aes_ctx->ac_remainder_len > 0)) {
827		ret = aes_counter_final(aes_ctx, ciphertext);
828	}
829
830	if (ret == CRYPTO_SUCCESS) {
831		if (plaintext != ciphertext)
832			ciphertext->cd_length =
833			    ciphertext->cd_offset - saved_offset;
834	} else {
835		ciphertext->cd_length = saved_length;
836	}
837	ciphertext->cd_offset = saved_offset;
838
839	return (ret);
840}
841
842/* ARGSUSED */
843static int
844aes_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
845    crypto_data_t *plaintext, crypto_req_handle_t req)
846{
847	off_t saved_offset;
848	size_t saved_length, out_len;
849	int ret = CRYPTO_SUCCESS;
850	aes_ctx_t *aes_ctx;
851
852	ASSERT(ctx->cc_provider_private != NULL);
853
854	AES_ARG_INPLACE(ciphertext, plaintext);
855
856	/* compute number of bytes that will hold the plaintext */
857	out_len = ((aes_ctx_t *)ctx->cc_provider_private)->ac_remainder_len;
858	out_len += ciphertext->cd_length;
859	out_len &= ~(AES_BLOCK_LEN - 1);
860
861	/* return length needed to store the output */
862	if (plaintext->cd_length < out_len) {
863		plaintext->cd_length = out_len;
864		return (CRYPTO_BUFFER_TOO_SMALL);
865	}
866
867	saved_offset = plaintext->cd_offset;
868	saved_length = plaintext->cd_length;
869
870	/*
871	 * Do the AES update on the specified input data.
872	 */
873	switch (ciphertext->cd_format) {
874	case CRYPTO_DATA_RAW:
875		ret = aes_cipher_update_iov(ctx->cc_provider_private,
876		    ciphertext, plaintext, aes_decrypt_contiguous_blocks);
877		break;
878	case CRYPTO_DATA_UIO:
879		ret = aes_cipher_update_uio(ctx->cc_provider_private,
880		    ciphertext, plaintext, aes_decrypt_contiguous_blocks);
881		break;
882	case CRYPTO_DATA_MBLK:
883		ret = aes_cipher_update_mp(ctx->cc_provider_private,
884		    ciphertext, plaintext, aes_decrypt_contiguous_blocks);
885		break;
886	default:
887		ret = CRYPTO_ARGUMENTS_BAD;
888	}
889
890	/*
891	 * Since AES counter mode is a stream cipher, we call
892	 * aes_counter_final() to pick up any remaining bytes.
893	 * It is an internal function that does not destroy
894	 * the context like *normal* final routines.
895	 */
896	aes_ctx = ctx->cc_provider_private;
897	if ((aes_ctx->ac_flags & AES_CTR_MODE) &&
898	    (aes_ctx->ac_remainder_len > 0)) {
899		ret = aes_counter_final(aes_ctx, plaintext);
900	}
901
902	if (ret == CRYPTO_SUCCESS) {
903		if (ciphertext != plaintext)
904			plaintext->cd_length =
905			    plaintext->cd_offset - saved_offset;
906	} else {
907		plaintext->cd_length = saved_length;
908	}
909	plaintext->cd_offset = saved_offset;
910
911
912	return (ret);
913}
914
915/* ARGSUSED */
916static int
917aes_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *data,
918    crypto_req_handle_t req)
919{
920
921/* EXPORT DELETE START */
922
923	aes_ctx_t *aes_ctx;
924	int ret;
925
926	ASSERT(ctx->cc_provider_private != NULL);
927	aes_ctx = ctx->cc_provider_private;
928
929	if (data->cd_format != CRYPTO_DATA_RAW &&
930	    data->cd_format != CRYPTO_DATA_UIO &&
931	    data->cd_format != CRYPTO_DATA_MBLK) {
932		return (CRYPTO_ARGUMENTS_BAD);
933	}
934
935	if (aes_ctx->ac_flags & AES_CTR_MODE) {
936		if (aes_ctx->ac_remainder_len > 0) {
937			ret = aes_counter_final(aes_ctx, data);
938			if (ret != CRYPTO_SUCCESS)
939				return (ret);
940		}
941	} else if (aes_ctx->ac_flags & AES_CCM_MODE) {
942		ret = aes_ccm_encrypt_final(aes_ctx, data);
943		if (ret != CRYPTO_SUCCESS) {
944			return (ret);
945		}
946	} else {
947		/*
948		 * There must be no unprocessed plaintext.
949		 * This happens if the length of the last data is
950		 * not a multiple of the AES block length.
951		 */
952		if (aes_ctx->ac_remainder_len > 0) {
953			return (CRYPTO_DATA_LEN_RANGE);
954		}
955		data->cd_length = 0;
956	}
957
958	(void) aes_free_context(ctx);
959
960/* EXPORT DELETE END */
961
962	return (CRYPTO_SUCCESS);
963}
964
965/* ARGSUSED */
966static int
967aes_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *data,
968    crypto_req_handle_t req)
969{
970
971/* EXPORT DELETE START */
972
973	aes_ctx_t *aes_ctx;
974	int ret;
975	off_t saved_offset;
976	size_t saved_length;
977
978	ASSERT(ctx->cc_provider_private != NULL);
979	aes_ctx = ctx->cc_provider_private;
980
981	if (data->cd_format != CRYPTO_DATA_RAW &&
982	    data->cd_format != CRYPTO_DATA_UIO &&
983	    data->cd_format != CRYPTO_DATA_MBLK) {
984		return (CRYPTO_ARGUMENTS_BAD);
985	}
986
987	/*
988	 * There must be no unprocessed ciphertext.
989	 * This happens if the length of the last ciphertext is
990	 * not a multiple of the AES block length.
991	 */
992	if (aes_ctx->ac_remainder_len > 0) {
993		if ((aes_ctx->ac_flags & AES_CTR_MODE) == 0)
994			return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
995		else {
996			ret = aes_counter_final(aes_ctx, data);
997			if (ret != CRYPTO_SUCCESS)
998				return (ret);
999		}
1000	}
1001
1002	if (aes_ctx->ac_flags & AES_CCM_MODE) {
1003		/*
1004		 * This is where all the plaintext is returned, make sure
1005		 * the plaintext buffer is big enough
1006		 */
1007		size_t pt_len = aes_ctx->ac_ccm_data_len;
1008		if (data->cd_length < pt_len) {
1009			data->cd_length = pt_len;
1010			return (CRYPTO_BUFFER_TOO_SMALL);
1011		}
1012
1013		ASSERT(aes_ctx->ac_ccm_processed_data_len == pt_len);
1014		ASSERT(aes_ctx->ac_ccm_processed_mac_len
1015		    == aes_ctx->ac_ccm_mac_len);
1016		saved_offset = data->cd_offset;
1017		saved_length = data->cd_length;
1018		ret = aes_ccm_decrypt_final(aes_ctx, data);
1019		if (ret == CRYPTO_SUCCESS) {
1020			data->cd_length = data->cd_offset - saved_offset;
1021		} else {
1022			data->cd_length = saved_length;
1023		}
1024
1025		data->cd_offset = saved_offset;
1026		if (ret != CRYPTO_SUCCESS) {
1027			return (ret);
1028		}
1029	}
1030
1031
1032	if (((aes_ctx->ac_flags & AES_CTR_MODE) == 0) &&
1033	    ((aes_ctx->ac_flags & AES_CCM_MODE) == 0)) {
1034		data->cd_length = 0;
1035	}
1036
1037	if (aes_ctx->ac_ccm_pt_buf != NULL) {
1038		kmem_free(aes_ctx->ac_ccm_pt_buf, aes_ctx->ac_ccm_data_len);
1039	}
1040
1041	(void) aes_free_context(ctx);
1042
1043/* EXPORT DELETE END */
1044
1045	return (CRYPTO_SUCCESS);
1046}
1047
1048/* ARGSUSED */
1049static int
1050aes_encrypt_atomic(crypto_provider_handle_t provider,
1051    crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
1052    crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
1053    crypto_spi_ctx_template_t template, crypto_req_handle_t req)
1054{
1055	aes_ctx_t aes_ctx;	/* on the stack */
1056	off_t saved_offset;
1057	size_t saved_length;
1058	int ret;
1059
1060	AES_ARG_INPLACE(plaintext, ciphertext);
1061
1062	if ((mechanism->cm_type != AES_CTR_MECH_INFO_TYPE) &&
1063	    (mechanism->cm_type != AES_CCM_MECH_INFO_TYPE)) {
1064		/*
1065		 * Plaintext must be a multiple of AES block size.
1066		 * This test only works for non-padded mechanisms
1067		 * when blocksize is 2^N.
1068		 */
1069		if ((plaintext->cd_length & (AES_BLOCK_LEN - 1)) != 0)
1070			return (CRYPTO_DATA_LEN_RANGE);
1071	}
1072
1073	/* return length needed to store the output */
1074	if (ciphertext->cd_length < plaintext->cd_length) {
1075		ciphertext->cd_length = plaintext->cd_length;
1076		return (CRYPTO_BUFFER_TOO_SMALL);
1077	}
1078
1079	if ((ret = aes_check_mech_param(mechanism)) != CRYPTO_SUCCESS)
1080		return (ret);
1081
1082	bzero(&aes_ctx, sizeof (aes_ctx_t));
1083
1084	ret = aes_common_init_ctx(&aes_ctx, template, mechanism, key,
1085	    crypto_kmflag(req), B_TRUE);
1086	if (ret != CRYPTO_SUCCESS)
1087		return (ret);
1088
1089	if (mechanism->cm_type == AES_CCM_MECH_INFO_TYPE) {
1090		size_t length_needed
1091		    = plaintext->cd_length + aes_ctx.ac_ccm_mac_len;
1092		if (ciphertext->cd_length < length_needed) {
1093			ciphertext->cd_length = length_needed;
1094			return (CRYPTO_BUFFER_TOO_SMALL);
1095		}
1096	}
1097
1098
1099	saved_offset = ciphertext->cd_offset;
1100	saved_length = ciphertext->cd_length;
1101
1102	/*
1103	 * Do an update on the specified input data.
1104	 */
1105	switch (plaintext->cd_format) {
1106	case CRYPTO_DATA_RAW:
1107		ret = aes_cipher_update_iov(&aes_ctx, plaintext, ciphertext,
1108		    aes_encrypt_contiguous_blocks);
1109		break;
1110	case CRYPTO_DATA_UIO:
1111		ret = aes_cipher_update_uio(&aes_ctx, plaintext, ciphertext,
1112		    aes_encrypt_contiguous_blocks);
1113		break;
1114	case CRYPTO_DATA_MBLK:
1115		ret = aes_cipher_update_mp(&aes_ctx, plaintext, ciphertext,
1116		    aes_encrypt_contiguous_blocks);
1117		break;
1118	default:
1119		ret = CRYPTO_ARGUMENTS_BAD;
1120	}
1121
1122	if (ret == CRYPTO_SUCCESS) {
1123		if (mechanism->cm_type == AES_CCM_MECH_INFO_TYPE) {
1124			ret = aes_ccm_encrypt_final(&aes_ctx, ciphertext);
1125			if (ret != CRYPTO_SUCCESS)
1126				goto out;
1127			ASSERT(aes_ctx.ac_remainder_len == 0);
1128		} else if (mechanism->cm_type == AES_CTR_MECH_INFO_TYPE) {
1129			if (aes_ctx.ac_remainder_len > 0) {
1130				ret = aes_counter_final(&aes_ctx, ciphertext);
1131				if (ret != CRYPTO_SUCCESS)
1132					goto out;
1133			}
1134		} else {
1135			ASSERT(aes_ctx.ac_remainder_len == 0);
1136		}
1137
1138		if (plaintext != ciphertext) {
1139			ciphertext->cd_length =
1140			    ciphertext->cd_offset - saved_offset;
1141		}
1142	} else {
1143		ciphertext->cd_length = saved_length;
1144	}
1145	ciphertext->cd_offset = saved_offset;
1146
1147out:
1148	if (aes_ctx.ac_flags & AES_PROVIDER_OWNS_KEY_SCHEDULE) {
1149		bzero(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len);
1150		kmem_free(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len);
1151	}
1152
1153	return (ret);
1154}
1155
1156/* ARGSUSED */
1157static int
1158aes_decrypt_atomic(crypto_provider_handle_t provider,
1159    crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
1160    crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
1161    crypto_spi_ctx_template_t template, crypto_req_handle_t req)
1162{
1163	aes_ctx_t aes_ctx;	/* on the stack */
1164	off_t saved_offset;
1165	size_t saved_length;
1166	int ret;
1167
1168	AES_ARG_INPLACE(ciphertext, plaintext);
1169
1170	/*
1171	 * For block ciphers, ciphertext must be a multiple of AES block size.
1172	 * This test is only valid for non-padded mechanisms
1173	 * when blocksize is 2^N
1174	 * Even though AES CCM mode is a block cipher, it does not
1175	 * require the plaintext to be a multiple of AES block size.
1176	 * The length requirement for AES CCM mode will be checked
1177	 * at init time
1178	 */
1179	if ((mechanism->cm_type != AES_CTR_MECH_INFO_TYPE) &&
1180	    (mechanism->cm_type != AES_CCM_MECH_INFO_TYPE) &&
1181	    ((ciphertext->cd_length & (AES_BLOCK_LEN - 1)) != 0))
1182		return (CRYPTO_DATA_LEN_RANGE);
1183
1184	/*
1185	 * return length needed to store the output, length requirement
1186	 * for AES CCM mode can not be determined until later
1187	 */
1188	if ((plaintext->cd_length < ciphertext->cd_length) &&
1189	    (mechanism->cm_type != AES_CCM_MECH_INFO_TYPE)) {
1190		plaintext->cd_length = ciphertext->cd_length;
1191		return (CRYPTO_BUFFER_TOO_SMALL);
1192	}
1193
1194
1195	if ((ret = aes_check_mech_param(mechanism)) != CRYPTO_SUCCESS)
1196		return (ret);
1197
1198	bzero(&aes_ctx, sizeof (aes_ctx_t));
1199
1200	ret = aes_common_init_ctx(&aes_ctx, template, mechanism, key,
1201	    crypto_kmflag(req), B_FALSE);
1202	if (ret != CRYPTO_SUCCESS)
1203		return (ret);
1204
1205	/* check length requirement for AES CCM mode now */
1206	if (mechanism->cm_type == AES_CCM_MECH_INFO_TYPE) {
1207		if (plaintext->cd_length < aes_ctx.ac_ccm_data_len) {
1208			plaintext->cd_length = aes_ctx.ac_ccm_data_len;
1209			ret = CRYPTO_BUFFER_TOO_SMALL;
1210			goto out;
1211		}
1212	}
1213
1214	saved_offset = plaintext->cd_offset;
1215	saved_length = plaintext->cd_length;
1216
1217	/*
1218	 * Do an update on the specified input data.
1219	 */
1220	switch (ciphertext->cd_format) {
1221	case CRYPTO_DATA_RAW:
1222		ret = aes_cipher_update_iov(&aes_ctx, ciphertext, plaintext,
1223		    aes_decrypt_contiguous_blocks);
1224		break;
1225	case CRYPTO_DATA_UIO:
1226		ret = aes_cipher_update_uio(&aes_ctx, ciphertext, plaintext,
1227		    aes_decrypt_contiguous_blocks);
1228		break;
1229	case CRYPTO_DATA_MBLK:
1230		ret = aes_cipher_update_mp(&aes_ctx, ciphertext, plaintext,
1231		    aes_decrypt_contiguous_blocks);
1232		break;
1233	default:
1234		ret = CRYPTO_ARGUMENTS_BAD;
1235	}
1236
1237	if (ret == CRYPTO_SUCCESS) {
1238		if (mechanism->cm_type == AES_CCM_MECH_INFO_TYPE) {
1239			ASSERT(aes_ctx.ac_ccm_processed_data_len
1240			    == aes_ctx.ac_ccm_data_len);
1241			ASSERT(aes_ctx.ac_ccm_processed_mac_len
1242			    == aes_ctx.ac_ccm_mac_len);
1243			ret = aes_ccm_decrypt_final(&aes_ctx, plaintext);
1244			ASSERT(aes_ctx.ac_remainder_len == 0);
1245			if ((ret == CRYPTO_SUCCESS) &&
1246			    (ciphertext != plaintext)) {
1247				plaintext->cd_length =
1248				    plaintext->cd_offset - saved_offset;
1249			} else {
1250				plaintext->cd_length = saved_length;
1251			}
1252		} else if (mechanism->cm_type != AES_CTR_MECH_INFO_TYPE) {
1253			ASSERT(aes_ctx.ac_remainder_len == 0);
1254			if (ciphertext != plaintext)
1255				plaintext->cd_length =
1256				    plaintext->cd_offset - saved_offset;
1257		} else {
1258			if (aes_ctx.ac_remainder_len > 0) {
1259				ret = aes_counter_final(&aes_ctx, plaintext);
1260				if (ret != CRYPTO_SUCCESS)
1261					goto out;
1262			}
1263			if (ciphertext != plaintext)
1264				plaintext->cd_length =
1265				    plaintext->cd_offset - saved_offset;
1266		}
1267	} else {
1268		plaintext->cd_length = saved_length;
1269	}
1270	plaintext->cd_offset = saved_offset;
1271
1272out:
1273	if (aes_ctx.ac_flags & AES_PROVIDER_OWNS_KEY_SCHEDULE) {
1274		bzero(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len);
1275		kmem_free(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len);
1276	}
1277
1278	if (aes_ctx.ac_ccm_pt_buf != NULL) {
1279		kmem_free(aes_ctx.ac_ccm_pt_buf, aes_ctx.ac_ccm_data_len);
1280	}
1281
1282	return (ret);
1283}
1284
1285/*
1286 * KCF software provider context template entry points.
1287 */
1288/* ARGSUSED */
1289static int
1290aes_create_ctx_template(crypto_provider_handle_t provider,
1291    crypto_mechanism_t *mechanism, crypto_key_t *key,
1292    crypto_spi_ctx_template_t *tmpl, size_t *tmpl_size, crypto_req_handle_t req)
1293{
1294
1295/* EXPORT DELETE START */
1296
1297	void *keysched;
1298	size_t size;
1299	int rv;
1300
1301	if (mechanism->cm_type != AES_ECB_MECH_INFO_TYPE &&
1302	    mechanism->cm_type != AES_CBC_MECH_INFO_TYPE &&
1303	    mechanism->cm_type != AES_CTR_MECH_INFO_TYPE &&
1304	    mechanism->cm_type != AES_CCM_MECH_INFO_TYPE)
1305		return (CRYPTO_MECHANISM_INVALID);
1306
1307	if ((keysched = aes_alloc_keysched(&size,
1308	    crypto_kmflag(req))) == NULL) {
1309		return (CRYPTO_HOST_MEMORY);
1310	}
1311
1312	/*
1313	 * Initialize key schedule.  Key length information is stored
1314	 * in the key.
1315	 */
1316	if ((rv = init_keysched(key, keysched)) != CRYPTO_SUCCESS) {
1317		bzero(keysched, size);
1318		kmem_free(keysched, size);
1319		return (rv);
1320	}
1321
1322	*tmpl = keysched;
1323	*tmpl_size = size;
1324
1325/* EXPORT DELETE END */
1326
1327	return (CRYPTO_SUCCESS);
1328}
1329
1330/* ARGSUSED */
1331static int
1332aes_free_context(crypto_ctx_t *ctx)
1333{
1334
1335/* EXPORT DELETE START */
1336
1337	aes_ctx_t *aes_ctx = ctx->cc_provider_private;
1338
1339	if (aes_ctx != NULL) {
1340		if (aes_ctx->ac_flags & AES_PROVIDER_OWNS_KEY_SCHEDULE) {
1341			ASSERT(aes_ctx->ac_keysched_len != 0);
1342			bzero(aes_ctx->ac_keysched, aes_ctx->ac_keysched_len);
1343			kmem_free(aes_ctx->ac_keysched,
1344			    aes_ctx->ac_keysched_len);
1345		}
1346		kmem_free(aes_ctx, sizeof (aes_ctx_t));
1347		ctx->cc_provider_private = NULL;
1348	}
1349
1350/* EXPORT DELETE END */
1351
1352	return (CRYPTO_SUCCESS);
1353}
1354
1355/* ARGSUSED */
1356static int
1357aes_common_init_ctx(aes_ctx_t *aes_ctx, crypto_spi_ctx_template_t *template,
1358    crypto_mechanism_t *mechanism, crypto_key_t *key, int kmflag,
1359    boolean_t is_encrypt_init)
1360{
1361	int rv = CRYPTO_SUCCESS;
1362
1363/* EXPORT DELETE START */
1364
1365	void *keysched;
1366	size_t size;
1367	CK_AES_CCM_PARAMS *ccm_param = NULL;
1368
1369	aes_ctx->ac_flags = 0;
1370
1371	if (mechanism->cm_type == AES_CBC_MECH_INFO_TYPE) {
1372		/*
1373		 * Copy 128-bit IV into context.
1374		 *
1375		 * If cm_param == NULL then the IV comes from the
1376		 * cd_miscdata field in the crypto_data structure.
1377		 */
1378		if (mechanism->cm_param != NULL) {
1379			ASSERT(mechanism->cm_param_len == AES_BLOCK_LEN);
1380			if (IS_P2ALIGNED(mechanism->cm_param,
1381			    sizeof (uint64_t))) {
1382				uint64_t *param64;
1383				param64 = (uint64_t *)mechanism->cm_param;
1384
1385				aes_ctx->ac_iv[0] = *param64++;
1386				aes_ctx->ac_iv[1] = *param64;
1387			} else {
1388				uint8_t *iv8;
1389				uint8_t *p8;
1390				iv8 = (uint8_t *)&aes_ctx->ac_iv;
1391				p8 = (uint8_t *)&mechanism->cm_param[0];
1392
1393				iv8[0] = p8[0];
1394				iv8[1] = p8[1];
1395				iv8[2] = p8[2];
1396				iv8[3] = p8[3];
1397				iv8[4] = p8[4];
1398				iv8[5] = p8[5];
1399				iv8[6] = p8[6];
1400				iv8[7] = p8[7];
1401				iv8[8] = p8[8];
1402				iv8[9] = p8[9];
1403				iv8[10] = p8[10];
1404				iv8[11] = p8[11];
1405				iv8[12] = p8[12];
1406				iv8[13] = p8[13];
1407				iv8[14] = p8[14];
1408				iv8[15] = p8[15];
1409			}
1410		}
1411
1412		aes_ctx->ac_lastp = (uint8_t *)&aes_ctx->ac_iv[0];
1413		aes_ctx->ac_flags |= AES_CBC_MODE;
1414
1415	} else if (mechanism->cm_type == AES_CTR_MECH_INFO_TYPE) {
1416		if (mechanism->cm_param != NULL) {
1417			CK_AES_CTR_PARAMS *pp;
1418			uint64_t mask = 0;
1419			ulong_t count;
1420			uint8_t *iv8;
1421			uint8_t *p8;
1422
1423			/* XXX what to do about miscdata */
1424			pp = (CK_AES_CTR_PARAMS *)mechanism->cm_param;
1425			count = pp->ulCounterBits;
1426			if (count == 0 || count > 64) {
1427				return (CRYPTO_MECHANISM_PARAM_INVALID);
1428			}
1429			while (count-- > 0)
1430				mask |= (1ULL << count);
1431#ifdef _LITTLE_ENDIAN
1432			p8 = (uint8_t *)&mask;
1433			mask = (((uint64_t)p8[0] << 56) |
1434			    ((uint64_t)p8[1] << 48) |
1435			    ((uint64_t)p8[2] << 40) |
1436			    ((uint64_t)p8[3] << 32) |
1437			    ((uint64_t)p8[4] << 24) |
1438			    ((uint64_t)p8[5] << 16) |
1439			    ((uint64_t)p8[6] << 8) |
1440			    (uint64_t)p8[7]);
1441#endif
1442			aes_ctx->ac_counter_mask = mask;
1443
1444			iv8 = (uint8_t *)&aes_ctx->ac_iv;
1445			p8 = (uint8_t *)&pp->cb[0];
1446
1447			iv8[0] = p8[0];
1448			iv8[1] = p8[1];
1449			iv8[2] = p8[2];
1450			iv8[3] = p8[3];
1451			iv8[4] = p8[4];
1452			iv8[5] = p8[5];
1453			iv8[6] = p8[6];
1454			iv8[7] = p8[7];
1455			iv8[8] = p8[8];
1456			iv8[9] = p8[9];
1457			iv8[10] = p8[10];
1458			iv8[11] = p8[11];
1459			iv8[12] = p8[12];
1460			iv8[13] = p8[13];
1461			iv8[14] = p8[14];
1462			iv8[15] = p8[15];
1463		} else {
1464			return (CRYPTO_MECHANISM_PARAM_INVALID);
1465		}
1466
1467		aes_ctx->ac_lastp = (uint8_t *)&aes_ctx->ac_iv[0];
1468		aes_ctx->ac_flags |= AES_CTR_MODE;
1469	} else if (mechanism->cm_type == AES_CCM_MECH_INFO_TYPE) {
1470		if (mechanism->cm_param != NULL) {
1471			int rc;
1472
1473			ccm_param = (CK_AES_CCM_PARAMS *)mechanism->cm_param;
1474
1475			if ((rc = aes_ccm_validate_args(ccm_param,
1476			    is_encrypt_init)) != 0) {
1477				return (rc);
1478			}
1479
1480			aes_ctx->ac_ccm_mac_len = ccm_param->ulMACSize;
1481			if (is_encrypt_init) {
1482				aes_ctx->ac_ccm_data_len
1483				    = ccm_param->ulDataSize;
1484			} else {
1485				aes_ctx->ac_ccm_data_len =
1486				    ccm_param->ulDataSize
1487				    - aes_ctx->ac_ccm_mac_len;
1488				aes_ctx->ac_ccm_processed_mac_len = 0;
1489			}
1490			aes_ctx->ac_ccm_processed_data_len = 0;
1491
1492			aes_ctx->ac_flags |= AES_CCM_MODE;
1493		} else {
1494			return (CRYPTO_MECHANISM_PARAM_INVALID);
1495		}
1496	} else {
1497		aes_ctx->ac_flags |= AES_ECB_MODE;
1498	}
1499
1500	if (template == NULL) {
1501		if ((keysched = aes_alloc_keysched(&size, kmflag)) == NULL)
1502			return (CRYPTO_HOST_MEMORY);
1503		/*
1504		 * Initialize key schedule.
1505		 * Key length is stored in the key.
1506		 */
1507		if ((rv = init_keysched(key, keysched)) != CRYPTO_SUCCESS) {
1508			kmem_free(keysched, size);
1509			return (rv);
1510		}
1511
1512		aes_ctx->ac_flags |= AES_PROVIDER_OWNS_KEY_SCHEDULE;
1513		aes_ctx->ac_keysched_len = size;
1514	} else {
1515		keysched = template;
1516	}
1517	aes_ctx->ac_keysched = keysched;
1518
1519	/* process the nonce and associated data if it is AES CCM mode */
1520	if (mechanism->cm_type == AES_CCM_MECH_INFO_TYPE) {
1521		if (aes_ccm_init(aes_ctx, ccm_param->nonce,
1522		    ccm_param->ulNonceSize, ccm_param->authData,
1523		    ccm_param->ulAuthDataSize) != 0) {
1524			bzero(keysched, size);
1525			kmem_free(keysched, size);
1526			return (CRYPTO_MECHANISM_PARAM_INVALID);
1527		}
1528		if (!is_encrypt_init) {
1529			/* allocate buffer for storing decrypted plaintext */
1530			aes_ctx->ac_ccm_pt_buf =
1531			    kmem_alloc(aes_ctx->ac_ccm_data_len, kmflag);
1532			if (aes_ctx->ac_ccm_pt_buf == NULL) {
1533				bzero(keysched, size);
1534				kmem_free(keysched, size);
1535				return (CRYPTO_HOST_MEMORY);
1536			}
1537		}
1538	}
1539
1540/* EXPORT DELETE END */
1541
1542	return (rv);
1543}
1544