Annotation of embedaddon/strongswan/src/libstrongswan/plugins/wolfssl/wolfssl_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: #ifndef NO_DH
! 26:
! 27: #include <wolfssl/wolfcrypt/dh.h>
! 28:
! 29: #include "wolfssl_diffie_hellman.h"
! 30: #include "wolfssl_util.h"
! 31:
! 32: #include <utils/debug.h>
! 33:
! 34: typedef struct private_wolfssl_diffie_hellman_t private_wolfssl_diffie_hellman_t;
! 35:
! 36: /**
! 37: * Private data of an wolfssl_diffie_hellman_t object.
! 38: */
! 39: struct private_wolfssl_diffie_hellman_t {
! 40:
! 41: /**
! 42: * Public wolfssl_diffie_hellman_t interface.
! 43: */
! 44: wolfssl_diffie_hellman_t public;
! 45:
! 46: /**
! 47: * Diffie Hellman group number.
! 48: */
! 49: diffie_hellman_group_t group;
! 50:
! 51: /**
! 52: * Diffie Hellman object
! 53: */
! 54: DhKey dh;
! 55:
! 56: /**
! 57: * Length of public values
! 58: */
! 59: int len;
! 60:
! 61: /**
! 62: * Private key
! 63: */
! 64: chunk_t priv;
! 65:
! 66: /**
! 67: * Public key
! 68: */
! 69: chunk_t pub;
! 70:
! 71: /**
! 72: * Shared secret
! 73: */
! 74: chunk_t shared_secret;
! 75: };
! 76:
! 77: METHOD(diffie_hellman_t, get_my_public_value, bool,
! 78: private_wolfssl_diffie_hellman_t *this, chunk_t *value)
! 79: {
! 80: *value = chunk_copy_pad(chunk_alloc(this->len), this->pub, 0x00);
! 81: return TRUE;
! 82: }
! 83:
! 84: METHOD(diffie_hellman_t, get_shared_secret, bool,
! 85: private_wolfssl_diffie_hellman_t *this, chunk_t *secret)
! 86: {
! 87: if (!this->shared_secret.len)
! 88: {
! 89: return FALSE;
! 90: }
! 91: *secret = chunk_copy_pad(chunk_alloc(this->len), this->shared_secret, 0x00);
! 92: return TRUE;
! 93: }
! 94:
! 95: METHOD(diffie_hellman_t, set_other_public_value, bool,
! 96: private_wolfssl_diffie_hellman_t *this, chunk_t value)
! 97: {
! 98: word32 len;
! 99:
! 100: if (!diffie_hellman_verify_value(this->group, value))
! 101: {
! 102: return FALSE;
! 103: }
! 104:
! 105: chunk_clear(&this->shared_secret);
! 106: this->shared_secret = chunk_alloc(this->len);
! 107: if (wc_DhAgree(&this->dh, this->shared_secret.ptr, &len, this->priv.ptr,
! 108: this->priv.len, value.ptr, value.len) != 0)
! 109: {
! 110: DBG1(DBG_LIB, "DH shared secret computation failed");
! 111: chunk_free(&this->shared_secret);
! 112: return FALSE;
! 113: }
! 114: this->shared_secret.len = len;
! 115: return TRUE;
! 116: }
! 117:
! 118: METHOD(diffie_hellman_t, set_private_value, bool,
! 119: private_wolfssl_diffie_hellman_t *this, chunk_t value)
! 120: {
! 121: bool success = FALSE;
! 122: chunk_t g;
! 123: word32 len;
! 124:
! 125: chunk_clear(&this->priv);
! 126: this->priv = chunk_clone(value);
! 127:
! 128: /* calculate public value - g^priv mod p */
! 129: if (wolfssl_mp2chunk(&this->dh.g, &g))
! 130: {
! 131: len = this->pub.len;
! 132: if (wc_DhAgree(&this->dh, this->pub.ptr, &len, this->priv.ptr,
! 133: this->priv.len, g.ptr, g.len) == 0)
! 134: {
! 135: this->pub.len = len;
! 136: success = TRUE;
! 137: }
! 138: }
! 139:
! 140: free(g.ptr);
! 141: return success;
! 142: }
! 143:
! 144: METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
! 145: private_wolfssl_diffie_hellman_t *this)
! 146: {
! 147: return this->group;
! 148: }
! 149:
! 150: METHOD(diffie_hellman_t, destroy, void,
! 151: private_wolfssl_diffie_hellman_t *this)
! 152: {
! 153: wc_FreeDhKey(&this->dh);
! 154: chunk_clear(&this->pub);
! 155: chunk_clear(&this->priv);
! 156: chunk_clear(&this->shared_secret);
! 157: free(this);
! 158: }
! 159:
! 160: /**
! 161: * Maximum private key length when generating key
! 162: */
! 163: static int wolfssl_priv_key_size(int len)
! 164: {
! 165: if (len <= 128)
! 166: {
! 167: return 21;
! 168: }
! 169: if (len <= 256)
! 170: {
! 171: return 29;
! 172: }
! 173: if (len <= 384)
! 174: {
! 175: return 34;
! 176: }
! 177: if (len <= 512)
! 178: {
! 179: return 39;
! 180: }
! 181: if (len <= 640)
! 182: {
! 183: return 42;
! 184: }
! 185: if (len <= 768)
! 186: {
! 187: return 46;
! 188: }
! 189: if (len <= 896)
! 190: {
! 191: return 49;
! 192: }
! 193: if (len <= 1024)
! 194: {
! 195: return 52;
! 196: }
! 197: return len / 20;
! 198: }
! 199:
! 200: /**
! 201: * Generic internal constructor
! 202: */
! 203: static wolfssl_diffie_hellman_t *create_generic(diffie_hellman_group_t group,
! 204: chunk_t g, chunk_t p)
! 205: {
! 206: private_wolfssl_diffie_hellman_t *this;
! 207: word32 privLen, pubLen;
! 208: WC_RNG rng;
! 209:
! 210: INIT(this,
! 211: .public = {
! 212: .dh = {
! 213: .get_shared_secret = _get_shared_secret,
! 214: .set_other_public_value = _set_other_public_value,
! 215: .get_my_public_value = _get_my_public_value,
! 216: .set_private_value = _set_private_value,
! 217: .get_dh_group = _get_dh_group,
! 218: .destroy = _destroy,
! 219: },
! 220: },
! 221: .group = group,
! 222: .len = p.len,
! 223: );
! 224:
! 225: if (wc_InitDhKey(&this->dh) != 0)
! 226: {
! 227: free(this);
! 228: return NULL;
! 229: }
! 230:
! 231: if (wc_DhSetKey(&this->dh, p.ptr, p.len, g.ptr, g.len) != 0)
! 232: {
! 233: destroy(this);
! 234: return NULL;
! 235: }
! 236:
! 237: if (wc_InitRng(&rng) != 0)
! 238: {
! 239: destroy(this);
! 240: return NULL;
! 241: }
! 242:
! 243: this->priv = chunk_alloc(wolfssl_priv_key_size(this->len));
! 244: this->pub = chunk_alloc(this->len);
! 245: privLen = this->priv.len;
! 246: pubLen = this->pub.len;
! 247: /* generate my public and private values */
! 248: if (wc_DhGenerateKeyPair(&this->dh, &rng, this->priv.ptr, &privLen,
! 249: this->pub.ptr, &pubLen) != 0)
! 250: {
! 251: wc_FreeRng(&rng);
! 252: destroy(this);
! 253: return NULL;
! 254: }
! 255: this->pub.len = pubLen;
! 256: this->priv.len = privLen;
! 257: wc_FreeRng(&rng);
! 258:
! 259: return &this->public;
! 260: }
! 261:
! 262: /*
! 263: * Described in header
! 264: */
! 265: wolfssl_diffie_hellman_t *wolfssl_diffie_hellman_create(
! 266: diffie_hellman_group_t group, ...)
! 267: {
! 268: diffie_hellman_params_t *params;
! 269: chunk_t g, p;
! 270:
! 271: if (group == MODP_CUSTOM)
! 272: {
! 273: VA_ARGS_GET(group, g, p);
! 274: return create_generic(group, g, p);
! 275: }
! 276: params = diffie_hellman_get_params(group);
! 277: if (!params)
! 278: {
! 279: return NULL;
! 280: }
! 281: /* wolfSSL doesn't support optimized exponent sizes according to RFC 3526 */
! 282: return create_generic(group, params->generator, params->prime);
! 283: }
! 284:
! 285: #endif /* NO_DH */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>