Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
sPymbed
Date:
Tue Nov 19 14:32:16 2019 +0000
Revision:
16:048e5e270a58
Parent:
15:117db924cf7c
working ssl

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 15:117db924cf7c 1 /* ed25519.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 ed25519 Public Domain ref10 work. */
wolfSSL 15:117db924cf7c 24
wolfSSL 15:117db924cf7c 25 #ifdef HAVE_CONFIG_H
wolfSSL 15:117db924cf7c 26 #include <config.h>
wolfSSL 15:117db924cf7c 27 #endif
wolfSSL 15:117db924cf7c 28
wolfSSL 15:117db924cf7c 29 /* in case user set HAVE_ED25519 there */
wolfSSL 15:117db924cf7c 30 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 15:117db924cf7c 31
wolfSSL 15:117db924cf7c 32 #ifdef HAVE_ED25519
wolfSSL 15:117db924cf7c 33
wolfSSL 15:117db924cf7c 34 #include <wolfssl/wolfcrypt/ed25519.h>
wolfSSL 15:117db924cf7c 35 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 15:117db924cf7c 36 #include <wolfssl/wolfcrypt/hash.h>
wolfSSL 15:117db924cf7c 37 #ifdef NO_INLINE
wolfSSL 15:117db924cf7c 38 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 15:117db924cf7c 39 #else
wolfSSL 15:117db924cf7c 40 #define WOLFSSL_MISC_INCLUDED
wolfSSL 15:117db924cf7c 41 #include <wolfcrypt/src/misc.c>
wolfSSL 15:117db924cf7c 42 #endif
wolfSSL 15:117db924cf7c 43
wolfSSL 15:117db924cf7c 44 #ifdef FREESCALE_LTC_ECC
wolfSSL 15:117db924cf7c 45 #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
wolfSSL 15:117db924cf7c 46 #endif
wolfSSL 15:117db924cf7c 47
wolfSSL 15:117db924cf7c 48 /* generate an ed25519 key pair.
wolfSSL 15:117db924cf7c 49 * returns 0 on success
wolfSSL 15:117db924cf7c 50 */
wolfSSL 15:117db924cf7c 51 int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key)
wolfSSL 15:117db924cf7c 52 {
wolfSSL 15:117db924cf7c 53 byte az[ED25519_PRV_KEY_SIZE];
wolfSSL 15:117db924cf7c 54 int ret;
wolfSSL 15:117db924cf7c 55 #if !defined(FREESCALE_LTC_ECC)
wolfSSL 15:117db924cf7c 56 ge_p3 A;
wolfSSL 15:117db924cf7c 57 #endif
wolfSSL 15:117db924cf7c 58
wolfSSL 15:117db924cf7c 59 if (rng == NULL || key == NULL)
wolfSSL 15:117db924cf7c 60 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 61
wolfSSL 15:117db924cf7c 62 /* ed25519 has 32 byte key sizes */
wolfSSL 15:117db924cf7c 63 if (keySz != ED25519_KEY_SIZE)
wolfSSL 15:117db924cf7c 64 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 65
wolfSSL 15:117db924cf7c 66 ret = wc_RNG_GenerateBlock(rng, key->k, ED25519_KEY_SIZE);
wolfSSL 15:117db924cf7c 67 if (ret != 0)
wolfSSL 15:117db924cf7c 68 return ret;
wolfSSL 15:117db924cf7c 69 ret = wc_Sha512Hash(key->k, ED25519_KEY_SIZE, az);
wolfSSL 15:117db924cf7c 70 if (ret != 0) {
wolfSSL 15:117db924cf7c 71 ForceZero(key->k, ED25519_KEY_SIZE);
wolfSSL 15:117db924cf7c 72 return ret;
wolfSSL 15:117db924cf7c 73 }
wolfSSL 15:117db924cf7c 74
wolfSSL 15:117db924cf7c 75 /* apply clamp */
wolfSSL 15:117db924cf7c 76 az[0] &= 248;
wolfSSL 15:117db924cf7c 77 az[31] &= 63; /* same than az[31] &= 127 because of az[31] |= 64 */
wolfSSL 15:117db924cf7c 78 az[31] |= 64;
wolfSSL 15:117db924cf7c 79
wolfSSL 15:117db924cf7c 80 #ifdef FREESCALE_LTC_ECC
wolfSSL 15:117db924cf7c 81 ltc_pkha_ecc_point_t publicKey = {0};
wolfSSL 15:117db924cf7c 82 publicKey.X = key->pointX;
wolfSSL 15:117db924cf7c 83 publicKey.Y = key->pointY;
wolfSSL 15:117db924cf7c 84 LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), az, ED25519_KEY_SIZE, &publicKey, kLTC_Ed25519 /* result on Ed25519 */);
wolfSSL 15:117db924cf7c 85 LTC_PKHA_Ed25519_Compress(&publicKey, key->p);
wolfSSL 15:117db924cf7c 86 #else
wolfSSL 15:117db924cf7c 87 ge_scalarmult_base(&A, az);
wolfSSL 15:117db924cf7c 88 ge_p3_tobytes(key->p, &A);
wolfSSL 15:117db924cf7c 89 #endif
wolfSSL 15:117db924cf7c 90 /* put public key after private key, on the same buffer */
wolfSSL 15:117db924cf7c 91 XMEMMOVE(key->k + ED25519_KEY_SIZE, key->p, ED25519_PUB_KEY_SIZE);
wolfSSL 15:117db924cf7c 92
wolfSSL 15:117db924cf7c 93 key->pubKeySet = 1;
wolfSSL 15:117db924cf7c 94
wolfSSL 15:117db924cf7c 95 return ret;
wolfSSL 15:117db924cf7c 96 }
wolfSSL 15:117db924cf7c 97
wolfSSL 15:117db924cf7c 98
wolfSSL 15:117db924cf7c 99 #ifdef HAVE_ED25519_SIGN
wolfSSL 15:117db924cf7c 100 /*
wolfSSL 15:117db924cf7c 101 in contains the message to sign
wolfSSL 15:117db924cf7c 102 inlen is the length of the message to sign
wolfSSL 15:117db924cf7c 103 out is the buffer to write the signature
wolfSSL 15:117db924cf7c 104 outLen [in/out] input size of out buf
wolfSSL 15:117db924cf7c 105 output gets set as the final length of out
wolfSSL 15:117db924cf7c 106 key is the ed25519 key to use when signing
wolfSSL 15:117db924cf7c 107 return 0 on success
wolfSSL 15:117db924cf7c 108 */
wolfSSL 15:117db924cf7c 109 int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
wolfSSL 15:117db924cf7c 110 word32 *outLen, ed25519_key* key)
wolfSSL 15:117db924cf7c 111 {
wolfSSL 15:117db924cf7c 112 #ifdef FREESCALE_LTC_ECC
wolfSSL 15:117db924cf7c 113 byte tempBuf[ED25519_PRV_KEY_SIZE];
wolfSSL 15:117db924cf7c 114 #else
wolfSSL 15:117db924cf7c 115 ge_p3 R;
wolfSSL 15:117db924cf7c 116 #endif
wolfSSL 15:117db924cf7c 117 byte nonce[WC_SHA512_DIGEST_SIZE];
wolfSSL 15:117db924cf7c 118 byte hram[WC_SHA512_DIGEST_SIZE];
wolfSSL 15:117db924cf7c 119 byte az[ED25519_PRV_KEY_SIZE];
wolfSSL 15:117db924cf7c 120 wc_Sha512 sha;
wolfSSL 15:117db924cf7c 121 int ret;
wolfSSL 15:117db924cf7c 122
wolfSSL 15:117db924cf7c 123 /* sanity check on arguments */
wolfSSL 15:117db924cf7c 124 if (in == NULL || out == NULL || outLen == NULL || key == NULL)
wolfSSL 15:117db924cf7c 125 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 126 if (!key->pubKeySet)
wolfSSL 15:117db924cf7c 127 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 128
wolfSSL 15:117db924cf7c 129 /* check and set up out length */
wolfSSL 15:117db924cf7c 130 if (*outLen < ED25519_SIG_SIZE) {
wolfSSL 15:117db924cf7c 131 *outLen = ED25519_SIG_SIZE;
wolfSSL 15:117db924cf7c 132 return BUFFER_E;
wolfSSL 15:117db924cf7c 133 }
wolfSSL 15:117db924cf7c 134 *outLen = ED25519_SIG_SIZE;
wolfSSL 15:117db924cf7c 135
wolfSSL 15:117db924cf7c 136 /* step 1: create nonce to use where nonce is r in
wolfSSL 15:117db924cf7c 137 r = H(h_b, ... ,h_2b-1,M) */
wolfSSL 15:117db924cf7c 138 ret = wc_Sha512Hash(key->k, ED25519_KEY_SIZE, az);
wolfSSL 15:117db924cf7c 139 if (ret != 0)
wolfSSL 15:117db924cf7c 140 return ret;
wolfSSL 15:117db924cf7c 141
wolfSSL 15:117db924cf7c 142 /* apply clamp */
wolfSSL 15:117db924cf7c 143 az[0] &= 248;
wolfSSL 15:117db924cf7c 144 az[31] &= 63; /* same than az[31] &= 127 because of az[31] |= 64 */
wolfSSL 15:117db924cf7c 145 az[31] |= 64;
wolfSSL 15:117db924cf7c 146
wolfSSL 15:117db924cf7c 147 ret = wc_InitSha512(&sha);
wolfSSL 15:117db924cf7c 148 if (ret != 0)
wolfSSL 15:117db924cf7c 149 return ret;
wolfSSL 15:117db924cf7c 150 ret = wc_Sha512Update(&sha, az + ED25519_KEY_SIZE, ED25519_KEY_SIZE);
wolfSSL 15:117db924cf7c 151 if (ret == 0)
wolfSSL 15:117db924cf7c 152 ret = wc_Sha512Update(&sha, in, inlen);
wolfSSL 15:117db924cf7c 153 if (ret == 0)
wolfSSL 15:117db924cf7c 154 ret = wc_Sha512Final(&sha, nonce);
wolfSSL 15:117db924cf7c 155 wc_Sha512Free(&sha);
wolfSSL 15:117db924cf7c 156 if (ret != 0)
wolfSSL 15:117db924cf7c 157 return ret;
wolfSSL 15:117db924cf7c 158
wolfSSL 15:117db924cf7c 159 #ifdef FREESCALE_LTC_ECC
wolfSSL 15:117db924cf7c 160 ltc_pkha_ecc_point_t ltcPoint = {0};
wolfSSL 15:117db924cf7c 161 ltcPoint.X = &tempBuf[0];
wolfSSL 15:117db924cf7c 162 ltcPoint.Y = &tempBuf[32];
wolfSSL 15:117db924cf7c 163 LTC_PKHA_sc_reduce(nonce);
wolfSSL 15:117db924cf7c 164 LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), nonce, ED25519_KEY_SIZE, &ltcPoint, kLTC_Ed25519 /* result on Ed25519 */);
wolfSSL 15:117db924cf7c 165 LTC_PKHA_Ed25519_Compress(&ltcPoint, out);
wolfSSL 15:117db924cf7c 166 #else
wolfSSL 15:117db924cf7c 167 sc_reduce(nonce);
wolfSSL 15:117db924cf7c 168
wolfSSL 15:117db924cf7c 169 /* step 2: computing R = rB where rB is the scalar multiplication of
wolfSSL 15:117db924cf7c 170 r and B */
wolfSSL 15:117db924cf7c 171 ge_scalarmult_base(&R,nonce);
wolfSSL 15:117db924cf7c 172 ge_p3_tobytes(out,&R);
wolfSSL 15:117db924cf7c 173 #endif
wolfSSL 15:117db924cf7c 174
wolfSSL 15:117db924cf7c 175 /* step 3: hash R + public key + message getting H(R,A,M) then
wolfSSL 15:117db924cf7c 176 creating S = (r + H(R,A,M)a) mod l */
wolfSSL 15:117db924cf7c 177 ret = wc_InitSha512(&sha);
wolfSSL 15:117db924cf7c 178 if (ret != 0)
wolfSSL 15:117db924cf7c 179 return ret;
wolfSSL 15:117db924cf7c 180 ret = wc_Sha512Update(&sha, out, ED25519_SIG_SIZE/2);
wolfSSL 15:117db924cf7c 181 if (ret == 0)
wolfSSL 15:117db924cf7c 182 ret = wc_Sha512Update(&sha, key->p, ED25519_PUB_KEY_SIZE);
wolfSSL 15:117db924cf7c 183 if (ret == 0)
wolfSSL 15:117db924cf7c 184 ret = wc_Sha512Update(&sha, in, inlen);
wolfSSL 15:117db924cf7c 185 if (ret == 0)
wolfSSL 15:117db924cf7c 186 ret = wc_Sha512Final(&sha, hram);
wolfSSL 15:117db924cf7c 187 wc_Sha512Free(&sha);
wolfSSL 15:117db924cf7c 188 if (ret != 0)
wolfSSL 15:117db924cf7c 189 return ret;
wolfSSL 15:117db924cf7c 190
wolfSSL 15:117db924cf7c 191 #ifdef FREESCALE_LTC_ECC
wolfSSL 15:117db924cf7c 192 LTC_PKHA_sc_reduce(hram);
wolfSSL 15:117db924cf7c 193 LTC_PKHA_sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce);
wolfSSL 15:117db924cf7c 194 #else
wolfSSL 15:117db924cf7c 195 sc_reduce(hram);
wolfSSL 15:117db924cf7c 196 sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce);
wolfSSL 15:117db924cf7c 197 #endif
wolfSSL 15:117db924cf7c 198
wolfSSL 15:117db924cf7c 199 return ret;
wolfSSL 15:117db924cf7c 200 }
wolfSSL 15:117db924cf7c 201
wolfSSL 15:117db924cf7c 202 #endif /* HAVE_ED25519_SIGN */
wolfSSL 15:117db924cf7c 203
wolfSSL 15:117db924cf7c 204 #ifdef HAVE_ED25519_VERIFY
wolfSSL 15:117db924cf7c 205
wolfSSL 15:117db924cf7c 206 /*
wolfSSL 15:117db924cf7c 207 sig is array of bytes containing the signature
wolfSSL 15:117db924cf7c 208 siglen is the length of sig byte array
wolfSSL 15:117db924cf7c 209 msg the array of bytes containing the message
wolfSSL 15:117db924cf7c 210 msglen length of msg array
wolfSSL 15:117db924cf7c 211 res will be 1 on successful verify and 0 on unsuccessful
wolfSSL 15:117db924cf7c 212 return 0 and res of 1 on success
wolfSSL 15:117db924cf7c 213 */
wolfSSL 15:117db924cf7c 214 int wc_ed25519_verify_msg(const byte* sig, word32 siglen, const byte* msg,
wolfSSL 15:117db924cf7c 215 word32 msglen, int* res, ed25519_key* key)
wolfSSL 15:117db924cf7c 216 {
wolfSSL 15:117db924cf7c 217 byte rcheck[ED25519_KEY_SIZE];
wolfSSL 15:117db924cf7c 218 byte h[WC_SHA512_DIGEST_SIZE];
wolfSSL 15:117db924cf7c 219 #ifndef FREESCALE_LTC_ECC
wolfSSL 15:117db924cf7c 220 ge_p3 A;
wolfSSL 15:117db924cf7c 221 ge_p2 R;
wolfSSL 15:117db924cf7c 222 #endif
wolfSSL 15:117db924cf7c 223 int ret;
wolfSSL 15:117db924cf7c 224 wc_Sha512 sha;
wolfSSL 15:117db924cf7c 225
wolfSSL 15:117db924cf7c 226 /* sanity check on arguments */
wolfSSL 15:117db924cf7c 227 if (sig == NULL || msg == NULL || res == NULL || key == NULL)
wolfSSL 15:117db924cf7c 228 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 229
wolfSSL 15:117db924cf7c 230 /* set verification failed by default */
wolfSSL 15:117db924cf7c 231 *res = 0;
wolfSSL 15:117db924cf7c 232
wolfSSL 15:117db924cf7c 233 /* check on basics needed to verify signature */
wolfSSL 15:117db924cf7c 234 if (siglen < ED25519_SIG_SIZE || (sig[ED25519_SIG_SIZE-1] & 224))
wolfSSL 15:117db924cf7c 235 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 236
wolfSSL 15:117db924cf7c 237 /* uncompress A (public key), test if valid, and negate it */
wolfSSL 15:117db924cf7c 238 #ifndef FREESCALE_LTC_ECC
wolfSSL 15:117db924cf7c 239 if (ge_frombytes_negate_vartime(&A, key->p) != 0)
wolfSSL 15:117db924cf7c 240 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 241 #endif
wolfSSL 15:117db924cf7c 242
wolfSSL 15:117db924cf7c 243 /* find H(R,A,M) and store it as h */
wolfSSL 15:117db924cf7c 244 ret = wc_InitSha512(&sha);
wolfSSL 15:117db924cf7c 245 if (ret != 0)
wolfSSL 15:117db924cf7c 246 return ret;
wolfSSL 15:117db924cf7c 247 ret = wc_Sha512Update(&sha, sig, ED25519_SIG_SIZE/2);
wolfSSL 15:117db924cf7c 248 if (ret == 0)
wolfSSL 15:117db924cf7c 249 ret = wc_Sha512Update(&sha, key->p, ED25519_PUB_KEY_SIZE);
wolfSSL 15:117db924cf7c 250 if (ret == 0)
wolfSSL 15:117db924cf7c 251 ret = wc_Sha512Update(&sha, msg, msglen);
wolfSSL 15:117db924cf7c 252 if (ret == 0)
wolfSSL 15:117db924cf7c 253 ret = wc_Sha512Final(&sha, h);
wolfSSL 15:117db924cf7c 254 wc_Sha512Free(&sha);
wolfSSL 15:117db924cf7c 255 if (ret != 0)
wolfSSL 15:117db924cf7c 256 return ret;
wolfSSL 15:117db924cf7c 257
wolfSSL 15:117db924cf7c 258 #ifdef FREESCALE_LTC_ECC
wolfSSL 15:117db924cf7c 259 LTC_PKHA_sc_reduce(h);
wolfSSL 15:117db924cf7c 260 LTC_PKHA_SignatureForVerify(rcheck, h, sig + (ED25519_SIG_SIZE/2), key);
wolfSSL 15:117db924cf7c 261 #else
wolfSSL 15:117db924cf7c 262 sc_reduce(h);
wolfSSL 15:117db924cf7c 263
wolfSSL 15:117db924cf7c 264 /*
wolfSSL 15:117db924cf7c 265 Uses a fast single-signature verification SB = R + H(R,A,M)A becomes
wolfSSL 15:117db924cf7c 266 SB - H(R,A,M)A saving decompression of R
wolfSSL 15:117db924cf7c 267 */
wolfSSL 15:117db924cf7c 268 ret = ge_double_scalarmult_vartime(&R, h, &A, sig + (ED25519_SIG_SIZE/2));
wolfSSL 15:117db924cf7c 269 if (ret != 0)
wolfSSL 15:117db924cf7c 270 return ret;
wolfSSL 15:117db924cf7c 271
wolfSSL 15:117db924cf7c 272 ge_tobytes(rcheck, &R);
wolfSSL 15:117db924cf7c 273 #endif /* FREESCALE_LTC_ECC */
wolfSSL 15:117db924cf7c 274
wolfSSL 15:117db924cf7c 275 /* comparison of R created to R in sig */
wolfSSL 15:117db924cf7c 276 ret = ConstantCompare(rcheck, sig, ED25519_SIG_SIZE/2);
wolfSSL 15:117db924cf7c 277 if (ret != 0)
wolfSSL 15:117db924cf7c 278 return SIG_VERIFY_E;
wolfSSL 15:117db924cf7c 279
wolfSSL 15:117db924cf7c 280 /* set the verification status */
wolfSSL 15:117db924cf7c 281 *res = 1;
wolfSSL 15:117db924cf7c 282
wolfSSL 15:117db924cf7c 283 return ret;
wolfSSL 15:117db924cf7c 284 }
wolfSSL 15:117db924cf7c 285
wolfSSL 15:117db924cf7c 286 #endif /* HAVE_ED25519_VERIFY */
wolfSSL 15:117db924cf7c 287
wolfSSL 15:117db924cf7c 288
wolfSSL 15:117db924cf7c 289 /* initialize information and memory for key */
wolfSSL 15:117db924cf7c 290 int wc_ed25519_init(ed25519_key* key)
wolfSSL 15:117db924cf7c 291 {
wolfSSL 15:117db924cf7c 292 if (key == NULL)
wolfSSL 15:117db924cf7c 293 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 294
wolfSSL 15:117db924cf7c 295 XMEMSET(key, 0, sizeof(ed25519_key));
wolfSSL 15:117db924cf7c 296
wolfSSL 15:117db924cf7c 297 #ifndef FREESCALE_LTC_ECC
wolfSSL 15:117db924cf7c 298 fe_init();
wolfSSL 15:117db924cf7c 299 #endif
wolfSSL 15:117db924cf7c 300
wolfSSL 15:117db924cf7c 301 return 0;
wolfSSL 15:117db924cf7c 302 }
wolfSSL 15:117db924cf7c 303
wolfSSL 15:117db924cf7c 304
wolfSSL 15:117db924cf7c 305 /* clear memory of key */
wolfSSL 15:117db924cf7c 306 void wc_ed25519_free(ed25519_key* key)
wolfSSL 15:117db924cf7c 307 {
wolfSSL 15:117db924cf7c 308 if (key == NULL)
wolfSSL 15:117db924cf7c 309 return;
wolfSSL 15:117db924cf7c 310
wolfSSL 15:117db924cf7c 311 ForceZero(key, sizeof(ed25519_key));
wolfSSL 15:117db924cf7c 312 }
wolfSSL 15:117db924cf7c 313
wolfSSL 15:117db924cf7c 314
wolfSSL 15:117db924cf7c 315 #ifdef HAVE_ED25519_KEY_EXPORT
wolfSSL 15:117db924cf7c 316
wolfSSL 15:117db924cf7c 317 /*
wolfSSL 15:117db924cf7c 318 outLen should contain the size of out buffer when input. outLen is than set
wolfSSL 15:117db924cf7c 319 to the final output length.
wolfSSL 15:117db924cf7c 320 returns 0 on success
wolfSSL 15:117db924cf7c 321 */
wolfSSL 15:117db924cf7c 322 int wc_ed25519_export_public(ed25519_key* key, byte* out, word32* outLen)
wolfSSL 15:117db924cf7c 323 {
wolfSSL 15:117db924cf7c 324 /* sanity check on arguments */
wolfSSL 15:117db924cf7c 325 if (key == NULL || out == NULL || outLen == NULL)
wolfSSL 15:117db924cf7c 326 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 327
wolfSSL 15:117db924cf7c 328 if (*outLen < ED25519_PUB_KEY_SIZE) {
wolfSSL 15:117db924cf7c 329 *outLen = ED25519_PUB_KEY_SIZE;
wolfSSL 15:117db924cf7c 330 return BUFFER_E;
wolfSSL 15:117db924cf7c 331 }
wolfSSL 15:117db924cf7c 332
wolfSSL 15:117db924cf7c 333 *outLen = ED25519_PUB_KEY_SIZE;
wolfSSL 15:117db924cf7c 334 XMEMCPY(out, key->p, ED25519_PUB_KEY_SIZE);
wolfSSL 15:117db924cf7c 335
wolfSSL 15:117db924cf7c 336 return 0;
wolfSSL 15:117db924cf7c 337 }
wolfSSL 15:117db924cf7c 338
wolfSSL 15:117db924cf7c 339 #endif /* HAVE_ED25519_KEY_EXPORT */
wolfSSL 15:117db924cf7c 340
wolfSSL 15:117db924cf7c 341
wolfSSL 15:117db924cf7c 342 #ifdef HAVE_ED25519_KEY_IMPORT
wolfSSL 15:117db924cf7c 343 /*
wolfSSL 15:117db924cf7c 344 Imports a compressed/uncompressed public key.
wolfSSL 15:117db924cf7c 345 in the byte array containing the public key
wolfSSL 15:117db924cf7c 346 inLen the length of the byte array being passed in
wolfSSL 15:117db924cf7c 347 key ed25519 key struct to put the public key in
wolfSSL 15:117db924cf7c 348 */
wolfSSL 15:117db924cf7c 349 int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key)
wolfSSL 15:117db924cf7c 350 {
wolfSSL 15:117db924cf7c 351 int ret;
wolfSSL 15:117db924cf7c 352
wolfSSL 15:117db924cf7c 353 /* sanity check on arguments */
wolfSSL 15:117db924cf7c 354 if (in == NULL || key == NULL)
wolfSSL 15:117db924cf7c 355 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 356
wolfSSL 15:117db924cf7c 357 if (inLen < ED25519_PUB_KEY_SIZE)
wolfSSL 15:117db924cf7c 358 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 359
wolfSSL 15:117db924cf7c 360 /* compressed prefix according to draft
wolfSSL 15:117db924cf7c 361 http://www.ietf.org/id/draft-koch-eddsa-for-openpgp-02.txt */
wolfSSL 15:117db924cf7c 362 if (in[0] == 0x40 && inLen > ED25519_PUB_KEY_SIZE) {
wolfSSL 15:117db924cf7c 363 /* key is stored in compressed format so just copy in */
wolfSSL 15:117db924cf7c 364 XMEMCPY(key->p, (in + 1), ED25519_PUB_KEY_SIZE);
wolfSSL 15:117db924cf7c 365 #ifdef FREESCALE_LTC_ECC
wolfSSL 15:117db924cf7c 366 /* recover X coordinate */
wolfSSL 15:117db924cf7c 367 ltc_pkha_ecc_point_t pubKey;
wolfSSL 15:117db924cf7c 368 pubKey.X = key->pointX;
wolfSSL 15:117db924cf7c 369 pubKey.Y = key->pointY;
wolfSSL 15:117db924cf7c 370 LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey);
wolfSSL 15:117db924cf7c 371 #endif
wolfSSL 15:117db924cf7c 372 key->pubKeySet = 1;
wolfSSL 15:117db924cf7c 373 return 0;
wolfSSL 15:117db924cf7c 374 }
wolfSSL 15:117db924cf7c 375
wolfSSL 15:117db924cf7c 376 /* importing uncompressed public key */
wolfSSL 15:117db924cf7c 377 if (in[0] == 0x04 && inLen > 2*ED25519_PUB_KEY_SIZE) {
wolfSSL 15:117db924cf7c 378 #ifdef FREESCALE_LTC_ECC
wolfSSL 15:117db924cf7c 379 /* reverse bytes for little endian byte order */
wolfSSL 15:117db924cf7c 380 for (int i = 0; i < ED25519_KEY_SIZE; i++)
wolfSSL 15:117db924cf7c 381 {
wolfSSL 15:117db924cf7c 382 key->pointX[i] = *(in + ED25519_KEY_SIZE - i);
wolfSSL 15:117db924cf7c 383 key->pointY[i] = *(in + 2*ED25519_KEY_SIZE - i);
wolfSSL 15:117db924cf7c 384 }
wolfSSL 15:117db924cf7c 385 XMEMCPY(key->p, key->pointY, ED25519_KEY_SIZE);
wolfSSL 15:117db924cf7c 386 ret = 0;
wolfSSL 15:117db924cf7c 387 #else
wolfSSL 15:117db924cf7c 388 /* pass in (x,y) and store compressed key */
wolfSSL 15:117db924cf7c 389 ret = ge_compress_key(key->p, in+1,
wolfSSL 15:117db924cf7c 390 in+1+ED25519_PUB_KEY_SIZE, ED25519_PUB_KEY_SIZE);
wolfSSL 15:117db924cf7c 391 #endif /* FREESCALE_LTC_ECC */
wolfSSL 15:117db924cf7c 392 if (ret == 0)
wolfSSL 15:117db924cf7c 393 key->pubKeySet = 1;
wolfSSL 15:117db924cf7c 394 return ret;
wolfSSL 15:117db924cf7c 395 }
wolfSSL 15:117db924cf7c 396
wolfSSL 15:117db924cf7c 397 /* if not specified compressed or uncompressed check key size
wolfSSL 15:117db924cf7c 398 if key size is equal to compressed key size copy in key */
wolfSSL 15:117db924cf7c 399 if (inLen == ED25519_PUB_KEY_SIZE) {
wolfSSL 15:117db924cf7c 400 XMEMCPY(key->p, in, ED25519_PUB_KEY_SIZE);
wolfSSL 15:117db924cf7c 401 #ifdef FREESCALE_LTC_ECC
wolfSSL 15:117db924cf7c 402 /* recover X coordinate */
wolfSSL 15:117db924cf7c 403 ltc_pkha_ecc_point_t pubKey;
wolfSSL 15:117db924cf7c 404 pubKey.X = key->pointX;
wolfSSL 15:117db924cf7c 405 pubKey.Y = key->pointY;
wolfSSL 15:117db924cf7c 406 LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey);
wolfSSL 15:117db924cf7c 407 #endif
wolfSSL 15:117db924cf7c 408 key->pubKeySet = 1;
wolfSSL 15:117db924cf7c 409 return 0;
wolfSSL 15:117db924cf7c 410 }
wolfSSL 15:117db924cf7c 411
wolfSSL 15:117db924cf7c 412 /* bad public key format */
wolfSSL 15:117db924cf7c 413 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 414 }
wolfSSL 15:117db924cf7c 415
wolfSSL 15:117db924cf7c 416
wolfSSL 15:117db924cf7c 417 /*
wolfSSL 15:117db924cf7c 418 For importing a private key.
wolfSSL 15:117db924cf7c 419 */
wolfSSL 15:117db924cf7c 420 int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
wolfSSL 15:117db924cf7c 421 ed25519_key* key)
wolfSSL 15:117db924cf7c 422 {
wolfSSL 15:117db924cf7c 423 /* sanity check on arguments */
wolfSSL 15:117db924cf7c 424 if (priv == NULL || key == NULL)
wolfSSL 15:117db924cf7c 425 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 426
wolfSSL 15:117db924cf7c 427 /* key size check */
wolfSSL 15:117db924cf7c 428 if (privSz < ED25519_KEY_SIZE)
wolfSSL 15:117db924cf7c 429 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 430
wolfSSL 15:117db924cf7c 431 XMEMCPY(key->k, priv, ED25519_KEY_SIZE);
wolfSSL 15:117db924cf7c 432
wolfSSL 15:117db924cf7c 433 return 0;
wolfSSL 15:117db924cf7c 434 }
wolfSSL 15:117db924cf7c 435
wolfSSL 15:117db924cf7c 436 /*
wolfSSL 15:117db924cf7c 437 For importing a private key and its associated public key.
wolfSSL 15:117db924cf7c 438 */
wolfSSL 15:117db924cf7c 439 int wc_ed25519_import_private_key(const byte* priv, word32 privSz,
wolfSSL 15:117db924cf7c 440 const byte* pub, word32 pubSz, ed25519_key* key)
wolfSSL 15:117db924cf7c 441 {
wolfSSL 15:117db924cf7c 442 int ret;
wolfSSL 15:117db924cf7c 443
wolfSSL 15:117db924cf7c 444 /* sanity check on arguments */
wolfSSL 15:117db924cf7c 445 if (priv == NULL || pub == NULL || key == NULL)
wolfSSL 15:117db924cf7c 446 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 447
wolfSSL 15:117db924cf7c 448 /* key size check */
wolfSSL 15:117db924cf7c 449 if (privSz < ED25519_KEY_SIZE || pubSz < ED25519_PUB_KEY_SIZE)
wolfSSL 15:117db924cf7c 450 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 451
wolfSSL 15:117db924cf7c 452 /* import public key */
wolfSSL 15:117db924cf7c 453 ret = wc_ed25519_import_public(pub, pubSz, key);
wolfSSL 15:117db924cf7c 454 if (ret != 0)
wolfSSL 15:117db924cf7c 455 return ret;
wolfSSL 15:117db924cf7c 456
wolfSSL 15:117db924cf7c 457 /* make the private key (priv + pub) */
wolfSSL 15:117db924cf7c 458 XMEMCPY(key->k, priv, ED25519_KEY_SIZE);
wolfSSL 15:117db924cf7c 459 XMEMCPY(key->k + ED25519_KEY_SIZE, key->p, ED25519_PUB_KEY_SIZE);
wolfSSL 15:117db924cf7c 460
wolfSSL 15:117db924cf7c 461 return ret;
wolfSSL 15:117db924cf7c 462 }
wolfSSL 15:117db924cf7c 463
wolfSSL 15:117db924cf7c 464 #endif /* HAVE_ED25519_KEY_IMPORT */
wolfSSL 15:117db924cf7c 465
wolfSSL 15:117db924cf7c 466
wolfSSL 15:117db924cf7c 467 #ifdef HAVE_ED25519_KEY_EXPORT
wolfSSL 15:117db924cf7c 468
wolfSSL 15:117db924cf7c 469 /*
wolfSSL 15:117db924cf7c 470 export private key only (secret part so 32 bytes)
wolfSSL 15:117db924cf7c 471 outLen should contain the size of out buffer when input. outLen is than set
wolfSSL 15:117db924cf7c 472 to the final output length.
wolfSSL 15:117db924cf7c 473 returns 0 on success
wolfSSL 15:117db924cf7c 474 */
wolfSSL 15:117db924cf7c 475 int wc_ed25519_export_private_only(ed25519_key* key, byte* out, word32* outLen)
wolfSSL 15:117db924cf7c 476 {
wolfSSL 15:117db924cf7c 477 /* sanity checks on arguments */
wolfSSL 15:117db924cf7c 478 if (key == NULL || out == NULL || outLen == NULL)
wolfSSL 15:117db924cf7c 479 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 480
wolfSSL 15:117db924cf7c 481 if (*outLen < ED25519_KEY_SIZE) {
wolfSSL 15:117db924cf7c 482 *outLen = ED25519_KEY_SIZE;
wolfSSL 15:117db924cf7c 483 return BUFFER_E;
wolfSSL 15:117db924cf7c 484 }
wolfSSL 15:117db924cf7c 485
wolfSSL 15:117db924cf7c 486 *outLen = ED25519_KEY_SIZE;
wolfSSL 15:117db924cf7c 487 XMEMCPY(out, key->k, ED25519_KEY_SIZE);
wolfSSL 15:117db924cf7c 488
wolfSSL 15:117db924cf7c 489 return 0;
wolfSSL 15:117db924cf7c 490 }
wolfSSL 15:117db924cf7c 491
wolfSSL 15:117db924cf7c 492 /*
wolfSSL 15:117db924cf7c 493 export private key, including public part
wolfSSL 15:117db924cf7c 494 outLen should contain the size of out buffer when input. outLen is than set
wolfSSL 15:117db924cf7c 495 to the final output length.
wolfSSL 15:117db924cf7c 496 returns 0 on success
wolfSSL 15:117db924cf7c 497 */
wolfSSL 15:117db924cf7c 498 int wc_ed25519_export_private(ed25519_key* key, byte* out, word32* outLen)
wolfSSL 15:117db924cf7c 499 {
wolfSSL 15:117db924cf7c 500 /* sanity checks on arguments */
wolfSSL 15:117db924cf7c 501 if (key == NULL || out == NULL || outLen == NULL)
wolfSSL 15:117db924cf7c 502 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 503
wolfSSL 15:117db924cf7c 504 if (*outLen < ED25519_PRV_KEY_SIZE) {
wolfSSL 15:117db924cf7c 505 *outLen = ED25519_PRV_KEY_SIZE;
wolfSSL 15:117db924cf7c 506 return BUFFER_E;
wolfSSL 15:117db924cf7c 507 }
wolfSSL 15:117db924cf7c 508
wolfSSL 15:117db924cf7c 509 *outLen = ED25519_PRV_KEY_SIZE;
wolfSSL 15:117db924cf7c 510 XMEMCPY(out, key->k, ED25519_PRV_KEY_SIZE);
wolfSSL 15:117db924cf7c 511
wolfSSL 15:117db924cf7c 512 return 0;
wolfSSL 15:117db924cf7c 513 }
wolfSSL 15:117db924cf7c 514
wolfSSL 15:117db924cf7c 515 /* export full private key and public key
wolfSSL 15:117db924cf7c 516 return 0 on success
wolfSSL 15:117db924cf7c 517 */
wolfSSL 15:117db924cf7c 518 int wc_ed25519_export_key(ed25519_key* key,
wolfSSL 15:117db924cf7c 519 byte* priv, word32 *privSz,
wolfSSL 15:117db924cf7c 520 byte* pub, word32 *pubSz)
wolfSSL 15:117db924cf7c 521 {
wolfSSL 15:117db924cf7c 522 int ret;
wolfSSL 15:117db924cf7c 523
wolfSSL 15:117db924cf7c 524 /* export 'full' private part */
wolfSSL 15:117db924cf7c 525 ret = wc_ed25519_export_private(key, priv, privSz);
wolfSSL 15:117db924cf7c 526 if (ret != 0)
wolfSSL 15:117db924cf7c 527 return ret;
wolfSSL 15:117db924cf7c 528
wolfSSL 15:117db924cf7c 529 /* export public part */
wolfSSL 15:117db924cf7c 530 ret = wc_ed25519_export_public(key, pub, pubSz);
wolfSSL 15:117db924cf7c 531
wolfSSL 15:117db924cf7c 532 return ret;
wolfSSL 15:117db924cf7c 533 }
wolfSSL 15:117db924cf7c 534
wolfSSL 15:117db924cf7c 535 #endif /* HAVE_ED25519_KEY_EXPORT */
wolfSSL 15:117db924cf7c 536
wolfSSL 15:117db924cf7c 537 /* check the private and public keys match */
wolfSSL 15:117db924cf7c 538 int wc_ed25519_check_key(ed25519_key* key)
wolfSSL 15:117db924cf7c 539 {
wolfSSL 15:117db924cf7c 540 /* TODO: Perform check of private and public key */
wolfSSL 15:117db924cf7c 541 (void)key;
wolfSSL 15:117db924cf7c 542
wolfSSL 15:117db924cf7c 543 return 0;
wolfSSL 15:117db924cf7c 544 }
wolfSSL 15:117db924cf7c 545
wolfSSL 15:117db924cf7c 546 /* returns the private key size (secret only) in bytes */
wolfSSL 15:117db924cf7c 547 int wc_ed25519_size(ed25519_key* key)
wolfSSL 15:117db924cf7c 548 {
wolfSSL 15:117db924cf7c 549 if (key == NULL)
wolfSSL 15:117db924cf7c 550 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 551
wolfSSL 15:117db924cf7c 552 return ED25519_KEY_SIZE;
wolfSSL 15:117db924cf7c 553 }
wolfSSL 15:117db924cf7c 554
wolfSSL 15:117db924cf7c 555 /* returns the private key size (secret + public) in bytes */
wolfSSL 15:117db924cf7c 556 int wc_ed25519_priv_size(ed25519_key* key)
wolfSSL 15:117db924cf7c 557 {
wolfSSL 15:117db924cf7c 558 if (key == NULL)
wolfSSL 15:117db924cf7c 559 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 560
wolfSSL 15:117db924cf7c 561 return ED25519_PRV_KEY_SIZE;
wolfSSL 15:117db924cf7c 562 }
wolfSSL 15:117db924cf7c 563
wolfSSL 15:117db924cf7c 564 /* returns the compressed key size in bytes (public key) */
wolfSSL 15:117db924cf7c 565 int wc_ed25519_pub_size(ed25519_key* key)
wolfSSL 15:117db924cf7c 566 {
wolfSSL 15:117db924cf7c 567 if (key == NULL)
wolfSSL 15:117db924cf7c 568 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 569
wolfSSL 15:117db924cf7c 570 return ED25519_PUB_KEY_SIZE;
wolfSSL 15:117db924cf7c 571 }
wolfSSL 15:117db924cf7c 572
wolfSSL 15:117db924cf7c 573 /* returns the size of signature in bytes */
wolfSSL 15:117db924cf7c 574 int wc_ed25519_sig_size(ed25519_key* key)
wolfSSL 15:117db924cf7c 575 {
wolfSSL 15:117db924cf7c 576 if (key == NULL)
wolfSSL 15:117db924cf7c 577 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 578
wolfSSL 15:117db924cf7c 579 return ED25519_SIG_SIZE;
wolfSSL 15:117db924cf7c 580 }
wolfSSL 15:117db924cf7c 581
wolfSSL 15:117db924cf7c 582 #endif /* HAVE_ED25519 */
wolfSSL 15:117db924cf7c 583
wolfSSL 15:117db924cf7c 584