Annotation of embedaddon/strongswan/src/libstrongswan/plugins/wolfssl/wolfssl_x_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: #ifdef HAVE_CURVE25519
26:
27: #include "wolfssl_x_diffie_hellman.h"
28:
29: #include <utils/debug.h>
30:
31: #include <wolfssl/wolfcrypt/curve25519.h>
32: #include <wolfssl/wolfcrypt/fe_operations.h>
33:
34: typedef struct private_diffie_hellman_t private_diffie_hellman_t;
35:
36: /**
37: * Private data
38: */
39: struct private_diffie_hellman_t {
40: /**
41: * Public interface.
42: */
43: diffie_hellman_t public;
44:
45: /**
46: * Diffie Hellman group number.
47: */
48: diffie_hellman_group_t group;
49:
50: /**
51: * Private (public) key
52: */
53: curve25519_key key;
54:
55: /**
56: * Shared secret
57: */
58: chunk_t shared_secret;
59: };
60:
61: /**
62: * Compute the shared secret
63: */
64: static bool compute_shared_key(private_diffie_hellman_t *this,
65: curve25519_key *pub, chunk_t *shared_secret)
66: {
67: word32 len = CURVE25519_KEYSIZE;
68: int ret;
69:
70: *shared_secret = chunk_alloc(len);
71: ret = wc_curve25519_shared_secret_ex(&this->key, pub, shared_secret->ptr,
72: &len, EC25519_LITTLE_ENDIAN);
73: return ret == 0;
74: }
75:
76: METHOD(diffie_hellman_t, set_other_public_value, bool,
77: private_diffie_hellman_t *this, chunk_t value)
78: {
79: curve25519_key pub;
80: int ret;
81:
82: if (!diffie_hellman_verify_value(this->group, value))
83: {
84: return FALSE;
85: }
86:
87: ret = wc_curve25519_init(&pub);
88: if (ret != 0)
89: {
90: DBG1(DBG_LIB, "%N public key initialization failed",
91: diffie_hellman_group_names, this->group);
92: return FALSE;
93: }
94:
95: ret = wc_curve25519_import_public_ex(value.ptr, value.len, &pub,
96: EC25519_LITTLE_ENDIAN);
97: if (ret != 0)
98: {
99: DBG1(DBG_LIB, "%N public value is malformed",
100: diffie_hellman_group_names, this->group);
101: return FALSE;
102: }
103:
104: chunk_clear(&this->shared_secret);
105:
106: if (!compute_shared_key(this, &pub, &this->shared_secret))
107: {
108: DBG1(DBG_LIB, "%N shared secret computation failed",
109: diffie_hellman_group_names, this->group);
110: chunk_clear(&this->shared_secret);
111: wc_curve25519_free(&pub);
112: return FALSE;
113: }
114: wc_curve25519_free(&pub);
115: return TRUE;
116: }
117:
118: METHOD(diffie_hellman_t, get_my_public_value, bool,
119: private_diffie_hellman_t *this, chunk_t *value)
120: {
121: word32 len = CURVE25519_KEYSIZE;
122:
123: *value = chunk_alloc(len);
124: if (wc_curve25519_export_public_ex(&this->key, value->ptr, &len,
125: EC25519_LITTLE_ENDIAN) != 0)
126: {
127: chunk_free(value);
128: return FALSE;
129: }
130: return TRUE;
131: }
132:
133: METHOD(diffie_hellman_t, set_private_value, bool,
134: private_diffie_hellman_t *this, chunk_t value)
135: {
136: curve25519_key pub;
137: u_char basepoint[CURVE25519_KEYSIZE] = {9};
138: word32 len = CURVE25519_KEYSIZE;
139: int ret;
140:
141: ret = wc_curve25519_init(&pub);
142: /* create base point for calculating public key */
143: if (ret == 0)
144: {
145: ret = wc_curve25519_import_public_ex(basepoint, CURVE25519_KEYSIZE,
146: &pub, EC25519_LITTLE_ENDIAN);
147: }
148: if (ret == 0)
149: {
150: ret = wc_curve25519_import_private_ex(value.ptr, value.len, &this->key,
151: EC25519_LITTLE_ENDIAN);
152: }
153: if (ret == 0)
154: {
155: ret = wc_curve25519_shared_secret_ex(&this->key, &pub,
156: this->key.p.point, &len, EC25519_LITTLE_ENDIAN);
157: }
158: return ret == 0;
159: }
160:
161: METHOD(diffie_hellman_t, get_shared_secret, bool,
162: private_diffie_hellman_t *this, chunk_t *secret)
163: {
164: if (!this->shared_secret.len)
165: {
166: return FALSE;
167: }
168: *secret = chunk_clone(this->shared_secret);
169: return TRUE;
170: }
171:
172: METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
173: private_diffie_hellman_t *this)
174: {
175: return this->group;
176: }
177:
178: METHOD(diffie_hellman_t, destroy, void,
179: private_diffie_hellman_t *this)
180: {
181: wc_curve25519_free(&this->key);
182: chunk_clear(&this->shared_secret);
183: free(this);
184: }
185:
186: /*
187: * Described in header
188: */
189: diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group)
190: {
191: private_diffie_hellman_t *this;
192: WC_RNG rng;
193: int ret;
194:
195: INIT(this,
196: .public = {
197: .get_shared_secret = _get_shared_secret,
198: .set_other_public_value = _set_other_public_value,
199: .get_my_public_value = _get_my_public_value,
200: .set_private_value = _set_private_value,
201: .get_dh_group = _get_dh_group,
202: .destroy = _destroy,
203: },
204: .group = group,
205: );
206:
207: if (wc_curve25519_init(&this->key) != 0)
208: {
209: DBG1(DBG_LIB, "initializing key failed");
210: free(this);
211: return NULL;
212: }
213:
214: if (wc_InitRng(&rng) != 0)
215: {
216: DBG1(DBG_LIB, "initializing a random number generator failed");
217: destroy(this);
218: return NULL;
219: }
220: ret = wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &this->key);
221: wc_FreeRng(&rng);
222: if (ret != 0)
223: {
224: DBG1(DBG_LIB, "making a key failed");
225: destroy(this);
226: return NULL;
227: }
228: return &this->public;
229: }
230:
231: #endif /* HAVE_CURVE25519 */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>