Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
wolfcrypt/src/curve25519.c@15:117db924cf7c, 2018-08-18 (annotated)
- Committer:
- wolfSSL
- Date:
- Sat Aug 18 22:20:43 2018 +0000
- Revision:
- 15:117db924cf7c
wolfSSL 3.15.3
Who changed what in which revision?
User | Revision | Line number | New 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(<cPoint); |
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 |