Annotation of embedaddon/strongswan/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
3: *
4: * Permission is hereby granted, free of charge, to any person obtaining a copy
5: * of this software and associated documentation files (the "Software"), to deal
6: * in the Software without restriction, including without limitation the rights
7: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8: * copies of the Software, and to permit persons to whom the Software is
9: * furnished to do so, subject to the following conditions:
10: *
11: * The above copyright notice and this permission notice shall be included in
12: * all copies or substantial portions of the Software.
13: *
14: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20: * THE SOFTWARE.
21: */
22:
23: #include "wolfssl_common.h"
24:
25: #ifndef NO_DH
26:
27: #include <wolfssl/wolfcrypt/dh.h>
28:
29: #include "wolfssl_diffie_hellman.h"
30: #include "wolfssl_util.h"
31:
32: #include <utils/debug.h>
33:
34: typedef struct private_wolfssl_diffie_hellman_t private_wolfssl_diffie_hellman_t;
35:
36: /**
37: * Private data of an wolfssl_diffie_hellman_t object.
38: */
39: struct private_wolfssl_diffie_hellman_t {
40:
41: /**
42: * Public wolfssl_diffie_hellman_t interface.
43: */
44: wolfssl_diffie_hellman_t public;
45:
46: /**
47: * Diffie Hellman group number.
48: */
49: diffie_hellman_group_t group;
50:
51: /**
52: * Diffie Hellman object
53: */
54: DhKey dh;
55:
56: /**
57: * Length of public values
58: */
59: int len;
60:
61: /**
62: * Private key
63: */
64: chunk_t priv;
65:
66: /**
67: * Public key
68: */
69: chunk_t pub;
70:
71: /**
72: * Shared secret
73: */
74: chunk_t shared_secret;
75: };
76:
77: METHOD(diffie_hellman_t, get_my_public_value, bool,
78: private_wolfssl_diffie_hellman_t *this, chunk_t *value)
79: {
80: *value = chunk_copy_pad(chunk_alloc(this->len), this->pub, 0x00);
81: return TRUE;
82: }
83:
84: METHOD(diffie_hellman_t, get_shared_secret, bool,
85: private_wolfssl_diffie_hellman_t *this, chunk_t *secret)
86: {
87: if (!this->shared_secret.len)
88: {
89: return FALSE;
90: }
91: *secret = chunk_copy_pad(chunk_alloc(this->len), this->shared_secret, 0x00);
92: return TRUE;
93: }
94:
95: METHOD(diffie_hellman_t, set_other_public_value, bool,
96: private_wolfssl_diffie_hellman_t *this, chunk_t value)
97: {
98: word32 len;
99:
100: if (!diffie_hellman_verify_value(this->group, value))
101: {
102: return FALSE;
103: }
104:
105: chunk_clear(&this->shared_secret);
106: this->shared_secret = chunk_alloc(this->len);
107: if (wc_DhAgree(&this->dh, this->shared_secret.ptr, &len, this->priv.ptr,
108: this->priv.len, value.ptr, value.len) != 0)
109: {
110: DBG1(DBG_LIB, "DH shared secret computation failed");
111: chunk_free(&this->shared_secret);
112: return FALSE;
113: }
114: this->shared_secret.len = len;
115: return TRUE;
116: }
117:
118: METHOD(diffie_hellman_t, set_private_value, bool,
119: private_wolfssl_diffie_hellman_t *this, chunk_t value)
120: {
121: bool success = FALSE;
122: chunk_t g;
123: word32 len;
124:
125: chunk_clear(&this->priv);
126: this->priv = chunk_clone(value);
127:
128: /* calculate public value - g^priv mod p */
129: if (wolfssl_mp2chunk(&this->dh.g, &g))
130: {
131: len = this->pub.len;
132: if (wc_DhAgree(&this->dh, this->pub.ptr, &len, this->priv.ptr,
133: this->priv.len, g.ptr, g.len) == 0)
134: {
135: this->pub.len = len;
136: success = TRUE;
137: }
138: }
139:
140: free(g.ptr);
141: return success;
142: }
143:
144: METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
145: private_wolfssl_diffie_hellman_t *this)
146: {
147: return this->group;
148: }
149:
150: METHOD(diffie_hellman_t, destroy, void,
151: private_wolfssl_diffie_hellman_t *this)
152: {
153: wc_FreeDhKey(&this->dh);
154: chunk_clear(&this->pub);
155: chunk_clear(&this->priv);
156: chunk_clear(&this->shared_secret);
157: free(this);
158: }
159:
160: /**
161: * Maximum private key length when generating key
162: */
163: static int wolfssl_priv_key_size(int len)
164: {
165: if (len <= 128)
166: {
167: return 21;
168: }
169: if (len <= 256)
170: {
171: return 29;
172: }
173: if (len <= 384)
174: {
175: return 34;
176: }
177: if (len <= 512)
178: {
179: return 39;
180: }
181: if (len <= 640)
182: {
183: return 42;
184: }
185: if (len <= 768)
186: {
187: return 46;
188: }
189: if (len <= 896)
190: {
191: return 49;
192: }
193: if (len <= 1024)
194: {
195: return 52;
196: }
197: return len / 20;
198: }
199:
200: /**
201: * Generic internal constructor
202: */
203: static wolfssl_diffie_hellman_t *create_generic(diffie_hellman_group_t group,
204: chunk_t g, chunk_t p)
205: {
206: private_wolfssl_diffie_hellman_t *this;
207: word32 privLen, pubLen;
208: WC_RNG rng;
209:
210: INIT(this,
211: .public = {
212: .dh = {
213: .get_shared_secret = _get_shared_secret,
214: .set_other_public_value = _set_other_public_value,
215: .get_my_public_value = _get_my_public_value,
216: .set_private_value = _set_private_value,
217: .get_dh_group = _get_dh_group,
218: .destroy = _destroy,
219: },
220: },
221: .group = group,
222: .len = p.len,
223: );
224:
225: if (wc_InitDhKey(&this->dh) != 0)
226: {
227: free(this);
228: return NULL;
229: }
230:
231: if (wc_DhSetKey(&this->dh, p.ptr, p.len, g.ptr, g.len) != 0)
232: {
233: destroy(this);
234: return NULL;
235: }
236:
237: if (wc_InitRng(&rng) != 0)
238: {
239: destroy(this);
240: return NULL;
241: }
242:
243: this->priv = chunk_alloc(wolfssl_priv_key_size(this->len));
244: this->pub = chunk_alloc(this->len);
245: privLen = this->priv.len;
246: pubLen = this->pub.len;
247: /* generate my public and private values */
248: if (wc_DhGenerateKeyPair(&this->dh, &rng, this->priv.ptr, &privLen,
249: this->pub.ptr, &pubLen) != 0)
250: {
251: wc_FreeRng(&rng);
252: destroy(this);
253: return NULL;
254: }
255: this->pub.len = pubLen;
256: this->priv.len = privLen;
257: wc_FreeRng(&rng);
258:
259: return &this->public;
260: }
261:
262: /*
263: * Described in header
264: */
265: wolfssl_diffie_hellman_t *wolfssl_diffie_hellman_create(
266: diffie_hellman_group_t group, ...)
267: {
268: diffie_hellman_params_t *params;
269: chunk_t g, p;
270:
271: if (group == MODP_CUSTOM)
272: {
273: VA_ARGS_GET(group, g, p);
274: return create_generic(group, g, p);
275: }
276: params = diffie_hellman_get_params(group);
277: if (!params)
278: {
279: return NULL;
280: }
281: /* wolfSSL doesn't support optimized exponent sizes according to RFC 3526 */
282: return create_generic(group, params->generator, params->prime);
283: }
284:
285: #endif /* NO_DH */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>