Mercurial > dropbear
comparison dsa_sign_hash.c @ 3:7faae8f46238 libtomcrypt-orig
Branch renaming
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 31 May 2004 18:25:41 +0000 |
parents | |
children | 5d99163f7e32 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 3:7faae8f46238 |
---|---|
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
2 * | |
3 * LibTomCrypt is a library that provides various cryptographic | |
4 * algorithms in a highly modular and flexible manner. | |
5 * | |
6 * The library is free for all purposes without any express | |
7 * guarantee it works. | |
8 * | |
9 * Tom St Denis, [email protected], http://libtomcrypt.org | |
10 */ | |
11 #include "mycrypt.h" | |
12 | |
13 #ifdef MDSA | |
14 | |
15 int dsa_sign_hash(const unsigned char *in, unsigned long inlen, | |
16 unsigned char *out, unsigned long *outlen, | |
17 prng_state *prng, int wprng, dsa_key *key) | |
18 { | |
19 mp_int k, kinv, tmp, r, s; | |
20 unsigned char buf[512]; | |
21 int err, y; | |
22 unsigned long len; | |
23 | |
24 | |
25 _ARGCHK(in != NULL); | |
26 _ARGCHK(out != NULL); | |
27 _ARGCHK(outlen != NULL); | |
28 _ARGCHK(key != NULL); | |
29 | |
30 if ((err = prng_is_valid(wprng)) != CRYPT_OK) { | |
31 return err; | |
32 } | |
33 if (key->type != PK_PRIVATE) { | |
34 return CRYPT_PK_NOT_PRIVATE; | |
35 } | |
36 | |
37 /* check group order size */ | |
38 if (key->qord >= (int)sizeof(buf)) { | |
39 return CRYPT_INVALID_ARG; | |
40 } | |
41 | |
42 /* Init our temps */ | |
43 if ((err = mp_init_multi(&k, &kinv, &r, &s, &tmp, NULL)) != MP_OKAY) { goto error; } | |
44 | |
45 retry: | |
46 | |
47 do { | |
48 /* gen random k */ | |
49 if (prng_descriptor[wprng].read(buf, key->qord, prng) != (unsigned long)key->qord) { | |
50 err = CRYPT_ERROR_READPRNG; | |
51 goto done; | |
52 } | |
53 | |
54 /* read k */ | |
55 if ((err = mp_read_unsigned_bin(&k, buf, key->qord)) != MP_OKAY) { goto error; } | |
56 | |
57 /* k > 1 ? */ | |
58 if (mp_cmp_d(&k, 1) != MP_GT) { goto retry; } | |
59 | |
60 /* test gcd */ | |
61 if ((err = mp_gcd(&k, &key->q, &tmp)) != MP_OKAY) { goto error; } | |
62 } while (mp_cmp_d(&tmp, 1) != MP_EQ); | |
63 | |
64 /* now find 1/k mod q */ | |
65 if ((err = mp_invmod(&k, &key->q, &kinv)) != MP_OKAY) { goto error; } | |
66 | |
67 /* now find r = g^k mod p mod q */ | |
68 if ((err = mp_exptmod(&key->g, &k, &key->p, &r)) != MP_OKAY) { goto error; } | |
69 if ((err = mp_mod(&r, &key->q, &r)) != MP_OKAY) { goto error; } | |
70 | |
71 if (mp_iszero(&r) == MP_YES) { goto retry; } | |
72 | |
73 /* now find s = (in + xr)/k mod q */ | |
74 if ((err = mp_read_unsigned_bin(&tmp, (unsigned char *)in, inlen)) != MP_OKAY) { goto error; } | |
75 if ((err = mp_mul(&key->x, &r, &s)) != MP_OKAY) { goto error; } | |
76 if ((err = mp_add(&s, &tmp, &s)) != MP_OKAY) { goto error; } | |
77 if ((err = mp_mulmod(&s, &kinv, &key->q, &s)) != MP_OKAY) { goto error; } | |
78 | |
79 if (mp_iszero(&s) == MP_YES) { goto retry; } | |
80 | |
81 /* now store em both */ | |
82 | |
83 /* first check that we have enough room */ | |
84 if (*outlen < (unsigned long)(PACKET_SIZE + 4 + mp_unsigned_bin_size(&s) + mp_unsigned_bin_size(&r))) { | |
85 err = CRYPT_BUFFER_OVERFLOW; | |
86 goto done; | |
87 } | |
88 | |
89 /* packet header */ | |
90 packet_store_header(out, PACKET_SECT_DSA, PACKET_SUB_SIGNED); | |
91 y = PACKET_SIZE; | |
92 | |
93 /* store length of r */ | |
94 len = mp_unsigned_bin_size(&r); | |
95 out[y++] = (len>>8)&255; | |
96 out[y++] = len&255; | |
97 | |
98 /* store r */ | |
99 if ((err = mp_to_unsigned_bin(&r, out+y)) != MP_OKAY) { goto error; } | |
100 y += len; | |
101 | |
102 /* store length of s */ | |
103 len = mp_unsigned_bin_size(&s); | |
104 out[y++] = (len>>8)&255; | |
105 out[y++] = len&255; | |
106 | |
107 /* store s */ | |
108 if ((err = mp_to_unsigned_bin(&s, out+y)) != MP_OKAY) { goto error; } | |
109 y += len; | |
110 | |
111 /* reset size */ | |
112 *outlen = y; | |
113 | |
114 err = CRYPT_OK; | |
115 goto done; | |
116 | |
117 error : err = mpi_to_ltc_error(err); | |
118 done : mp_clear_multi(&k, &kinv, &r, &s, &tmp, NULL); | |
119 #ifdef CLEAN_STACK | |
120 zeromem(buf, sizeof(buf)); | |
121 #endif | |
122 return err; | |
123 } | |
124 | |
125 #endif |