Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
wolfSSL
Date:
Tue Aug 22 10:48:22 2017 +0000
Revision:
13:f67a6c6013ca
wolfSSL3.12.0 with TLS1.3

Who changed what in which revision?

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