xref: /titanic_44/usr/src/uts/common/crypto/io/ecc.c (revision 0dc2366f7b9f9f36e10909b1e95edbf2a261c2ac)
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 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <sys/types.h>
27 #include <sys/systm.h>
28 #include <sys/param.h>
29 #include <sys/modctl.h>
30 #include <sys/ddi.h>
31 #include <sys/crypto/spi.h>
32 #include <sys/crypto/impl.h>
33 #include <sys/crypto/ioctladmin.h>
34 #include <sys/sysmacros.h>
35 #include <sys/strsun.h>
36 #include <sys/sha1.h>
37 #include <sys/random.h>
38 #include <sys/conf.h>
39 #include <sys/devops.h>
40 #include <sys/sunddi.h>
41 #include <sys/varargs.h>
42 #include <sys/kmem.h>
43 #include <sys/kstat.h>
44 
45 #include <des/des_impl.h>
46 #include <ecc/ecc_impl.h>
47 
48 #define	CKD_NULL		0x00000001
49 
50 extern struct mod_ops mod_cryptoops;
51 
52 /*
53  * Module linkage information for the kernel.
54  */
55 static struct modlcrypto modlcrypto = {
56 	&mod_cryptoops,
57 	"EC Kernel SW Provider"
58 };
59 
60 static struct modlinkage modlinkage = {
61 	MODREV_1,
62 	(void *)&modlcrypto,
63 	NULL
64 };
65 
66 /*
67  * CSPI information (entry points, provider info, etc.)
68  */
69 typedef enum ecc_mech_type {
70 	EC_KEY_PAIR_GEN_MECH_INFO_TYPE,	/* SUN_CKM_EC_KEY_PAIR_GEN */
71 	ECDSA_MECH_INFO_TYPE,		/* SUN_CKM_ECDSA */
72 	ECDSA_SHA1_MECH_INFO_TYPE,	/* SUN_CKM_ECDSA_SHA1 */
73 	ECDH1_DERIVE_MECH_INFO_TYPE	/* SUN_CKM_ECDH1_DERIVE */
74 } ecc_mech_type_t;
75 
76 /*
77  * Context for ECDSA mechanism.
78  */
79 typedef struct ecc_ctx {
80 	ecc_mech_type_t	mech_type;
81 	crypto_key_t *key;
82 	size_t keychunk_size;
83 	ECParams ecparams;
84 } ecc_ctx_t;
85 
86 /*
87  * Context for ECDSA_SHA1 mechanism.
88  */
89 typedef struct digest_ecc_ctx {
90 	ecc_mech_type_t	mech_type;
91 	crypto_key_t *key;
92 	size_t keychunk_size;
93 	ECParams ecparams;
94 	union {
95 		SHA1_CTX sha1ctx;
96 	} dctx_u;
97 } digest_ecc_ctx_t;
98 
99 #define	sha1_ctx	dctx_u.sha1ctx
100 
101 /*
102  * Mechanism info structure passed to KCF during registration.
103  */
104 static crypto_mech_info_t ecc_mech_info_tab[] = {
105 	/* EC_KEY_PAIR_GEN */
106 	{SUN_CKM_EC_KEY_PAIR_GEN, EC_KEY_PAIR_GEN_MECH_INFO_TYPE,
107 	    CRYPTO_FG_GENERATE_KEY_PAIR, EC_MIN_KEY_LEN, EC_MAX_KEY_LEN,
108 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
109 	/* ECDH */
110 	{SUN_CKM_ECDH1_DERIVE, ECDH1_DERIVE_MECH_INFO_TYPE, CRYPTO_FG_DERIVE,
111 	    EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
112 	/* ECDSA */
113 	{SUN_CKM_ECDSA, ECDSA_MECH_INFO_TYPE,
114 	    CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY |
115 	    CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC,
116 	    EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
117 	/* ECDSA_SHA1 */
118 	{SUN_CKM_ECDSA_SHA1, ECDSA_SHA1_MECH_INFO_TYPE,
119 	    CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY |
120 	    CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC,
121 	    EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}
122 };
123 
124 static void ecc_provider_status(crypto_provider_handle_t, uint_t *);
125 
126 static crypto_control_ops_t ecc_control_ops = {
127 	ecc_provider_status
128 };
129 
130 static int ecc_sign_init(crypto_ctx_t *, crypto_mechanism_t *,
131     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
132 static int ecc_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
133     crypto_req_handle_t);
134 static int ecc_sign_update(crypto_ctx_t *, crypto_data_t *,
135     crypto_req_handle_t);
136 static int ecc_sign_final(crypto_ctx_t *, crypto_data_t *,
137     crypto_req_handle_t);
138 static int ecc_sign_atomic(crypto_provider_handle_t, crypto_session_id_t,
139     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
140     crypto_spi_ctx_template_t, crypto_req_handle_t);
141 
142 static crypto_sign_ops_t ecc_sign_ops = {
143 	ecc_sign_init,
144 	ecc_sign,
145 	ecc_sign_update,
146 	ecc_sign_final,
147 	ecc_sign_atomic,
148 	NULL,
149 	NULL,
150 	NULL
151 };
152 
153 static int ecc_verify_init(crypto_ctx_t *, crypto_mechanism_t *,
154     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
155 static int ecc_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
156     crypto_req_handle_t);
157 static int ecc_verify_update(crypto_ctx_t *, crypto_data_t *,
158     crypto_req_handle_t);
159 static int ecc_verify_final(crypto_ctx_t *, crypto_data_t *,
160     crypto_req_handle_t);
161 static int ecc_verify_atomic(crypto_provider_handle_t, crypto_session_id_t,
162     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
163     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
164 
165 static crypto_verify_ops_t ecc_verify_ops = {
166 	ecc_verify_init,
167 	ecc_verify,
168 	ecc_verify_update,
169 	ecc_verify_final,
170 	ecc_verify_atomic,
171 	NULL,
172 	NULL,
173 	NULL
174 };
175 
176 static int ecc_nostore_key_generate_pair(crypto_provider_handle_t,
177     crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
178     uint_t, crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
179     uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
180 static int ecc_nostore_key_derive(crypto_provider_handle_t,
181     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
182     crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
183     uint_t, crypto_req_handle_t);
184 
185 static crypto_nostore_key_ops_t ecc_nostore_key_ops = {
186 	NULL,
187 	ecc_nostore_key_generate_pair,
188 	ecc_nostore_key_derive
189 };
190 
191 static void ecc_POST(int *);
192 
193 static crypto_fips140_ops_t ecc_fips140_ops = {
194 	ecc_POST
195 };
196 
197 
198 static crypto_ops_t ecc_crypto_ops = {
199 	&ecc_control_ops,
200 	NULL,
201 	NULL,
202 	NULL,
203 	&ecc_sign_ops,
204 	&ecc_verify_ops,
205 	NULL,
206 	NULL,
207 	NULL,
208 	NULL,
209 	NULL,
210 	NULL,
211 	NULL,
212 	NULL,
213 	NULL,
214 	&ecc_nostore_key_ops,
215 	&ecc_fips140_ops
216 };
217 
218 static crypto_provider_info_t ecc_prov_info = {
219 	CRYPTO_SPI_VERSION_4,
220 	"EC Software Provider",
221 	CRYPTO_SW_PROVIDER,
222 	{&modlinkage},
223 	NULL,
224 	&ecc_crypto_ops,
225 	sizeof (ecc_mech_info_tab)/sizeof (crypto_mech_info_t),
226 	ecc_mech_info_tab
227 };
228 
229 static crypto_kcf_provider_handle_t ecc_prov_handle = NULL;
230 
231 static int ecc_sign_common(ecc_ctx_t *, crypto_data_t *, crypto_data_t *,
232     crypto_req_handle_t);
233 static int ecc_verify_common(ecc_ctx_t *, crypto_data_t *, crypto_data_t *,
234     crypto_req_handle_t);
235 static int find_attr(crypto_object_attribute_t *, uint_t, uint64_t);
236 static int get_template_attr_ulong(crypto_object_attribute_t *,
237     uint_t, uint64_t, ulong_t *);
238 static void ecc_free_context(crypto_ctx_t *);
239 static void free_ecparams(ECParams *, boolean_t);
240 static void free_ecprivkey(ECPrivateKey *);
241 
242 static int fips_pairwise_check(ECPrivateKey *);
243 extern int fips_ecdsa_post(void);
244 
245 
246 int
247 _init(void)
248 {
249 	int ret;
250 
251 	if ((ret = mod_install(&modlinkage)) != 0)
252 		return (ret);
253 
254 	/* Register with KCF.  If the registration fails, remove the module. */
255 	if (crypto_register_provider(&ecc_prov_info, &ecc_prov_handle)) {
256 		(void) mod_remove(&modlinkage);
257 		return (EACCES);
258 	}
259 
260 	return (0);
261 }
262 
263 int
264 _fini(void)
265 {
266 	/* Unregister from KCF if module is registered */
267 	if (ecc_prov_handle != NULL) {
268 		if (crypto_unregister_provider(ecc_prov_handle))
269 			return (EBUSY);
270 
271 		ecc_prov_handle = NULL;
272 	}
273 
274 	return (mod_remove(&modlinkage));
275 }
276 
277 int
278 _info(struct modinfo *modinfop)
279 {
280 	return (mod_info(&modlinkage, modinfop));
281 }
282 
283 /* ARGSUSED */
284 static void
285 ecc_provider_status(crypto_provider_handle_t provider, uint_t *status)
286 {
287 	*status = CRYPTO_PROVIDER_READY;
288 }
289 
290 /*
291  * Return the index of an attribute of specified type found in
292  * the specified array of attributes. If the attribute cannot
293  * found, return -1.
294  */
295 static int
296 find_attr(crypto_object_attribute_t *attr, uint_t nattr, uint64_t attr_type)
297 {
298 	int i;
299 
300 	for (i = 0; i < nattr; i++)
301 		if (attr[i].oa_value != NULL && attr[i].oa_type == attr_type)
302 			return (i);
303 	return (-1);
304 }
305 
306 /*
307  * Common function used by the get_template_attr_*() family of
308  * functions. Returns the value of the specified attribute of specified
309  * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
310  * if the length of the attribute does not match the specified length,
311  * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
312  */
313 static int
314 get_template_attr_scalar_common(crypto_object_attribute_t *template,
315     uint_t nattr, uint64_t attr_type, void *value, size_t value_len)
316 {
317 	size_t oa_value_len;
318 	size_t offset = 0;
319 	int attr_idx;
320 
321 	if ((attr_idx = find_attr(template, nattr, attr_type)) == -1)
322 		return (CRYPTO_ARGUMENTS_BAD);
323 
324 	oa_value_len = template[attr_idx].oa_value_len;
325 	if (oa_value_len != value_len) {
326 		return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
327 	}
328 
329 do_copy:
330 	bcopy(template[attr_idx].oa_value, (uchar_t *)value + offset,
331 	    oa_value_len);
332 
333 	return (CRYPTO_SUCCESS);
334 }
335 
336 /*
337  * Get the value of a ulong_t attribute from the specified template.
338  */
339 static int
340 get_template_attr_ulong(crypto_object_attribute_t *template,
341     uint_t nattr, uint64_t attr_type, ulong_t *attr_value)
342 {
343 	return (get_template_attr_scalar_common(template, nattr,
344 	    attr_type, attr_value, sizeof (ulong_t)));
345 }
346 
347 /*
348  * Called from init routines to do basic sanity checks. Init routines,
349  * e.g. sign_init should fail rather than subsequent operations.
350  */
351 static int
352 check_mech_and_key(ecc_mech_type_t mech_type, crypto_key_t *key, ulong_t class)
353 {
354 	int rv = CRYPTO_SUCCESS;
355 	uchar_t *foo;
356 	ssize_t point_len;
357 	ssize_t value_len;
358 
359 	if (mech_type != ECDSA_SHA1_MECH_INFO_TYPE &&
360 	    mech_type != ECDSA_MECH_INFO_TYPE)
361 		return (CRYPTO_MECHANISM_INVALID);
362 
363 	if (key->ck_format != CRYPTO_KEY_ATTR_LIST) {
364 		return (CRYPTO_KEY_TYPE_INCONSISTENT);
365 	}
366 
367 	switch (class) {
368 	case CKO_PUBLIC_KEY:
369 		if ((rv = crypto_get_key_attr(key, CKA_EC_POINT, &foo,
370 		    &point_len)) != CRYPTO_SUCCESS) {
371 			return (CRYPTO_TEMPLATE_INCOMPLETE);
372 		}
373 		if (point_len < CRYPTO_BITS2BYTES(EC_MIN_KEY_LEN) * 2 + 1 ||
374 		    point_len > CRYPTO_BITS2BYTES(EC_MAX_KEY_LEN) * 2 + 1)
375 			return (CRYPTO_KEY_SIZE_RANGE);
376 		break;
377 
378 	case CKO_PRIVATE_KEY:
379 		if ((rv = crypto_get_key_attr(key, CKA_VALUE, &foo,
380 		    &value_len)) != CRYPTO_SUCCESS) {
381 			return (CRYPTO_TEMPLATE_INCOMPLETE);
382 		}
383 		if (value_len < CRYPTO_BITS2BYTES(EC_MIN_KEY_LEN) ||
384 		    value_len > CRYPTO_BITS2BYTES(EC_MAX_KEY_LEN))
385 			return (CRYPTO_KEY_SIZE_RANGE);
386 		break;
387 
388 	default:
389 		return (CRYPTO_TEMPLATE_INCONSISTENT);
390 	}
391 
392 	return (rv);
393 }
394 
395 /*
396  * This function guarantees to return non-zero random numbers.
397  * This is needed as the /dev/urandom kernel interface,
398  * random_get_pseudo_bytes(), may return zeros.
399  */
400 int
401 ecc_knzero_random_generator(uint8_t *ran_out, size_t ran_len)
402 {
403 	int rv;
404 	size_t ebc = 0; /* count of extra bytes in extrarand */
405 	size_t i = 0;
406 	uint8_t extrarand[32];
407 	size_t extrarand_len;
408 
409 	if ((rv = random_get_pseudo_bytes_fips140(ran_out, ran_len)) != 0)
410 		return (rv);
411 
412 	/*
413 	 * Walk through the returned random numbers pointed by ran_out,
414 	 * and look for any random number which is zero.
415 	 * If we find zero, call random_get_pseudo_bytes() to generate
416 	 * another 32 random numbers pool. Replace any zeros in ran_out[]
417 	 * from the random number in pool.
418 	 */
419 	while (i < ran_len) {
420 		if (ran_out[i] != 0) {
421 			i++;
422 			continue;
423 		}
424 
425 		/*
426 		 * Note that it is 'while' so we are guaranteed a
427 		 * non-zero value on exit.
428 		 */
429 		if (ebc == 0) {
430 			/* refresh extrarand */
431 			extrarand_len = sizeof (extrarand);
432 			if ((rv = random_get_pseudo_bytes_fips140(extrarand,
433 			    extrarand_len)) != 0) {
434 				return (rv);
435 			}
436 
437 			ebc = extrarand_len;
438 		}
439 		/* Replace zero with byte from extrarand. */
440 		-- ebc;
441 
442 		/*
443 		 * The new random byte zero/non-zero will be checked in
444 		 * the next pass through the loop.
445 		 */
446 		ran_out[i] = extrarand[ebc];
447 	}
448 
449 	return (CRYPTO_SUCCESS);
450 }
451 
452 static void
453 ecc_free_context(crypto_ctx_t *ctx)
454 {
455 	ecc_ctx_t *ctxp = ctx->cc_provider_private;
456 
457 	if (ctxp != NULL) {
458 		bzero(ctxp->key, ctxp->keychunk_size);
459 		kmem_free(ctxp->key, ctxp->keychunk_size);
460 
461 		free_ecparams(&ctxp->ecparams, B_FALSE);
462 
463 		if (ctxp->mech_type == ECDSA_MECH_INFO_TYPE)
464 			kmem_free(ctxp, sizeof (ecc_ctx_t));
465 		else
466 			kmem_free(ctxp, sizeof (digest_ecc_ctx_t));
467 
468 		ctx->cc_provider_private = NULL;
469 	}
470 }
471 
472 /* ARGSUSED */
473 static int
474 ecc_sign_verify_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
475     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
476     crypto_req_handle_t req)
477 {
478 	int rv;
479 	int kmflag;
480 	ecc_ctx_t *ctxp;
481 	digest_ecc_ctx_t *dctxp;
482 	ecc_mech_type_t mech_type = mechanism->cm_type;
483 	uchar_t *params;
484 	ssize_t params_len;
485 	ECParams  *ecparams;
486 	SECKEYECParams params_item;
487 
488 	if (crypto_get_key_attr(key, CKA_EC_PARAMS, (void *) &params,
489 	    &params_len)) {
490 		return (CRYPTO_ARGUMENTS_BAD);
491 	}
492 
493 	/* ASN1 check */
494 	if (params[0] != 0x06 ||
495 	    params[1] != params_len - 2) {
496 		return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
497 	}
498 	params_item.data = params;
499 	params_item.len = (uint_t)params_len;
500 	kmflag = crypto_kmflag(req);
501 	if (EC_DecodeParams(&params_item, &ecparams, kmflag) != SECSuccess) {
502 		/* bad curve OID */
503 		return (CRYPTO_ARGUMENTS_BAD);
504 	}
505 
506 	/*
507 	 * Allocate an ECC context.
508 	 */
509 	switch (mech_type) {
510 	case ECDSA_SHA1_MECH_INFO_TYPE:
511 		dctxp = kmem_zalloc(sizeof (digest_ecc_ctx_t), kmflag);
512 		ctxp = (ecc_ctx_t *)dctxp;
513 		break;
514 	default:
515 		ctxp = kmem_zalloc(sizeof (ecc_ctx_t), kmflag);
516 		break;
517 	}
518 
519 	if (ctxp == NULL) {
520 		free_ecparams(ecparams, B_TRUE);
521 		return (CRYPTO_HOST_MEMORY);
522 	}
523 
524 	if ((rv = crypto_copy_key_to_ctx(key, &ctxp->key, &ctxp->keychunk_size,
525 	    kmflag)) != CRYPTO_SUCCESS) {
526 		switch (mech_type) {
527 		case ECDSA_SHA1_MECH_INFO_TYPE:
528 			kmem_free(dctxp, sizeof (digest_ecc_ctx_t));
529 			break;
530 		default:
531 			kmem_free(ctxp, sizeof (ecc_ctx_t));
532 			break;
533 		}
534 		free_ecparams(ecparams, B_TRUE);
535 		return (rv);
536 	}
537 	ctxp->mech_type = mech_type;
538 	ctxp->ecparams = *ecparams;
539 	kmem_free(ecparams, sizeof (ECParams));
540 
541 	switch (mech_type) {
542 	case ECDSA_SHA1_MECH_INFO_TYPE:
543 		SHA1Init(&(dctxp->sha1_ctx));
544 		break;
545 	}
546 
547 	ctx->cc_provider_private = ctxp;
548 
549 	return (CRYPTO_SUCCESS);
550 }
551 
552 /* ARGSUSED */
553 static int
554 ecc_sign_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
555     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
556     crypto_req_handle_t req)
557 {
558 	int rv;
559 
560 	ecc_mech_type_t mech_type = mechanism->cm_type;
561 
562 	if ((rv = check_mech_and_key(mech_type, key,
563 	    CKO_PRIVATE_KEY)) != CRYPTO_SUCCESS)
564 		return (rv);
565 
566 	rv = ecc_sign_verify_common_init(ctx, mechanism, key,
567 	    ctx_template, req);
568 
569 	return (rv);
570 }
571 
572 /* ARGSUSED */
573 static int
574 ecc_verify_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
575     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
576     crypto_req_handle_t req)
577 {
578 	int rv;
579 
580 	ecc_mech_type_t mech_type = mechanism->cm_type;
581 
582 	if ((rv = check_mech_and_key(mech_type, key,
583 	    CKO_PUBLIC_KEY)) != CRYPTO_SUCCESS)
584 		return (rv);
585 
586 	rv = ecc_sign_verify_common_init(ctx, mechanism, key,
587 	    ctx_template, req);
588 
589 	return (rv);
590 }
591 
592 #define	SHA1_DIGEST_SIZE 20
593 
594 #define	INIT_RAW_CRYPTO_DATA(data, base, len, cd_len)	\
595 	(data).cd_format = CRYPTO_DATA_RAW;		\
596 	(data).cd_offset = 0;				\
597 	(data).cd_raw.iov_base = (char *)base;		\
598 	(data).cd_raw.iov_len = len;			\
599 	(data).cd_length = cd_len;
600 
601 static int
602 ecc_digest_svrfy_common(digest_ecc_ctx_t *ctxp, crypto_data_t *data,
603     crypto_data_t *signature, uchar_t flag, crypto_req_handle_t req)
604 {
605 	int rv = CRYPTO_FAILED;
606 	uchar_t digest[SHA1_DIGEST_LENGTH];
607 	crypto_data_t der_cd;
608 	ecc_mech_type_t mech_type;
609 
610 	ASSERT(flag & CRYPTO_DO_SIGN || flag & CRYPTO_DO_VERIFY);
611 	ASSERT(data != NULL || (flag & CRYPTO_DO_FINAL));
612 
613 	mech_type = ctxp->mech_type;
614 	if (mech_type != ECDSA_SHA1_MECH_INFO_TYPE)
615 		return (CRYPTO_MECHANISM_INVALID);
616 
617 	/* Don't digest if only returning length of signature. */
618 	if (signature->cd_length > 0) {
619 		if (mech_type == ECDSA_SHA1_MECH_INFO_TYPE) {
620 			rv = crypto_digest_data(data, &(ctxp->sha1_ctx),
621 			    digest, (void (*)())SHA1Update,
622 			    (void (*)())SHA1Final, flag | CRYPTO_DO_SHA1);
623 			if (rv != CRYPTO_SUCCESS)
624 				return (rv);
625 		}
626 	}
627 
628 	INIT_RAW_CRYPTO_DATA(der_cd, digest, SHA1_DIGEST_SIZE,
629 	    SHA1_DIGEST_SIZE);
630 
631 	if (flag & CRYPTO_DO_SIGN) {
632 		rv = ecc_sign_common((ecc_ctx_t *)ctxp, &der_cd, signature,
633 		    req);
634 	} else
635 		rv = ecc_verify_common((ecc_ctx_t *)ctxp, &der_cd, signature,
636 		    req);
637 
638 	return (rv);
639 }
640 
641 /*
642  * This is a single-part signing routine. It does not
643  * compute a hash before signing.
644  */
645 static int
646 ecc_sign_common(ecc_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
647     crypto_req_handle_t req)
648 {
649 	int rv = CRYPTO_FAILED;
650 	SECStatus ss;
651 	uchar_t *param;
652 	uchar_t *private;
653 	ssize_t param_len;
654 	ssize_t private_len;
655 	uchar_t tmp_data[EC_MAX_DIGEST_LEN];
656 	uchar_t signed_data[EC_MAX_SIG_LEN];
657 	ECPrivateKey ECkey;
658 	SECItem signature_item;
659 	SECItem digest_item;
660 	crypto_key_t *key = ctx->key;
661 	int kmflag;
662 
663 	if ((rv = crypto_get_key_attr(key, CKA_EC_PARAMS, &param,
664 	    &param_len)) != CRYPTO_SUCCESS) {
665 		return (rv);
666 	}
667 
668 	if (data->cd_length > sizeof (tmp_data))
669 		return (CRYPTO_DATA_LEN_RANGE);
670 
671 	if ((rv = crypto_get_input_data(data, &digest_item.data, tmp_data))
672 	    != CRYPTO_SUCCESS) {
673 		return (rv);
674 	}
675 	digest_item.len = data->cd_length;
676 
677 	/* structure assignment */
678 	ECkey.ecParams = ctx->ecparams;
679 
680 	if ((rv = crypto_get_key_attr(key, CKA_VALUE, &private,
681 	    &private_len)) != CRYPTO_SUCCESS) {
682 		return (rv);
683 	}
684 	ECkey.privateValue.data = private;
685 	ECkey.privateValue.len = (uint_t)private_len;
686 
687 	signature_item.data = signed_data;
688 	signature_item.len = sizeof (signed_data);
689 
690 	kmflag = crypto_kmflag(req);
691 	if ((ss = ECDSA_SignDigest(&ECkey, &signature_item, &digest_item,
692 	    kmflag)) != SECSuccess) {
693 		if (ss == SECBufferTooSmall)
694 			return (CRYPTO_BUFFER_TOO_SMALL);
695 
696 		return (CRYPTO_FAILED);
697 	}
698 
699 	if (rv == CRYPTO_SUCCESS) {
700 		/* copy out the signature */
701 		if ((rv = crypto_put_output_data(signed_data,
702 		    signature, signature_item.len)) != CRYPTO_SUCCESS)
703 			return (rv);
704 
705 		signature->cd_length = signature_item.len;
706 	}
707 
708 	return (rv);
709 }
710 
711 /* ARGSUSED */
712 static int
713 ecc_sign(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
714     crypto_req_handle_t req)
715 {
716 	int rv;
717 	ecc_ctx_t *ctxp;
718 
719 	ASSERT(ctx->cc_provider_private != NULL);
720 	ctxp = ctx->cc_provider_private;
721 
722 	switch (ctxp->mech_type) {
723 	case ECDSA_SHA1_MECH_INFO_TYPE:
724 		rv = ecc_digest_svrfy_common((digest_ecc_ctx_t *)ctxp, data,
725 		    signature, CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE |
726 		    CRYPTO_DO_FINAL, req);
727 		break;
728 	default:
729 		rv = ecc_sign_common(ctxp, data, signature, req);
730 		break;
731 	}
732 
733 	if (rv != CRYPTO_BUFFER_TOO_SMALL)
734 		ecc_free_context(ctx);
735 
736 	return (rv);
737 }
738 
739 /* ARGSUSED */
740 static int
741 ecc_sign_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req)
742 {
743 	int rv;
744 	digest_ecc_ctx_t *ctxp;
745 	ecc_mech_type_t mech_type;
746 
747 	ASSERT(ctx->cc_provider_private != NULL);
748 	ctxp = ctx->cc_provider_private;
749 	mech_type = ctxp->mech_type;
750 
751 	if (mech_type == ECDSA_MECH_INFO_TYPE) {
752 		ecc_free_context(ctx);
753 		return (CRYPTO_MECHANISM_INVALID);
754 	}
755 
756 	if (mech_type == ECDSA_SHA1_MECH_INFO_TYPE)
757 		rv = crypto_digest_data(data, &(ctxp->sha1_ctx), NULL,
758 		    (void (*)())SHA1Update, (void (*)())SHA1Final,
759 		    CRYPTO_DO_SHA1 | CRYPTO_DO_UPDATE);
760 
761 	if (rv != CRYPTO_SUCCESS)
762 		ecc_free_context(ctx);
763 
764 	return (rv);
765 }
766 
767 /* ARGSUSED */
768 static int
769 ecc_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature,
770     crypto_req_handle_t req)
771 {
772 	int rv;
773 	digest_ecc_ctx_t *ctxp;
774 
775 	ASSERT(ctx->cc_provider_private != NULL);
776 	ctxp = ctx->cc_provider_private;
777 
778 	rv = ecc_digest_svrfy_common(ctxp, NULL, signature, CRYPTO_DO_SIGN |
779 	    CRYPTO_DO_FINAL, req);
780 	if (rv != CRYPTO_BUFFER_TOO_SMALL)
781 		ecc_free_context(ctx);
782 
783 	return (rv);
784 }
785 
786 /* ARGSUSED */
787 static int
788 ecc_sign_atomic(crypto_provider_handle_t provider,
789     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
790     crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
791     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
792 {
793 	int rv;
794 	ecc_mech_type_t mech_type = mechanism->cm_type;
795 	uchar_t *params;
796 	ssize_t params_len;
797 	ECParams  *ecparams;
798 	SECKEYECParams params_item;
799 	int kmflag;
800 
801 	if ((rv = check_mech_and_key(mech_type, key,
802 	    CKO_PRIVATE_KEY)) != CRYPTO_SUCCESS)
803 		return (rv);
804 
805 	if (crypto_get_key_attr(key, CKA_EC_PARAMS, (void *) &params,
806 	    &params_len)) {
807 		return (CRYPTO_ARGUMENTS_BAD);
808 	}
809 
810 	/* ASN1 check */
811 	if (params[0] != 0x06 ||
812 	    params[1] != params_len - 2) {
813 		return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
814 	}
815 	params_item.data = params;
816 	params_item.len = (uint_t)params_len;
817 	kmflag = crypto_kmflag(req);
818 	if (EC_DecodeParams(&params_item, &ecparams, kmflag) != SECSuccess) {
819 		/* bad curve OID */
820 		return (CRYPTO_ARGUMENTS_BAD);
821 	}
822 
823 	if (mechanism->cm_type == ECDSA_MECH_INFO_TYPE) {
824 		ecc_ctx_t ctx;
825 
826 		ctx.mech_type = mech_type;
827 		/* structure assignment */
828 		ctx.ecparams = *ecparams;
829 		ctx.key = key;
830 		rv = ecc_sign_common(&ctx, data, signature, req);
831 	} else {
832 		digest_ecc_ctx_t dctx;
833 
834 		dctx.mech_type = mech_type;
835 		/* structure assignment */
836 		dctx.ecparams = *ecparams;
837 		dctx.key = key;
838 		SHA1Init(&(dctx.sha1_ctx));
839 
840 		rv = ecc_digest_svrfy_common(&dctx, data, signature,
841 		    CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE | CRYPTO_DO_FINAL, req);
842 	}
843 	free_ecparams(ecparams, B_TRUE);
844 
845 	return (rv);
846 }
847 
848 static int
849 ecc_verify_common(ecc_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
850     crypto_req_handle_t req)
851 {
852 	int rv = CRYPTO_FAILED;
853 	uchar_t *param;
854 	uchar_t *public;
855 	ssize_t param_len;
856 	ssize_t public_len;
857 	uchar_t tmp_data[EC_MAX_DIGEST_LEN];
858 	uchar_t signed_data[EC_MAX_SIG_LEN];
859 	ECPublicKey ECkey;
860 	SECItem signature_item;
861 	SECItem digest_item;
862 	crypto_key_t *key = ctx->key;
863 	int kmflag;
864 
865 	if ((rv = crypto_get_key_attr(key, CKA_EC_PARAMS, &param,
866 	    &param_len)) != CRYPTO_SUCCESS) {
867 		return (rv);
868 	}
869 
870 	if (signature->cd_length > sizeof (signed_data)) {
871 		return (CRYPTO_SIGNATURE_LEN_RANGE);
872 	}
873 
874 	if ((rv = crypto_get_input_data(signature, &signature_item.data,
875 	    signed_data)) != CRYPTO_SUCCESS) {
876 		return (rv);
877 	}
878 	signature_item.len = signature->cd_length;
879 
880 	if (data->cd_length > sizeof (tmp_data))
881 		return (CRYPTO_DATA_LEN_RANGE);
882 
883 	if ((rv = crypto_get_input_data(data, &digest_item.data, tmp_data))
884 	    != CRYPTO_SUCCESS) {
885 		return (rv);
886 	}
887 	digest_item.len = data->cd_length;
888 
889 	/* structure assignment */
890 	ECkey.ecParams = ctx->ecparams;
891 
892 	if ((rv = crypto_get_key_attr(key, CKA_EC_POINT, &public,
893 	    &public_len)) != CRYPTO_SUCCESS) {
894 		return (rv);
895 	}
896 	ECkey.publicValue.data = public;
897 	ECkey.publicValue.len = (uint_t)public_len;
898 
899 	kmflag = crypto_kmflag(req);
900 	if (ECDSA_VerifyDigest(&ECkey, &signature_item, &digest_item, kmflag)
901 	    != SECSuccess) {
902 		rv = CRYPTO_SIGNATURE_INVALID;
903 	} else {
904 		rv = CRYPTO_SUCCESS;
905 	}
906 
907 	return (rv);
908 }
909 
910 /* ARGSUSED */
911 static int
912 ecc_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
913     crypto_req_handle_t req)
914 {
915 	int rv;
916 	ecc_ctx_t *ctxp;
917 
918 	ASSERT(ctx->cc_provider_private != NULL);
919 	ctxp = ctx->cc_provider_private;
920 
921 	switch (ctxp->mech_type) {
922 	case ECDSA_SHA1_MECH_INFO_TYPE:
923 		rv = ecc_digest_svrfy_common((digest_ecc_ctx_t *)ctxp, data,
924 		    signature, CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE |
925 		    CRYPTO_DO_FINAL, req);
926 		break;
927 	default:
928 		rv = ecc_verify_common(ctxp, data, signature, req);
929 		break;
930 	}
931 
932 	ecc_free_context(ctx);
933 	return (rv);
934 }
935 
936 /* ARGSUSED */
937 static int
938 ecc_verify_update(crypto_ctx_t *ctx, crypto_data_t *data,
939     crypto_req_handle_t req)
940 {
941 	int rv;
942 	digest_ecc_ctx_t *ctxp;
943 
944 	ASSERT(ctx->cc_provider_private != NULL);
945 	ctxp = ctx->cc_provider_private;
946 
947 	switch (ctxp->mech_type) {
948 	case ECDSA_SHA1_MECH_INFO_TYPE:
949 		rv = crypto_digest_data(data, &(ctxp->sha1_ctx), NULL,
950 		    (void (*)())SHA1Update, (void (*)())SHA1Final,
951 		    CRYPTO_DO_SHA1 | CRYPTO_DO_UPDATE);
952 		break;
953 	default:
954 		rv = CRYPTO_MECHANISM_INVALID;
955 	}
956 
957 	if (rv != CRYPTO_SUCCESS)
958 		ecc_free_context(ctx);
959 
960 	return (rv);
961 }
962 
963 /* ARGSUSED */
964 static int
965 ecc_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature,
966     crypto_req_handle_t req)
967 {
968 	int rv;
969 	digest_ecc_ctx_t *ctxp;
970 
971 	ASSERT(ctx->cc_provider_private != NULL);
972 	ctxp = ctx->cc_provider_private;
973 
974 	rv = ecc_digest_svrfy_common(ctxp, NULL, signature,
975 	    CRYPTO_DO_VERIFY | CRYPTO_DO_FINAL, req);
976 
977 	ecc_free_context(ctx);
978 
979 	return (rv);
980 }
981 
982 
983 /* ARGSUSED */
984 static int
985 ecc_verify_atomic(crypto_provider_handle_t provider,
986     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
987     crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
988     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
989 {
990 	int rv;
991 	ecc_mech_type_t mech_type = mechanism->cm_type;
992 	uchar_t *params;
993 	ssize_t params_len;
994 	ECParams  *ecparams;
995 	SECKEYECParams params_item;
996 	int kmflag;
997 
998 	if ((rv = check_mech_and_key(mech_type, key,
999 	    CKO_PUBLIC_KEY)) != CRYPTO_SUCCESS)
1000 		return (rv);
1001 
1002 	if (crypto_get_key_attr(key, CKA_EC_PARAMS, (void *) &params,
1003 	    &params_len)) {
1004 		return (CRYPTO_ARGUMENTS_BAD);
1005 	}
1006 
1007 	/* ASN1 check */
1008 	if (params[0] != 0x06 ||
1009 	    params[1] != params_len - 2) {
1010 		return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
1011 	}
1012 	params_item.data = params;
1013 	params_item.len = (uint_t)params_len;
1014 	kmflag = crypto_kmflag(req);
1015 	if (EC_DecodeParams(&params_item, &ecparams, kmflag) != SECSuccess) {
1016 		/* bad curve OID */
1017 		return (CRYPTO_ARGUMENTS_BAD);
1018 	}
1019 
1020 	if (mechanism->cm_type == ECDSA_MECH_INFO_TYPE) {
1021 		ecc_ctx_t ctx;
1022 
1023 		ctx.mech_type = mech_type;
1024 		/* structure assignment */
1025 		ctx.ecparams = *ecparams;
1026 		ctx.key = key;
1027 		rv = ecc_verify_common(&ctx, data, signature, req);
1028 	} else {
1029 		digest_ecc_ctx_t dctx;
1030 
1031 		dctx.mech_type = mech_type;
1032 		/* structure assignment */
1033 		dctx.ecparams = *ecparams;
1034 		dctx.key = key;
1035 		SHA1Init(&(dctx.sha1_ctx));
1036 
1037 		rv = ecc_digest_svrfy_common(&dctx, data, signature,
1038 		    CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE | CRYPTO_DO_FINAL, req);
1039 	}
1040 	free_ecparams(ecparams, B_TRUE);
1041 	return (rv);
1042 }
1043 
1044 /* ARGSUSED */
1045 static int
1046 ecc_nostore_key_generate_pair(crypto_provider_handle_t provider,
1047     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
1048     crypto_object_attribute_t *pub_template, uint_t pub_attribute_count,
1049     crypto_object_attribute_t *pri_template, uint_t pri_attribute_count,
1050     crypto_object_attribute_t *pub_out_template, uint_t pub_out_attribute_count,
1051     crypto_object_attribute_t *pri_out_template, uint_t pri_out_attribute_count,
1052     crypto_req_handle_t req)
1053 {
1054 	int rv = CRYPTO_SUCCESS;
1055 	ECPrivateKey *privKey;	/* contains both public and private values */
1056 	ECParams *ecparams;
1057 	SECKEYECParams params_item;
1058 	ulong_t pub_key_type = ~0UL, pub_class = ~0UL;
1059 	ulong_t pri_key_type = ~0UL, pri_class = ~0UL;
1060 	int params_idx, value_idx, point_idx;
1061 	uchar_t *params = NULL;
1062 	unsigned params_len;
1063 	uchar_t *value = NULL;
1064 	uchar_t *point = NULL;
1065 	int valuelen;
1066 	int pointlen;
1067 	int xylen;
1068 	int kmflag;
1069 
1070 	if (mechanism->cm_type != EC_KEY_PAIR_GEN_MECH_INFO_TYPE) {
1071 		return (CRYPTO_MECHANISM_INVALID);
1072 	}
1073 
1074 	/* optional */
1075 	(void) get_template_attr_ulong(pub_template,
1076 	    pub_attribute_count, CKA_CLASS, &pub_class);
1077 
1078 	/* optional */
1079 	(void) get_template_attr_ulong(pri_template,
1080 	    pri_attribute_count, CKA_CLASS, &pri_class);
1081 
1082 	/* optional */
1083 	(void) get_template_attr_ulong(pub_template,
1084 	    pub_attribute_count, CKA_KEY_TYPE, &pub_key_type);
1085 
1086 	/* optional */
1087 	(void) get_template_attr_ulong(pri_template,
1088 	    pri_attribute_count, CKA_KEY_TYPE, &pri_key_type);
1089 
1090 	if (pub_class != ~0UL && pub_class != CKO_PUBLIC_KEY) {
1091 		return (CRYPTO_TEMPLATE_INCONSISTENT);
1092 	}
1093 	pub_class = CKO_PUBLIC_KEY;
1094 
1095 	if (pri_class != ~0UL && pri_class != CKO_PRIVATE_KEY) {
1096 		return (CRYPTO_TEMPLATE_INCONSISTENT);
1097 	}
1098 	pri_class = CKO_PRIVATE_KEY;
1099 
1100 	if (pub_key_type != ~0UL && pub_key_type != CKK_EC) {
1101 		return (CRYPTO_TEMPLATE_INCONSISTENT);
1102 	}
1103 	pub_key_type = CKK_EC;
1104 
1105 	if (pri_key_type != ~0UL && pri_key_type != CKK_EC) {
1106 		return (CRYPTO_TEMPLATE_INCONSISTENT);
1107 	}
1108 	pri_key_type = CKK_EC;
1109 
1110 	/* public output template must contain CKA_EC_POINT attribute */
1111 	if ((point_idx = find_attr(pub_out_template, pub_out_attribute_count,
1112 	    CKA_EC_POINT)) == -1) {
1113 		return (CRYPTO_TEMPLATE_INCOMPLETE);
1114 	}
1115 
1116 	/* private output template must contain CKA_VALUE attribute */
1117 	if ((value_idx = find_attr(pri_out_template, pri_out_attribute_count,
1118 	    CKA_VALUE)) == -1) {
1119 		return (CRYPTO_TEMPLATE_INCOMPLETE);
1120 	}
1121 
1122 	if ((params_idx = find_attr(pub_template, pub_attribute_count,
1123 	    CKA_EC_PARAMS)) == -1) {
1124 		return (CRYPTO_TEMPLATE_INCOMPLETE);
1125 	}
1126 
1127 	params = (uchar_t *)pub_template[params_idx].oa_value;
1128 	params_len = pub_template[params_idx].oa_value_len;
1129 
1130 	value = (uchar_t *)pri_out_template[value_idx].oa_value;
1131 	valuelen = (int)pri_out_template[value_idx].oa_value_len;
1132 	point = (uchar_t *)pub_out_template[point_idx].oa_value;
1133 	pointlen = (int)pub_out_template[point_idx].oa_value_len;
1134 
1135 	/* ASN1 check */
1136 	if (params[0] != 0x06 ||
1137 	    params[1] != params_len - 2) {
1138 		return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
1139 	}
1140 	params_item.data = params;
1141 	params_item.len = params_len;
1142 	kmflag = crypto_kmflag(req);
1143 	if (EC_DecodeParams(&params_item, &ecparams, kmflag) != SECSuccess) {
1144 		/* bad curve OID */
1145 		return (CRYPTO_ARGUMENTS_BAD);
1146 	}
1147 
1148 	if (EC_NewKey(ecparams, &privKey, kmflag) != SECSuccess) {
1149 		free_ecparams(ecparams, B_TRUE);
1150 		return (CRYPTO_FAILED);
1151 	}
1152 
1153 	xylen = privKey->publicValue.len;
1154 	/* ASSERT that xylen - 1 is divisible by 2 */
1155 	if (xylen > pointlen) {
1156 		rv = CRYPTO_BUFFER_TOO_SMALL;
1157 		goto out;
1158 	}
1159 
1160 	if (privKey->privateValue.len > valuelen) {
1161 		rv = CRYPTO_BUFFER_TOO_SMALL;
1162 		goto out;
1163 	}
1164 	bcopy(privKey->privateValue.data, value, privKey->privateValue.len);
1165 	pri_out_template[value_idx].oa_value_len = privKey->privateValue.len;
1166 
1167 	bcopy(privKey->publicValue.data, point, xylen);
1168 	pub_out_template[point_idx].oa_value_len = xylen;
1169 
1170 	if (kcf_get_fips140_mode() == FIPS140_MODE_ENABLED) {
1171 		/* Pair-wise consistency test */
1172 		if ((rv = fips_pairwise_check(privKey)) != CRYPTO_SUCCESS)
1173 			cmn_err(CE_WARN, "ecc: fips_pairwise_check() "
1174 			    "failed (0x%x).", rv);
1175 	}
1176 
1177 out:
1178 	free_ecprivkey(privKey);
1179 	free_ecparams(ecparams, B_TRUE);
1180 	return (rv);
1181 }
1182 
1183 /* ARGSUSED */
1184 static int
1185 ecc_nostore_key_derive(crypto_provider_handle_t provider,
1186     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
1187     crypto_key_t *base_key, crypto_object_attribute_t *in_attrs,
1188     uint_t in_attr_count, crypto_object_attribute_t *out_attrs,
1189     uint_t out_attr_count, crypto_req_handle_t req)
1190 {
1191 	int rv = CRYPTO_SUCCESS;
1192 	int params_idx, value_idx = -1, out_value_idx = -1;
1193 	ulong_t key_type;
1194 	ulong_t key_len;
1195 	crypto_object_attribute_t *attrs;
1196 	ECParams *ecparams;
1197 	SECKEYECParams params_item;
1198 	CK_ECDH1_DERIVE_PARAMS *mech_param;
1199 	SECItem public_value_item, private_value_item, secret_item;
1200 	int kmflag;
1201 
1202 	if (mechanism->cm_type != ECDH1_DERIVE_MECH_INFO_TYPE) {
1203 		return (CRYPTO_MECHANISM_INVALID);
1204 	}
1205 
1206 	ASSERT(IS_P2ALIGNED(mechanism->cm_param, sizeof (uint64_t)));
1207 	/* LINTED: pointer alignment */
1208 	mech_param = (CK_ECDH1_DERIVE_PARAMS *)mechanism->cm_param;
1209 	if (mech_param->kdf != CKD_NULL) {
1210 		return (CRYPTO_MECHANISM_PARAM_INVALID);
1211 	}
1212 
1213 	if ((base_key->ck_format != CRYPTO_KEY_ATTR_LIST) ||
1214 	    (base_key->ck_count == 0)) {
1215 		return (CRYPTO_ARGUMENTS_BAD);
1216 	}
1217 
1218 	if ((rv = get_template_attr_ulong(in_attrs, in_attr_count,
1219 	    CKA_KEY_TYPE, &key_type)) != CRYPTO_SUCCESS) {
1220 		return (rv);
1221 	}
1222 
1223 	switch (key_type) {
1224 	case CKK_DES:
1225 		key_len = DES_KEYSIZE;
1226 		break;
1227 	case CKK_DES2:
1228 		key_len = DES2_KEYSIZE;
1229 		break;
1230 	case CKK_DES3:
1231 		key_len = DES3_KEYSIZE;
1232 		break;
1233 	case CKK_RC4:
1234 	case CKK_AES:
1235 	case CKK_GENERIC_SECRET:
1236 		if ((rv = get_template_attr_ulong(in_attrs, in_attr_count,
1237 		    CKA_VALUE_LEN, &key_len)) != CRYPTO_SUCCESS) {
1238 			return (rv);
1239 		}
1240 		break;
1241 	default:
1242 		key_len = 0;
1243 	}
1244 
1245 	attrs = base_key->ck_attrs;
1246 	if ((value_idx = find_attr(attrs, base_key->ck_count,
1247 	    CKA_VALUE)) == -1) {
1248 		return (CRYPTO_TEMPLATE_INCOMPLETE);
1249 	}
1250 
1251 	if ((params_idx = find_attr(attrs, base_key->ck_count,
1252 	    CKA_EC_PARAMS)) == -1) {
1253 		return (CRYPTO_TEMPLATE_INCOMPLETE);
1254 	}
1255 
1256 	private_value_item.data = (uchar_t *)attrs[value_idx].oa_value;
1257 	private_value_item.len = attrs[value_idx].oa_value_len;
1258 
1259 	params_item.len = attrs[params_idx].oa_value_len;
1260 	params_item.data = (uchar_t *)attrs[params_idx].oa_value;
1261 
1262 	/* ASN1 check */
1263 	if (params_item.data[0] != 0x06 ||
1264 	    params_item.data[1] != params_item.len - 2) {
1265 		return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
1266 	}
1267 	kmflag = crypto_kmflag(req);
1268 	if (EC_DecodeParams(&params_item, &ecparams, kmflag) != SECSuccess) {
1269 		/* bad curve OID */
1270 		return (CRYPTO_ARGUMENTS_BAD);
1271 	}
1272 
1273 	public_value_item.data = (uchar_t *)mech_param->pPublicData;
1274 	public_value_item.len = mech_param->ulPublicDataLen;
1275 
1276 	if ((out_value_idx = find_attr(out_attrs, out_attr_count,
1277 	    CKA_VALUE)) == -1) {
1278 		rv = CRYPTO_TEMPLATE_INCOMPLETE;
1279 		goto out;
1280 	}
1281 	secret_item.data = NULL;
1282 	secret_item.len = 0;
1283 
1284 	if (ECDH_Derive(&public_value_item, ecparams, &private_value_item,
1285 	    B_FALSE, &secret_item, kmflag) != SECSuccess) {
1286 		free_ecparams(ecparams, B_TRUE);
1287 		return (CRYPTO_FAILED);
1288 	} else {
1289 		rv = CRYPTO_SUCCESS;
1290 	}
1291 
1292 	if (key_len == 0)
1293 		key_len = secret_item.len;
1294 
1295 	if (key_len > secret_item.len) {
1296 		rv = CRYPTO_ATTRIBUTE_VALUE_INVALID;
1297 		goto out;
1298 	}
1299 	if (key_len > out_attrs[out_value_idx].oa_value_len) {
1300 		rv = CRYPTO_BUFFER_TOO_SMALL;
1301 		goto out;
1302 	}
1303 	bcopy(secret_item.data + secret_item.len - key_len,
1304 	    (uchar_t *)out_attrs[out_value_idx].oa_value, key_len);
1305 	out_attrs[out_value_idx].oa_value_len = key_len;
1306 out:
1307 	free_ecparams(ecparams, B_TRUE);
1308 	SECITEM_FreeItem(&secret_item, B_FALSE);
1309 	return (rv);
1310 }
1311 
1312 static void
1313 free_ecparams(ECParams *params, boolean_t freeit)
1314 {
1315 	SECITEM_FreeItem(&params->fieldID.u.prime, B_FALSE);
1316 	SECITEM_FreeItem(&params->curve.a, B_FALSE);
1317 	SECITEM_FreeItem(&params->curve.b, B_FALSE);
1318 	SECITEM_FreeItem(&params->curve.seed, B_FALSE);
1319 	SECITEM_FreeItem(&params->base, B_FALSE);
1320 	SECITEM_FreeItem(&params->order, B_FALSE);
1321 	SECITEM_FreeItem(&params->DEREncoding, B_FALSE);
1322 	SECITEM_FreeItem(&params->curveOID, B_FALSE);
1323 	if (freeit)
1324 		kmem_free(params, sizeof (ECParams));
1325 }
1326 
1327 static void
1328 free_ecprivkey(ECPrivateKey *key)
1329 {
1330 	free_ecparams(&key->ecParams, B_FALSE);
1331 	SECITEM_FreeItem(&key->publicValue, B_FALSE);
1332 	bzero(key->privateValue.data, key->privateValue.len);
1333 	SECITEM_FreeItem(&key->privateValue, B_FALSE);
1334 	SECITEM_FreeItem(&key->version, B_FALSE);
1335 	kmem_free(key, sizeof (ECPrivateKey));
1336 }
1337 
1338 /*
1339  * Pair-wise Consistency Test
1340  */
1341 static int
1342 fips_pairwise_check(ECPrivateKey *ecdsa_private_key)
1343 {
1344 
1345 	SECItem signature_item;
1346 	SECItem digest_item;
1347 	uchar_t signed_data[EC_MAX_SIG_LEN];
1348 	uchar_t sha1[SHA1_DIGEST_SIZE];
1349 	ECPublicKey ecdsa_public_key;
1350 	SHA1_CTX *sha1_context;
1351 	int rv;
1352 	static uint8_t msg[] = {
1353 		"OpenSolarisCommunity"
1354 	};
1355 
1356 	/* construct public key from private key. */
1357 	if ((EC_CopyParams(ecdsa_private_key->ecParams.arena,
1358 	    &ecdsa_public_key.ecParams, &ecdsa_private_key->ecParams))
1359 	    != SECSuccess)
1360 		return (CRYPTO_FAILED);
1361 
1362 	ecdsa_public_key.publicValue = ecdsa_private_key->publicValue;
1363 
1364 	if ((sha1_context = kmem_zalloc(sizeof (SHA1_CTX),
1365 	    KM_SLEEP)) == NULL)
1366 		return (CRYPTO_HOST_MEMORY);
1367 
1368 	SHA1Init(sha1_context);
1369 	SHA1Update(sha1_context, msg, SHA1_DIGEST_SIZE);
1370 	SHA1Final(sha1, sha1_context);
1371 
1372 	digest_item.data = sha1;
1373 	digest_item.len = SHA1_DIGEST_SIZE;
1374 	signature_item.data = signed_data;
1375 	signature_item.len = sizeof (signed_data);
1376 
1377 	if ((ECDSA_SignDigest(ecdsa_private_key, &signature_item,
1378 	    &digest_item, 0)) != SECSuccess) {
1379 		rv = CRYPTO_FAILED;
1380 		goto loser;
1381 	}
1382 
1383 	if (ECDSA_VerifyDigest(&ecdsa_public_key, &signature_item,
1384 	    &digest_item, 0) != SECSuccess) {
1385 		rv = CRYPTO_SIGNATURE_INVALID;
1386 	} else {
1387 		rv = CRYPTO_SUCCESS;
1388 	}
1389 
1390 loser:
1391 	kmem_free(sha1_context, sizeof (SHA1_CTX));
1392 	return (rv);
1393 
1394 }
1395 
1396 
1397 /*
1398  * ECC Power-Up Self-Test
1399  */
1400 void
1401 ecc_POST(int *rc)
1402 {
1403 
1404 	*rc = fips_ecdsa_post();
1405 
1406 }
1407