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