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 /*
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /*
27 * This file contains DSA helper routines common to
28 * the PKCS11 soft token code and the kernel DSA code.
29 */
30
31 #include <sys/types.h>
32 #include <bignum.h>
33
34 #ifdef _KERNEL
35 #include <sys/param.h>
36 #else
37 #include <strings.h>
38 #include <cryptoutil.h>
39 #endif
40
41 #include <sys/crypto/common.h>
42 #include "dsa_impl.h"
43
44
45 static CK_RV
convert_rv(BIG_ERR_CODE err)46 convert_rv(BIG_ERR_CODE err)
47 {
48 switch (err) {
49
50 case BIG_OK:
51 return (CKR_OK);
52
53 case BIG_NO_MEM:
54 return (CKR_HOST_MEMORY);
55
56 case BIG_NO_RANDOM:
57 return (CKR_DEVICE_ERROR);
58
59 case BIG_INVALID_ARGS:
60 return (CKR_ARGUMENTS_BAD);
61
62 case BIG_DIV_BY_0:
63 default:
64 return (CKR_GENERAL_ERROR);
65 }
66 }
67
68 /* size is in bits */
69 static BIG_ERR_CODE
DSA_key_init(DSAkey * key,int size)70 DSA_key_init(DSAkey *key, int size)
71 {
72 BIG_ERR_CODE err = BIG_OK;
73 int len, len160;
74
75 len = BITLEN2BIGNUMLEN(size);
76 len160 = BIG_CHUNKS_FOR_160BITS;
77 key->size = size;
78 if ((err = big_init(&(key->q), len160)) != BIG_OK)
79 return (err);
80 if ((err = big_init(&(key->p), len)) != BIG_OK)
81 goto ret1;
82 if ((err = big_init(&(key->g), len)) != BIG_OK)
83 goto ret2;
84 if ((err = big_init(&(key->x), len160)) != BIG_OK)
85 goto ret3;
86 if ((err = big_init(&(key->y), len)) != BIG_OK)
87 goto ret4;
88 if ((err = big_init(&(key->k), len160)) != BIG_OK)
89 goto ret5;
90 if ((err = big_init(&(key->r), len160)) != BIG_OK)
91 goto ret6;
92 if ((err = big_init(&(key->s), len160)) != BIG_OK)
93 goto ret7;
94 if ((err = big_init(&(key->v), len160)) != BIG_OK)
95 goto ret8;
96
97 return (BIG_OK);
98
99 ret8:
100 big_finish(&(key->s));
101 ret7:
102 big_finish(&(key->r));
103 ret6:
104 big_finish(&(key->k));
105 ret5:
106 big_finish(&(key->y));
107 ret4:
108 big_finish(&(key->x));
109 ret3:
110 big_finish(&(key->g));
111 ret2:
112 big_finish(&(key->p));
113 ret1:
114 big_finish(&(key->q));
115 return (err);
116 }
117
118 static void
DSA_key_finish(DSAkey * key)119 DSA_key_finish(DSAkey *key)
120 {
121
122 big_finish(&(key->v));
123 big_finish(&(key->s));
124 big_finish(&(key->r));
125 big_finish(&(key->k));
126 big_finish(&(key->y));
127 big_finish(&(key->x));
128 big_finish(&(key->g));
129 big_finish(&(key->p));
130 big_finish(&(key->q));
131
132 }
133
134 /*
135 * Generate DSA private x and public y from prime p, subprime q, and base g.
136 */
137 static CK_RV
generate_dsa_key(DSAkey * key,int (* rfunc)(void *,size_t))138 generate_dsa_key(DSAkey *key, int (*rfunc)(void *, size_t))
139 {
140 BIG_ERR_CODE err;
141 int (*rf)(void *, size_t);
142
143 rf = rfunc;
144 if (rf == NULL) {
145 #ifdef _KERNEL
146 rf = random_get_pseudo_bytes;
147 #else
148 rf = pkcs11_get_urandom;
149 #endif
150 }
151 do {
152 if ((err = big_random(&(key->x), DSA_SUBPRIME_BITS, rf)) !=
153 BIG_OK) {
154 return (convert_rv(err));
155 }
156 } while (big_cmp_abs(&(key->x), &(key->q)) > 0);
157
158 if ((err = big_modexp(&(key->y), &(key->g), (&key->x), (&key->p),
159 NULL)) != BIG_OK)
160 return (convert_rv(err));
161
162 return (CKR_OK);
163 }
164
165 CK_RV
dsa_genkey_pair(DSAbytekey * bkey)166 dsa_genkey_pair(DSAbytekey *bkey)
167 {
168 CK_RV rv = CKR_OK;
169 BIG_ERR_CODE brv;
170 DSAkey dsakey;
171 uint32_t prime_bytes;
172 uint32_t subprime_bytes;
173
174 prime_bytes = CRYPTO_BITS2BYTES(bkey->prime_bits);
175
176 if ((prime_bytes < MIN_DSA_KEY_LEN) ||
177 (prime_bytes > MAX_DSA_KEY_LEN)) {
178 return (CKR_ATTRIBUTE_VALUE_INVALID);
179 }
180
181 /*
182 * There is no check here that prime_bits must be a multiple of 64,
183 * and thus that prime_bytes must be a multiple of 8.
184 */
185
186 subprime_bytes = CRYPTO_BITS2BYTES(bkey->subprime_bits);
187
188 if (subprime_bytes != DSA_SUBPRIME_BYTES) {
189 return (CKR_ATTRIBUTE_VALUE_INVALID);
190 }
191
192 if (bkey->public_y == NULL || bkey->private_x == NULL) {
193 return (CKR_ARGUMENTS_BAD);
194 }
195
196 /*
197 * Initialize the DSA key.
198 * Note: big_extend takes length in words.
199 */
200 if ((brv = DSA_key_init(&dsakey, bkey->prime_bits)) != BIG_OK) {
201 rv = convert_rv(brv);
202 goto cleanexit;
203 }
204
205 /* Convert prime p to bignum. */
206 if ((brv = big_extend(&(dsakey.p),
207 CHARLEN2BIGNUMLEN(prime_bytes))) != BIG_OK) {
208 rv = convert_rv(brv);
209 goto cleanexit;
210 }
211 bytestring2bignum(&(dsakey.p), bkey->prime, prime_bytes);
212
213 /* Convert prime q to bignum. */
214 if ((brv = big_extend(&(dsakey.q),
215 CHARLEN2BIGNUMLEN(subprime_bytes))) != BIG_OK) {
216 rv = convert_rv(brv);
217 goto cleanexit;
218 }
219 bytestring2bignum(&(dsakey.q), bkey->subprime, subprime_bytes);
220
221 /* Convert base g to bignum. */
222 if ((brv = big_extend(&(dsakey.g),
223 CHARLEN2BIGNUMLEN(bkey->base_bytes))) != BIG_OK) {
224 rv = convert_rv(brv);
225 goto cleanexit;
226 }
227 bytestring2bignum(&(dsakey.g), bkey->base, bkey->base_bytes);
228
229 /*
230 * Generate DSA key pair.
231 * Note: bignum.len is length of value in words.
232 */
233 if ((rv = generate_dsa_key(&dsakey, bkey->rfunc)) !=
234 CKR_OK) {
235 goto cleanexit;
236 }
237
238 bkey->public_y_bits = CRYPTO_BYTES2BITS(prime_bytes);
239 bignum2bytestring(bkey->public_y, &(dsakey.y), prime_bytes);
240
241 bkey->private_x_bits = CRYPTO_BYTES2BITS(DSA_SUBPRIME_BYTES);
242 bignum2bytestring(bkey->private_x, &(dsakey.x), DSA_SUBPRIME_BYTES);
243
244 cleanexit:
245 DSA_key_finish(&dsakey);
246
247 return (rv);
248 }
249
250 /*
251 * DSA sign operation
252 */
253 CK_RV
dsa_sign(DSAbytekey * bkey,uchar_t * in,uint32_t inlen,uchar_t * out)254 dsa_sign(DSAbytekey *bkey, uchar_t *in, uint32_t inlen, uchar_t *out)
255 {
256 CK_RV rv = CKR_OK;
257 BIG_ERR_CODE brv;
258 DSAkey dsakey;
259 BIGNUM msg, tmp, tmp1;
260 uint32_t prime_bytes;
261 uint32_t subprime_bytes;
262 uint32_t value_bytes;
263 int (*rf)(void *, size_t);
264
265 prime_bytes = CRYPTO_BITS2BYTES(bkey->prime_bits);
266 subprime_bytes = CRYPTO_BITS2BYTES(bkey->subprime_bits);
267
268 if (DSA_SUBPRIME_BYTES != subprime_bytes) {
269 return (CKR_KEY_SIZE_RANGE);
270 }
271
272 value_bytes = CRYPTO_BITS2BYTES(bkey->private_x_bits); /* len of x */
273
274 if (DSA_SUBPRIME_BYTES < value_bytes) {
275 return (CKR_KEY_SIZE_RANGE);
276 }
277
278 /*
279 * Initialize the DH key.
280 * Note: big_extend takes length in words.
281 */
282 if ((brv = DSA_key_init(&dsakey, bkey->prime_bits)) != BIG_OK) {
283 return (CKR_HOST_MEMORY);
284 }
285
286 if ((brv = big_extend(&(dsakey.p),
287 CHARLEN2BIGNUMLEN(prime_bytes))) != BIG_OK) {
288 rv = convert_rv(brv);
289 goto clean1;
290 }
291 bytestring2bignum(&(dsakey.p), bkey->prime, prime_bytes);
292
293 if ((brv = big_extend(&(dsakey.q),
294 CHARLEN2BIGNUMLEN(subprime_bytes))) != BIG_OK) {
295 rv = convert_rv(brv);
296 goto clean1;
297 }
298 bytestring2bignum(&(dsakey.q), bkey->subprime, subprime_bytes);
299
300 if ((brv = big_extend(&(dsakey.g),
301 CHARLEN2BIGNUMLEN(bkey->base_bytes))) != BIG_OK) {
302 rv = convert_rv(brv);
303 goto clean1;
304 }
305 bytestring2bignum(&(dsakey.g), bkey->base, bkey->base_bytes);
306
307 if ((brv = big_extend(&(dsakey.x),
308 CHARLEN2BIGNUMLEN(value_bytes))) != BIG_OK) {
309 rv = convert_rv(brv);
310 goto clean1;
311 }
312 bytestring2bignum(&(dsakey.x), bkey->private_x, value_bytes);
313
314 if ((brv = big_init(&msg, BIG_CHUNKS_FOR_160BITS)) != BIG_OK) {
315 rv = convert_rv(brv);
316 goto clean1;
317 }
318 bytestring2bignum(&msg, in, inlen);
319
320 /*
321 * Compute signature.
322 */
323 if ((brv = big_init(&tmp, CHARLEN2BIGNUMLEN(prime_bytes) +
324 2 * BIG_CHUNKS_FOR_160BITS + 1)) != BIG_OK) {
325 rv = convert_rv(brv);
326 goto clean2;
327 }
328 if ((brv = big_init(&tmp1, 2 * BIG_CHUNKS_FOR_160BITS + 1)) != BIG_OK) {
329 rv = convert_rv(brv);
330 goto clean3;
331 }
332
333 rf = bkey->rfunc;
334 if (rf == NULL) {
335 #ifdef _KERNEL
336 rf = random_get_pseudo_bytes;
337 #else
338 rf = pkcs11_get_urandom;
339 #endif
340 }
341 if ((brv = big_random(&(dsakey.k), DSA_SUBPRIME_BITS, rf)) != BIG_OK) {
342 rv = convert_rv(brv);
343 goto clean4;
344 }
345
346 if ((brv = big_div_pos(NULL, &(dsakey.k), &(dsakey.k),
347 &(dsakey.q))) != BIG_OK) {
348 rv = convert_rv(brv);
349 goto clean4;
350 }
351
352 if ((brv = big_modexp(&tmp, &(dsakey.g), &(dsakey.k), &(dsakey.p),
353 NULL)) != BIG_OK) {
354 rv = convert_rv(brv);
355 goto clean4;
356 }
357
358 if ((brv = big_div_pos(NULL, &(dsakey.r), &tmp, &(dsakey.q))) !=
359 BIG_OK) {
360 rv = convert_rv(brv);
361 goto clean4;
362 }
363
364
365 if ((brv = big_ext_gcd_pos(NULL, NULL, &tmp, &(dsakey.q),
366 &(dsakey.k))) != BIG_OK) {
367 rv = convert_rv(brv);
368 goto clean4;
369 }
370
371 if (tmp.sign == -1)
372 if ((brv = big_add(&tmp, &tmp, &(dsakey.q))) != BIG_OK) {
373 rv = convert_rv(brv);
374 goto clean4; /* tmp <- k^-1 */
375 }
376
377 if ((brv = big_mul(&tmp1, &(dsakey.x), &(dsakey.r))) != BIG_OK) {
378 rv = convert_rv(brv);
379 goto clean4;
380 }
381
382 if ((brv = big_add(&tmp1, &tmp1, &msg)) != BIG_OK) {
383 rv = convert_rv(brv);
384 goto clean4;
385 }
386
387 if ((brv = big_mul(&tmp, &tmp1, &tmp)) != BIG_OK) {
388 rv = convert_rv(brv);
389 goto clean4;
390 }
391
392 if ((brv = big_div_pos(NULL, &(dsakey.s), &tmp, &(dsakey.q))) !=
393 BIG_OK) {
394 rv = convert_rv(brv);
395 goto clean4;
396 }
397
398 /*
399 * Signature is in DSA key r and s values, copy to out
400 */
401 bignum2bytestring(out, &(dsakey.r), DSA_SUBPRIME_BYTES);
402 bignum2bytestring(out + DSA_SUBPRIME_BYTES, &(dsakey.s),
403 DSA_SUBPRIME_BYTES);
404
405 clean4:
406 big_finish(&tmp1);
407 clean3:
408 big_finish(&tmp);
409 clean2:
410 big_finish(&msg);
411 clean1:
412 DSA_key_finish(&dsakey);
413
414 return (rv);
415 }
416
417 /*
418 * DSA verify operation
419 */
420 CK_RV
dsa_verify(DSAbytekey * bkey,uchar_t * data,uchar_t * sig)421 dsa_verify(DSAbytekey *bkey, uchar_t *data, uchar_t *sig)
422 {
423 CK_RV rv = CKR_OK;
424 BIG_ERR_CODE brv;
425 DSAkey dsakey;
426 BIGNUM msg, tmp1, tmp2, tmp3;
427 uint32_t prime_bytes;
428 uint32_t subprime_bytes;
429 uint32_t value_bytes;
430
431 prime_bytes = CRYPTO_BITS2BYTES(bkey->prime_bits);
432 subprime_bytes = CRYPTO_BITS2BYTES(bkey->subprime_bits);
433
434 if (DSA_SUBPRIME_BYTES != subprime_bytes) {
435 return (CKR_KEY_SIZE_RANGE);
436 }
437
438 if (prime_bytes < bkey->base_bytes) {
439 return (CKR_KEY_SIZE_RANGE);
440 }
441
442 value_bytes = CRYPTO_BITS2BYTES(bkey->public_y_bits); /* len of y */
443 if (prime_bytes < value_bytes) {
444 return (CKR_KEY_SIZE_RANGE);
445 }
446
447 /*
448 * Initialize the DSA key.
449 * Note: big_extend takes length in words.
450 */
451 if (DSA_key_init(&dsakey, bkey->prime_bits) != BIG_OK) {
452 return (CKR_HOST_MEMORY);
453 }
454
455 if ((brv = big_extend(&(dsakey.p),
456 CHARLEN2BIGNUMLEN(prime_bytes))) != BIG_OK) {
457 rv = convert_rv(brv);
458 goto clean1;
459 }
460 bytestring2bignum(&(dsakey.p), bkey->prime, prime_bytes);
461
462 if ((brv = big_extend(&(dsakey.q),
463 CHARLEN2BIGNUMLEN(subprime_bytes))) != BIG_OK) {
464 rv = convert_rv(brv);
465 goto clean1;
466 }
467 bytestring2bignum(&(dsakey.q), bkey->subprime, subprime_bytes);
468
469 if ((brv = big_extend(&(dsakey.g),
470 CHARLEN2BIGNUMLEN(bkey->base_bytes))) != BIG_OK) {
471 rv = convert_rv(brv);
472 goto clean1;
473 }
474 bytestring2bignum(&(dsakey.g), bkey->base, bkey->base_bytes);
475
476 if ((brv = big_extend(&(dsakey.y),
477 CHARLEN2BIGNUMLEN(value_bytes))) != BIG_OK) {
478 rv = convert_rv(brv);
479 goto clean1;
480 }
481 bytestring2bignum(&(dsakey.y), bkey->public_y, value_bytes);
482
483 /*
484 * Copy signature to DSA key r and s values
485 */
486 if ((brv = big_extend(&(dsakey.r),
487 CHARLEN2BIGNUMLEN(DSA_SUBPRIME_BYTES))) != BIG_OK) {
488 rv = convert_rv(brv);
489 goto clean1;
490 }
491 bytestring2bignum(&(dsakey.r), sig, DSA_SUBPRIME_BYTES);
492
493 if ((brv = big_extend(&(dsakey.s),
494 CHARLEN2BIGNUMLEN(DSA_SUBPRIME_BYTES))) != BIG_OK) {
495 rv = convert_rv(brv);
496 goto clean1;
497 }
498 bytestring2bignum(&(dsakey.s), sig + DSA_SUBPRIME_BYTES,
499 DSA_SUBPRIME_BYTES);
500
501
502 if (big_init(&msg, BIG_CHUNKS_FOR_160BITS) != BIG_OK) {
503 rv = CKR_HOST_MEMORY;
504 goto clean1;
505 }
506 bytestring2bignum(&msg, data, DSA_SUBPRIME_BYTES);
507
508 if (big_init(&tmp1, 2 * CHARLEN2BIGNUMLEN(prime_bytes)) != BIG_OK) {
509 rv = CKR_HOST_MEMORY;
510 goto clean2;
511 }
512 if (big_init(&tmp2, CHARLEN2BIGNUMLEN(prime_bytes)) != BIG_OK) {
513 rv = CKR_HOST_MEMORY;
514 goto clean3;
515 }
516 if (big_init(&tmp3, 2 * BIG_CHUNKS_FOR_160BITS) != BIG_OK) {
517 rv = CKR_HOST_MEMORY;
518 goto clean4;
519 }
520
521 /*
522 * Verify signature against msg.
523 */
524 if (big_ext_gcd_pos(NULL, &tmp2, NULL, &(dsakey.s), &(dsakey.q)) !=
525 BIG_OK) {
526 rv = convert_rv(brv);
527 goto clean5;
528 }
529
530 if (tmp2.sign == -1)
531 if (big_add(&tmp2, &tmp2, &(dsakey.q)) != BIG_OK) {
532 rv = convert_rv(brv);
533 goto clean5; /* tmp2 <- w */
534 }
535
536 if (big_mul(&tmp1, &msg, &tmp2) != BIG_OK) {
537 rv = convert_rv(brv);
538 goto clean5;
539 }
540
541 if (big_div_pos(NULL, &tmp1, &tmp1, &(dsakey.q)) != BIG_OK) {
542 rv = convert_rv(brv);
543 goto clean5; /* tmp1 <- u_1 */
544 }
545
546 if (big_mul(&tmp2, &tmp2, &(dsakey.r)) != BIG_OK) {
547 rv = convert_rv(brv);
548 goto clean5;
549 }
550
551 if (big_div_pos(NULL, &tmp2, &tmp2, &(dsakey.q)) != BIG_OK) {
552 rv = convert_rv(brv);
553 goto clean5; /* tmp2 <- u_2 */
554 }
555
556 if (big_modexp(&tmp1, &(dsakey.g), &tmp1, &(dsakey.p), NULL) !=
557 BIG_OK) {
558 rv = convert_rv(brv);
559 goto clean5;
560 }
561
562 if (big_modexp(&tmp2, &(dsakey.y), &tmp2, &(dsakey.p), NULL) !=
563 BIG_OK) {
564 rv = convert_rv(brv);
565 goto clean5;
566 }
567
568 if (big_mul(&tmp1, &tmp1, &tmp2) != BIG_OK) {
569 rv = convert_rv(brv);
570 goto clean5;
571 }
572
573 if (big_div_pos(NULL, &tmp1, &tmp1, &(dsakey.p)) != BIG_OK) {
574 rv = convert_rv(brv);
575 goto clean5;
576 }
577
578 if (big_div_pos(NULL, &tmp1, &tmp1, &(dsakey.q)) != BIG_OK) {
579 rv = convert_rv(brv);
580 goto clean5;
581 }
582
583 if (big_cmp_abs(&tmp1, &(dsakey.r)) == 0)
584 rv = CKR_OK;
585 else
586 rv = CKR_SIGNATURE_INVALID;
587
588 clean5:
589 big_finish(&tmp3);
590 clean4:
591 big_finish(&tmp2);
592 clean3:
593 big_finish(&tmp1);
594 clean2:
595 big_finish(&msg);
596 clean1:
597 DSA_key_finish(&dsakey);
598
599 return (rv);
600 }
601