Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
wolfSSL
Date:
Sat Aug 18 22:20:43 2018 +0000
Revision:
15:117db924cf7c
wolfSSL 3.15.3

Who changed what in which revision?

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