wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Committer:
wolfSSL
Date:
Thu Apr 28 00:57:21 2016 +0000
Revision:
4:1b0d80432c79
wolfSSL 3.9.0

Who changed what in which revision?

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