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