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