1 /*
2 * Copyright (c) 2004 Beeyond Software Holding BV
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22
23 #include "beecrypt/c++/provider/DHKeyAgreement.h"
24 #include "beecrypt/c++/provider/DHPublicKeyImpl.h"
25
26 #include "beecrypt/c++/crypto/interfaces/DHPrivateKey.h"
27 using beecrypt::crypto::interfaces::DHPrivateKey;
28 #include "beecrypt/c++/crypto/interfaces/DHPublicKey.h"
29 using beecrypt::crypto::interfaces::DHPublicKey;
30 #include "beecrypt/c++/crypto/SecretKeyFactory.h"
31 using beecrypt::crypto::SecretKeyFactory;
32 #include "beecrypt/c++/crypto/spec/SecretKeySpec.h"
33 using beecrypt::crypto::spec::SecretKeySpec;
34 #include "beecrypt/c++/security/ProviderException.h"
35 using beecrypt::security::ProviderException;
36
37 #include <memory>
38 using std::auto_ptr;
39
40 using namespace beecrypt::provider;
41
DHKeyAgreement()42 DHKeyAgreement::DHKeyAgreement()
43 {
44 _state = UNINITIALIZED;
45 _secret = 0;
46 }
47
~DHKeyAgreement()48 DHKeyAgreement::~DHKeyAgreement()
49 {
50 delete _secret;
51 }
52
engineDoPhase(const Key & key,bool lastPhase)53 Key* DHKeyAgreement::engineDoPhase(const Key& key, bool lastPhase) throw (InvalidKeyException, IllegalStateException)
54 {
55 if (_state == INITIALIZED)
56 {
57 const DHPublicKey* pub = dynamic_cast<const DHPublicKey*>(&key);
58 if (pub)
59 {
60 transform(_y, pub->getY());
61
62 if (mpz(_y.size, _y.data) || mpgex(_y.size, _y.data, _param.p.size, _param.p.modl))
63 throw InvalidKeyException("y must be in range [1 .. (p-1)]");
64
65 mpnumber _s;
66
67 if (dlsvdp_pDHSecret(&_param, &_x, &_y, &_s))
68 throw ProviderException("BeeCrypt internal error in dlsvdp_pDHSecret");
69
70 if (lastPhase)
71 {
72 size_t req = (_s.bitlength() + 8) >> 3;
73
74 _secret = new bytearray(req);
75
76 i2osp(_secret->data(), _secret->size(), _s.data, _s.size);
77
78 _state = SHARED;
79
80 return 0;
81 }
82 else
83 {
84 // multi-party DH
85 return new DHPublicKeyImpl(_param, _s);
86 }
87 }
88 else
89 throw InvalidKeyException("not a DHPublicKey");
90 }
91 else
92 throw IllegalStateException("DHKeyAgreement wasn't initialized");
93 }
94
95
engineInit(const Key & key,SecureRandom * random)96 void DHKeyAgreement::engineInit(const Key& key, SecureRandom* random) throw (InvalidKeyException)
97 {
98 const DHPrivateKey* pri = dynamic_cast<const DHPrivateKey*>(&key);
99 if (pri)
100 {
101 transform(_param.p, pri->getParams().getP());
102 transform(_param.g, pri->getParams().getG());
103
104 transform(_x, pri->getX());
105
106 _state = INITIALIZED;
107 }
108 else
109 throw InvalidKeyException("not a DHPrivateKey");
110 }
111
engineGenerateSecret()112 bytearray* DHKeyAgreement::engineGenerateSecret() throw (IllegalStateException)
113 {
114 if (_state == SHARED)
115 {
116 bytearray* tmp = _secret;
117 _secret = 0;
118
119 _state = INITIALIZED;
120
121 return tmp;
122 }
123 else
124 throw IllegalStateException();
125 }
126
engineGenerateSecret(bytearray & b,int offset)127 int DHKeyAgreement::engineGenerateSecret(bytearray& b, int offset) throw (IllegalStateException, ShortBufferException)
128 {
129 if (_state == SHARED)
130 {
131 int size = _secret->size();
132
133 if ((b.size() - offset) > size)
134 throw ShortBufferException();
135
136 memcpy(b.data() + offset, _secret->data(), size);
137
138 delete _secret;
139 _secret = 0;
140
141 _state = INITIALIZED;
142
143 return size;
144 }
145 else
146 throw IllegalStateException();
147 }
148
engineGenerateSecret(const String & algorithm)149 SecretKey* DHKeyAgreement::engineGenerateSecret(const String& algorithm) throw (IllegalStateException, NoSuchAlgorithmException, InvalidKeyException)
150 {
151 if (_state == SHARED)
152 {
153 _state = INITIALIZED;
154
155 SecretKeyFactory* skf = SecretKeyFactory::getInstance(algorithm);
156
157 SecretKeySpec spec(*_secret, algorithm);
158
159 delete _secret;
160 _secret = 0;
161
162 try
163 {
164 auto_ptr<SecretKey> tmp(skf->generateSecret(spec));
165
166 return tmp.release();
167 }
168 catch (InvalidKeySpecException& e)
169 {
170 throw InvalidKeyException().initCause(e);
171 }
172 }
173 else
174 throw IllegalStateException();
175 }
176
engineInit(const Key & key,const AlgorithmParameterSpec & spec,SecureRandom * random)177 void DHKeyAgreement::engineInit(const Key& key, const AlgorithmParameterSpec& spec, SecureRandom* random) throw (InvalidKeyException, InvalidAlgorithmParameterException)
178 {
179 engineInit(key, random);
180 }
181