Annotation of embedaddon/strongswan/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.c, revision 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>