Xuyi Wang / wolfcrypt

Dependents:   OS

Committer:
sPymbed
Date:
Wed Nov 20 13:28:01 2019 +0000
Revision:
0:1387ff3eed4a
initial version

Who changed what in which revision?

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