Annotation of embedaddon/strongswan/src/libstrongswan/plugins/botan/botan_diffie_hellman.c, revision 1.1
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
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>