Return to botan_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: * Copyright (C) 2018 Konstantinos Kolelis 4: * Rohde & Schwarz Cybersecurity GmbH 5: * 6: * Permission is hereby granted, free of charge, to any person obtaining a copy 7: * of this software and associated documentation files (the "Software"), to deal 8: * in the Software without restriction, including without limitation the rights 9: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10: * copies of the Software, and to permit persons to whom the Software is 11: * furnished to do so, subject to the following conditions: 12: * 13: * The above copyright notice and this permission notice shall be included in 14: * all copies or substantial portions of the Software. 15: * 16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22: * THE SOFTWARE. 23: */ 24: 25: #include "botan_diffie_hellman.h" 26: 27: #include <botan/build.h> 28: 29: #ifdef BOTAN_HAS_DIFFIE_HELLMAN 30: 31: #include "botan_util.h" 32: 33: #include <botan/ffi.h> 34: 35: #include <utils/debug.h> 36: 37: typedef struct private_botan_diffie_hellman_t private_botan_diffie_hellman_t; 38: 39: /** 40: * Private data of an botan_diffie_hellman_t object. 41: */ 42: struct private_botan_diffie_hellman_t { 43: 44: /** 45: * Public botan_diffie_hellman_t interface 46: */ 47: botan_diffie_hellman_t public; 48: 49: /** 50: * Diffie Hellman group number 51: */ 52: diffie_hellman_group_t group; 53: 54: /** 55: * Private key 56: */ 57: botan_privkey_t dh_key; 58: 59: /** 60: * Diffie hellman shared secret 61: */ 62: chunk_t shared_secret; 63: 64: /** 65: * Generator value 66: */ 67: botan_mp_t g; 68: 69: /** 70: * Modulus 71: */ 72: botan_mp_t p; 73: }; 74: 75: /** 76: * Load a DH private key 77: */ 78: bool load_private_key(private_botan_diffie_hellman_t *this, chunk_t value) 79: { 80: botan_mp_t xa; 81: 82: if (!chunk_to_botan_mp(value, &xa)) 83: { 84: return FALSE; 85: } 86: 87: if (botan_privkey_destroy(this->dh_key) || 88: botan_privkey_load_dh(&this->dh_key, this->p, this->g, xa)) 89: { 90: botan_mp_destroy(xa); 91: return FALSE; 92: } 93: botan_mp_destroy(xa); 94: return TRUE; 95: } 96: 97: METHOD(diffie_hellman_t, set_other_public_value, bool, 98: private_botan_diffie_hellman_t *this, chunk_t value) 99: { 100: if (!diffie_hellman_verify_value(this->group, value)) 101: { 102: return FALSE; 103: } 104: 105: chunk_clear(&this->shared_secret); 106: 107: return botan_dh_key_derivation(this->dh_key, value, &this->shared_secret); 108: } 109: 110: METHOD(diffie_hellman_t, get_my_public_value, bool, 111: private_botan_diffie_hellman_t *this, chunk_t *value) 112: { 113: *value = chunk_empty; 114: 115: /* get key size of public key first */ 116: if (botan_pk_op_key_agreement_export_public(this->dh_key, NULL, &value->len) 117: != BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE) 118: { 119: return FALSE; 120: } 121: 122: *value = chunk_alloc(value->len); 123: if (botan_pk_op_key_agreement_export_public(this->dh_key, value->ptr, 124: &value->len)) 125: { 126: chunk_clear(value); 127: return FALSE; 128: } 129: return TRUE; 130: } 131: 132: METHOD(diffie_hellman_t, set_private_value, bool, 133: private_botan_diffie_hellman_t *this, chunk_t value) 134: { 135: chunk_clear(&this->shared_secret); 136: return load_private_key(this, value); 137: } 138: 139: METHOD(diffie_hellman_t, get_shared_secret, bool, 140: private_botan_diffie_hellman_t *this, chunk_t *secret) 141: { 142: if (!this->shared_secret.len) 143: { 144: return FALSE; 145: } 146: *secret = chunk_clone(this->shared_secret); 147: return TRUE; 148: } 149: 150: METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, 151: private_botan_diffie_hellman_t *this) 152: { 153: return this->group; 154: } 155: 156: METHOD(diffie_hellman_t, destroy, void, 157: private_botan_diffie_hellman_t *this) 158: { 159: botan_mp_destroy(this->p); 160: botan_mp_destroy(this->g); 161: botan_privkey_destroy(this->dh_key); 162: chunk_clear(&this->shared_secret); 163: free(this); 164: } 165: 166: /* 167: * Generic internal constructor 168: */ 169: static botan_diffie_hellman_t *create_generic(diffie_hellman_group_t group, 170: chunk_t g, chunk_t p, size_t exp_len) 171: { 172: private_botan_diffie_hellman_t *this; 173: chunk_t random; 174: rng_t *rng; 175: 176: INIT(this, 177: .public = { 178: .dh = { 179: .get_shared_secret = _get_shared_secret, 180: .set_other_public_value = _set_other_public_value, 181: .get_my_public_value = _get_my_public_value, 182: .set_private_value = _set_private_value, 183: .get_dh_group = _get_dh_group, 184: .destroy = _destroy, 185: }, 186: }, 187: .group = group, 188: ); 189: 190: if (!chunk_to_botan_mp(p, &this->p)) 191: { 192: destroy(this); 193: return NULL; 194: } 195: 196: if (!chunk_to_botan_mp(g, &this->g)) 197: { 198: destroy(this); 199: return NULL; 200: } 201: 202: rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG); 203: if (!rng || !rng->allocate_bytes(rng, exp_len, &random)) 204: { 205: DESTROY_IF(rng); 206: destroy(this); 207: return NULL; 208: } 209: rng->destroy(rng); 210: 211: if (!load_private_key(this, random)) 212: { 213: chunk_clear(&random); 214: destroy(this); 215: return NULL; 216: } 217: chunk_clear(&random); 218: return &this->public; 219: } 220: 221: /* 222: * Described in header. 223: */ 224: botan_diffie_hellman_t *botan_diffie_hellman_create( 225: diffie_hellman_group_t group, ...) 226: { 227: diffie_hellman_params_t *params; 228: chunk_t g, p; 229: 230: if (group == MODP_CUSTOM) 231: { 232: VA_ARGS_GET(group, g, p); 233: return create_generic(group, g, p, p.len); 234: } 235: 236: params = diffie_hellman_get_params(group); 237: if (!params) 238: { 239: return NULL; 240: } 241: return create_generic(group, params->generator, params->prime, 242: params->exp_len); 243: } 244: 245: #endif