wolfSSL SSL/TLS library, support up to TLS1.3
Dependents: CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more
wolfcrypt/src/curve448.c@17:a5f916481144, 2020-06-05 (annotated)
- Committer:
- wolfSSL
- Date:
- Fri Jun 05 00:11:07 2020 +0000
- Revision:
- 17:a5f916481144
- Parent:
- 16:8e0d178b1d1e
wolfSSL 4.4.0
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wolfSSL | 16:8e0d178b1d1e | 1 | /* curve448.c |
wolfSSL | 16:8e0d178b1d1e | 2 | * |
wolfSSL | 16:8e0d178b1d1e | 3 | * Copyright (C) 2006-2020 wolfSSL Inc. |
wolfSSL | 16:8e0d178b1d1e | 4 | * |
wolfSSL | 16:8e0d178b1d1e | 5 | * This file is part of wolfSSL. |
wolfSSL | 16:8e0d178b1d1e | 6 | * |
wolfSSL | 16:8e0d178b1d1e | 7 | * wolfSSL is free software; you can redistribute it and/or modify |
wolfSSL | 16:8e0d178b1d1e | 8 | * it under the terms of the GNU General Public License as published by |
wolfSSL | 16:8e0d178b1d1e | 9 | * the Free Software Foundation; either version 2 of the License, or |
wolfSSL | 16:8e0d178b1d1e | 10 | * (at your option) any later version. |
wolfSSL | 16:8e0d178b1d1e | 11 | * |
wolfSSL | 16:8e0d178b1d1e | 12 | * wolfSSL is distributed in the hope that it will be useful, |
wolfSSL | 16:8e0d178b1d1e | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
wolfSSL | 16:8e0d178b1d1e | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
wolfSSL | 16:8e0d178b1d1e | 15 | * GNU General Public License for more details. |
wolfSSL | 16:8e0d178b1d1e | 16 | * |
wolfSSL | 16:8e0d178b1d1e | 17 | * You should have received a copy of the GNU General Public License |
wolfSSL | 16:8e0d178b1d1e | 18 | * along with this program; if not, write to the Free Software |
wolfSSL | 16:8e0d178b1d1e | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA |
wolfSSL | 16:8e0d178b1d1e | 20 | */ |
wolfSSL | 16:8e0d178b1d1e | 21 | |
wolfSSL | 16:8e0d178b1d1e | 22 | /* Implemented to: RFC 7748 */ |
wolfSSL | 16:8e0d178b1d1e | 23 | |
wolfSSL | 16:8e0d178b1d1e | 24 | /* Based On Daniel J Bernstein's curve25519 Public Domain ref10 work. |
wolfSSL | 16:8e0d178b1d1e | 25 | * Reworked for curve448 by Sean Parkinson. |
wolfSSL | 16:8e0d178b1d1e | 26 | */ |
wolfSSL | 16:8e0d178b1d1e | 27 | |
wolfSSL | 16:8e0d178b1d1e | 28 | #ifdef HAVE_CONFIG_H |
wolfSSL | 16:8e0d178b1d1e | 29 | #include <config.h> |
wolfSSL | 16:8e0d178b1d1e | 30 | #endif |
wolfSSL | 16:8e0d178b1d1e | 31 | |
wolfSSL | 16:8e0d178b1d1e | 32 | #include <wolfssl/wolfcrypt/settings.h> |
wolfSSL | 16:8e0d178b1d1e | 33 | |
wolfSSL | 16:8e0d178b1d1e | 34 | #ifdef HAVE_CURVE448 |
wolfSSL | 16:8e0d178b1d1e | 35 | |
wolfSSL | 16:8e0d178b1d1e | 36 | #include <wolfssl/wolfcrypt/curve448.h> |
wolfSSL | 16:8e0d178b1d1e | 37 | #include <wolfssl/wolfcrypt/error-crypt.h> |
wolfSSL | 16:8e0d178b1d1e | 38 | #ifdef NO_INLINE |
wolfSSL | 16:8e0d178b1d1e | 39 | #include <wolfssl/wolfcrypt/misc.h> |
wolfSSL | 16:8e0d178b1d1e | 40 | #else |
wolfSSL | 16:8e0d178b1d1e | 41 | #define WOLFSSL_MISC_INCLUDED |
wolfSSL | 16:8e0d178b1d1e | 42 | #include <wolfcrypt/src/misc.c> |
wolfSSL | 16:8e0d178b1d1e | 43 | #endif |
wolfSSL | 16:8e0d178b1d1e | 44 | |
wolfSSL | 16:8e0d178b1d1e | 45 | |
wolfSSL | 16:8e0d178b1d1e | 46 | /* Make a new curve448 private/public key. |
wolfSSL | 16:8e0d178b1d1e | 47 | * |
wolfSSL | 16:8e0d178b1d1e | 48 | * rng [in] Random number generator. |
wolfSSL | 16:8e0d178b1d1e | 49 | * keysize [in] Size of the key to generate. |
wolfSSL | 16:8e0d178b1d1e | 50 | * key [in] Curve448 key object. |
wolfSSL | 16:8e0d178b1d1e | 51 | * returns BAD_FUNC_ARG when rng or key are NULL, |
wolfSSL | 16:8e0d178b1d1e | 52 | * ECC_BAD_ARG_E when keysize is not CURVE448_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 53 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 54 | */ |
wolfSSL | 16:8e0d178b1d1e | 55 | int wc_curve448_make_key(WC_RNG* rng, int keysize, curve448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 56 | { |
wolfSSL | 16:8e0d178b1d1e | 57 | unsigned char basepoint[CURVE448_KEY_SIZE] = {5}; |
wolfSSL | 16:8e0d178b1d1e | 58 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 59 | |
wolfSSL | 16:8e0d178b1d1e | 60 | if ((key == NULL) || (rng == NULL)) { |
wolfSSL | 16:8e0d178b1d1e | 61 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 62 | } |
wolfSSL | 16:8e0d178b1d1e | 63 | |
wolfSSL | 16:8e0d178b1d1e | 64 | /* currently only a key size of 56 bytes is used */ |
wolfSSL | 16:8e0d178b1d1e | 65 | if ((ret == 0) && (keysize != CURVE448_KEY_SIZE)) { |
wolfSSL | 16:8e0d178b1d1e | 66 | ret = ECC_BAD_ARG_E; |
wolfSSL | 16:8e0d178b1d1e | 67 | } |
wolfSSL | 16:8e0d178b1d1e | 68 | |
wolfSSL | 16:8e0d178b1d1e | 69 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 70 | fe448_init(); |
wolfSSL | 16:8e0d178b1d1e | 71 | |
wolfSSL | 16:8e0d178b1d1e | 72 | /* random number for private key */ |
wolfSSL | 16:8e0d178b1d1e | 73 | ret = wc_RNG_GenerateBlock(rng, key->k, keysize); |
wolfSSL | 16:8e0d178b1d1e | 74 | } |
wolfSSL | 16:8e0d178b1d1e | 75 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 76 | /* Clamp the private key */ |
wolfSSL | 16:8e0d178b1d1e | 77 | key->k[0] &= 0xfc; |
wolfSSL | 16:8e0d178b1d1e | 78 | key->k[CURVE448_KEY_SIZE-1] |= 0x80; |
wolfSSL | 16:8e0d178b1d1e | 79 | |
wolfSSL | 16:8e0d178b1d1e | 80 | /* compute public key */ |
wolfSSL | 16:8e0d178b1d1e | 81 | ret = curve448(key->p, key->k, basepoint); |
wolfSSL | 16:8e0d178b1d1e | 82 | if (ret != 0) { |
wolfSSL | 16:8e0d178b1d1e | 83 | ForceZero(key->k, keysize); |
wolfSSL | 16:8e0d178b1d1e | 84 | ForceZero(key->p, keysize); |
wolfSSL | 16:8e0d178b1d1e | 85 | } |
wolfSSL | 16:8e0d178b1d1e | 86 | } |
wolfSSL | 16:8e0d178b1d1e | 87 | |
wolfSSL | 16:8e0d178b1d1e | 88 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 89 | } |
wolfSSL | 16:8e0d178b1d1e | 90 | |
wolfSSL | 16:8e0d178b1d1e | 91 | #ifdef HAVE_CURVE448_SHARED_SECRET |
wolfSSL | 16:8e0d178b1d1e | 92 | |
wolfSSL | 16:8e0d178b1d1e | 93 | /* Calculate the shared secret from the private key and peer's public key. |
wolfSSL | 16:8e0d178b1d1e | 94 | * Calculation over curve448. |
wolfSSL | 16:8e0d178b1d1e | 95 | * Secret encoded big-endian. |
wolfSSL | 16:8e0d178b1d1e | 96 | * |
wolfSSL | 16:8e0d178b1d1e | 97 | * private_key [in] Curve448 private key. |
wolfSSL | 16:8e0d178b1d1e | 98 | * public_key [in] Curve448 public key. |
wolfSSL | 16:8e0d178b1d1e | 99 | * out [in] Array to hold shared secret. |
wolfSSL | 16:8e0d178b1d1e | 100 | * outLen [in/out] On in, the number of bytes in array. |
wolfSSL | 16:8e0d178b1d1e | 101 | * On out, the number bytes put into array. |
wolfSSL | 16:8e0d178b1d1e | 102 | * returns BAD_FUNC_ARG when a parameter is NULL or outLen is less than |
wolfSSL | 16:8e0d178b1d1e | 103 | * CURVE448_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 104 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 105 | */ |
wolfSSL | 16:8e0d178b1d1e | 106 | int wc_curve448_shared_secret(curve448_key* private_key, |
wolfSSL | 16:8e0d178b1d1e | 107 | curve448_key* public_key, |
wolfSSL | 16:8e0d178b1d1e | 108 | byte* out, word32* outLen) |
wolfSSL | 16:8e0d178b1d1e | 109 | { |
wolfSSL | 16:8e0d178b1d1e | 110 | return wc_curve448_shared_secret_ex(private_key, public_key, out, outLen, |
wolfSSL | 16:8e0d178b1d1e | 111 | EC448_BIG_ENDIAN); |
wolfSSL | 16:8e0d178b1d1e | 112 | } |
wolfSSL | 16:8e0d178b1d1e | 113 | |
wolfSSL | 16:8e0d178b1d1e | 114 | /* Calculate the shared secret from the private key and peer's public key. |
wolfSSL | 16:8e0d178b1d1e | 115 | * Calculation over curve448. |
wolfSSL | 16:8e0d178b1d1e | 116 | * |
wolfSSL | 16:8e0d178b1d1e | 117 | * private_key [in] Curve448 private key. |
wolfSSL | 16:8e0d178b1d1e | 118 | * public_key [in] Curve448 public key. |
wolfSSL | 16:8e0d178b1d1e | 119 | * out [in] Array to hold shared secret. |
wolfSSL | 16:8e0d178b1d1e | 120 | * outLen [in/out] On in, the number of bytes in array. |
wolfSSL | 16:8e0d178b1d1e | 121 | * On out, the number bytes put into array. |
wolfSSL | 16:8e0d178b1d1e | 122 | * endian [in] Endianness to use when encoding number in array. |
wolfSSL | 16:8e0d178b1d1e | 123 | * returns BAD_FUNC_ARG when a parameter is NULL or outLen is less than |
wolfSSL | 16:8e0d178b1d1e | 124 | * CURVE448_PUB_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 125 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 126 | */ |
wolfSSL | 16:8e0d178b1d1e | 127 | int wc_curve448_shared_secret_ex(curve448_key* private_key, |
wolfSSL | 16:8e0d178b1d1e | 128 | curve448_key* public_key, |
wolfSSL | 16:8e0d178b1d1e | 129 | byte* out, word32* outLen, int endian) |
wolfSSL | 16:8e0d178b1d1e | 130 | { |
wolfSSL | 16:8e0d178b1d1e | 131 | unsigned char o[CURVE448_PUB_KEY_SIZE]; |
wolfSSL | 16:8e0d178b1d1e | 132 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 133 | int i; |
wolfSSL | 16:8e0d178b1d1e | 134 | |
wolfSSL | 16:8e0d178b1d1e | 135 | /* sanity check */ |
wolfSSL | 16:8e0d178b1d1e | 136 | if ((private_key == NULL) || (public_key == NULL) || (out == NULL) || |
wolfSSL | 16:8e0d178b1d1e | 137 | (outLen == NULL) || (*outLen < CURVE448_PUB_KEY_SIZE)) { |
wolfSSL | 16:8e0d178b1d1e | 138 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 139 | } |
wolfSSL | 16:8e0d178b1d1e | 140 | |
wolfSSL | 16:8e0d178b1d1e | 141 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 142 | ret = curve448(o, private_key->k, public_key->p); |
wolfSSL | 16:8e0d178b1d1e | 143 | } |
wolfSSL | 16:8e0d178b1d1e | 144 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 145 | if (endian == EC448_BIG_ENDIAN) { |
wolfSSL | 16:8e0d178b1d1e | 146 | /* put shared secret key in Big Endian format */ |
wolfSSL | 16:8e0d178b1d1e | 147 | for (i = 0; i < CURVE448_PUB_KEY_SIZE; i++) { |
wolfSSL | 16:8e0d178b1d1e | 148 | out[i] = o[CURVE448_PUB_KEY_SIZE - i -1]; |
wolfSSL | 16:8e0d178b1d1e | 149 | } |
wolfSSL | 16:8e0d178b1d1e | 150 | } |
wolfSSL | 16:8e0d178b1d1e | 151 | else { |
wolfSSL | 16:8e0d178b1d1e | 152 | /* put shared secret key in Little Endian format */ |
wolfSSL | 16:8e0d178b1d1e | 153 | XMEMCPY(out, o, CURVE448_PUB_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 154 | } |
wolfSSL | 16:8e0d178b1d1e | 155 | |
wolfSSL | 16:8e0d178b1d1e | 156 | *outLen = CURVE448_PUB_KEY_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 157 | } |
wolfSSL | 16:8e0d178b1d1e | 158 | |
wolfSSL | 16:8e0d178b1d1e | 159 | ForceZero(o, CURVE448_PUB_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 160 | |
wolfSSL | 16:8e0d178b1d1e | 161 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 162 | } |
wolfSSL | 16:8e0d178b1d1e | 163 | |
wolfSSL | 16:8e0d178b1d1e | 164 | #endif /* HAVE_CURVE448_SHARED_SECRET */ |
wolfSSL | 16:8e0d178b1d1e | 165 | |
wolfSSL | 16:8e0d178b1d1e | 166 | #ifdef HAVE_CURVE448_KEY_EXPORT |
wolfSSL | 16:8e0d178b1d1e | 167 | |
wolfSSL | 16:8e0d178b1d1e | 168 | /* Export the curve448 public key. |
wolfSSL | 16:8e0d178b1d1e | 169 | * Public key encoded big-endian. |
wolfSSL | 16:8e0d178b1d1e | 170 | * |
wolfSSL | 16:8e0d178b1d1e | 171 | * key [in] Curve448 public key. |
wolfSSL | 16:8e0d178b1d1e | 172 | * out [in] Array to hold public key. |
wolfSSL | 16:8e0d178b1d1e | 173 | * outLen [in/out] On in, the number of bytes in array. |
wolfSSL | 16:8e0d178b1d1e | 174 | * On out, the number bytes put into array. |
wolfSSL | 16:8e0d178b1d1e | 175 | * returns BAD_FUNC_ARG when a parameter is NULL, |
wolfSSL | 16:8e0d178b1d1e | 176 | * ECC_BAD_ARG_E when outLen is less than CURVE448_PUB_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 177 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 178 | */ |
wolfSSL | 16:8e0d178b1d1e | 179 | int wc_curve448_export_public(curve448_key* key, byte* out, word32* outLen) |
wolfSSL | 16:8e0d178b1d1e | 180 | { |
wolfSSL | 16:8e0d178b1d1e | 181 | return wc_curve448_export_public_ex(key, out, outLen, EC448_BIG_ENDIAN); |
wolfSSL | 16:8e0d178b1d1e | 182 | } |
wolfSSL | 16:8e0d178b1d1e | 183 | |
wolfSSL | 16:8e0d178b1d1e | 184 | /* Export the curve448 public key. |
wolfSSL | 16:8e0d178b1d1e | 185 | * |
wolfSSL | 16:8e0d178b1d1e | 186 | * key [in] Curve448 public key. |
wolfSSL | 16:8e0d178b1d1e | 187 | * out [in] Array to hold public key. |
wolfSSL | 16:8e0d178b1d1e | 188 | * outLen [in/out] On in, the number of bytes in array. |
wolfSSL | 16:8e0d178b1d1e | 189 | * On out, the number bytes put into array. |
wolfSSL | 16:8e0d178b1d1e | 190 | * endian [in] Endianness to use when encoding number in array. |
wolfSSL | 16:8e0d178b1d1e | 191 | * returns BAD_FUNC_ARG when a parameter is NULL, |
wolfSSL | 16:8e0d178b1d1e | 192 | * ECC_BAD_ARG_E when outLen is less than CURVE448_PUB_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 193 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 194 | */ |
wolfSSL | 16:8e0d178b1d1e | 195 | int wc_curve448_export_public_ex(curve448_key* key, byte* out, word32* outLen, |
wolfSSL | 16:8e0d178b1d1e | 196 | int endian) |
wolfSSL | 16:8e0d178b1d1e | 197 | { |
wolfSSL | 16:8e0d178b1d1e | 198 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 199 | int i; |
wolfSSL | 16:8e0d178b1d1e | 200 | |
wolfSSL | 16:8e0d178b1d1e | 201 | if ((key == NULL) || (out == NULL) || (outLen == NULL)) { |
wolfSSL | 16:8e0d178b1d1e | 202 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 203 | } |
wolfSSL | 16:8e0d178b1d1e | 204 | |
wolfSSL | 16:8e0d178b1d1e | 205 | /* check and set outgoing key size */ |
wolfSSL | 16:8e0d178b1d1e | 206 | if ((ret == 0) && (*outLen < CURVE448_PUB_KEY_SIZE)) { |
wolfSSL | 16:8e0d178b1d1e | 207 | *outLen = CURVE448_PUB_KEY_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 208 | ret = ECC_BAD_ARG_E; |
wolfSSL | 16:8e0d178b1d1e | 209 | } |
wolfSSL | 16:8e0d178b1d1e | 210 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 211 | *outLen = CURVE448_PUB_KEY_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 212 | |
wolfSSL | 16:8e0d178b1d1e | 213 | if (endian == EC448_BIG_ENDIAN) { |
wolfSSL | 16:8e0d178b1d1e | 214 | /* read keys in Big Endian format */ |
wolfSSL | 16:8e0d178b1d1e | 215 | for (i = 0; i < CURVE448_PUB_KEY_SIZE; i++) { |
wolfSSL | 16:8e0d178b1d1e | 216 | out[i] = key->p[CURVE448_PUB_KEY_SIZE - i - 1]; |
wolfSSL | 16:8e0d178b1d1e | 217 | } |
wolfSSL | 16:8e0d178b1d1e | 218 | } |
wolfSSL | 16:8e0d178b1d1e | 219 | else { |
wolfSSL | 16:8e0d178b1d1e | 220 | XMEMCPY(out, key->p, CURVE448_PUB_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 221 | } |
wolfSSL | 16:8e0d178b1d1e | 222 | } |
wolfSSL | 16:8e0d178b1d1e | 223 | |
wolfSSL | 16:8e0d178b1d1e | 224 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 225 | } |
wolfSSL | 16:8e0d178b1d1e | 226 | |
wolfSSL | 16:8e0d178b1d1e | 227 | #endif /* HAVE_CURVE448_KEY_EXPORT */ |
wolfSSL | 16:8e0d178b1d1e | 228 | |
wolfSSL | 16:8e0d178b1d1e | 229 | #ifdef HAVE_CURVE448_KEY_IMPORT |
wolfSSL | 16:8e0d178b1d1e | 230 | |
wolfSSL | 16:8e0d178b1d1e | 231 | /* Import a curve448 public key from a byte array. |
wolfSSL | 16:8e0d178b1d1e | 232 | * Public key encoded in big-endian. |
wolfSSL | 16:8e0d178b1d1e | 233 | * |
wolfSSL | 16:8e0d178b1d1e | 234 | * in [in] Array holding public key. |
wolfSSL | 16:8e0d178b1d1e | 235 | * inLen [in] Number of bytes of data in array. |
wolfSSL | 16:8e0d178b1d1e | 236 | * key [in] Curve448 public key. |
wolfSSL | 16:8e0d178b1d1e | 237 | * returns BAD_FUNC_ARG when a parameter is NULL, |
wolfSSL | 16:8e0d178b1d1e | 238 | * ECC_BAD_ARG_E when inLen is less than CURVE448_PUB_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 239 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 240 | */ |
wolfSSL | 16:8e0d178b1d1e | 241 | int wc_curve448_import_public(const byte* in, word32 inLen, curve448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 242 | { |
wolfSSL | 16:8e0d178b1d1e | 243 | return wc_curve448_import_public_ex(in, inLen, key, EC448_BIG_ENDIAN); |
wolfSSL | 16:8e0d178b1d1e | 244 | } |
wolfSSL | 16:8e0d178b1d1e | 245 | |
wolfSSL | 16:8e0d178b1d1e | 246 | /* Import a curve448 public key from a byte array. |
wolfSSL | 16:8e0d178b1d1e | 247 | * |
wolfSSL | 16:8e0d178b1d1e | 248 | * in [in] Array holding public key. |
wolfSSL | 16:8e0d178b1d1e | 249 | * inLen [in] Number of bytes of data in array. |
wolfSSL | 16:8e0d178b1d1e | 250 | * key [in] Curve448 public key. |
wolfSSL | 16:8e0d178b1d1e | 251 | * endian [in] Endianness of encoded number in byte array. |
wolfSSL | 16:8e0d178b1d1e | 252 | * returns BAD_FUNC_ARG when a parameter is NULL, |
wolfSSL | 16:8e0d178b1d1e | 253 | * ECC_BAD_ARG_E when inLen is less than CURVE448_PUB_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 254 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 255 | */ |
wolfSSL | 16:8e0d178b1d1e | 256 | int wc_curve448_import_public_ex(const byte* in, word32 inLen, |
wolfSSL | 16:8e0d178b1d1e | 257 | curve448_key* key, int endian) |
wolfSSL | 16:8e0d178b1d1e | 258 | { |
wolfSSL | 16:8e0d178b1d1e | 259 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 260 | int i; |
wolfSSL | 16:8e0d178b1d1e | 261 | |
wolfSSL | 16:8e0d178b1d1e | 262 | /* sanity check */ |
wolfSSL | 16:8e0d178b1d1e | 263 | if ((key == NULL) || (in == NULL)) { |
wolfSSL | 16:8e0d178b1d1e | 264 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 265 | } |
wolfSSL | 16:8e0d178b1d1e | 266 | |
wolfSSL | 16:8e0d178b1d1e | 267 | /* check size of incoming keys */ |
wolfSSL | 16:8e0d178b1d1e | 268 | if ((ret == 0) && (inLen != CURVE448_PUB_KEY_SIZE)) { |
wolfSSL | 16:8e0d178b1d1e | 269 | ret = ECC_BAD_ARG_E; |
wolfSSL | 16:8e0d178b1d1e | 270 | } |
wolfSSL | 16:8e0d178b1d1e | 271 | |
wolfSSL | 16:8e0d178b1d1e | 272 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 273 | if (endian == EC448_BIG_ENDIAN) { |
wolfSSL | 16:8e0d178b1d1e | 274 | /* read keys in Big Endian format */ |
wolfSSL | 16:8e0d178b1d1e | 275 | for (i = 0; i < CURVE448_PUB_KEY_SIZE; i++) { |
wolfSSL | 16:8e0d178b1d1e | 276 | key->p[i] = in[CURVE448_PUB_KEY_SIZE - i - 1]; |
wolfSSL | 16:8e0d178b1d1e | 277 | } |
wolfSSL | 16:8e0d178b1d1e | 278 | } |
wolfSSL | 16:8e0d178b1d1e | 279 | else |
wolfSSL | 16:8e0d178b1d1e | 280 | XMEMCPY(key->p, in, inLen); |
wolfSSL | 16:8e0d178b1d1e | 281 | } |
wolfSSL | 16:8e0d178b1d1e | 282 | |
wolfSSL | 16:8e0d178b1d1e | 283 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 284 | } |
wolfSSL | 16:8e0d178b1d1e | 285 | |
wolfSSL | 16:8e0d178b1d1e | 286 | /* Check the public key value (big or little endian) |
wolfSSL | 16:8e0d178b1d1e | 287 | * |
wolfSSL | 16:8e0d178b1d1e | 288 | * pub [in] Public key bytes. |
wolfSSL | 16:8e0d178b1d1e | 289 | * pubSz [in] Size of public key in bytes. |
wolfSSL | 16:8e0d178b1d1e | 290 | * endian [in] Public key bytes passed in as big-endian or little-endian. |
wolfSSL | 16:8e0d178b1d1e | 291 | * returns BAD_FUNC_ARGS when pub is NULL, |
wolfSSL | 16:8e0d178b1d1e | 292 | * ECC_BAD_ARG_E when key length is not 56 bytes, public key value is |
wolfSSL | 16:8e0d178b1d1e | 293 | * zero or one; |
wolfSSL | 16:8e0d178b1d1e | 294 | * BUFFER_E when size of public key is zero; |
wolfSSL | 16:8e0d178b1d1e | 295 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 296 | */ |
wolfSSL | 16:8e0d178b1d1e | 297 | int wc_curve448_check_public(const byte* pub, word32 pubSz, int endian) |
wolfSSL | 16:8e0d178b1d1e | 298 | { |
wolfSSL | 16:8e0d178b1d1e | 299 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 300 | word32 i; |
wolfSSL | 16:8e0d178b1d1e | 301 | |
wolfSSL | 16:8e0d178b1d1e | 302 | if (pub == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 303 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 304 | } |
wolfSSL | 16:8e0d178b1d1e | 305 | |
wolfSSL | 16:8e0d178b1d1e | 306 | /* Check for empty key data */ |
wolfSSL | 16:8e0d178b1d1e | 307 | if ((ret == 0) && (pubSz == 0)) { |
wolfSSL | 16:8e0d178b1d1e | 308 | ret = BUFFER_E; |
wolfSSL | 16:8e0d178b1d1e | 309 | } |
wolfSSL | 16:8e0d178b1d1e | 310 | |
wolfSSL | 16:8e0d178b1d1e | 311 | /* Check key length */ |
wolfSSL | 16:8e0d178b1d1e | 312 | if ((ret == 0) && (pubSz != CURVE448_PUB_KEY_SIZE)) { |
wolfSSL | 16:8e0d178b1d1e | 313 | ret = ECC_BAD_ARG_E; |
wolfSSL | 16:8e0d178b1d1e | 314 | } |
wolfSSL | 16:8e0d178b1d1e | 315 | |
wolfSSL | 16:8e0d178b1d1e | 316 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 317 | if (endian == EC448_LITTLE_ENDIAN) { |
wolfSSL | 16:8e0d178b1d1e | 318 | /* Check for value of zero or one */ |
wolfSSL | 16:8e0d178b1d1e | 319 | for (i = pubSz - 1; i > 0; i--) { |
wolfSSL | 16:8e0d178b1d1e | 320 | if (pub[i] != 0) { |
wolfSSL | 16:8e0d178b1d1e | 321 | break; |
wolfSSL | 16:8e0d178b1d1e | 322 | } |
wolfSSL | 16:8e0d178b1d1e | 323 | } |
wolfSSL | 16:8e0d178b1d1e | 324 | if ((i == 0) && (pub[0] == 0 || pub[0] == 1)) { |
wolfSSL | 16:8e0d178b1d1e | 325 | return ECC_BAD_ARG_E; |
wolfSSL | 16:8e0d178b1d1e | 326 | } |
wolfSSL | 16:8e0d178b1d1e | 327 | } |
wolfSSL | 16:8e0d178b1d1e | 328 | else { |
wolfSSL | 16:8e0d178b1d1e | 329 | /* Check for value of zero or one */ |
wolfSSL | 16:8e0d178b1d1e | 330 | for (i = 0; i < pubSz-1; i++) { |
wolfSSL | 16:8e0d178b1d1e | 331 | if (pub[i] != 0) { |
wolfSSL | 16:8e0d178b1d1e | 332 | break; |
wolfSSL | 16:8e0d178b1d1e | 333 | } |
wolfSSL | 16:8e0d178b1d1e | 334 | } |
wolfSSL | 16:8e0d178b1d1e | 335 | if ((i == pubSz - 1) && (pub[i] == 0 || pub[i] == 1)) { |
wolfSSL | 16:8e0d178b1d1e | 336 | ret = ECC_BAD_ARG_E; |
wolfSSL | 16:8e0d178b1d1e | 337 | } |
wolfSSL | 16:8e0d178b1d1e | 338 | } |
wolfSSL | 16:8e0d178b1d1e | 339 | } |
wolfSSL | 16:8e0d178b1d1e | 340 | |
wolfSSL | 16:8e0d178b1d1e | 341 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 342 | } |
wolfSSL | 16:8e0d178b1d1e | 343 | |
wolfSSL | 16:8e0d178b1d1e | 344 | #endif /* HAVE_CURVE448_KEY_IMPORT */ |
wolfSSL | 16:8e0d178b1d1e | 345 | |
wolfSSL | 16:8e0d178b1d1e | 346 | |
wolfSSL | 16:8e0d178b1d1e | 347 | #ifdef HAVE_CURVE448_KEY_EXPORT |
wolfSSL | 16:8e0d178b1d1e | 348 | |
wolfSSL | 16:8e0d178b1d1e | 349 | /* Export the curve448 private key raw form. |
wolfSSL | 16:8e0d178b1d1e | 350 | * Private key encoded big-endian. |
wolfSSL | 16:8e0d178b1d1e | 351 | * |
wolfSSL | 16:8e0d178b1d1e | 352 | * key [in] Curve448 private key. |
wolfSSL | 16:8e0d178b1d1e | 353 | * out [in] Array to hold private key. |
wolfSSL | 16:8e0d178b1d1e | 354 | * outLen [in/out] On in, the number of bytes in array. |
wolfSSL | 16:8e0d178b1d1e | 355 | * On out, the number bytes put into array. |
wolfSSL | 16:8e0d178b1d1e | 356 | * returns BAD_FUNC_ARG when a parameter is NULL, |
wolfSSL | 16:8e0d178b1d1e | 357 | * ECC_BAD_ARG_E when outLen is less than CURVE448_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 358 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 359 | */ |
wolfSSL | 16:8e0d178b1d1e | 360 | int wc_curve448_export_private_raw(curve448_key* key, byte* out, word32* outLen) |
wolfSSL | 16:8e0d178b1d1e | 361 | { |
wolfSSL | 16:8e0d178b1d1e | 362 | return wc_curve448_export_private_raw_ex(key, out, outLen, |
wolfSSL | 16:8e0d178b1d1e | 363 | EC448_BIG_ENDIAN); |
wolfSSL | 16:8e0d178b1d1e | 364 | } |
wolfSSL | 16:8e0d178b1d1e | 365 | |
wolfSSL | 16:8e0d178b1d1e | 366 | /* Export the curve448 private key raw form. |
wolfSSL | 16:8e0d178b1d1e | 367 | * |
wolfSSL | 16:8e0d178b1d1e | 368 | * key [in] Curve448 private key. |
wolfSSL | 16:8e0d178b1d1e | 369 | * out [in] Array to hold private key. |
wolfSSL | 16:8e0d178b1d1e | 370 | * outLen [in/out] On in, the number of bytes in array. |
wolfSSL | 16:8e0d178b1d1e | 371 | * On out, the number bytes put into array. |
wolfSSL | 16:8e0d178b1d1e | 372 | * endian [in] Endianness to use when encoding number in array. |
wolfSSL | 16:8e0d178b1d1e | 373 | * returns BAD_FUNC_ARG when a parameter is NULL, |
wolfSSL | 16:8e0d178b1d1e | 374 | * ECC_BAD_ARG_E when outLen is less than CURVE448_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 375 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 376 | */ |
wolfSSL | 16:8e0d178b1d1e | 377 | int wc_curve448_export_private_raw_ex(curve448_key* key, byte* out, |
wolfSSL | 16:8e0d178b1d1e | 378 | word32* outLen, int endian) |
wolfSSL | 16:8e0d178b1d1e | 379 | { |
wolfSSL | 16:8e0d178b1d1e | 380 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 381 | int i; |
wolfSSL | 16:8e0d178b1d1e | 382 | |
wolfSSL | 16:8e0d178b1d1e | 383 | /* sanity check */ |
wolfSSL | 16:8e0d178b1d1e | 384 | if ((key == NULL) || (out == NULL) || (outLen == NULL)) { |
wolfSSL | 16:8e0d178b1d1e | 385 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 386 | } |
wolfSSL | 16:8e0d178b1d1e | 387 | |
wolfSSL | 16:8e0d178b1d1e | 388 | /* check size of outgoing buffer */ |
wolfSSL | 16:8e0d178b1d1e | 389 | if ((ret == 0) && (*outLen < CURVE448_KEY_SIZE)) { |
wolfSSL | 16:8e0d178b1d1e | 390 | *outLen = CURVE448_KEY_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 391 | ret = ECC_BAD_ARG_E; |
wolfSSL | 16:8e0d178b1d1e | 392 | } |
wolfSSL | 16:8e0d178b1d1e | 393 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 394 | *outLen = CURVE448_KEY_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 395 | |
wolfSSL | 16:8e0d178b1d1e | 396 | if (endian == EC448_BIG_ENDIAN) { |
wolfSSL | 16:8e0d178b1d1e | 397 | /* put the key in Big Endian format */ |
wolfSSL | 16:8e0d178b1d1e | 398 | for (i = 0; i < CURVE448_KEY_SIZE; i++) { |
wolfSSL | 16:8e0d178b1d1e | 399 | out[i] = key->k[CURVE448_KEY_SIZE - i - 1]; |
wolfSSL | 16:8e0d178b1d1e | 400 | } |
wolfSSL | 16:8e0d178b1d1e | 401 | } |
wolfSSL | 16:8e0d178b1d1e | 402 | else { |
wolfSSL | 16:8e0d178b1d1e | 403 | XMEMCPY(out, key->k, CURVE448_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 404 | } |
wolfSSL | 16:8e0d178b1d1e | 405 | } |
wolfSSL | 16:8e0d178b1d1e | 406 | |
wolfSSL | 16:8e0d178b1d1e | 407 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 408 | } |
wolfSSL | 16:8e0d178b1d1e | 409 | |
wolfSSL | 16:8e0d178b1d1e | 410 | /* Export the curve448 private and public keys in raw form. |
wolfSSL | 16:8e0d178b1d1e | 411 | * Private and public key encoded big-endian. |
wolfSSL | 16:8e0d178b1d1e | 412 | * |
wolfSSL | 16:8e0d178b1d1e | 413 | * key [in] Curve448 private key. |
wolfSSL | 16:8e0d178b1d1e | 414 | * priv [in] Array to hold private key. |
wolfSSL | 16:8e0d178b1d1e | 415 | * privSz [in/out] On in, the number of bytes in private key array. |
wolfSSL | 16:8e0d178b1d1e | 416 | * On out, the number bytes put into private key array. |
wolfSSL | 16:8e0d178b1d1e | 417 | * pub [in] Array to hold public key. |
wolfSSL | 16:8e0d178b1d1e | 418 | * pubSz [in/out] On in, the number of bytes in public key array. |
wolfSSL | 16:8e0d178b1d1e | 419 | * On out, the number bytes put into public key array. |
wolfSSL | 16:8e0d178b1d1e | 420 | * returns BAD_FUNC_ARG when a parameter is NULL, |
wolfSSL | 16:8e0d178b1d1e | 421 | * ECC_BAD_ARG_E when privSz is less than CURVE448_KEY_SIZE or pubSz is |
wolfSSL | 16:8e0d178b1d1e | 422 | * less than CURVE448_PUB_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 423 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 424 | */ |
wolfSSL | 16:8e0d178b1d1e | 425 | int wc_curve448_export_key_raw(curve448_key* key, byte* priv, word32 *privSz, |
wolfSSL | 16:8e0d178b1d1e | 426 | byte* pub, word32 *pubSz) |
wolfSSL | 16:8e0d178b1d1e | 427 | { |
wolfSSL | 16:8e0d178b1d1e | 428 | return wc_curve448_export_key_raw_ex(key, priv, privSz, pub, pubSz, |
wolfSSL | 16:8e0d178b1d1e | 429 | EC448_BIG_ENDIAN); |
wolfSSL | 16:8e0d178b1d1e | 430 | } |
wolfSSL | 16:8e0d178b1d1e | 431 | |
wolfSSL | 16:8e0d178b1d1e | 432 | /* Export the curve448 private and public keys in raw form. |
wolfSSL | 16:8e0d178b1d1e | 433 | * |
wolfSSL | 16:8e0d178b1d1e | 434 | * key [in] Curve448 private key. |
wolfSSL | 16:8e0d178b1d1e | 435 | * priv [in] Array to hold private key. |
wolfSSL | 16:8e0d178b1d1e | 436 | * privSz [in/out] On in, the number of bytes in private key array. |
wolfSSL | 16:8e0d178b1d1e | 437 | * On out, the number bytes put into private key array. |
wolfSSL | 16:8e0d178b1d1e | 438 | * pub [in] Array to hold public key. |
wolfSSL | 16:8e0d178b1d1e | 439 | * pubSz [in/out] On in, the number of bytes in public key array. |
wolfSSL | 16:8e0d178b1d1e | 440 | * On out, the number bytes put into public key array. |
wolfSSL | 16:8e0d178b1d1e | 441 | * endian [in] Endianness to use when encoding number in array. |
wolfSSL | 16:8e0d178b1d1e | 442 | * returns BAD_FUNC_ARG when a parameter is NULL, |
wolfSSL | 16:8e0d178b1d1e | 443 | * ECC_BAD_ARG_E when privSz is less than CURVE448_KEY_SIZE or pubSz is |
wolfSSL | 16:8e0d178b1d1e | 444 | * less than CURVE448_PUB_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 445 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 446 | */ |
wolfSSL | 16:8e0d178b1d1e | 447 | int wc_curve448_export_key_raw_ex(curve448_key* key, byte* priv, word32 *privSz, |
wolfSSL | 16:8e0d178b1d1e | 448 | byte* pub, word32 *pubSz, int endian) |
wolfSSL | 16:8e0d178b1d1e | 449 | { |
wolfSSL | 16:8e0d178b1d1e | 450 | int ret; |
wolfSSL | 16:8e0d178b1d1e | 451 | |
wolfSSL | 16:8e0d178b1d1e | 452 | /* export private part */ |
wolfSSL | 16:8e0d178b1d1e | 453 | ret = wc_curve448_export_private_raw_ex(key, priv, privSz, endian); |
wolfSSL | 16:8e0d178b1d1e | 454 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 455 | /* export public part */ |
wolfSSL | 16:8e0d178b1d1e | 456 | ret = wc_curve448_export_public_ex(key, pub, pubSz, endian); |
wolfSSL | 16:8e0d178b1d1e | 457 | } |
wolfSSL | 16:8e0d178b1d1e | 458 | |
wolfSSL | 16:8e0d178b1d1e | 459 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 460 | } |
wolfSSL | 16:8e0d178b1d1e | 461 | |
wolfSSL | 16:8e0d178b1d1e | 462 | #endif /* HAVE_CURVE448_KEY_EXPORT */ |
wolfSSL | 16:8e0d178b1d1e | 463 | |
wolfSSL | 16:8e0d178b1d1e | 464 | #ifdef HAVE_CURVE448_KEY_IMPORT |
wolfSSL | 16:8e0d178b1d1e | 465 | |
wolfSSL | 16:8e0d178b1d1e | 466 | /* Import curve448 private and public keys from a byte arrays. |
wolfSSL | 16:8e0d178b1d1e | 467 | * Private and public keys encoded in big-endian. |
wolfSSL | 16:8e0d178b1d1e | 468 | * |
wolfSSL | 16:8e0d178b1d1e | 469 | * piv [in] Array holding private key. |
wolfSSL | 16:8e0d178b1d1e | 470 | * privSz [in] Number of bytes of data in private key array. |
wolfSSL | 16:8e0d178b1d1e | 471 | * pub [in] Array holding public key. |
wolfSSL | 16:8e0d178b1d1e | 472 | * pubSz [in] Number of bytes of data in public key array. |
wolfSSL | 16:8e0d178b1d1e | 473 | * key [in] Curve448 private/public key. |
wolfSSL | 16:8e0d178b1d1e | 474 | * returns BAD_FUNC_ARG when a parameter is NULL, |
wolfSSL | 16:8e0d178b1d1e | 475 | * ECC_BAD_ARG_E when privSz is less than CURVE448_KEY_SIZE or pubSz is |
wolfSSL | 16:8e0d178b1d1e | 476 | * less than CURVE448_PUB_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 477 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 478 | */ |
wolfSSL | 16:8e0d178b1d1e | 479 | int wc_curve448_import_private_raw(const byte* priv, word32 privSz, |
wolfSSL | 16:8e0d178b1d1e | 480 | const byte* pub, word32 pubSz, |
wolfSSL | 16:8e0d178b1d1e | 481 | curve448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 482 | { |
wolfSSL | 16:8e0d178b1d1e | 483 | return wc_curve448_import_private_raw_ex(priv, privSz, pub, pubSz, key, |
wolfSSL | 16:8e0d178b1d1e | 484 | EC448_BIG_ENDIAN); |
wolfSSL | 16:8e0d178b1d1e | 485 | } |
wolfSSL | 16:8e0d178b1d1e | 486 | |
wolfSSL | 16:8e0d178b1d1e | 487 | /* Import curve448 private and public keys from a byte arrays. |
wolfSSL | 16:8e0d178b1d1e | 488 | * |
wolfSSL | 16:8e0d178b1d1e | 489 | * piv [in] Array holding private key. |
wolfSSL | 16:8e0d178b1d1e | 490 | * privSz [in] Number of bytes of data in private key array. |
wolfSSL | 16:8e0d178b1d1e | 491 | * pub [in] Array holding public key. |
wolfSSL | 16:8e0d178b1d1e | 492 | * pubSz [in] Number of bytes of data in public key array. |
wolfSSL | 16:8e0d178b1d1e | 493 | * key [in] Curve448 private/public key. |
wolfSSL | 16:8e0d178b1d1e | 494 | * endian [in] Endianness of encoded numbers in byte arrays. |
wolfSSL | 16:8e0d178b1d1e | 495 | * returns BAD_FUNC_ARG when a parameter is NULL, |
wolfSSL | 16:8e0d178b1d1e | 496 | * ECC_BAD_ARG_E when privSz is less than CURVE448_KEY_SIZE or pubSz is |
wolfSSL | 16:8e0d178b1d1e | 497 | * less than CURVE448_PUB_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 498 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 499 | */ |
wolfSSL | 16:8e0d178b1d1e | 500 | int wc_curve448_import_private_raw_ex(const byte* priv, word32 privSz, |
wolfSSL | 16:8e0d178b1d1e | 501 | const byte* pub, word32 pubSz, |
wolfSSL | 16:8e0d178b1d1e | 502 | curve448_key* key, int endian) |
wolfSSL | 16:8e0d178b1d1e | 503 | { |
wolfSSL | 16:8e0d178b1d1e | 504 | int ret; |
wolfSSL | 16:8e0d178b1d1e | 505 | |
wolfSSL | 16:8e0d178b1d1e | 506 | /* import private part */ |
wolfSSL | 16:8e0d178b1d1e | 507 | ret = wc_curve448_import_private_ex(priv, privSz, key, endian); |
wolfSSL | 16:8e0d178b1d1e | 508 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 509 | /* import public part */ |
wolfSSL | 16:8e0d178b1d1e | 510 | return wc_curve448_import_public_ex(pub, pubSz, key, endian); |
wolfSSL | 16:8e0d178b1d1e | 511 | } |
wolfSSL | 16:8e0d178b1d1e | 512 | |
wolfSSL | 16:8e0d178b1d1e | 513 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 514 | } |
wolfSSL | 16:8e0d178b1d1e | 515 | |
wolfSSL | 16:8e0d178b1d1e | 516 | /* Import curve448 private key from a byte array. |
wolfSSL | 16:8e0d178b1d1e | 517 | * Private key encoded in big-endian. |
wolfSSL | 16:8e0d178b1d1e | 518 | * |
wolfSSL | 16:8e0d178b1d1e | 519 | * piv [in] Array holding private key. |
wolfSSL | 16:8e0d178b1d1e | 520 | * privSz [in] Number of bytes of data in private key array. |
wolfSSL | 16:8e0d178b1d1e | 521 | * key [in] Curve448 private/public key. |
wolfSSL | 16:8e0d178b1d1e | 522 | * returns BAD_FUNC_ARG when a parameter is NULL, |
wolfSSL | 16:8e0d178b1d1e | 523 | * ECC_BAD_ARG_E when privSz is less than CURVE448_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 524 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 525 | */ |
wolfSSL | 16:8e0d178b1d1e | 526 | int wc_curve448_import_private(const byte* priv, word32 privSz, |
wolfSSL | 16:8e0d178b1d1e | 527 | curve448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 528 | { |
wolfSSL | 16:8e0d178b1d1e | 529 | return wc_curve448_import_private_ex(priv, privSz, key, EC448_BIG_ENDIAN); |
wolfSSL | 16:8e0d178b1d1e | 530 | } |
wolfSSL | 16:8e0d178b1d1e | 531 | |
wolfSSL | 16:8e0d178b1d1e | 532 | /* Import curve448 private key from a byte array. |
wolfSSL | 16:8e0d178b1d1e | 533 | * |
wolfSSL | 16:8e0d178b1d1e | 534 | * piv [in] Array holding private key. |
wolfSSL | 16:8e0d178b1d1e | 535 | * privSz [in] Number of bytes of data in private key array. |
wolfSSL | 16:8e0d178b1d1e | 536 | * key [in] Curve448 private/public key. |
wolfSSL | 16:8e0d178b1d1e | 537 | * endian [in] Endianness of encoded number in byte array. |
wolfSSL | 16:8e0d178b1d1e | 538 | * returns BAD_FUNC_ARG when a parameter is NULL, |
wolfSSL | 16:8e0d178b1d1e | 539 | * ECC_BAD_ARG_E when privSz is less than CURVE448_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 540 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 541 | */ |
wolfSSL | 16:8e0d178b1d1e | 542 | int wc_curve448_import_private_ex(const byte* priv, word32 privSz, |
wolfSSL | 16:8e0d178b1d1e | 543 | curve448_key* key, int endian) |
wolfSSL | 16:8e0d178b1d1e | 544 | { |
wolfSSL | 16:8e0d178b1d1e | 545 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 546 | int i; |
wolfSSL | 16:8e0d178b1d1e | 547 | |
wolfSSL | 16:8e0d178b1d1e | 548 | /* sanity check */ |
wolfSSL | 16:8e0d178b1d1e | 549 | if ((key == NULL) || (priv == NULL)) { |
wolfSSL | 16:8e0d178b1d1e | 550 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 551 | } |
wolfSSL | 16:8e0d178b1d1e | 552 | |
wolfSSL | 16:8e0d178b1d1e | 553 | /* check size of incoming keys */ |
wolfSSL | 16:8e0d178b1d1e | 554 | if ((ret == 0) && ((int)privSz != CURVE448_KEY_SIZE)) { |
wolfSSL | 16:8e0d178b1d1e | 555 | ret = ECC_BAD_ARG_E; |
wolfSSL | 16:8e0d178b1d1e | 556 | } |
wolfSSL | 16:8e0d178b1d1e | 557 | |
wolfSSL | 16:8e0d178b1d1e | 558 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 559 | if (endian == EC448_BIG_ENDIAN) { |
wolfSSL | 16:8e0d178b1d1e | 560 | /* read the key in Big Endian format */ |
wolfSSL | 16:8e0d178b1d1e | 561 | for (i = 0; i < CURVE448_KEY_SIZE; i++) { |
wolfSSL | 16:8e0d178b1d1e | 562 | key->k[i] = priv[CURVE448_KEY_SIZE - i - 1]; |
wolfSSL | 16:8e0d178b1d1e | 563 | } |
wolfSSL | 16:8e0d178b1d1e | 564 | } |
wolfSSL | 16:8e0d178b1d1e | 565 | else { |
wolfSSL | 16:8e0d178b1d1e | 566 | XMEMCPY(key->k, priv, CURVE448_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 567 | } |
wolfSSL | 16:8e0d178b1d1e | 568 | |
wolfSSL | 16:8e0d178b1d1e | 569 | /* Clamp the key */ |
wolfSSL | 16:8e0d178b1d1e | 570 | key->k[0] &= 0xfc; |
wolfSSL | 16:8e0d178b1d1e | 571 | key->k[CURVE448_KEY_SIZE-1] |= 0x80; |
wolfSSL | 16:8e0d178b1d1e | 572 | } |
wolfSSL | 16:8e0d178b1d1e | 573 | |
wolfSSL | 16:8e0d178b1d1e | 574 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 575 | } |
wolfSSL | 16:8e0d178b1d1e | 576 | |
wolfSSL | 16:8e0d178b1d1e | 577 | #endif /* HAVE_CURVE448_KEY_IMPORT */ |
wolfSSL | 16:8e0d178b1d1e | 578 | |
wolfSSL | 16:8e0d178b1d1e | 579 | |
wolfSSL | 16:8e0d178b1d1e | 580 | /* Initialize the curve448 key. |
wolfSSL | 16:8e0d178b1d1e | 581 | * |
wolfSSL | 16:8e0d178b1d1e | 582 | * key [in] Curve448 key object. |
wolfSSL | 16:8e0d178b1d1e | 583 | * returns BAD_FUNC_ARG when key is NULL, |
wolfSSL | 16:8e0d178b1d1e | 584 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 585 | */ |
wolfSSL | 16:8e0d178b1d1e | 586 | int wc_curve448_init(curve448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 587 | { |
wolfSSL | 16:8e0d178b1d1e | 588 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 589 | |
wolfSSL | 16:8e0d178b1d1e | 590 | if (key == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 591 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 592 | } |
wolfSSL | 16:8e0d178b1d1e | 593 | |
wolfSSL | 16:8e0d178b1d1e | 594 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 595 | XMEMSET(key, 0, sizeof(*key)); |
wolfSSL | 16:8e0d178b1d1e | 596 | |
wolfSSL | 16:8e0d178b1d1e | 597 | fe448_init(); |
wolfSSL | 16:8e0d178b1d1e | 598 | } |
wolfSSL | 16:8e0d178b1d1e | 599 | |
wolfSSL | 16:8e0d178b1d1e | 600 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 601 | } |
wolfSSL | 16:8e0d178b1d1e | 602 | |
wolfSSL | 16:8e0d178b1d1e | 603 | |
wolfSSL | 16:8e0d178b1d1e | 604 | /* Clears the curve448 key data. |
wolfSSL | 16:8e0d178b1d1e | 605 | * |
wolfSSL | 16:8e0d178b1d1e | 606 | * key [in] Curve448 key object. |
wolfSSL | 16:8e0d178b1d1e | 607 | */ |
wolfSSL | 16:8e0d178b1d1e | 608 | void wc_curve448_free(curve448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 609 | { |
wolfSSL | 16:8e0d178b1d1e | 610 | if (key != NULL) { |
wolfSSL | 16:8e0d178b1d1e | 611 | ForceZero(key->p, sizeof(key->p)); |
wolfSSL | 16:8e0d178b1d1e | 612 | ForceZero(key->k, sizeof(key->k)); |
wolfSSL | 16:8e0d178b1d1e | 613 | } |
wolfSSL | 16:8e0d178b1d1e | 614 | } |
wolfSSL | 16:8e0d178b1d1e | 615 | |
wolfSSL | 16:8e0d178b1d1e | 616 | |
wolfSSL | 16:8e0d178b1d1e | 617 | /* Get the curve448 key's size. |
wolfSSL | 16:8e0d178b1d1e | 618 | * |
wolfSSL | 16:8e0d178b1d1e | 619 | * key [in] Curve448 key object. |
wolfSSL | 16:8e0d178b1d1e | 620 | * returns 0 if key is NULL, |
wolfSSL | 16:8e0d178b1d1e | 621 | * CURVE448_KEY_SIZE otherwise. |
wolfSSL | 16:8e0d178b1d1e | 622 | */ |
wolfSSL | 16:8e0d178b1d1e | 623 | int wc_curve448_size(curve448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 624 | { |
wolfSSL | 16:8e0d178b1d1e | 625 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 626 | |
wolfSSL | 16:8e0d178b1d1e | 627 | if (key != NULL) { |
wolfSSL | 16:8e0d178b1d1e | 628 | ret = CURVE448_KEY_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 629 | } |
wolfSSL | 16:8e0d178b1d1e | 630 | |
wolfSSL | 16:8e0d178b1d1e | 631 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 632 | } |
wolfSSL | 16:8e0d178b1d1e | 633 | |
wolfSSL | 16:8e0d178b1d1e | 634 | #endif /* HAVE_CURVE448 */ |
wolfSSL | 16:8e0d178b1d1e | 635 | |
wolfSSL | 16:8e0d178b1d1e | 636 |