1 /*
2 Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; see the file COPYING. If not, write to the
15 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
16 MA 02110-1301 USA.
17 */
18
19
20 #include "runtime.hpp"
21 #include "dsa.hpp"
22 #include "sha.hpp"
23 #include "asn.hpp"
24 #include "modarith.hpp"
25
26
27 namespace TaoCrypt {
28
29
Swap(DSA_PublicKey & other)30 void DSA_PublicKey::Swap(DSA_PublicKey& other)
31 {
32 p_.Swap(other.p_);
33 q_.Swap(other.q_);
34 g_.Swap(other.g_);
35 y_.Swap(other.y_);
36 }
37
38
DSA_PublicKey(const DSA_PublicKey & other)39 DSA_PublicKey::DSA_PublicKey(const DSA_PublicKey& other)
40 : p_(other.p_), q_(other.q_), g_(other.g_), y_(other.y_)
41 {}
42
43
operator =(const DSA_PublicKey & that)44 DSA_PublicKey& DSA_PublicKey::operator=(const DSA_PublicKey& that)
45 {
46 DSA_PublicKey tmp(that);
47 Swap(tmp);
48 return *this;
49 }
50
51
DSA_PublicKey(Source & source)52 DSA_PublicKey::DSA_PublicKey(Source& source)
53 {
54 Initialize(source);
55 }
56
57
Initialize(Source & source)58 void DSA_PublicKey::Initialize(Source& source)
59 {
60 DSA_Public_Decoder decoder(source);
61 decoder.Decode(*this);
62 }
63
64
Initialize(const Integer & p,const Integer & q,const Integer & g,const Integer & y)65 void DSA_PublicKey::Initialize(const Integer& p, const Integer& q,
66 const Integer& g, const Integer& y)
67 {
68 p_ = p;
69 q_ = q;
70 g_ = g;
71 y_ = y;
72 }
73
74
GetModulus() const75 const Integer& DSA_PublicKey::GetModulus() const
76 {
77 return p_;
78 }
79
GetSubGroupOrder() const80 const Integer& DSA_PublicKey::GetSubGroupOrder() const
81 {
82 return q_;
83 }
84
85
GetSubGroupGenerator() const86 const Integer& DSA_PublicKey::GetSubGroupGenerator() const
87 {
88 return g_;
89 }
90
91
GetPublicPart() const92 const Integer& DSA_PublicKey::GetPublicPart() const
93 {
94 return y_;
95 }
96
97
SetModulus(const Integer & p)98 void DSA_PublicKey::SetModulus(const Integer& p)
99 {
100 p_ = p;
101 }
102
103
SetSubGroupOrder(const Integer & q)104 void DSA_PublicKey::SetSubGroupOrder(const Integer& q)
105 {
106 q_ = q;
107 }
108
109
SetSubGroupGenerator(const Integer & g)110 void DSA_PublicKey::SetSubGroupGenerator(const Integer& g)
111 {
112 g_ = g;
113 }
114
115
SetPublicPart(const Integer & y)116 void DSA_PublicKey::SetPublicPart(const Integer& y)
117 {
118 y_ = y;
119 }
120
121
SignatureLength() const122 word32 DSA_PublicKey::SignatureLength() const
123 {
124 return GetSubGroupOrder().ByteCount() * 2; // r and s
125 }
126
127
128
DSA_PrivateKey(Source & source)129 DSA_PrivateKey::DSA_PrivateKey(Source& source)
130 {
131 Initialize(source);
132 }
133
134
Initialize(Source & source)135 void DSA_PrivateKey::Initialize(Source& source)
136 {
137 DSA_Private_Decoder decoder(source);
138 decoder.Decode(*this);
139 }
140
141
Initialize(const Integer & p,const Integer & q,const Integer & g,const Integer & y,const Integer & x)142 void DSA_PrivateKey::Initialize(const Integer& p, const Integer& q,
143 const Integer& g, const Integer& y,
144 const Integer& x)
145 {
146 DSA_PublicKey::Initialize(p, q, g, y);
147 x_ = x;
148 }
149
150
GetPrivatePart() const151 const Integer& DSA_PrivateKey::GetPrivatePart() const
152 {
153 return x_;
154 }
155
156
SetPrivatePart(const Integer & x)157 void DSA_PrivateKey::SetPrivatePart(const Integer& x)
158 {
159 x_ = x;
160 }
161
162
DSA_Signer(const DSA_PrivateKey & key)163 DSA_Signer::DSA_Signer(const DSA_PrivateKey& key)
164 : key_(key)
165 {}
166
167
Sign(const byte * sha_digest,byte * sig,RandomNumberGenerator & rng)168 word32 DSA_Signer::Sign(const byte* sha_digest, byte* sig,
169 RandomNumberGenerator& rng)
170 {
171 const Integer& p = key_.GetModulus();
172 const Integer& q = key_.GetSubGroupOrder();
173 const Integer& g = key_.GetSubGroupGenerator();
174 const Integer& x = key_.GetPrivatePart();
175 byte* tmpPtr = sig; // initial signature output
176
177 Integer k(rng, 1, q - 1);
178
179 r_ = a_exp_b_mod_c(g, k, p);
180 r_ %= q;
181
182 Integer H(sha_digest, SHA::DIGEST_SIZE); // sha Hash(m)
183
184 Integer kInv = k.InverseMod(q);
185 s_ = (kInv * (H + x*r_)) % q;
186
187 if (!(!!r_ && !!s_))
188 return -1;
189
190 int rSz = r_.ByteCount();
191 int tmpSz = rSz;
192
193 while (tmpSz++ < SHA::DIGEST_SIZE) {
194 *sig++ = 0;
195 }
196
197 r_.Encode(sig, rSz);
198
199 sig = tmpPtr + SHA::DIGEST_SIZE; // advance sig output to s
200 int sSz = s_.ByteCount();
201 tmpSz = sSz;
202
203 while (tmpSz++ < SHA::DIGEST_SIZE) {
204 *sig++ = 0;
205 }
206
207 s_.Encode(sig, sSz);
208
209 return 40;
210 }
211
212
DSA_Verifier(const DSA_PublicKey & key)213 DSA_Verifier::DSA_Verifier(const DSA_PublicKey& key)
214 : key_(key)
215 {}
216
217
Verify(const byte * sha_digest,const byte * sig)218 bool DSA_Verifier::Verify(const byte* sha_digest, const byte* sig)
219 {
220 const Integer& p = key_.GetModulus();
221 const Integer& q = key_.GetSubGroupOrder();
222 const Integer& g = key_.GetSubGroupGenerator();
223 const Integer& y = key_.GetPublicPart();
224
225 int sz = q.ByteCount();
226
227 r_.Decode(sig, sz);
228 s_.Decode(sig + sz, sz);
229
230 if (r_ >= q || r_ < 1 || s_ >= q || s_ < 1)
231 return false;
232
233 Integer H(sha_digest, SHA::DIGEST_SIZE); // sha Hash(m)
234
235 Integer w = s_.InverseMod(q);
236 Integer u1 = (H * w) % q;
237 Integer u2 = (r_ * w) % q;
238
239 // verify r == ((g^u1 * y^u2) mod p) mod q
240 ModularArithmetic ma(p);
241 Integer v = ma.CascadeExponentiate(g, u1, y, u2);
242 v %= q;
243
244 return r_ == v;
245 }
246
247
248
249
GetR() const250 const Integer& DSA_Signer::GetR() const
251 {
252 return r_;
253 }
254
255
GetS() const256 const Integer& DSA_Signer::GetS() const
257 {
258 return s_;
259 }
260
261
GetR() const262 const Integer& DSA_Verifier::GetR() const
263 {
264 return r_;
265 }
266
267
GetS() const268 const Integer& DSA_Verifier::GetS() const
269 {
270 return s_;
271 }
272
273
274 } // namespace
275