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.
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.
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]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
29 #include <sys/types.h>
30 #include <sys/systm.h>
31 #include <sys/param.h>
32 #include <sys/modctl.h>
34 #include <sys/crypto/spi.h>
35 #include <sys/crypto/impl.h>
36 #include <sys/crypto/ioctladmin.h>
37 #include <sys/sysmacros.h>
38 #include <sys/strsun.h>
40 #include <sys/random.h>
42 #include <sys/devops.h>
43 #include <sys/sunddi.h>
44 #include <sys/varargs.h>
46 #include <sys/kstat.h>
48 #include <des/des_impl.h>
49 #include <ecc/ecc_impl.h>
51 #define CKD_NULL 0x00000001
53 extern struct mod_ops mod_cryptoops
;
56 * Module linkage information for the kernel.
58 static struct modlcrypto modlcrypto
= {
60 "EC Kernel SW Provider"
63 static struct modlinkage modlinkage
= {
70 * CSPI information (entry points, provider info, etc.)
72 typedef enum ecc_mech_type
{
73 EC_KEY_PAIR_GEN_MECH_INFO_TYPE
, /* SUN_CKM_EC_KEY_PAIR_GEN */
74 ECDSA_MECH_INFO_TYPE
, /* SUN_CKM_ECDSA */
75 ECDSA_SHA1_MECH_INFO_TYPE
, /* SUN_CKM_ECDSA_SHA1 */
76 ECDH1_DERIVE_MECH_INFO_TYPE
/* SUN_CKM_ECDH1_DERIVE */
80 * Context for ECDSA mechanism.
82 typedef struct ecc_ctx
{
83 ecc_mech_type_t mech_type
;
90 * Context for ECDSA_SHA1 mechanism.
92 typedef struct digest_ecc_ctx
{
93 ecc_mech_type_t mech_type
;
102 #define sha1_ctx dctx_u.sha1ctx
105 * Mechanism info structure passed to KCF during registration.
107 static crypto_mech_info_t ecc_mech_info_tab
[] = {
108 /* EC_KEY_PAIR_GEN */
109 {SUN_CKM_EC_KEY_PAIR_GEN
, EC_KEY_PAIR_GEN_MECH_INFO_TYPE
,
110 CRYPTO_FG_GENERATE_KEY_PAIR
, EC_MIN_KEY_LEN
, EC_MAX_KEY_LEN
,
111 CRYPTO_KEYSIZE_UNIT_IN_BITS
},
113 {SUN_CKM_ECDH1_DERIVE
, ECDH1_DERIVE_MECH_INFO_TYPE
, CRYPTO_FG_DERIVE
,
114 EC_MIN_KEY_LEN
, EC_MAX_KEY_LEN
, CRYPTO_KEYSIZE_UNIT_IN_BITS
},
116 {SUN_CKM_ECDSA
, ECDSA_MECH_INFO_TYPE
,
117 CRYPTO_FG_SIGN
| CRYPTO_FG_VERIFY
|
118 CRYPTO_FG_SIGN_ATOMIC
| CRYPTO_FG_VERIFY_ATOMIC
,
119 EC_MIN_KEY_LEN
, EC_MAX_KEY_LEN
, CRYPTO_KEYSIZE_UNIT_IN_BITS
},
121 {SUN_CKM_ECDSA_SHA1
, ECDSA_SHA1_MECH_INFO_TYPE
,
122 CRYPTO_FG_SIGN
| CRYPTO_FG_VERIFY
|
123 CRYPTO_FG_SIGN_ATOMIC
| CRYPTO_FG_VERIFY_ATOMIC
,
124 EC_MIN_KEY_LEN
, EC_MAX_KEY_LEN
, CRYPTO_KEYSIZE_UNIT_IN_BITS
}
127 static void ecc_provider_status(crypto_provider_handle_t
, uint_t
*);
129 static crypto_control_ops_t ecc_control_ops
= {
133 static int ecc_sign_init(crypto_ctx_t
*, crypto_mechanism_t
*,
134 crypto_key_t
*, crypto_spi_ctx_template_t
, crypto_req_handle_t
);
135 static int ecc_sign(crypto_ctx_t
*, crypto_data_t
*, crypto_data_t
*,
136 crypto_req_handle_t
);
137 static int ecc_sign_update(crypto_ctx_t
*, crypto_data_t
*,
138 crypto_req_handle_t
);
139 static int ecc_sign_final(crypto_ctx_t
*, crypto_data_t
*,
140 crypto_req_handle_t
);
141 static int ecc_sign_atomic(crypto_provider_handle_t
, crypto_session_id_t
,
142 crypto_mechanism_t
*, crypto_key_t
*, crypto_data_t
*, crypto_data_t
*,
143 crypto_spi_ctx_template_t
, crypto_req_handle_t
);
145 static crypto_sign_ops_t ecc_sign_ops
= {
156 static int ecc_verify_init(crypto_ctx_t
*, crypto_mechanism_t
*,
157 crypto_key_t
*, crypto_spi_ctx_template_t
, crypto_req_handle_t
);
158 static int ecc_verify(crypto_ctx_t
*, crypto_data_t
*, crypto_data_t
*,
159 crypto_req_handle_t
);
160 static int ecc_verify_update(crypto_ctx_t
*, crypto_data_t
*,
161 crypto_req_handle_t
);
162 static int ecc_verify_final(crypto_ctx_t
*, crypto_data_t
*,
163 crypto_req_handle_t
);
164 static int ecc_verify_atomic(crypto_provider_handle_t
, crypto_session_id_t
,
165 crypto_mechanism_t
*, crypto_key_t
*, crypto_data_t
*,
166 crypto_data_t
*, crypto_spi_ctx_template_t
, crypto_req_handle_t
);
168 static crypto_verify_ops_t ecc_verify_ops
= {
179 static int ecc_nostore_key_generate_pair(crypto_provider_handle_t
,
180 crypto_session_id_t
, crypto_mechanism_t
*, crypto_object_attribute_t
*,
181 uint_t
, crypto_object_attribute_t
*, uint_t
, crypto_object_attribute_t
*,
182 uint_t
, crypto_object_attribute_t
*, uint_t
, crypto_req_handle_t
);
183 static int ecc_nostore_key_derive(crypto_provider_handle_t
,
184 crypto_session_id_t
, crypto_mechanism_t
*, crypto_key_t
*,
185 crypto_object_attribute_t
*, uint_t
, crypto_object_attribute_t
*,
186 uint_t
, crypto_req_handle_t
);
188 static crypto_nostore_key_ops_t ecc_nostore_key_ops
= {
190 ecc_nostore_key_generate_pair
,
191 ecc_nostore_key_derive
194 static crypto_ops_t ecc_crypto_ops
= {
210 &ecc_nostore_key_ops
,
214 static crypto_provider_info_t ecc_prov_info
= {
215 CRYPTO_SPI_VERSION_4
,
216 "EC Software Provider",
221 sizeof (ecc_mech_info_tab
)/sizeof (crypto_mech_info_t
),
225 static crypto_kcf_provider_handle_t ecc_prov_handle
= 0;
227 static int ecc_sign_common(ecc_ctx_t
*, crypto_data_t
*, crypto_data_t
*,
228 crypto_req_handle_t
);
229 static int ecc_verify_common(ecc_ctx_t
*, crypto_data_t
*, crypto_data_t
*,
230 crypto_req_handle_t
);
231 static int find_attr(crypto_object_attribute_t
*, uint_t
, uint64_t);
232 static int get_template_attr_ulong(crypto_object_attribute_t
*,
233 uint_t
, uint64_t, ulong_t
*);
234 static void ecc_free_context(crypto_ctx_t
*);
235 static void free_ecparams(ECParams
*, boolean_t
);
236 static void free_ecprivkey(ECPrivateKey
*);
243 if ((ret
= mod_install(&modlinkage
)) != 0)
246 /* Register with KCF. If the registration fails, remove the module. */
247 if (crypto_register_provider(&ecc_prov_info
, &ecc_prov_handle
)) {
248 (void) mod_remove(&modlinkage
);
258 /* Unregister from KCF if module is registered */
259 if (ecc_prov_handle
!= 0) {
260 if (crypto_unregister_provider(ecc_prov_handle
))
266 return (mod_remove(&modlinkage
));
270 _info(struct modinfo
*modinfop
)
272 return (mod_info(&modlinkage
, modinfop
));
277 ecc_provider_status(crypto_provider_handle_t provider
, uint_t
*status
)
279 *status
= CRYPTO_PROVIDER_READY
;
283 * Return the index of an attribute of specified type found in
284 * the specified array of attributes. If the attribute cannot
288 find_attr(crypto_object_attribute_t
*attr
, uint_t nattr
, uint64_t attr_type
)
292 for (i
= 0; i
< nattr
; i
++)
293 if (attr
[i
].oa_value
!= NULL
&& attr
[i
].oa_type
== attr_type
)
299 * Common function used by the get_template_attr_*() family of
300 * functions. Returns the value of the specified attribute of specified
301 * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
302 * if the length of the attribute does not match the specified length,
303 * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
306 get_template_attr_scalar_common(crypto_object_attribute_t
*template,
307 uint_t nattr
, uint64_t attr_type
, void *value
, size_t value_len
)
313 if ((attr_idx
= find_attr(template, nattr
, attr_type
)) == -1)
314 return (CRYPTO_ARGUMENTS_BAD
);
316 oa_value_len
= template[attr_idx
].oa_value_len
;
317 if (oa_value_len
!= value_len
) {
318 return (CRYPTO_ATTRIBUTE_VALUE_INVALID
);
322 bcopy(template[attr_idx
].oa_value
, (uchar_t
*)value
+ offset
,
325 return (CRYPTO_SUCCESS
);
329 * Get the value of a ulong_t attribute from the specified template.
332 get_template_attr_ulong(crypto_object_attribute_t
*template,
333 uint_t nattr
, uint64_t attr_type
, ulong_t
*attr_value
)
335 return (get_template_attr_scalar_common(template, nattr
,
336 attr_type
, attr_value
, sizeof (ulong_t
)));
340 * Called from init routines to do basic sanity checks. Init routines,
341 * e.g. sign_init should fail rather than subsequent operations.
344 check_mech_and_key(ecc_mech_type_t mech_type
, crypto_key_t
*key
, ulong_t
class)
346 int rv
= CRYPTO_SUCCESS
;
351 if (mech_type
!= ECDSA_SHA1_MECH_INFO_TYPE
&&
352 mech_type
!= ECDSA_MECH_INFO_TYPE
)
353 return (CRYPTO_MECHANISM_INVALID
);
355 if (key
->ck_format
!= CRYPTO_KEY_ATTR_LIST
) {
356 return (CRYPTO_KEY_TYPE_INCONSISTENT
);
361 if ((rv
= crypto_get_key_attr(key
, CKA_EC_POINT
, &foo
,
362 &point_len
)) != CRYPTO_SUCCESS
) {
363 return (CRYPTO_TEMPLATE_INCOMPLETE
);
365 if (point_len
< CRYPTO_BITS2BYTES(EC_MIN_KEY_LEN
) * 2 + 1 ||
366 point_len
> CRYPTO_BITS2BYTES(EC_MAX_KEY_LEN
) * 2 + 1)
367 return (CRYPTO_KEY_SIZE_RANGE
);
370 case CKO_PRIVATE_KEY
:
371 if ((rv
= crypto_get_key_attr(key
, CKA_VALUE
, &foo
,
372 &value_len
)) != CRYPTO_SUCCESS
) {
373 return (CRYPTO_TEMPLATE_INCOMPLETE
);
375 if (value_len
< CRYPTO_BITS2BYTES(EC_MIN_KEY_LEN
) ||
376 value_len
> CRYPTO_BITS2BYTES(EC_MAX_KEY_LEN
))
377 return (CRYPTO_KEY_SIZE_RANGE
);
381 return (CRYPTO_TEMPLATE_INCONSISTENT
);
388 * This function guarantees to return non-zero random numbers.
389 * This is needed as the /dev/urandom kernel interface,
390 * random_get_pseudo_bytes(), may return zeros.
393 ecc_knzero_random_generator(uint8_t *ran_out
, size_t ran_len
)
396 size_t ebc
= 0; /* count of extra bytes in extrarand */
398 uint8_t extrarand
[32];
399 size_t extrarand_len
;
401 if ((rv
= random_get_pseudo_bytes(ran_out
, ran_len
)) != 0)
405 * Walk through the returned random numbers pointed by ran_out,
406 * and look for any random number which is zero.
407 * If we find zero, call random_get_pseudo_bytes() to generate
408 * another 32 random numbers pool. Replace any zeros in ran_out[]
409 * from the random number in pool.
411 while (i
< ran_len
) {
412 if (ran_out
[i
] != 0) {
418 * Note that it is 'while' so we are guaranteed a
419 * non-zero value on exit.
422 /* refresh extrarand */
423 extrarand_len
= sizeof (extrarand
);
424 if ((rv
= random_get_pseudo_bytes(extrarand
,
425 extrarand_len
)) != 0) {
431 /* Replace zero with byte from extrarand. */
435 * The new random byte zero/non-zero will be checked in
436 * the next pass through the loop.
438 ran_out
[i
] = extrarand
[ebc
];
441 return (CRYPTO_SUCCESS
);
445 ecc_free_context(crypto_ctx_t
*ctx
)
447 ecc_ctx_t
*ctxp
= ctx
->cc_provider_private
;
450 bzero(ctxp
->key
, ctxp
->keychunk_size
);
451 kmem_free(ctxp
->key
, ctxp
->keychunk_size
);
453 free_ecparams(&ctxp
->ecparams
, B_FALSE
);
455 if (ctxp
->mech_type
== ECDSA_MECH_INFO_TYPE
)
456 kmem_free(ctxp
, sizeof (ecc_ctx_t
));
458 kmem_free(ctxp
, sizeof (digest_ecc_ctx_t
));
460 ctx
->cc_provider_private
= NULL
;
466 ecc_sign_verify_common_init(crypto_ctx_t
*ctx
, crypto_mechanism_t
*mechanism
,
467 crypto_key_t
*key
, crypto_spi_ctx_template_t ctx_template
,
468 crypto_req_handle_t req
)
473 digest_ecc_ctx_t
*dctxp
;
474 ecc_mech_type_t mech_type
= mechanism
->cm_type
;
478 SECKEYECParams params_item
;
480 if (crypto_get_key_attr(key
, CKA_EC_PARAMS
, (void *) ¶ms
,
482 return (CRYPTO_ARGUMENTS_BAD
);
486 if (params
[0] != 0x06 ||
487 params
[1] != params_len
- 2) {
488 return (CRYPTO_ATTRIBUTE_VALUE_INVALID
);
490 params_item
.data
= params
;
491 params_item
.len
= (uint_t
)params_len
;
492 kmflag
= crypto_kmflag(req
);
493 if (EC_DecodeParams(¶ms_item
, &ecparams
, kmflag
) != SECSuccess
) {
495 return (CRYPTO_ARGUMENTS_BAD
);
499 * Allocate an ECC context.
502 case ECDSA_SHA1_MECH_INFO_TYPE
:
503 dctxp
= kmem_zalloc(sizeof (digest_ecc_ctx_t
), kmflag
);
504 ctxp
= (ecc_ctx_t
*)dctxp
;
507 ctxp
= kmem_zalloc(sizeof (ecc_ctx_t
), kmflag
);
512 free_ecparams(ecparams
, B_TRUE
);
513 return (CRYPTO_HOST_MEMORY
);
516 if ((rv
= crypto_copy_key_to_ctx(key
, &ctxp
->key
, &ctxp
->keychunk_size
,
517 kmflag
)) != CRYPTO_SUCCESS
) {
519 case ECDSA_SHA1_MECH_INFO_TYPE
:
520 kmem_free(dctxp
, sizeof (digest_ecc_ctx_t
));
523 kmem_free(ctxp
, sizeof (ecc_ctx_t
));
526 free_ecparams(ecparams
, B_TRUE
);
529 ctxp
->mech_type
= mech_type
;
530 ctxp
->ecparams
= *ecparams
;
531 kmem_free(ecparams
, sizeof (ECParams
));
534 case ECDSA_SHA1_MECH_INFO_TYPE
:
535 SHA1Init(&(dctxp
->sha1_ctx
));
539 ctx
->cc_provider_private
= ctxp
;
541 return (CRYPTO_SUCCESS
);
546 ecc_sign_init(crypto_ctx_t
*ctx
, crypto_mechanism_t
*mechanism
,
547 crypto_key_t
*key
, crypto_spi_ctx_template_t ctx_template
,
548 crypto_req_handle_t req
)
552 ecc_mech_type_t mech_type
= mechanism
->cm_type
;
554 if ((rv
= check_mech_and_key(mech_type
, key
,
555 CKO_PRIVATE_KEY
)) != CRYPTO_SUCCESS
)
558 rv
= ecc_sign_verify_common_init(ctx
, mechanism
, key
,
566 ecc_verify_init(crypto_ctx_t
*ctx
, crypto_mechanism_t
*mechanism
,
567 crypto_key_t
*key
, crypto_spi_ctx_template_t ctx_template
,
568 crypto_req_handle_t req
)
572 ecc_mech_type_t mech_type
= mechanism
->cm_type
;
574 if ((rv
= check_mech_and_key(mech_type
, key
,
575 CKO_PUBLIC_KEY
)) != CRYPTO_SUCCESS
)
578 rv
= ecc_sign_verify_common_init(ctx
, mechanism
, key
,
584 #define SHA1_DIGEST_SIZE 20
586 #define INIT_RAW_CRYPTO_DATA(data, base, len, cd_len) \
587 (data).cd_format = CRYPTO_DATA_RAW; \
588 (data).cd_offset = 0; \
589 (data).cd_raw.iov_base = (char *)base; \
590 (data).cd_raw.iov_len = len; \
591 (data).cd_length = cd_len;
594 ecc_digest_svrfy_common(digest_ecc_ctx_t
*ctxp
, crypto_data_t
*data
,
595 crypto_data_t
*signature
, uchar_t flag
, crypto_req_handle_t req
)
597 int rv
= CRYPTO_FAILED
;
598 uchar_t digest
[SHA1_DIGEST_LENGTH
];
599 crypto_data_t der_cd
;
600 ecc_mech_type_t mech_type
;
602 ASSERT(flag
& CRYPTO_DO_SIGN
|| flag
& CRYPTO_DO_VERIFY
);
603 ASSERT(data
!= NULL
|| (flag
& CRYPTO_DO_FINAL
));
605 mech_type
= ctxp
->mech_type
;
606 if (mech_type
!= ECDSA_SHA1_MECH_INFO_TYPE
)
607 return (CRYPTO_MECHANISM_INVALID
);
609 /* Don't digest if only returning length of signature. */
610 if (signature
->cd_length
> 0) {
611 if (mech_type
== ECDSA_SHA1_MECH_INFO_TYPE
) {
612 rv
= crypto_digest_data(data
, &(ctxp
->sha1_ctx
),
613 digest
, (void (*)())SHA1Update
,
614 (void (*)())SHA1Final
, flag
| CRYPTO_DO_SHA1
);
615 if (rv
!= CRYPTO_SUCCESS
)
620 INIT_RAW_CRYPTO_DATA(der_cd
, digest
, SHA1_DIGEST_SIZE
,
623 if (flag
& CRYPTO_DO_SIGN
) {
624 rv
= ecc_sign_common((ecc_ctx_t
*)ctxp
, &der_cd
, signature
,
627 rv
= ecc_verify_common((ecc_ctx_t
*)ctxp
, &der_cd
, signature
,
634 * This is a single-part signing routine. It does not
635 * compute a hash before signing.
638 ecc_sign_common(ecc_ctx_t
*ctx
, crypto_data_t
*data
, crypto_data_t
*signature
,
639 crypto_req_handle_t req
)
641 int rv
= CRYPTO_FAILED
;
647 uchar_t tmp_data
[EC_MAX_DIGEST_LEN
];
648 uchar_t signed_data
[EC_MAX_SIG_LEN
];
650 SECItem signature_item
;
652 crypto_key_t
*key
= ctx
->key
;
655 if ((rv
= crypto_get_key_attr(key
, CKA_EC_PARAMS
, ¶m
,
656 ¶m_len
)) != CRYPTO_SUCCESS
) {
660 if (data
->cd_length
> sizeof (tmp_data
))
661 return (CRYPTO_DATA_LEN_RANGE
);
663 if ((rv
= crypto_get_input_data(data
, &digest_item
.data
, tmp_data
))
667 digest_item
.len
= data
->cd_length
;
669 /* structure assignment */
670 ECkey
.ecParams
= ctx
->ecparams
;
672 if ((rv
= crypto_get_key_attr(key
, CKA_VALUE
, &private,
673 &private_len
)) != CRYPTO_SUCCESS
) {
676 ECkey
.privateValue
.data
= private;
677 ECkey
.privateValue
.len
= (uint_t
)private_len
;
679 signature_item
.data
= signed_data
;
680 signature_item
.len
= sizeof (signed_data
);
682 kmflag
= crypto_kmflag(req
);
683 if ((ss
= ECDSA_SignDigest(&ECkey
, &signature_item
, &digest_item
,
684 kmflag
)) != SECSuccess
) {
685 if (ss
== SECBufferTooSmall
)
686 return (CRYPTO_BUFFER_TOO_SMALL
);
688 return (CRYPTO_FAILED
);
691 if (rv
== CRYPTO_SUCCESS
) {
692 /* copy out the signature */
693 if ((rv
= crypto_put_output_data(signed_data
,
694 signature
, signature_item
.len
)) != CRYPTO_SUCCESS
)
697 signature
->cd_length
= signature_item
.len
;
705 ecc_sign(crypto_ctx_t
*ctx
, crypto_data_t
*data
, crypto_data_t
*signature
,
706 crypto_req_handle_t req
)
711 ASSERT(ctx
->cc_provider_private
!= NULL
);
712 ctxp
= ctx
->cc_provider_private
;
714 switch (ctxp
->mech_type
) {
715 case ECDSA_SHA1_MECH_INFO_TYPE
:
716 rv
= ecc_digest_svrfy_common((digest_ecc_ctx_t
*)ctxp
, data
,
717 signature
, CRYPTO_DO_SIGN
| CRYPTO_DO_UPDATE
|
718 CRYPTO_DO_FINAL
, req
);
721 rv
= ecc_sign_common(ctxp
, data
, signature
, req
);
725 if (rv
!= CRYPTO_BUFFER_TOO_SMALL
)
726 ecc_free_context(ctx
);
733 ecc_sign_update(crypto_ctx_t
*ctx
, crypto_data_t
*data
, crypto_req_handle_t req
)
736 digest_ecc_ctx_t
*ctxp
;
737 ecc_mech_type_t mech_type
;
739 ASSERT(ctx
->cc_provider_private
!= NULL
);
740 ctxp
= ctx
->cc_provider_private
;
741 mech_type
= ctxp
->mech_type
;
743 if (mech_type
== ECDSA_MECH_INFO_TYPE
) {
744 ecc_free_context(ctx
);
745 return (CRYPTO_MECHANISM_INVALID
);
748 if (mech_type
== ECDSA_SHA1_MECH_INFO_TYPE
)
749 rv
= crypto_digest_data(data
, &(ctxp
->sha1_ctx
), NULL
,
750 (void (*)())SHA1Update
, (void (*)())SHA1Final
,
751 CRYPTO_DO_SHA1
| CRYPTO_DO_UPDATE
);
753 if (rv
!= CRYPTO_SUCCESS
)
754 ecc_free_context(ctx
);
761 ecc_sign_final(crypto_ctx_t
*ctx
, crypto_data_t
*signature
,
762 crypto_req_handle_t req
)
765 digest_ecc_ctx_t
*ctxp
;
767 ASSERT(ctx
->cc_provider_private
!= NULL
);
768 ctxp
= ctx
->cc_provider_private
;
770 rv
= ecc_digest_svrfy_common(ctxp
, NULL
, signature
, CRYPTO_DO_SIGN
|
771 CRYPTO_DO_FINAL
, req
);
772 if (rv
!= CRYPTO_BUFFER_TOO_SMALL
)
773 ecc_free_context(ctx
);
780 ecc_sign_atomic(crypto_provider_handle_t provider
,
781 crypto_session_id_t session_id
, crypto_mechanism_t
*mechanism
,
782 crypto_key_t
*key
, crypto_data_t
*data
, crypto_data_t
*signature
,
783 crypto_spi_ctx_template_t ctx_template
, crypto_req_handle_t req
)
786 ecc_mech_type_t mech_type
= mechanism
->cm_type
;
790 SECKEYECParams params_item
;
793 if ((rv
= check_mech_and_key(mech_type
, key
,
794 CKO_PRIVATE_KEY
)) != CRYPTO_SUCCESS
)
797 if (crypto_get_key_attr(key
, CKA_EC_PARAMS
, (void *) ¶ms
,
799 return (CRYPTO_ARGUMENTS_BAD
);
803 if (params
[0] != 0x06 ||
804 params
[1] != params_len
- 2) {
805 return (CRYPTO_ATTRIBUTE_VALUE_INVALID
);
807 params_item
.data
= params
;
808 params_item
.len
= (uint_t
)params_len
;
809 kmflag
= crypto_kmflag(req
);
810 if (EC_DecodeParams(¶ms_item
, &ecparams
, kmflag
) != SECSuccess
) {
812 return (CRYPTO_ARGUMENTS_BAD
);
815 if (mechanism
->cm_type
== ECDSA_MECH_INFO_TYPE
) {
818 ctx
.mech_type
= mech_type
;
819 /* structure assignment */
820 ctx
.ecparams
= *ecparams
;
822 rv
= ecc_sign_common(&ctx
, data
, signature
, req
);
824 digest_ecc_ctx_t dctx
;
826 dctx
.mech_type
= mech_type
;
827 /* structure assignment */
828 dctx
.ecparams
= *ecparams
;
830 SHA1Init(&(dctx
.sha1_ctx
));
832 rv
= ecc_digest_svrfy_common(&dctx
, data
, signature
,
833 CRYPTO_DO_SIGN
| CRYPTO_DO_UPDATE
| CRYPTO_DO_FINAL
, req
);
835 free_ecparams(ecparams
, B_TRUE
);
841 ecc_verify_common(ecc_ctx_t
*ctx
, crypto_data_t
*data
, crypto_data_t
*signature
,
842 crypto_req_handle_t req
)
844 int rv
= CRYPTO_FAILED
;
849 uchar_t tmp_data
[EC_MAX_DIGEST_LEN
];
850 uchar_t signed_data
[EC_MAX_SIG_LEN
];
852 SECItem signature_item
;
854 crypto_key_t
*key
= ctx
->key
;
857 if ((rv
= crypto_get_key_attr(key
, CKA_EC_PARAMS
, ¶m
,
858 ¶m_len
)) != CRYPTO_SUCCESS
) {
862 if (signature
->cd_length
> sizeof (signed_data
)) {
863 return (CRYPTO_SIGNATURE_LEN_RANGE
);
866 if ((rv
= crypto_get_input_data(signature
, &signature_item
.data
,
867 signed_data
)) != CRYPTO_SUCCESS
) {
870 signature_item
.len
= signature
->cd_length
;
872 if (data
->cd_length
> sizeof (tmp_data
))
873 return (CRYPTO_DATA_LEN_RANGE
);
875 if ((rv
= crypto_get_input_data(data
, &digest_item
.data
, tmp_data
))
879 digest_item
.len
= data
->cd_length
;
881 /* structure assignment */
882 ECkey
.ecParams
= ctx
->ecparams
;
884 if ((rv
= crypto_get_key_attr(key
, CKA_EC_POINT
, &public,
885 &public_len
)) != CRYPTO_SUCCESS
) {
888 ECkey
.publicValue
.data
= public;
889 ECkey
.publicValue
.len
= (uint_t
)public_len
;
891 kmflag
= crypto_kmflag(req
);
892 if (ECDSA_VerifyDigest(&ECkey
, &signature_item
, &digest_item
, kmflag
)
894 rv
= CRYPTO_SIGNATURE_INVALID
;
904 ecc_verify(crypto_ctx_t
*ctx
, crypto_data_t
*data
, crypto_data_t
*signature
,
905 crypto_req_handle_t req
)
910 ASSERT(ctx
->cc_provider_private
!= NULL
);
911 ctxp
= ctx
->cc_provider_private
;
913 switch (ctxp
->mech_type
) {
914 case ECDSA_SHA1_MECH_INFO_TYPE
:
915 rv
= ecc_digest_svrfy_common((digest_ecc_ctx_t
*)ctxp
, data
,
916 signature
, CRYPTO_DO_VERIFY
| CRYPTO_DO_UPDATE
|
917 CRYPTO_DO_FINAL
, req
);
920 rv
= ecc_verify_common(ctxp
, data
, signature
, req
);
924 ecc_free_context(ctx
);
930 ecc_verify_update(crypto_ctx_t
*ctx
, crypto_data_t
*data
,
931 crypto_req_handle_t req
)
934 digest_ecc_ctx_t
*ctxp
;
936 ASSERT(ctx
->cc_provider_private
!= NULL
);
937 ctxp
= ctx
->cc_provider_private
;
939 switch (ctxp
->mech_type
) {
940 case ECDSA_SHA1_MECH_INFO_TYPE
:
941 rv
= crypto_digest_data(data
, &(ctxp
->sha1_ctx
), NULL
,
942 (void (*)())SHA1Update
, (void (*)())SHA1Final
,
943 CRYPTO_DO_SHA1
| CRYPTO_DO_UPDATE
);
946 rv
= CRYPTO_MECHANISM_INVALID
;
949 if (rv
!= CRYPTO_SUCCESS
)
950 ecc_free_context(ctx
);
957 ecc_verify_final(crypto_ctx_t
*ctx
, crypto_data_t
*signature
,
958 crypto_req_handle_t req
)
961 digest_ecc_ctx_t
*ctxp
;
963 ASSERT(ctx
->cc_provider_private
!= NULL
);
964 ctxp
= ctx
->cc_provider_private
;
966 rv
= ecc_digest_svrfy_common(ctxp
, NULL
, signature
,
967 CRYPTO_DO_VERIFY
| CRYPTO_DO_FINAL
, req
);
969 ecc_free_context(ctx
);
977 ecc_verify_atomic(crypto_provider_handle_t provider
,
978 crypto_session_id_t session_id
, crypto_mechanism_t
*mechanism
,
979 crypto_key_t
*key
, crypto_data_t
*data
, crypto_data_t
*signature
,
980 crypto_spi_ctx_template_t ctx_template
, crypto_req_handle_t req
)
983 ecc_mech_type_t mech_type
= mechanism
->cm_type
;
987 SECKEYECParams params_item
;
990 if ((rv
= check_mech_and_key(mech_type
, key
,
991 CKO_PUBLIC_KEY
)) != CRYPTO_SUCCESS
)
994 if (crypto_get_key_attr(key
, CKA_EC_PARAMS
, (void *) ¶ms
,
996 return (CRYPTO_ARGUMENTS_BAD
);
1000 if (params
[0] != 0x06 ||
1001 params
[1] != params_len
- 2) {
1002 return (CRYPTO_ATTRIBUTE_VALUE_INVALID
);
1004 params_item
.data
= params
;
1005 params_item
.len
= (uint_t
)params_len
;
1006 kmflag
= crypto_kmflag(req
);
1007 if (EC_DecodeParams(¶ms_item
, &ecparams
, kmflag
) != SECSuccess
) {
1009 return (CRYPTO_ARGUMENTS_BAD
);
1012 if (mechanism
->cm_type
== ECDSA_MECH_INFO_TYPE
) {
1015 ctx
.mech_type
= mech_type
;
1016 /* structure assignment */
1017 ctx
.ecparams
= *ecparams
;
1019 rv
= ecc_verify_common(&ctx
, data
, signature
, req
);
1021 digest_ecc_ctx_t dctx
;
1023 dctx
.mech_type
= mech_type
;
1024 /* structure assignment */
1025 dctx
.ecparams
= *ecparams
;
1027 SHA1Init(&(dctx
.sha1_ctx
));
1029 rv
= ecc_digest_svrfy_common(&dctx
, data
, signature
,
1030 CRYPTO_DO_VERIFY
| CRYPTO_DO_UPDATE
| CRYPTO_DO_FINAL
, req
);
1032 free_ecparams(ecparams
, B_TRUE
);
1038 ecc_nostore_key_generate_pair(crypto_provider_handle_t provider
,
1039 crypto_session_id_t session_id
, crypto_mechanism_t
*mechanism
,
1040 crypto_object_attribute_t
*pub_template
, uint_t pub_attribute_count
,
1041 crypto_object_attribute_t
*pri_template
, uint_t pri_attribute_count
,
1042 crypto_object_attribute_t
*pub_out_template
, uint_t pub_out_attribute_count
,
1043 crypto_object_attribute_t
*pri_out_template
, uint_t pri_out_attribute_count
,
1044 crypto_req_handle_t req
)
1046 int rv
= CRYPTO_SUCCESS
;
1047 ECPrivateKey
*privKey
; /* contains both public and private values */
1049 SECKEYECParams params_item
;
1050 ulong_t pub_key_type
= ~0UL, pub_class
= ~0UL;
1051 ulong_t pri_key_type
= ~0UL, pri_class
= ~0UL;
1052 int params_idx
, value_idx
, point_idx
;
1053 uchar_t
*params
= NULL
;
1054 unsigned params_len
;
1055 uchar_t
*value
= NULL
;
1056 uchar_t
*point
= NULL
;
1062 if (mechanism
->cm_type
!= EC_KEY_PAIR_GEN_MECH_INFO_TYPE
) {
1063 return (CRYPTO_MECHANISM_INVALID
);
1067 (void) get_template_attr_ulong(pub_template
,
1068 pub_attribute_count
, CKA_CLASS
, &pub_class
);
1071 (void) get_template_attr_ulong(pri_template
,
1072 pri_attribute_count
, CKA_CLASS
, &pri_class
);
1075 (void) get_template_attr_ulong(pub_template
,
1076 pub_attribute_count
, CKA_KEY_TYPE
, &pub_key_type
);
1079 (void) get_template_attr_ulong(pri_template
,
1080 pri_attribute_count
, CKA_KEY_TYPE
, &pri_key_type
);
1082 if (pub_class
!= ~0UL && pub_class
!= CKO_PUBLIC_KEY
) {
1083 return (CRYPTO_TEMPLATE_INCONSISTENT
);
1085 pub_class
= CKO_PUBLIC_KEY
;
1087 if (pri_class
!= ~0UL && pri_class
!= CKO_PRIVATE_KEY
) {
1088 return (CRYPTO_TEMPLATE_INCONSISTENT
);
1090 pri_class
= CKO_PRIVATE_KEY
;
1092 if (pub_key_type
!= ~0UL && pub_key_type
!= CKK_EC
) {
1093 return (CRYPTO_TEMPLATE_INCONSISTENT
);
1095 pub_key_type
= CKK_EC
;
1097 if (pri_key_type
!= ~0UL && pri_key_type
!= CKK_EC
) {
1098 return (CRYPTO_TEMPLATE_INCONSISTENT
);
1100 pri_key_type
= CKK_EC
;
1102 /* public output template must contain CKA_EC_POINT attribute */
1103 if ((point_idx
= find_attr(pub_out_template
, pub_out_attribute_count
,
1104 CKA_EC_POINT
)) == -1) {
1105 return (CRYPTO_TEMPLATE_INCOMPLETE
);
1108 /* private output template must contain CKA_VALUE attribute */
1109 if ((value_idx
= find_attr(pri_out_template
, pri_out_attribute_count
,
1110 CKA_VALUE
)) == -1) {
1111 return (CRYPTO_TEMPLATE_INCOMPLETE
);
1114 if ((params_idx
= find_attr(pub_template
, pub_attribute_count
,
1115 CKA_EC_PARAMS
)) == -1) {
1116 return (CRYPTO_TEMPLATE_INCOMPLETE
);
1119 params
= (uchar_t
*)pub_template
[params_idx
].oa_value
;
1120 params_len
= pub_template
[params_idx
].oa_value_len
;
1122 value
= (uchar_t
*)pri_out_template
[value_idx
].oa_value
;
1123 valuelen
= (int)pri_out_template
[value_idx
].oa_value_len
;
1124 point
= (uchar_t
*)pub_out_template
[point_idx
].oa_value
;
1125 pointlen
= (int)pub_out_template
[point_idx
].oa_value_len
;
1128 if (params
[0] != 0x06 ||
1129 params
[1] != params_len
- 2) {
1130 return (CRYPTO_ATTRIBUTE_VALUE_INVALID
);
1132 params_item
.data
= params
;
1133 params_item
.len
= params_len
;
1134 kmflag
= crypto_kmflag(req
);
1135 if (EC_DecodeParams(¶ms_item
, &ecparams
, kmflag
) != SECSuccess
) {
1137 return (CRYPTO_ARGUMENTS_BAD
);
1140 if (EC_NewKey(ecparams
, &privKey
, kmflag
) != SECSuccess
) {
1141 free_ecparams(ecparams
, B_TRUE
);
1142 return (CRYPTO_FAILED
);
1145 xylen
= privKey
->publicValue
.len
;
1146 /* ASSERT that xylen - 1 is divisible by 2 */
1147 if (xylen
> pointlen
) {
1148 rv
= CRYPTO_BUFFER_TOO_SMALL
;
1152 if (privKey
->privateValue
.len
> valuelen
) {
1153 rv
= CRYPTO_BUFFER_TOO_SMALL
;
1156 bcopy(privKey
->privateValue
.data
, value
, privKey
->privateValue
.len
);
1157 pri_out_template
[value_idx
].oa_value_len
= privKey
->privateValue
.len
;
1159 bcopy(privKey
->publicValue
.data
, point
, xylen
);
1160 pub_out_template
[point_idx
].oa_value_len
= xylen
;
1163 free_ecprivkey(privKey
);
1164 free_ecparams(ecparams
, B_TRUE
);
1170 ecc_nostore_key_derive(crypto_provider_handle_t provider
,
1171 crypto_session_id_t session_id
, crypto_mechanism_t
*mechanism
,
1172 crypto_key_t
*base_key
, crypto_object_attribute_t
*in_attrs
,
1173 uint_t in_attr_count
, crypto_object_attribute_t
*out_attrs
,
1174 uint_t out_attr_count
, crypto_req_handle_t req
)
1176 int rv
= CRYPTO_SUCCESS
;
1177 int params_idx
, value_idx
= -1, out_value_idx
= -1;
1180 crypto_object_attribute_t
*attrs
;
1182 SECKEYECParams params_item
;
1183 CK_ECDH1_DERIVE_PARAMS
*mech_param
;
1184 SECItem public_value_item
, private_value_item
, secret_item
;
1187 if (mechanism
->cm_type
!= ECDH1_DERIVE_MECH_INFO_TYPE
) {
1188 return (CRYPTO_MECHANISM_INVALID
);
1191 ASSERT(IS_P2ALIGNED(mechanism
->cm_param
, sizeof (uint64_t)));
1192 /* LINTED: pointer alignment */
1193 mech_param
= (CK_ECDH1_DERIVE_PARAMS
*)mechanism
->cm_param
;
1194 if (mech_param
->kdf
!= CKD_NULL
) {
1195 return (CRYPTO_MECHANISM_PARAM_INVALID
);
1198 if ((base_key
->ck_format
!= CRYPTO_KEY_ATTR_LIST
) ||
1199 (base_key
->ck_count
== 0)) {
1200 return (CRYPTO_ARGUMENTS_BAD
);
1203 if ((rv
= get_template_attr_ulong(in_attrs
, in_attr_count
,
1204 CKA_KEY_TYPE
, &key_type
)) != CRYPTO_SUCCESS
) {
1210 key_len
= DES_KEYSIZE
;
1213 key_len
= DES2_KEYSIZE
;
1216 key_len
= DES3_KEYSIZE
;
1220 case CKK_GENERIC_SECRET
:
1221 if ((rv
= get_template_attr_ulong(in_attrs
, in_attr_count
,
1222 CKA_VALUE_LEN
, &key_len
)) != CRYPTO_SUCCESS
) {
1230 attrs
= base_key
->ck_attrs
;
1231 if ((value_idx
= find_attr(attrs
, base_key
->ck_count
,
1232 CKA_VALUE
)) == -1) {
1233 return (CRYPTO_TEMPLATE_INCOMPLETE
);
1236 if ((params_idx
= find_attr(attrs
, base_key
->ck_count
,
1237 CKA_EC_PARAMS
)) == -1) {
1238 return (CRYPTO_TEMPLATE_INCOMPLETE
);
1241 private_value_item
.data
= (uchar_t
*)attrs
[value_idx
].oa_value
;
1242 private_value_item
.len
= attrs
[value_idx
].oa_value_len
;
1244 params_item
.len
= attrs
[params_idx
].oa_value_len
;
1245 params_item
.data
= (uchar_t
*)attrs
[params_idx
].oa_value
;
1248 if (params_item
.data
[0] != 0x06 ||
1249 params_item
.data
[1] != params_item
.len
- 2) {
1250 return (CRYPTO_ATTRIBUTE_VALUE_INVALID
);
1252 kmflag
= crypto_kmflag(req
);
1253 if (EC_DecodeParams(¶ms_item
, &ecparams
, kmflag
) != SECSuccess
) {
1255 return (CRYPTO_ARGUMENTS_BAD
);
1258 public_value_item
.data
= (uchar_t
*)mech_param
->pPublicData
;
1259 public_value_item
.len
= mech_param
->ulPublicDataLen
;
1261 if ((out_value_idx
= find_attr(out_attrs
, out_attr_count
,
1262 CKA_VALUE
)) == -1) {
1263 rv
= CRYPTO_TEMPLATE_INCOMPLETE
;
1266 secret_item
.data
= NULL
;
1267 secret_item
.len
= 0;
1269 if (ECDH_Derive(&public_value_item
, ecparams
, &private_value_item
,
1270 B_FALSE
, &secret_item
, kmflag
) != SECSuccess
) {
1271 free_ecparams(ecparams
, B_TRUE
);
1272 return (CRYPTO_FAILED
);
1274 rv
= CRYPTO_SUCCESS
;
1278 key_len
= secret_item
.len
;
1280 if (key_len
> secret_item
.len
) {
1281 rv
= CRYPTO_ATTRIBUTE_VALUE_INVALID
;
1284 if (key_len
> out_attrs
[out_value_idx
].oa_value_len
) {
1285 rv
= CRYPTO_BUFFER_TOO_SMALL
;
1288 bcopy(secret_item
.data
+ secret_item
.len
- key_len
,
1289 (uchar_t
*)out_attrs
[out_value_idx
].oa_value
, key_len
);
1290 out_attrs
[out_value_idx
].oa_value_len
= key_len
;
1292 free_ecparams(ecparams
, B_TRUE
);
1293 SECITEM_FreeItem(&secret_item
, B_FALSE
);
1298 free_ecparams(ECParams
*params
, boolean_t freeit
)
1300 SECITEM_FreeItem(¶ms
->fieldID
.u
.prime
, B_FALSE
);
1301 SECITEM_FreeItem(¶ms
->curve
.a
, B_FALSE
);
1302 SECITEM_FreeItem(¶ms
->curve
.b
, B_FALSE
);
1303 SECITEM_FreeItem(¶ms
->curve
.seed
, B_FALSE
);
1304 SECITEM_FreeItem(¶ms
->base
, B_FALSE
);
1305 SECITEM_FreeItem(¶ms
->order
, B_FALSE
);
1306 SECITEM_FreeItem(¶ms
->DEREncoding
, B_FALSE
);
1307 SECITEM_FreeItem(¶ms
->curveOID
, B_FALSE
);
1309 kmem_free(params
, sizeof (ECParams
));
1313 free_ecprivkey(ECPrivateKey
*key
)
1315 free_ecparams(&key
->ecParams
, B_FALSE
);
1316 SECITEM_FreeItem(&key
->publicValue
, B_FALSE
);
1317 bzero(key
->privateValue
.data
, key
->privateValue
.len
);
1318 SECITEM_FreeItem(&key
->privateValue
, B_FALSE
);
1319 SECITEM_FreeItem(&key
->version
, B_FALSE
);
1320 kmem_free(key
, sizeof (ECPrivateKey
));