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