import less(1)
[unleashed/tickless.git] / usr / src / common / crypto / dsa / dsa_impl.c
blobf2c4c5ccec913926329c7b7c8510d4f57622eff4
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
27 * This file contains DSA helper routines common to
28 * the PKCS11 soft token code and the kernel DSA code.
31 #include <sys/types.h>
32 #include <bignum.h>
34 #ifdef _KERNEL
35 #include <sys/param.h>
36 #else
37 #include <strings.h>
38 #include <cryptoutil.h>
39 #endif
41 #include <sys/crypto/common.h>
42 #include "dsa_impl.h"
45 static CK_RV
46 convert_rv(BIG_ERR_CODE err)
48 switch (err) {
50 case BIG_OK:
51 return (CKR_OK);
53 case BIG_NO_MEM:
54 return (CKR_HOST_MEMORY);
56 case BIG_NO_RANDOM:
57 return (CKR_DEVICE_ERROR);
59 case BIG_INVALID_ARGS:
60 return (CKR_ARGUMENTS_BAD);
62 case BIG_DIV_BY_0:
63 default:
64 return (CKR_GENERAL_ERROR);
68 /* size is in bits */
69 static BIG_ERR_CODE
70 DSA_key_init(DSAkey *key, int size)
72 BIG_ERR_CODE err = BIG_OK;
73 int len, len160;
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;
97 return (BIG_OK);
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);
118 static void
119 DSA_key_finish(DSAkey *key)
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));
135 * Generate DSA private x and public y from prime p, subprime q, and base g.
137 static CK_RV
138 generate_dsa_key(DSAkey *key, int (*rfunc)(void *, size_t))
140 BIG_ERR_CODE err;
141 int (*rf)(void *, size_t);
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
151 do {
152 if ((err = big_random(&(key->x), DSA_SUBPRIME_BITS, rf)) !=
153 BIG_OK) {
154 return (convert_rv(err));
156 } while (big_cmp_abs(&(key->x), &(key->q)) > 0);
158 if ((err = big_modexp(&(key->y), &(key->g), (&key->x), (&key->p),
159 NULL)) != BIG_OK)
160 return (convert_rv(err));
162 return (CKR_OK);
165 CK_RV
166 dsa_genkey_pair(DSAbytekey *bkey)
168 CK_RV rv = CKR_OK;
169 BIG_ERR_CODE brv;
170 DSAkey dsakey;
171 uint32_t prime_bytes;
172 uint32_t subprime_bytes;
174 prime_bytes = CRYPTO_BITS2BYTES(bkey->prime_bits);
176 if ((prime_bytes < MIN_DSA_KEY_LEN) ||
177 (prime_bytes > MAX_DSA_KEY_LEN)) {
178 return (CKR_ATTRIBUTE_VALUE_INVALID);
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.
186 subprime_bytes = CRYPTO_BITS2BYTES(bkey->subprime_bits);
188 if (subprime_bytes != DSA_SUBPRIME_BYTES) {
189 return (CKR_ATTRIBUTE_VALUE_INVALID);
192 if (bkey->public_y == NULL || bkey->private_x == NULL) {
193 return (CKR_ARGUMENTS_BAD);
197 * Initialize the DSA key.
198 * Note: big_extend takes length in words.
200 if ((brv = DSA_key_init(&dsakey, bkey->prime_bits)) != BIG_OK) {
201 rv = convert_rv(brv);
202 goto cleanexit;
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;
211 bytestring2bignum(&(dsakey.p), bkey->prime, prime_bytes);
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;
219 bytestring2bignum(&(dsakey.q), bkey->subprime, subprime_bytes);
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;
227 bytestring2bignum(&(dsakey.g), bkey->base, bkey->base_bytes);
230 * Generate DSA key pair.
231 * Note: bignum.len is length of value in words.
233 if ((rv = generate_dsa_key(&dsakey, bkey->rfunc)) !=
234 CKR_OK) {
235 goto cleanexit;
238 bkey->public_y_bits = CRYPTO_BYTES2BITS(prime_bytes);
239 bignum2bytestring(bkey->public_y, &(dsakey.y), prime_bytes);
241 bkey->private_x_bits = CRYPTO_BYTES2BITS(DSA_SUBPRIME_BYTES);
242 bignum2bytestring(bkey->private_x, &(dsakey.x), DSA_SUBPRIME_BYTES);
244 cleanexit:
245 DSA_key_finish(&dsakey);
247 return (rv);
251 * DSA sign operation
253 CK_RV
254 dsa_sign(DSAbytekey *bkey, uchar_t *in, uint32_t inlen, uchar_t *out)
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);
265 prime_bytes = CRYPTO_BITS2BYTES(bkey->prime_bits);
266 subprime_bytes = CRYPTO_BITS2BYTES(bkey->subprime_bits);
268 if (DSA_SUBPRIME_BYTES != subprime_bytes) {
269 return (CKR_KEY_SIZE_RANGE);
272 value_bytes = CRYPTO_BITS2BYTES(bkey->private_x_bits); /* len of x */
274 if (DSA_SUBPRIME_BYTES < value_bytes) {
275 return (CKR_KEY_SIZE_RANGE);
279 * Initialize the DH key.
280 * Note: big_extend takes length in words.
282 if ((brv = DSA_key_init(&dsakey, bkey->prime_bits)) != BIG_OK) {
283 return (CKR_HOST_MEMORY);
286 if ((brv = big_extend(&(dsakey.p),
287 CHARLEN2BIGNUMLEN(prime_bytes))) != BIG_OK) {
288 rv = convert_rv(brv);
289 goto clean1;
291 bytestring2bignum(&(dsakey.p), bkey->prime, prime_bytes);
293 if ((brv = big_extend(&(dsakey.q),
294 CHARLEN2BIGNUMLEN(subprime_bytes))) != BIG_OK) {
295 rv = convert_rv(brv);
296 goto clean1;
298 bytestring2bignum(&(dsakey.q), bkey->subprime, subprime_bytes);
300 if ((brv = big_extend(&(dsakey.g),
301 CHARLEN2BIGNUMLEN(bkey->base_bytes))) != BIG_OK) {
302 rv = convert_rv(brv);
303 goto clean1;
305 bytestring2bignum(&(dsakey.g), bkey->base, bkey->base_bytes);
307 if ((brv = big_extend(&(dsakey.x),
308 CHARLEN2BIGNUMLEN(value_bytes))) != BIG_OK) {
309 rv = convert_rv(brv);
310 goto clean1;
312 bytestring2bignum(&(dsakey.x), bkey->private_x, value_bytes);
314 if ((brv = big_init(&msg, BIG_CHUNKS_FOR_160BITS)) != BIG_OK) {
315 rv = convert_rv(brv);
316 goto clean1;
318 bytestring2bignum(&msg, in, inlen);
321 * Compute signature.
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;
328 if ((brv = big_init(&tmp1, 2 * BIG_CHUNKS_FOR_160BITS + 1)) != BIG_OK) {
329 rv = convert_rv(brv);
330 goto clean3;
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
341 if ((brv = big_random(&(dsakey.k), DSA_SUBPRIME_BITS, rf)) != BIG_OK) {
342 rv = convert_rv(brv);
343 goto clean4;
346 if ((brv = big_div_pos(NULL, &(dsakey.k), &(dsakey.k),
347 &(dsakey.q))) != BIG_OK) {
348 rv = convert_rv(brv);
349 goto clean4;
352 if ((brv = big_modexp(&tmp, &(dsakey.g), &(dsakey.k), &(dsakey.p),
353 NULL)) != BIG_OK) {
354 rv = convert_rv(brv);
355 goto clean4;
358 if ((brv = big_div_pos(NULL, &(dsakey.r), &tmp, &(dsakey.q))) !=
359 BIG_OK) {
360 rv = convert_rv(brv);
361 goto clean4;
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;
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 */
377 if ((brv = big_mul(&tmp1, &(dsakey.x), &(dsakey.r))) != BIG_OK) {
378 rv = convert_rv(brv);
379 goto clean4;
382 if ((brv = big_add(&tmp1, &tmp1, &msg)) != BIG_OK) {
383 rv = convert_rv(brv);
384 goto clean4;
387 if ((brv = big_mul(&tmp, &tmp1, &tmp)) != BIG_OK) {
388 rv = convert_rv(brv);
389 goto clean4;
392 if ((brv = big_div_pos(NULL, &(dsakey.s), &tmp, &(dsakey.q))) !=
393 BIG_OK) {
394 rv = convert_rv(brv);
395 goto clean4;
399 * Signature is in DSA key r and s values, copy to out
401 bignum2bytestring(out, &(dsakey.r), DSA_SUBPRIME_BYTES);
402 bignum2bytestring(out + DSA_SUBPRIME_BYTES, &(dsakey.s),
403 DSA_SUBPRIME_BYTES);
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);
414 return (rv);
418 * DSA verify operation
420 CK_RV
421 dsa_verify(DSAbytekey *bkey, uchar_t *data, uchar_t *sig)
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;
431 prime_bytes = CRYPTO_BITS2BYTES(bkey->prime_bits);
432 subprime_bytes = CRYPTO_BITS2BYTES(bkey->subprime_bits);
434 if (DSA_SUBPRIME_BYTES != subprime_bytes) {
435 return (CKR_KEY_SIZE_RANGE);
438 if (prime_bytes < bkey->base_bytes) {
439 return (CKR_KEY_SIZE_RANGE);
442 value_bytes = CRYPTO_BITS2BYTES(bkey->public_y_bits); /* len of y */
443 if (prime_bytes < value_bytes) {
444 return (CKR_KEY_SIZE_RANGE);
448 * Initialize the DSA key.
449 * Note: big_extend takes length in words.
451 if (DSA_key_init(&dsakey, bkey->prime_bits) != BIG_OK) {
452 return (CKR_HOST_MEMORY);
455 if ((brv = big_extend(&(dsakey.p),
456 CHARLEN2BIGNUMLEN(prime_bytes))) != BIG_OK) {
457 rv = convert_rv(brv);
458 goto clean1;
460 bytestring2bignum(&(dsakey.p), bkey->prime, prime_bytes);
462 if ((brv = big_extend(&(dsakey.q),
463 CHARLEN2BIGNUMLEN(subprime_bytes))) != BIG_OK) {
464 rv = convert_rv(brv);
465 goto clean1;
467 bytestring2bignum(&(dsakey.q), bkey->subprime, subprime_bytes);
469 if ((brv = big_extend(&(dsakey.g),
470 CHARLEN2BIGNUMLEN(bkey->base_bytes))) != BIG_OK) {
471 rv = convert_rv(brv);
472 goto clean1;
474 bytestring2bignum(&(dsakey.g), bkey->base, bkey->base_bytes);
476 if ((brv = big_extend(&(dsakey.y),
477 CHARLEN2BIGNUMLEN(value_bytes))) != BIG_OK) {
478 rv = convert_rv(brv);
479 goto clean1;
481 bytestring2bignum(&(dsakey.y), bkey->public_y, value_bytes);
484 * Copy signature to DSA key r and s values
486 if ((brv = big_extend(&(dsakey.r),
487 CHARLEN2BIGNUMLEN(DSA_SUBPRIME_BYTES))) != BIG_OK) {
488 rv = convert_rv(brv);
489 goto clean1;
491 bytestring2bignum(&(dsakey.r), sig, DSA_SUBPRIME_BYTES);
493 if ((brv = big_extend(&(dsakey.s),
494 CHARLEN2BIGNUMLEN(DSA_SUBPRIME_BYTES))) != BIG_OK) {
495 rv = convert_rv(brv);
496 goto clean1;
498 bytestring2bignum(&(dsakey.s), sig + DSA_SUBPRIME_BYTES,
499 DSA_SUBPRIME_BYTES);
502 if (big_init(&msg, BIG_CHUNKS_FOR_160BITS) != BIG_OK) {
503 rv = CKR_HOST_MEMORY;
504 goto clean1;
506 bytestring2bignum(&msg, data, DSA_SUBPRIME_BYTES);
508 if (big_init(&tmp1, 2 * CHARLEN2BIGNUMLEN(prime_bytes)) != BIG_OK) {
509 rv = CKR_HOST_MEMORY;
510 goto clean2;
512 if (big_init(&tmp2, CHARLEN2BIGNUMLEN(prime_bytes)) != BIG_OK) {
513 rv = CKR_HOST_MEMORY;
514 goto clean3;
516 if (big_init(&tmp3, 2 * BIG_CHUNKS_FOR_160BITS) != BIG_OK) {
517 rv = CKR_HOST_MEMORY;
518 goto clean4;
522 * Verify signature against msg.
524 if (big_ext_gcd_pos(NULL, &tmp2, NULL, &(dsakey.s), &(dsakey.q)) !=
525 BIG_OK) {
526 rv = convert_rv(brv);
527 goto clean5;
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 */
536 if (big_mul(&tmp1, &msg, &tmp2) != BIG_OK) {
537 rv = convert_rv(brv);
538 goto clean5;
541 if (big_div_pos(NULL, &tmp1, &tmp1, &(dsakey.q)) != BIG_OK) {
542 rv = convert_rv(brv);
543 goto clean5; /* tmp1 <- u_1 */
546 if (big_mul(&tmp2, &tmp2, &(dsakey.r)) != BIG_OK) {
547 rv = convert_rv(brv);
548 goto clean5;
551 if (big_div_pos(NULL, &tmp2, &tmp2, &(dsakey.q)) != BIG_OK) {
552 rv = convert_rv(brv);
553 goto clean5; /* tmp2 <- u_2 */
556 if (big_modexp(&tmp1, &(dsakey.g), &tmp1, &(dsakey.p), NULL) !=
557 BIG_OK) {
558 rv = convert_rv(brv);
559 goto clean5;
562 if (big_modexp(&tmp2, &(dsakey.y), &tmp2, &(dsakey.p), NULL) !=
563 BIG_OK) {
564 rv = convert_rv(brv);
565 goto clean5;
568 if (big_mul(&tmp1, &tmp1, &tmp2) != BIG_OK) {
569 rv = convert_rv(brv);
570 goto clean5;
573 if (big_div_pos(NULL, &tmp1, &tmp1, &(dsakey.p)) != BIG_OK) {
574 rv = convert_rv(brv);
575 goto clean5;
578 if (big_div_pos(NULL, &tmp1, &tmp1, &(dsakey.q)) != BIG_OK) {
579 rv = convert_rv(brv);
580 goto clean5;
583 if (big_cmp_abs(&tmp1, &(dsakey.r)) == 0)
584 rv = CKR_OK;
585 else
586 rv = CKR_SIGNATURE_INVALID;
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);
599 return (rv);