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
_init(void)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
_fini(void)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
_info(struct modinfo * modinfop)278 _info(struct modinfo *modinfop)
279 {
280 return (mod_info(&modlinkage, modinfop));
281 }
282
283 /* ARGSUSED */
284 static void
ecc_provider_status(crypto_provider_handle_t provider,uint_t * status)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
find_attr(crypto_object_attribute_t * attr,uint_t nattr,uint64_t attr_type)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
get_template_attr_scalar_common(crypto_object_attribute_t * template,uint_t nattr,uint64_t attr_type,void * value,size_t value_len)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
get_template_attr_ulong(crypto_object_attribute_t * template,uint_t nattr,uint64_t attr_type,ulong_t * attr_value)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
check_mech_and_key(ecc_mech_type_t mech_type,crypto_key_t * key,ulong_t class)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
ecc_knzero_random_generator(uint8_t * ran_out,size_t ran_len)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
ecc_free_context(crypto_ctx_t * ctx)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
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)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 *) ¶ms,
489 ¶ms_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(¶ms_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
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)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
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)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
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)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
ecc_sign_common(ecc_ctx_t * ctx,crypto_data_t * data,crypto_data_t * signature,crypto_req_handle_t req)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, ¶m,
664 ¶m_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
ecc_sign(crypto_ctx_t * ctx,crypto_data_t * data,crypto_data_t * signature,crypto_req_handle_t req)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
ecc_sign_update(crypto_ctx_t * ctx,crypto_data_t * data,crypto_req_handle_t req)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
ecc_sign_final(crypto_ctx_t * ctx,crypto_data_t * signature,crypto_req_handle_t req)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
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)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 *) ¶ms,
806 ¶ms_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(¶ms_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
ecc_verify_common(ecc_ctx_t * ctx,crypto_data_t * data,crypto_data_t * signature,crypto_req_handle_t req)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, ¶m,
866 ¶m_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
ecc_verify(crypto_ctx_t * ctx,crypto_data_t * data,crypto_data_t * signature,crypto_req_handle_t req)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
ecc_verify_update(crypto_ctx_t * ctx,crypto_data_t * data,crypto_req_handle_t req)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
ecc_verify_final(crypto_ctx_t * ctx,crypto_data_t * signature,crypto_req_handle_t req)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
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)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 *) ¶ms,
1003 ¶ms_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(¶ms_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
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)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(¶ms_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
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)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(¶ms_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
free_ecparams(ECParams * params,boolean_t freeit)1313 free_ecparams(ECParams *params, boolean_t freeit)
1314 {
1315 SECITEM_FreeItem(¶ms->fieldID.u.prime, B_FALSE);
1316 SECITEM_FreeItem(¶ms->curve.a, B_FALSE);
1317 SECITEM_FreeItem(¶ms->curve.b, B_FALSE);
1318 SECITEM_FreeItem(¶ms->curve.seed, B_FALSE);
1319 SECITEM_FreeItem(¶ms->base, B_FALSE);
1320 SECITEM_FreeItem(¶ms->order, B_FALSE);
1321 SECITEM_FreeItem(¶ms->DEREncoding, B_FALSE);
1322 SECITEM_FreeItem(¶ms->curveOID, B_FALSE);
1323 if (freeit)
1324 kmem_free(params, sizeof (ECParams));
1325 }
1326
1327 static void
free_ecprivkey(ECPrivateKey * key)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
fips_pairwise_check(ECPrivateKey * ecdsa_private_key)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
ecc_POST(int * rc)1401 ecc_POST(int *rc)
1402 {
1403
1404 *rc = fips_ecdsa_post();
1405
1406 }
1407