wolfSSL 3.11.1 for TLS1.3 beta

Fork of wolfSSL by wolf SSL

Committer:
wolfSSL
Date:
Tue May 30 06:16:19 2017 +0000
Revision:
13:80fb167dafdf
Parent:
11:cee25a834751
wolfSSL 3.11.1: TLS1.3 Beta

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 11:cee25a834751 1 /* curve25519.c
wolfSSL 11:cee25a834751 2 *
wolfSSL 11:cee25a834751 3 * Copyright (C) 2006-2016 wolfSSL Inc.
wolfSSL 11:cee25a834751 4 *
wolfSSL 11:cee25a834751 5 * This file is part of wolfSSL.
wolfSSL 11:cee25a834751 6 *
wolfSSL 11:cee25a834751 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 11:cee25a834751 8 * it under the terms of the GNU General Public License as published by
wolfSSL 11:cee25a834751 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 11:cee25a834751 10 * (at your option) any later version.
wolfSSL 11:cee25a834751 11 *
wolfSSL 11:cee25a834751 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 11:cee25a834751 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 11:cee25a834751 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 11:cee25a834751 15 * GNU General Public License for more details.
wolfSSL 11:cee25a834751 16 *
wolfSSL 11:cee25a834751 17 * You should have received a copy of the GNU General Public License
wolfSSL 11:cee25a834751 18 * along with this program; if not, write to the Free Software
wolfSSL 11:cee25a834751 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 11:cee25a834751 20 */
wolfSSL 11:cee25a834751 21
wolfSSL 11:cee25a834751 22
wolfSSL 11:cee25a834751 23 /* Based On Daniel J Bernstein's curve25519 Public Domain ref10 work. */
wolfSSL 11:cee25a834751 24
wolfSSL 11:cee25a834751 25
wolfSSL 11:cee25a834751 26 #ifdef HAVE_CONFIG_H
wolfSSL 11:cee25a834751 27 #include <config.h>
wolfSSL 11:cee25a834751 28 #endif
wolfSSL 11:cee25a834751 29
wolfSSL 11:cee25a834751 30 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 11:cee25a834751 31
wolfSSL 11:cee25a834751 32 #ifdef HAVE_CURVE25519
wolfSSL 11:cee25a834751 33
wolfSSL 11:cee25a834751 34 #include <wolfssl/wolfcrypt/curve25519.h>
wolfSSL 11:cee25a834751 35 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 11:cee25a834751 36 #ifdef NO_INLINE
wolfSSL 11:cee25a834751 37 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 11:cee25a834751 38 #else
wolfSSL 11:cee25a834751 39 #define WOLFSSL_MISC_INCLUDED
wolfSSL 11:cee25a834751 40 #include <wolfcrypt/src/misc.c>
wolfSSL 11:cee25a834751 41 #endif
wolfSSL 11:cee25a834751 42
wolfSSL 11:cee25a834751 43 #if defined(FREESCALE_LTC_ECC)
wolfSSL 11:cee25a834751 44 #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
wolfSSL 11:cee25a834751 45 #endif
wolfSSL 11:cee25a834751 46
wolfSSL 11:cee25a834751 47 const curve25519_set_type curve25519_sets[] = {
wolfSSL 11:cee25a834751 48 {
wolfSSL 11:cee25a834751 49 32,
wolfSSL 11:cee25a834751 50 "CURVE25519",
wolfSSL 11:cee25a834751 51 }
wolfSSL 11:cee25a834751 52 };
wolfSSL 11:cee25a834751 53
wolfSSL 11:cee25a834751 54 int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key)
wolfSSL 11:cee25a834751 55 {
wolfSSL 11:cee25a834751 56 #ifdef FREESCALE_LTC_ECC
wolfSSL 11:cee25a834751 57 const ECPoint* basepoint = wc_curve25519_GetBasePoint();
wolfSSL 11:cee25a834751 58 #else
wolfSSL 11:cee25a834751 59 unsigned char basepoint[CURVE25519_KEYSIZE] = {9};
wolfSSL 11:cee25a834751 60 #endif
wolfSSL 11:cee25a834751 61 int ret;
wolfSSL 11:cee25a834751 62
wolfSSL 11:cee25a834751 63 if (key == NULL || rng == NULL)
wolfSSL 11:cee25a834751 64 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 65
wolfSSL 11:cee25a834751 66 /* currently only a key size of 32 bytes is used */
wolfSSL 11:cee25a834751 67 if (keysize != CURVE25519_KEYSIZE)
wolfSSL 11:cee25a834751 68 return ECC_BAD_ARG_E;
wolfSSL 11:cee25a834751 69
wolfSSL 11:cee25a834751 70 /* random number for private key */
wolfSSL 11:cee25a834751 71 ret = wc_RNG_GenerateBlock(rng, key->k.point, keysize);
wolfSSL 11:cee25a834751 72 if (ret != 0)
wolfSSL 11:cee25a834751 73 return ret;
wolfSSL 11:cee25a834751 74
wolfSSL 11:cee25a834751 75 /* Clamp the private key */
wolfSSL 11:cee25a834751 76 key->k.point[0] &= 248;
wolfSSL 11:cee25a834751 77 key->k.point[CURVE25519_KEYSIZE-1] &= 63; /* same &=127 because |=64 after */
wolfSSL 11:cee25a834751 78 key->k.point[CURVE25519_KEYSIZE-1] |= 64;
wolfSSL 11:cee25a834751 79
wolfSSL 11:cee25a834751 80 /* compute public key */
wolfSSL 11:cee25a834751 81 #ifdef FREESCALE_LTC_ECC
wolfSSL 11:cee25a834751 82 ret = wc_curve25519(&key->p, key->k.point, basepoint, kLTC_Weierstrass); /* input basepoint on Weierstrass curve */
wolfSSL 11:cee25a834751 83 #else
wolfSSL 11:cee25a834751 84 ret = curve25519(key->p.point, key->k.point, basepoint);
wolfSSL 11:cee25a834751 85 #endif
wolfSSL 11:cee25a834751 86 if (ret != 0) {
wolfSSL 11:cee25a834751 87 ForceZero(key->k.point, keysize);
wolfSSL 11:cee25a834751 88 ForceZero(key->p.point, keysize);
wolfSSL 11:cee25a834751 89 return ret;
wolfSSL 11:cee25a834751 90 }
wolfSSL 11:cee25a834751 91
wolfSSL 11:cee25a834751 92 return ret;
wolfSSL 11:cee25a834751 93 }
wolfSSL 11:cee25a834751 94
wolfSSL 11:cee25a834751 95 #ifdef HAVE_CURVE25519_SHARED_SECRET
wolfSSL 11:cee25a834751 96
wolfSSL 11:cee25a834751 97 int wc_curve25519_shared_secret(curve25519_key* private_key,
wolfSSL 11:cee25a834751 98 curve25519_key* public_key,
wolfSSL 11:cee25a834751 99 byte* out, word32* outlen)
wolfSSL 11:cee25a834751 100 {
wolfSSL 11:cee25a834751 101 return wc_curve25519_shared_secret_ex(private_key, public_key,
wolfSSL 11:cee25a834751 102 out, outlen, EC25519_BIG_ENDIAN);
wolfSSL 11:cee25a834751 103 }
wolfSSL 11:cee25a834751 104
wolfSSL 11:cee25a834751 105 int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
wolfSSL 11:cee25a834751 106 curve25519_key* public_key,
wolfSSL 11:cee25a834751 107 byte* out, word32* outlen, int endian)
wolfSSL 11:cee25a834751 108 {
wolfSSL 11:cee25a834751 109 #ifdef FREESCALE_LTC_ECC
wolfSSL 11:cee25a834751 110 ECPoint o = {{0}};
wolfSSL 11:cee25a834751 111 #else
wolfSSL 11:cee25a834751 112 unsigned char o[CURVE25519_KEYSIZE];
wolfSSL 11:cee25a834751 113 #endif
wolfSSL 11:cee25a834751 114 int ret = 0;
wolfSSL 11:cee25a834751 115
wolfSSL 11:cee25a834751 116 /* sanity check */
wolfSSL 11:cee25a834751 117 if (private_key == NULL || public_key == NULL ||
wolfSSL 11:cee25a834751 118 out == NULL || outlen == NULL || *outlen < CURVE25519_KEYSIZE)
wolfSSL 11:cee25a834751 119 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 120
wolfSSL 11:cee25a834751 121 /* avoid implementation fingerprinting */
wolfSSL 11:cee25a834751 122 if (public_key->p.point[CURVE25519_KEYSIZE-1] > 0x7F)
wolfSSL 11:cee25a834751 123 return ECC_BAD_ARG_E;
wolfSSL 11:cee25a834751 124
wolfSSL 11:cee25a834751 125 #ifdef FREESCALE_LTC_ECC
wolfSSL 11:cee25a834751 126 ret = wc_curve25519(&o, private_key->k.point, &public_key->p, kLTC_Curve25519 /* input point P on Curve25519 */);
wolfSSL 11:cee25a834751 127 #else
wolfSSL 11:cee25a834751 128 ret = curve25519(o, private_key->k.point, public_key->p.point);
wolfSSL 11:cee25a834751 129 #endif
wolfSSL 11:cee25a834751 130 if (ret != 0) {
wolfSSL 11:cee25a834751 131 #ifdef FREESCALE_LTC_ECC
wolfSSL 11:cee25a834751 132 ForceZero(o.point, CURVE25519_KEYSIZE);
wolfSSL 11:cee25a834751 133 ForceZero(o.pointY, CURVE25519_KEYSIZE);
wolfSSL 11:cee25a834751 134 #else
wolfSSL 11:cee25a834751 135 ForceZero(o, CURVE25519_KEYSIZE);
wolfSSL 11:cee25a834751 136 #endif
wolfSSL 11:cee25a834751 137 return ret;
wolfSSL 11:cee25a834751 138 }
wolfSSL 11:cee25a834751 139
wolfSSL 11:cee25a834751 140 if (endian == EC25519_BIG_ENDIAN) {
wolfSSL 11:cee25a834751 141 int i;
wolfSSL 11:cee25a834751 142 /* put shared secret key in Big Endian format */
wolfSSL 11:cee25a834751 143 for (i = 0; i < CURVE25519_KEYSIZE; i++)
wolfSSL 11:cee25a834751 144 #ifdef FREESCALE_LTC_ECC
wolfSSL 11:cee25a834751 145 out[i] = o.point[CURVE25519_KEYSIZE - i -1];
wolfSSL 11:cee25a834751 146 #else
wolfSSL 11:cee25a834751 147 out[i] = o[CURVE25519_KEYSIZE - i -1];
wolfSSL 11:cee25a834751 148 #endif
wolfSSL 11:cee25a834751 149 }
wolfSSL 11:cee25a834751 150 else /* put shared secret key in Little Endian format */
wolfSSL 11:cee25a834751 151 #ifdef FREESCALE_LTC_ECC
wolfSSL 11:cee25a834751 152 XMEMCPY(out, o.point, CURVE25519_KEYSIZE);
wolfSSL 11:cee25a834751 153 #else
wolfSSL 11:cee25a834751 154 XMEMCPY(out, o, CURVE25519_KEYSIZE);
wolfSSL 11:cee25a834751 155 #endif
wolfSSL 11:cee25a834751 156
wolfSSL 11:cee25a834751 157 *outlen = CURVE25519_KEYSIZE;
wolfSSL 11:cee25a834751 158
wolfSSL 11:cee25a834751 159 #ifdef FREESCALE_LTC_ECC
wolfSSL 11:cee25a834751 160 ForceZero(o.point, CURVE25519_KEYSIZE);
wolfSSL 11:cee25a834751 161 ForceZero(o.pointY, CURVE25519_KEYSIZE);
wolfSSL 11:cee25a834751 162 #else
wolfSSL 11:cee25a834751 163 ForceZero(o, CURVE25519_KEYSIZE);
wolfSSL 11:cee25a834751 164 #endif
wolfSSL 11:cee25a834751 165
wolfSSL 11:cee25a834751 166 return ret;
wolfSSL 11:cee25a834751 167 }
wolfSSL 11:cee25a834751 168
wolfSSL 11:cee25a834751 169 #endif /* HAVE_CURVE25519_SHARED_SECRET */
wolfSSL 11:cee25a834751 170
wolfSSL 11:cee25a834751 171 #ifdef HAVE_CURVE25519_KEY_EXPORT
wolfSSL 11:cee25a834751 172
wolfSSL 11:cee25a834751 173 /* export curve25519 public key (Big endian)
wolfSSL 11:cee25a834751 174 * return 0 on success */
wolfSSL 11:cee25a834751 175 int wc_curve25519_export_public(curve25519_key* key, byte* out, word32* outLen)
wolfSSL 11:cee25a834751 176 {
wolfSSL 11:cee25a834751 177 return wc_curve25519_export_public_ex(key, out, outLen, EC25519_BIG_ENDIAN);
wolfSSL 11:cee25a834751 178 }
wolfSSL 11:cee25a834751 179
wolfSSL 11:cee25a834751 180 /* export curve25519 public key (Big or Little endian)
wolfSSL 11:cee25a834751 181 * return 0 on success */
wolfSSL 11:cee25a834751 182 int wc_curve25519_export_public_ex(curve25519_key* key, byte* out,
wolfSSL 11:cee25a834751 183 word32* outLen, int endian)
wolfSSL 11:cee25a834751 184 {
wolfSSL 11:cee25a834751 185 word32 keySz;
wolfSSL 11:cee25a834751 186
wolfSSL 11:cee25a834751 187 if (key == NULL || out == NULL || outLen == NULL)
wolfSSL 11:cee25a834751 188 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 189
wolfSSL 11:cee25a834751 190 /* check size of outgoing key */
wolfSSL 11:cee25a834751 191 keySz = wc_curve25519_size(key);
wolfSSL 11:cee25a834751 192
wolfSSL 11:cee25a834751 193 /* check and set outgoing key size */
wolfSSL 11:cee25a834751 194 if (*outLen < keySz) {
wolfSSL 11:cee25a834751 195 *outLen = keySz;
wolfSSL 11:cee25a834751 196 return ECC_BAD_ARG_E;
wolfSSL 11:cee25a834751 197 }
wolfSSL 11:cee25a834751 198 *outLen = keySz;
wolfSSL 11:cee25a834751 199
wolfSSL 11:cee25a834751 200 if (endian == EC25519_BIG_ENDIAN) {
wolfSSL 11:cee25a834751 201 int i;
wolfSSL 11:cee25a834751 202
wolfSSL 11:cee25a834751 203 /* read keys in Big Endian format */
wolfSSL 11:cee25a834751 204 for (i = 0; i < CURVE25519_KEYSIZE; i++)
wolfSSL 11:cee25a834751 205 out[i] = key->p.point[CURVE25519_KEYSIZE - i - 1];
wolfSSL 11:cee25a834751 206 }
wolfSSL 11:cee25a834751 207 else
wolfSSL 11:cee25a834751 208 XMEMCPY(out, key->p.point, keySz);
wolfSSL 11:cee25a834751 209
wolfSSL 11:cee25a834751 210 return 0;
wolfSSL 11:cee25a834751 211 }
wolfSSL 11:cee25a834751 212
wolfSSL 11:cee25a834751 213 #endif /* HAVE_CURVE25519_KEY_EXPORT */
wolfSSL 11:cee25a834751 214
wolfSSL 11:cee25a834751 215 #ifdef HAVE_CURVE25519_KEY_IMPORT
wolfSSL 11:cee25a834751 216
wolfSSL 11:cee25a834751 217 /* import curve25519 public key (Big endian)
wolfSSL 11:cee25a834751 218 * return 0 on success */
wolfSSL 11:cee25a834751 219 int wc_curve25519_import_public(const byte* in, word32 inLen,
wolfSSL 11:cee25a834751 220 curve25519_key* key)
wolfSSL 11:cee25a834751 221 {
wolfSSL 11:cee25a834751 222 return wc_curve25519_import_public_ex(in, inLen, key, EC25519_BIG_ENDIAN);
wolfSSL 11:cee25a834751 223 }
wolfSSL 11:cee25a834751 224
wolfSSL 11:cee25a834751 225 /* import curve25519 public key (Big or Little endian)
wolfSSL 11:cee25a834751 226 * return 0 on success */
wolfSSL 11:cee25a834751 227 int wc_curve25519_import_public_ex(const byte* in, word32 inLen,
wolfSSL 11:cee25a834751 228 curve25519_key* key, int endian)
wolfSSL 11:cee25a834751 229 {
wolfSSL 11:cee25a834751 230 word32 keySz;
wolfSSL 11:cee25a834751 231
wolfSSL 11:cee25a834751 232 /* sanity check */
wolfSSL 11:cee25a834751 233 if (key == NULL || in == NULL)
wolfSSL 11:cee25a834751 234 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 235
wolfSSL 11:cee25a834751 236 /* check size of incoming keys */
wolfSSL 11:cee25a834751 237 keySz = wc_curve25519_size(key);
wolfSSL 11:cee25a834751 238 if (inLen != keySz)
wolfSSL 11:cee25a834751 239 return ECC_BAD_ARG_E;
wolfSSL 11:cee25a834751 240
wolfSSL 11:cee25a834751 241 if (endian == EC25519_BIG_ENDIAN) {
wolfSSL 11:cee25a834751 242 int i;
wolfSSL 11:cee25a834751 243
wolfSSL 11:cee25a834751 244 /* read keys in Big Endian format */
wolfSSL 11:cee25a834751 245 for (i = 0; i < CURVE25519_KEYSIZE; i++)
wolfSSL 11:cee25a834751 246 key->p.point[i] = in[CURVE25519_KEYSIZE - i - 1];
wolfSSL 11:cee25a834751 247 }
wolfSSL 11:cee25a834751 248 else
wolfSSL 11:cee25a834751 249 XMEMCPY(key->p.point, in, inLen);
wolfSSL 11:cee25a834751 250
wolfSSL 11:cee25a834751 251 key->dp = &curve25519_sets[0];
wolfSSL 11:cee25a834751 252
wolfSSL 11:cee25a834751 253
wolfSSL 11:cee25a834751 254 /* LTC needs also Y coordinate - let's compute it */
wolfSSL 11:cee25a834751 255 #ifdef FREESCALE_LTC_ECC
wolfSSL 11:cee25a834751 256 ltc_pkha_ecc_point_t ltcPoint;
wolfSSL 11:cee25a834751 257 ltcPoint.X = &key->p.point[0];
wolfSSL 11:cee25a834751 258 ltcPoint.Y = &key->p.pointY[0];
wolfSSL 11:cee25a834751 259 LTC_PKHA_Curve25519ComputeY(&ltcPoint);
wolfSSL 11:cee25a834751 260 #endif
wolfSSL 11:cee25a834751 261
wolfSSL 11:cee25a834751 262 return 0;
wolfSSL 11:cee25a834751 263 }
wolfSSL 11:cee25a834751 264
wolfSSL 11:cee25a834751 265 #endif /* HAVE_CURVE25519_KEY_IMPORT */
wolfSSL 11:cee25a834751 266
wolfSSL 11:cee25a834751 267
wolfSSL 11:cee25a834751 268 #ifdef HAVE_CURVE25519_KEY_EXPORT
wolfSSL 11:cee25a834751 269
wolfSSL 11:cee25a834751 270 /* export curve25519 private key only raw (Big endian)
wolfSSL 11:cee25a834751 271 * outLen is in/out size
wolfSSL 11:cee25a834751 272 * return 0 on success */
wolfSSL 11:cee25a834751 273 int wc_curve25519_export_private_raw(curve25519_key* key, byte* out,
wolfSSL 11:cee25a834751 274 word32* outLen)
wolfSSL 11:cee25a834751 275 {
wolfSSL 11:cee25a834751 276 return wc_curve25519_export_private_raw_ex(key, out, outLen,
wolfSSL 11:cee25a834751 277 EC25519_BIG_ENDIAN);
wolfSSL 11:cee25a834751 278 }
wolfSSL 11:cee25a834751 279
wolfSSL 11:cee25a834751 280 /* export curve25519 private key only raw (Big or Little endian)
wolfSSL 11:cee25a834751 281 * outLen is in/out size
wolfSSL 11:cee25a834751 282 * return 0 on success */
wolfSSL 11:cee25a834751 283 int wc_curve25519_export_private_raw_ex(curve25519_key* key, byte* out,
wolfSSL 11:cee25a834751 284 word32* outLen, int endian)
wolfSSL 11:cee25a834751 285 {
wolfSSL 11:cee25a834751 286 word32 keySz;
wolfSSL 11:cee25a834751 287
wolfSSL 11:cee25a834751 288 /* sanity check */
wolfSSL 11:cee25a834751 289 if (key == NULL || out == NULL || outLen == NULL)
wolfSSL 11:cee25a834751 290 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 291
wolfSSL 11:cee25a834751 292 /* check size of outgoing buffer */
wolfSSL 11:cee25a834751 293 keySz = wc_curve25519_size(key);
wolfSSL 11:cee25a834751 294 if (*outLen < keySz) {
wolfSSL 11:cee25a834751 295 *outLen = keySz;
wolfSSL 11:cee25a834751 296 return ECC_BAD_ARG_E;
wolfSSL 11:cee25a834751 297 }
wolfSSL 11:cee25a834751 298 *outLen = keySz;
wolfSSL 11:cee25a834751 299
wolfSSL 11:cee25a834751 300 if (endian == EC25519_BIG_ENDIAN) {
wolfSSL 11:cee25a834751 301 int i;
wolfSSL 11:cee25a834751 302
wolfSSL 11:cee25a834751 303 /* put the key in Big Endian format */
wolfSSL 11:cee25a834751 304 for (i = 0; i < CURVE25519_KEYSIZE; i++)
wolfSSL 11:cee25a834751 305 out[i] = key->k.point[CURVE25519_KEYSIZE - i - 1];
wolfSSL 11:cee25a834751 306 }
wolfSSL 11:cee25a834751 307 else
wolfSSL 11:cee25a834751 308 XMEMCPY(out, key->k.point, keySz);
wolfSSL 11:cee25a834751 309
wolfSSL 11:cee25a834751 310 return 0;
wolfSSL 11:cee25a834751 311 }
wolfSSL 11:cee25a834751 312
wolfSSL 11:cee25a834751 313 /* curve25519 key pair export (Big or Little endian)
wolfSSL 11:cee25a834751 314 * return 0 on success */
wolfSSL 11:cee25a834751 315 int wc_curve25519_export_key_raw(curve25519_key* key,
wolfSSL 11:cee25a834751 316 byte* priv, word32 *privSz,
wolfSSL 11:cee25a834751 317 byte* pub, word32 *pubSz)
wolfSSL 11:cee25a834751 318 {
wolfSSL 11:cee25a834751 319 return wc_curve25519_export_key_raw_ex(key, priv, privSz,
wolfSSL 11:cee25a834751 320 pub, pubSz, EC25519_BIG_ENDIAN);
wolfSSL 11:cee25a834751 321 }
wolfSSL 11:cee25a834751 322
wolfSSL 11:cee25a834751 323 /* curve25519 key pair export (Big or Little endian)
wolfSSL 11:cee25a834751 324 * return 0 on success */
wolfSSL 11:cee25a834751 325 int wc_curve25519_export_key_raw_ex(curve25519_key* key,
wolfSSL 11:cee25a834751 326 byte* priv, word32 *privSz,
wolfSSL 11:cee25a834751 327 byte* pub, word32 *pubSz,
wolfSSL 11:cee25a834751 328 int endian)
wolfSSL 11:cee25a834751 329 {
wolfSSL 11:cee25a834751 330 int ret;
wolfSSL 11:cee25a834751 331
wolfSSL 11:cee25a834751 332 /* export private part */
wolfSSL 11:cee25a834751 333 ret = wc_curve25519_export_private_raw_ex(key, priv, privSz, endian);
wolfSSL 11:cee25a834751 334 if (ret != 0)
wolfSSL 11:cee25a834751 335 return ret;
wolfSSL 11:cee25a834751 336
wolfSSL 11:cee25a834751 337 /* export public part */
wolfSSL 11:cee25a834751 338 return wc_curve25519_export_public_ex(key, pub, pubSz, endian);
wolfSSL 11:cee25a834751 339 }
wolfSSL 11:cee25a834751 340
wolfSSL 11:cee25a834751 341 #endif /* HAVE_CURVE25519_KEY_EXPORT */
wolfSSL 11:cee25a834751 342
wolfSSL 11:cee25a834751 343 #ifdef HAVE_CURVE25519_KEY_IMPORT
wolfSSL 11:cee25a834751 344
wolfSSL 11:cee25a834751 345 /* curve25519 private key import (Big endian)
wolfSSL 11:cee25a834751 346 * Public key to match private key needs to be imported too
wolfSSL 11:cee25a834751 347 * return 0 on success */
wolfSSL 11:cee25a834751 348 int wc_curve25519_import_private_raw(const byte* priv, word32 privSz,
wolfSSL 11:cee25a834751 349 const byte* pub, word32 pubSz,
wolfSSL 11:cee25a834751 350 curve25519_key* key)
wolfSSL 11:cee25a834751 351 {
wolfSSL 11:cee25a834751 352 return wc_curve25519_import_private_raw_ex(priv, privSz, pub, pubSz,
wolfSSL 11:cee25a834751 353 key, EC25519_BIG_ENDIAN);
wolfSSL 11:cee25a834751 354 }
wolfSSL 11:cee25a834751 355
wolfSSL 11:cee25a834751 356 /* curve25519 private key import (Big or Little endian)
wolfSSL 11:cee25a834751 357 * Public key to match private key needs to be imported too
wolfSSL 11:cee25a834751 358 * return 0 on success */
wolfSSL 11:cee25a834751 359 int wc_curve25519_import_private_raw_ex(const byte* priv, word32 privSz,
wolfSSL 11:cee25a834751 360 const byte* pub, word32 pubSz,
wolfSSL 11:cee25a834751 361 curve25519_key* key, int endian)
wolfSSL 11:cee25a834751 362 {
wolfSSL 11:cee25a834751 363 int ret;
wolfSSL 11:cee25a834751 364
wolfSSL 11:cee25a834751 365 /* import private part */
wolfSSL 11:cee25a834751 366 ret = wc_curve25519_import_private_ex(priv, privSz, key, endian);
wolfSSL 11:cee25a834751 367 if (ret != 0)
wolfSSL 11:cee25a834751 368 return ret;
wolfSSL 11:cee25a834751 369
wolfSSL 11:cee25a834751 370 /* import public part */
wolfSSL 11:cee25a834751 371 return wc_curve25519_import_public_ex(pub, pubSz, key, endian);
wolfSSL 11:cee25a834751 372 }
wolfSSL 11:cee25a834751 373
wolfSSL 11:cee25a834751 374 /* curve25519 private key import only. (Big endian)
wolfSSL 11:cee25a834751 375 * return 0 on success */
wolfSSL 11:cee25a834751 376 int wc_curve25519_import_private(const byte* priv, word32 privSz,
wolfSSL 11:cee25a834751 377 curve25519_key* key)
wolfSSL 11:cee25a834751 378 {
wolfSSL 11:cee25a834751 379 return wc_curve25519_import_private_ex(priv, privSz,
wolfSSL 11:cee25a834751 380 key, EC25519_BIG_ENDIAN);
wolfSSL 11:cee25a834751 381 }
wolfSSL 11:cee25a834751 382
wolfSSL 11:cee25a834751 383 /* curve25519 private key import only. (Big or Little endian)
wolfSSL 11:cee25a834751 384 * return 0 on success */
wolfSSL 11:cee25a834751 385 int wc_curve25519_import_private_ex(const byte* priv, word32 privSz,
wolfSSL 11:cee25a834751 386 curve25519_key* key, int endian)
wolfSSL 11:cee25a834751 387 {
wolfSSL 11:cee25a834751 388 /* sanity check */
wolfSSL 11:cee25a834751 389 if (key == NULL || priv == NULL)
wolfSSL 11:cee25a834751 390 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 391
wolfSSL 11:cee25a834751 392 /* check size of incoming keys */
wolfSSL 11:cee25a834751 393 if ((int)privSz != wc_curve25519_size(key))
wolfSSL 11:cee25a834751 394 return ECC_BAD_ARG_E;
wolfSSL 11:cee25a834751 395
wolfSSL 11:cee25a834751 396 if (endian == EC25519_BIG_ENDIAN) {
wolfSSL 11:cee25a834751 397 int i;
wolfSSL 11:cee25a834751 398
wolfSSL 11:cee25a834751 399 /* read the key in Big Endian format */
wolfSSL 11:cee25a834751 400 for (i = 0; i < CURVE25519_KEYSIZE; i++)
wolfSSL 11:cee25a834751 401 key->k.point[i] = priv[CURVE25519_KEYSIZE - i - 1];
wolfSSL 11:cee25a834751 402 }
wolfSSL 11:cee25a834751 403 else
wolfSSL 11:cee25a834751 404 XMEMCPY(key->k.point, priv, privSz);
wolfSSL 11:cee25a834751 405
wolfSSL 11:cee25a834751 406 key->dp = &curve25519_sets[0];
wolfSSL 11:cee25a834751 407
wolfSSL 11:cee25a834751 408 /* Clamp the key */
wolfSSL 11:cee25a834751 409 key->k.point[0] &= 248;
wolfSSL 11:cee25a834751 410 key->k.point[privSz-1] &= 63; /* same &=127 because |=64 after */
wolfSSL 11:cee25a834751 411 key->k.point[privSz-1] |= 64;
wolfSSL 11:cee25a834751 412
wolfSSL 11:cee25a834751 413 return 0;
wolfSSL 11:cee25a834751 414 }
wolfSSL 11:cee25a834751 415
wolfSSL 11:cee25a834751 416 #endif /* HAVE_CURVE25519_KEY_IMPORT */
wolfSSL 11:cee25a834751 417
wolfSSL 11:cee25a834751 418
wolfSSL 11:cee25a834751 419 int wc_curve25519_init(curve25519_key* key)
wolfSSL 11:cee25a834751 420 {
wolfSSL 11:cee25a834751 421 if (key == NULL)
wolfSSL 11:cee25a834751 422 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 423
wolfSSL 11:cee25a834751 424 /* currently the format for curve25519 */
wolfSSL 11:cee25a834751 425 key->dp = &curve25519_sets[0];
wolfSSL 11:cee25a834751 426
wolfSSL 11:cee25a834751 427 XMEMSET(key->k.point, 0, key->dp->size);
wolfSSL 11:cee25a834751 428 XMEMSET(key->p.point, 0, key->dp->size);
wolfSSL 11:cee25a834751 429 #ifdef FREESCALE_LTC_ECC
wolfSSL 11:cee25a834751 430 XMEMSET(key->k.pointY, 0, key->dp->size);
wolfSSL 11:cee25a834751 431 XMEMSET(key->p.pointY, 0, key->dp->size);
wolfSSL 11:cee25a834751 432 #endif
wolfSSL 11:cee25a834751 433 return 0;
wolfSSL 11:cee25a834751 434 }
wolfSSL 11:cee25a834751 435
wolfSSL 11:cee25a834751 436
wolfSSL 11:cee25a834751 437 /* Clean the memory of a key */
wolfSSL 11:cee25a834751 438 void wc_curve25519_free(curve25519_key* key)
wolfSSL 11:cee25a834751 439 {
wolfSSL 11:cee25a834751 440 if (key == NULL)
wolfSSL 11:cee25a834751 441 return;
wolfSSL 11:cee25a834751 442
wolfSSL 11:cee25a834751 443 key->dp = NULL;
wolfSSL 11:cee25a834751 444 ForceZero(key->p.point, sizeof(key->p.point));
wolfSSL 11:cee25a834751 445 ForceZero(key->k.point, sizeof(key->k.point));
wolfSSL 11:cee25a834751 446 #ifdef FREESCALE_LTC_ECC
wolfSSL 11:cee25a834751 447 ForceZero(key->p.point, sizeof(key->p.pointY));
wolfSSL 11:cee25a834751 448 ForceZero(key->k.point, sizeof(key->k.pointY));
wolfSSL 11:cee25a834751 449 #endif
wolfSSL 11:cee25a834751 450 }
wolfSSL 11:cee25a834751 451
wolfSSL 11:cee25a834751 452
wolfSSL 11:cee25a834751 453 /* get key size */
wolfSSL 11:cee25a834751 454 int wc_curve25519_size(curve25519_key* key)
wolfSSL 11:cee25a834751 455 {
wolfSSL 11:cee25a834751 456 if (key == NULL)
wolfSSL 11:cee25a834751 457 return 0;
wolfSSL 11:cee25a834751 458
wolfSSL 11:cee25a834751 459 return key->dp->size;
wolfSSL 11:cee25a834751 460 }
wolfSSL 11:cee25a834751 461
wolfSSL 11:cee25a834751 462 #endif /*HAVE_CURVE25519*/
wolfSSL 11:cee25a834751 463
wolfSSL 11:cee25a834751 464