Return to botan_ec_diffie_hellman.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / botan |
1.1 misho 1: /*
2: * Copyright (C) 2018 René Korthaus
3: * Rohde & Schwarz Cybersecurity GmbH
4: *
5: * Permission is hereby granted, free of charge, to any person obtaining a copy
6: * of this software and associated documentation files (the "Software"), to deal
7: * in the Software without restriction, including without limitation the rights
8: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9: * copies of the Software, and to permit persons to whom the Software is
10: * furnished to do so, subject to the following conditions:
11: *
12: * The above copyright notice and this permission notice shall be included in
13: * all copies or substantial portions of the Software.
14: *
15: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21: * THE SOFTWARE.
22: */
23:
24: #include "botan_ec_diffie_hellman.h"
25:
26: #include <botan/build.h>
27:
28: #ifdef BOTAN_HAS_ECDH
29:
30: #include "botan_util.h"
31:
32: #include <utils/debug.h>
33:
34: #include <botan/ffi.h>
35:
36: typedef struct private_botan_ec_diffie_hellman_t private_botan_ec_diffie_hellman_t;
37:
38: /**
39: * Private data of a botan_ec_diffie_hellman_t object.
40: */
41: struct private_botan_ec_diffie_hellman_t {
42:
43: /**
44: * Public interface
45: */
46: botan_ec_diffie_hellman_t public;
47:
48: /**
49: * Diffie Hellman group
50: */
51: diffie_hellman_group_t group;
52:
53: /**
54: * EC curve name
55: */
56: const char* curve_name;
57:
58: /**
59: * EC private key
60: */
61: botan_privkey_t key;
62:
63: /**
64: * Shared secret
65: */
66: chunk_t shared_secret;
67: };
68:
69: METHOD(diffie_hellman_t, set_other_public_value, bool,
70: private_botan_ec_diffie_hellman_t *this, chunk_t value)
71: {
72: if (!diffie_hellman_verify_value(this->group, value))
73: {
74: return FALSE;
75: }
76:
77: chunk_clear(&this->shared_secret);
78:
79: /* prepend 0x04 to indicate uncompressed point format */
80: value = chunk_cata("cc", chunk_from_chars(0x04), value);
81:
82: return botan_dh_key_derivation(this->key, value, &this->shared_secret);
83: }
84:
85: METHOD(diffie_hellman_t, get_my_public_value, bool,
86: private_botan_ec_diffie_hellman_t *this, chunk_t *value)
87: {
88: chunk_t pkey = chunk_empty;
89:
90: if (botan_pk_op_key_agreement_export_public(this->key, NULL, &pkey.len)
91: != BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE)
92: {
93: return FALSE;
94: }
95:
96: pkey = chunk_alloca(pkey.len);
97: if (botan_pk_op_key_agreement_export_public(this->key, pkey.ptr, &pkey.len))
98: {
99: return FALSE;
100: }
101:
102: /* skip 0x04 byte prepended by botan */
103: *value = chunk_clone(chunk_skip(pkey, 1));
104: return TRUE;
105: }
106:
107: METHOD(diffie_hellman_t, set_private_value, bool,
108: private_botan_ec_diffie_hellman_t *this, chunk_t value)
109: {
110: botan_mp_t scalar;
111:
112: chunk_clear(&this->shared_secret);
113:
114: if (!chunk_to_botan_mp(value, &scalar))
115: {
116: return FALSE;
117: }
118:
119: if (botan_privkey_destroy(this->key))
120: {
121: botan_mp_destroy(scalar);
122: return FALSE;
123: }
124:
125: if (botan_privkey_load_ecdh(&this->key, scalar, this->curve_name))
126: {
127: botan_mp_destroy(scalar);
128: return FALSE;
129: }
130:
131: botan_mp_destroy(scalar);
132: return TRUE;
133: }
134:
135: METHOD(diffie_hellman_t, get_shared_secret, bool,
136: private_botan_ec_diffie_hellman_t *this, chunk_t *secret)
137: {
138: if (!this->shared_secret.len)
139: {
140: return FALSE;
141: }
142: *secret = chunk_clone(this->shared_secret);
143: return TRUE;
144: }
145:
146: METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
147: private_botan_ec_diffie_hellman_t *this)
148: {
149: return this->group;
150: }
151:
152: METHOD(diffie_hellman_t, destroy, void,
153: private_botan_ec_diffie_hellman_t *this)
154: {
155: botan_privkey_destroy(this->key);
156: chunk_clear(&this->shared_secret);
157: free(this);
158: }
159:
160: /*
161: * Described in header.
162: */
163: botan_ec_diffie_hellman_t *botan_ec_diffie_hellman_create(
164: diffie_hellman_group_t group)
165: {
166: private_botan_ec_diffie_hellman_t *this;
167: botan_rng_t rng;
168:
169: INIT(this,
170: .public = {
171: .dh = {
172: .get_shared_secret = _get_shared_secret,
173: .set_other_public_value = _set_other_public_value,
174: .get_my_public_value = _get_my_public_value,
175: .set_private_value = _set_private_value,
176: .get_dh_group = _get_dh_group,
177: .destroy = _destroy,
178: },
179: },
180: .group = group,
181: );
182:
183: switch (group)
184: {
185: case ECP_256_BIT:
186: this->curve_name = "secp256r1";
187: break;
188: case ECP_384_BIT:
189: this->curve_name = "secp384r1";
190: break;
191: case ECP_521_BIT:
192: this->curve_name = "secp521r1";
193: break;
194: case ECP_256_BP:
195: this->curve_name = "brainpool256r1";
196: break;
197: case ECP_384_BP:
198: this->curve_name = "brainpool384r1";
199: break;
200: case ECP_512_BP:
201: this->curve_name = "brainpool512r1";
202: break;
203: default:
204: free(this);
205: return NULL;
206: }
207:
1.1.1.2 ! misho 208: if (!botan_get_rng(&rng, RNG_STRONG))
1.1 misho 209: {
210: free(this);
211: return NULL;
212: }
213:
214: if (botan_privkey_create(&this->key, "ECDH", this->curve_name, rng))
215: {
216: DBG1(DBG_LIB, "ECDH private key generation failed");
217: botan_rng_destroy(rng);
218: free(this);
219: return NULL;
220: }
221:
222: botan_rng_destroy(rng);
223: return &this->public;
224: }
225:
226: #endif