|
|
1.1 misho 1: /*
2: * Copyright (C) 2015 Martin Willi
3: * Copyright (C) 2015 revosec AG
4: *
5: * This program is free software; you can redistribute it and/or modify it
6: * under the terms of the GNU General Public License as published by the
7: * Free Software Foundation; either version 2 of the License, or (at your
8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9: *
10: * This program is distributed in the hope that it will be useful, but
11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13: * for more details.
14: */
15:
16: #include <string.h>
17: #include <stdint.h>
18:
19: #include "curve25519_dh.h"
20: #include "curve25519_drv.h"
21:
22: typedef struct private_curve25519_dh_t private_curve25519_dh_t;
23:
24: /**
25: * Private data of an curve25519_dh_t object.
26: */
27: struct private_curve25519_dh_t {
28:
29: /**
30: * Public curve25519_dh_t interface.
31: */
32: curve25519_dh_t public;
33:
34: /**
35: * Shared key, if computed
36: */
37: u_char shared[CURVE25519_KEY_SIZE];
38:
39: /**
40: * TRUE if shared secret is computed
41: */
42: bool computed;
43:
44: /**
45: * Curve25519 backend
46: */
47: curve25519_drv_t *drv;
48: };
49:
50: /**
51: * Generate a valid Curve25519 key
52: */
53: static bool generate_key(private_curve25519_dh_t *this)
54: {
55: u_char key[CURVE25519_KEY_SIZE];
56: rng_t *rng;
57:
58: rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
59: if (!rng)
60: {
61: DBG1(DBG_LIB, "no RNG found for quality %N",
62: rng_quality_names, RNG_STRONG);
63: return FALSE;
64: }
65: if (!rng->get_bytes(rng, CURVE25519_KEY_SIZE, key))
66: {
67: rng->destroy(rng);
68: return FALSE;
69: }
70: rng->destroy(rng);
71:
72: return this->drv->set_key(this->drv, key);
73: }
74:
75: METHOD(diffie_hellman_t, set_other_public_value, bool,
76: private_curve25519_dh_t *this, chunk_t value)
77: {
78: if (value.len == CURVE25519_KEY_SIZE)
79: {
80: if (this->drv->curve25519(this->drv, value.ptr, this->shared))
81: {
82: this->computed = TRUE;
83: return TRUE;
84: }
85: }
86: return FALSE;
87: }
88:
89: METHOD(diffie_hellman_t, get_my_public_value, bool,
90: private_curve25519_dh_t *this, chunk_t *value)
91: {
92: u_char basepoint[CURVE25519_KEY_SIZE] = { 9 };
93:
94: *value = chunk_alloc(CURVE25519_KEY_SIZE);
95: if (this->drv->curve25519(this->drv, basepoint, value->ptr))
96: {
97: return TRUE;
98: }
99: free(value->ptr);
100: return FALSE;
101: }
102:
103: METHOD(diffie_hellman_t, set_private_value, bool,
104: private_curve25519_dh_t *this, chunk_t value)
105: {
106: if (value.len != CURVE25519_KEY_SIZE)
107: {
108: return FALSE;
109: }
110: return this->drv->set_key(this->drv, value.ptr);
111: }
112:
113: METHOD(diffie_hellman_t, get_shared_secret, bool,
114: private_curve25519_dh_t *this, chunk_t *secret)
115: {
116: if (!this->computed)
117: {
118: return FALSE;
119: }
120: *secret = chunk_clone(chunk_from_thing(this->shared));
121: return TRUE;
122: }
123:
124: METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
125: private_curve25519_dh_t *this)
126: {
127: return CURVE_25519;
128: }
129:
130: METHOD(diffie_hellman_t, destroy, void,
131: private_curve25519_dh_t *this)
132: {
133: this->drv->destroy(this->drv);
134: free(this);
135: }
136:
137: /*
138: * Described in header.
139: */
140: curve25519_dh_t *curve25519_dh_create(diffie_hellman_group_t group)
141: {
142: private_curve25519_dh_t *this;
143:
144: if (group != CURVE_25519)
145: {
146: return FALSE;
147: }
148:
149: INIT(this,
150: .public = {
151: .dh = {
152: .get_shared_secret = _get_shared_secret,
153: .set_other_public_value = _set_other_public_value,
154: .get_my_public_value = _get_my_public_value,
155: .set_private_value = _set_private_value,
156: .get_dh_group = _get_dh_group,
157: .destroy = _destroy,
158: },
159: },
160: .drv = curve25519_drv_probe(),
161: );
162:
163: if (!this->drv)
164: {
165: free(this);
166: return NULL;
167: }
168: if (!generate_key(this))
169: {
170: destroy(this);
171: return NULL;
172: }
173: return &this->public;
174: }