wolfSSL SSL/TLS library, support up to TLS1.3
Dependents: CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more
wolfcrypt/src/ed448.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 | /* ed448.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 8032 */ |
wolfSSL | 16:8e0d178b1d1e | 23 | |
wolfSSL | 16:8e0d178b1d1e | 24 | /* Based On Daniel J Bernstein's ed25519 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 | /* in case user set HAVE_ED448 there */ |
wolfSSL | 16:8e0d178b1d1e | 33 | #include <wolfssl/wolfcrypt/settings.h> |
wolfSSL | 16:8e0d178b1d1e | 34 | |
wolfSSL | 16:8e0d178b1d1e | 35 | #ifdef HAVE_ED448 |
wolfSSL | 16:8e0d178b1d1e | 36 | |
wolfSSL | 16:8e0d178b1d1e | 37 | #include <wolfssl/wolfcrypt/ed448.h> |
wolfSSL | 16:8e0d178b1d1e | 38 | #include <wolfssl/wolfcrypt/error-crypt.h> |
wolfSSL | 16:8e0d178b1d1e | 39 | #include <wolfssl/wolfcrypt/hash.h> |
wolfSSL | 16:8e0d178b1d1e | 40 | #ifdef NO_INLINE |
wolfSSL | 16:8e0d178b1d1e | 41 | #include <wolfssl/wolfcrypt/misc.h> |
wolfSSL | 16:8e0d178b1d1e | 42 | #else |
wolfSSL | 16:8e0d178b1d1e | 43 | #define WOLFSSL_MISC_INCLUDED |
wolfSSL | 16:8e0d178b1d1e | 44 | #include <wolfcrypt/src/misc.c> |
wolfSSL | 16:8e0d178b1d1e | 45 | #endif |
wolfSSL | 16:8e0d178b1d1e | 46 | |
wolfSSL | 16:8e0d178b1d1e | 47 | #if defined(HAVE_ED448_SIGN) || defined(HAVE_ED448_VERIFY) |
wolfSSL | 16:8e0d178b1d1e | 48 | /* Size of context bytes to use with hash when signing and verifying. */ |
wolfSSL | 16:8e0d178b1d1e | 49 | #define ED448CTX_SIZE 8 |
wolfSSL | 16:8e0d178b1d1e | 50 | /* Context to pass to hash when signing and verifying. */ |
wolfSSL | 16:8e0d178b1d1e | 51 | static const byte ed448Ctx[ED448CTX_SIZE+1] = "SigEd448"; |
wolfSSL | 16:8e0d178b1d1e | 52 | #endif |
wolfSSL | 16:8e0d178b1d1e | 53 | |
wolfSSL | 16:8e0d178b1d1e | 54 | /* Derive the public key for the private key. |
wolfSSL | 16:8e0d178b1d1e | 55 | * |
wolfSSL | 16:8e0d178b1d1e | 56 | * key [in] Ed448 key object. |
wolfSSL | 16:8e0d178b1d1e | 57 | * pubKey [in] Byte array to hold te public key. |
wolfSSL | 16:8e0d178b1d1e | 58 | * pubKeySz [in] Size of the array in bytes. |
wolfSSL | 16:8e0d178b1d1e | 59 | * returns BAD_FUNC_ARG when key is NULL or pubKeySz is not equal to |
wolfSSL | 16:8e0d178b1d1e | 60 | * ED448_PUB_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 61 | * other -ve value on hash failure, |
wolfSSL | 16:8e0d178b1d1e | 62 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 63 | */ |
wolfSSL | 16:8e0d178b1d1e | 64 | int wc_ed448_make_public(ed448_key* key, unsigned char* pubKey, word32 pubKeySz) |
wolfSSL | 16:8e0d178b1d1e | 65 | { |
wolfSSL | 16:8e0d178b1d1e | 66 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 67 | byte az[ED448_PRV_KEY_SIZE]; |
wolfSSL | 16:8e0d178b1d1e | 68 | ge448_p2 A; |
wolfSSL | 16:8e0d178b1d1e | 69 | |
wolfSSL | 16:8e0d178b1d1e | 70 | if ((key == NULL) || (pubKeySz != ED448_PUB_KEY_SIZE)) { |
wolfSSL | 16:8e0d178b1d1e | 71 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 72 | } |
wolfSSL | 16:8e0d178b1d1e | 73 | |
wolfSSL | 16:8e0d178b1d1e | 74 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 75 | ret = wc_Shake256Hash(key->k, ED448_KEY_SIZE, az, sizeof(az)); |
wolfSSL | 16:8e0d178b1d1e | 76 | } |
wolfSSL | 16:8e0d178b1d1e | 77 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 78 | /* apply clamp */ |
wolfSSL | 16:8e0d178b1d1e | 79 | az[0] &= 0xfc; |
wolfSSL | 16:8e0d178b1d1e | 80 | az[55] |= 0x80; |
wolfSSL | 16:8e0d178b1d1e | 81 | az[56] = 0x00; |
wolfSSL | 16:8e0d178b1d1e | 82 | |
wolfSSL | 16:8e0d178b1d1e | 83 | ge448_scalarmult_base(&A, az); |
wolfSSL | 16:8e0d178b1d1e | 84 | ge448_to_bytes(pubKey, &A); |
wolfSSL | 16:8e0d178b1d1e | 85 | } |
wolfSSL | 16:8e0d178b1d1e | 86 | |
wolfSSL | 16:8e0d178b1d1e | 87 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 88 | } |
wolfSSL | 16:8e0d178b1d1e | 89 | |
wolfSSL | 16:8e0d178b1d1e | 90 | /* Make a new ed448 private/public key. |
wolfSSL | 16:8e0d178b1d1e | 91 | * |
wolfSSL | 16:8e0d178b1d1e | 92 | * rng [in] Random number generator. |
wolfSSL | 16:8e0d178b1d1e | 93 | * keysize [in] Size of the key to generate. |
wolfSSL | 16:8e0d178b1d1e | 94 | * key [in] Ed448 key object. |
wolfSSL | 16:8e0d178b1d1e | 95 | * returns BAD_FUNC_ARG when rng or key is NULL or keySz is not equal to |
wolfSSL | 16:8e0d178b1d1e | 96 | * ED448_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 97 | * other -ve value on random number or hash failure, |
wolfSSL | 16:8e0d178b1d1e | 98 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 99 | */ |
wolfSSL | 16:8e0d178b1d1e | 100 | int wc_ed448_make_key(WC_RNG* rng, int keySz, ed448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 101 | { |
wolfSSL | 16:8e0d178b1d1e | 102 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 103 | |
wolfSSL | 16:8e0d178b1d1e | 104 | if ((rng == NULL) || (key == NULL)) { |
wolfSSL | 16:8e0d178b1d1e | 105 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 106 | } |
wolfSSL | 16:8e0d178b1d1e | 107 | |
wolfSSL | 16:8e0d178b1d1e | 108 | /* ed448 has 57 byte key sizes */ |
wolfSSL | 16:8e0d178b1d1e | 109 | if ((ret == 0) && (keySz != ED448_KEY_SIZE)) { |
wolfSSL | 16:8e0d178b1d1e | 110 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 111 | } |
wolfSSL | 16:8e0d178b1d1e | 112 | |
wolfSSL | 16:8e0d178b1d1e | 113 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 114 | ret = wc_RNG_GenerateBlock(rng, key->k, ED448_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 115 | } |
wolfSSL | 16:8e0d178b1d1e | 116 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 117 | ret = wc_ed448_make_public(key, key->p, ED448_PUB_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 118 | if (ret != 0) { |
wolfSSL | 16:8e0d178b1d1e | 119 | ForceZero(key->k, ED448_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 120 | } |
wolfSSL | 16:8e0d178b1d1e | 121 | } |
wolfSSL | 16:8e0d178b1d1e | 122 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 123 | /* put public key after private key, on the same buffer */ |
wolfSSL | 16:8e0d178b1d1e | 124 | XMEMMOVE(key->k + ED448_KEY_SIZE, key->p, ED448_PUB_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 125 | |
wolfSSL | 16:8e0d178b1d1e | 126 | key->pubKeySet = 1; |
wolfSSL | 16:8e0d178b1d1e | 127 | } |
wolfSSL | 16:8e0d178b1d1e | 128 | |
wolfSSL | 16:8e0d178b1d1e | 129 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 130 | } |
wolfSSL | 16:8e0d178b1d1e | 131 | |
wolfSSL | 16:8e0d178b1d1e | 132 | |
wolfSSL | 16:8e0d178b1d1e | 133 | #ifdef HAVE_ED448_SIGN |
wolfSSL | 16:8e0d178b1d1e | 134 | /* Sign the message using the ed448 private key. |
wolfSSL | 16:8e0d178b1d1e | 135 | * |
wolfSSL | 16:8e0d178b1d1e | 136 | * in [in] Message to sign. |
wolfSSL | 16:8e0d178b1d1e | 137 | * inLen [in] Length of the message in bytes. |
wolfSSL | 16:8e0d178b1d1e | 138 | * out [in] Buffer to write signature into. |
wolfSSL | 16:8e0d178b1d1e | 139 | * outLen [in/out] On in, size of buffer. |
wolfSSL | 16:8e0d178b1d1e | 140 | * On out, the length of the signature in bytes. |
wolfSSL | 16:8e0d178b1d1e | 141 | * key [in] Ed448 key to use when signing |
wolfSSL | 16:8e0d178b1d1e | 142 | * type [in] Type of signature to perform: Ed448 or Ed448ph |
wolfSSL | 16:8e0d178b1d1e | 143 | * context [in] Context of signing. |
wolfSSL | 16:8e0d178b1d1e | 144 | * contextLen [in] Length of context in bytes. |
wolfSSL | 16:8e0d178b1d1e | 145 | * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and |
wolfSSL | 16:8e0d178b1d1e | 146 | * context is not NULL or public key not set, |
wolfSSL | 16:8e0d178b1d1e | 147 | * BUFFER_E when outLen is less than ED448_SIG_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 148 | * other -ve values when hash fails, |
wolfSSL | 16:8e0d178b1d1e | 149 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 150 | */ |
wolfSSL | 16:8e0d178b1d1e | 151 | static int ed448_sign_msg(const byte* in, word32 inLen, byte* out, |
wolfSSL | 16:8e0d178b1d1e | 152 | word32 *outLen, ed448_key* key, byte type, |
wolfSSL | 16:8e0d178b1d1e | 153 | const byte* context, byte contextLen) |
wolfSSL | 16:8e0d178b1d1e | 154 | { |
wolfSSL | 16:8e0d178b1d1e | 155 | ge448_p2 R; |
wolfSSL | 16:8e0d178b1d1e | 156 | byte nonce[ED448_SIG_SIZE]; |
wolfSSL | 16:8e0d178b1d1e | 157 | byte hram[ED448_SIG_SIZE]; |
wolfSSL | 16:8e0d178b1d1e | 158 | byte az[ED448_PRV_KEY_SIZE]; |
wolfSSL | 16:8e0d178b1d1e | 159 | wc_Shake sha; |
wolfSSL | 16:8e0d178b1d1e | 160 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 161 | |
wolfSSL | 16:8e0d178b1d1e | 162 | /* sanity check on arguments */ |
wolfSSL | 16:8e0d178b1d1e | 163 | if ((in == NULL) || (out == NULL) || (outLen == NULL) || (key == NULL) || |
wolfSSL | 16:8e0d178b1d1e | 164 | ((context == NULL) && (contextLen != 0))) { |
wolfSSL | 16:8e0d178b1d1e | 165 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 166 | } |
wolfSSL | 16:8e0d178b1d1e | 167 | if ((ret == 0) && (!key->pubKeySet)) { |
wolfSSL | 16:8e0d178b1d1e | 168 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 169 | } |
wolfSSL | 16:8e0d178b1d1e | 170 | |
wolfSSL | 16:8e0d178b1d1e | 171 | /* check and set up out length */ |
wolfSSL | 16:8e0d178b1d1e | 172 | if ((ret == 0) && (*outLen < ED448_SIG_SIZE)) { |
wolfSSL | 16:8e0d178b1d1e | 173 | *outLen = ED448_SIG_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 174 | ret = BUFFER_E; |
wolfSSL | 16:8e0d178b1d1e | 175 | } |
wolfSSL | 16:8e0d178b1d1e | 176 | |
wolfSSL | 16:8e0d178b1d1e | 177 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 178 | *outLen = ED448_SIG_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 179 | |
wolfSSL | 16:8e0d178b1d1e | 180 | /* step 1: create nonce to use where nonce is r in |
wolfSSL | 16:8e0d178b1d1e | 181 | r = H(h_b, ... ,h_2b-1,M) */ |
wolfSSL | 16:8e0d178b1d1e | 182 | ret = wc_Shake256Hash(key->k, ED448_KEY_SIZE, az, sizeof(az)); |
wolfSSL | 16:8e0d178b1d1e | 183 | } |
wolfSSL | 16:8e0d178b1d1e | 184 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 185 | /* apply clamp */ |
wolfSSL | 16:8e0d178b1d1e | 186 | az[0] &= 0xfc; |
wolfSSL | 16:8e0d178b1d1e | 187 | az[55] |= 0x80; |
wolfSSL | 16:8e0d178b1d1e | 188 | az[56] = 0x00; |
wolfSSL | 16:8e0d178b1d1e | 189 | |
wolfSSL | 16:8e0d178b1d1e | 190 | ret = wc_InitShake256(&sha, NULL, INVALID_DEVID); |
wolfSSL | 16:8e0d178b1d1e | 191 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 192 | ret = wc_Shake256_Update(&sha, ed448Ctx, ED448CTX_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 193 | } |
wolfSSL | 16:8e0d178b1d1e | 194 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 195 | ret = wc_Shake256_Update(&sha, &type, sizeof(type)); |
wolfSSL | 16:8e0d178b1d1e | 196 | } |
wolfSSL | 16:8e0d178b1d1e | 197 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 198 | ret = wc_Shake256_Update(&sha, &contextLen, sizeof(contextLen)); |
wolfSSL | 16:8e0d178b1d1e | 199 | } |
wolfSSL | 16:8e0d178b1d1e | 200 | if (ret == 0 && context != NULL) { |
wolfSSL | 16:8e0d178b1d1e | 201 | ret = wc_Shake256_Update(&sha, context, contextLen); |
wolfSSL | 16:8e0d178b1d1e | 202 | } |
wolfSSL | 16:8e0d178b1d1e | 203 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 204 | ret = wc_Shake256_Update(&sha, az + ED448_KEY_SIZE, ED448_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 205 | } |
wolfSSL | 16:8e0d178b1d1e | 206 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 207 | ret = wc_Shake256_Update(&sha, in, inLen); |
wolfSSL | 16:8e0d178b1d1e | 208 | } |
wolfSSL | 16:8e0d178b1d1e | 209 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 210 | ret = wc_Shake256_Final(&sha, nonce, sizeof(nonce)); |
wolfSSL | 16:8e0d178b1d1e | 211 | } |
wolfSSL | 16:8e0d178b1d1e | 212 | wc_Shake256_Free(&sha); |
wolfSSL | 16:8e0d178b1d1e | 213 | } |
wolfSSL | 16:8e0d178b1d1e | 214 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 215 | sc448_reduce(nonce); |
wolfSSL | 16:8e0d178b1d1e | 216 | |
wolfSSL | 16:8e0d178b1d1e | 217 | /* step 2: computing R = rB where rB is the scalar multiplication of |
wolfSSL | 16:8e0d178b1d1e | 218 | r and B */ |
wolfSSL | 16:8e0d178b1d1e | 219 | ge448_scalarmult_base(&R,nonce); |
wolfSSL | 16:8e0d178b1d1e | 220 | ge448_to_bytes(out,&R); |
wolfSSL | 16:8e0d178b1d1e | 221 | |
wolfSSL | 16:8e0d178b1d1e | 222 | /* step 3: hash R + public key + message getting H(R,A,M) then |
wolfSSL | 16:8e0d178b1d1e | 223 | creating S = (r + H(R,A,M)a) mod l */ |
wolfSSL | 16:8e0d178b1d1e | 224 | ret = wc_InitShake256(&sha, NULL, INVALID_DEVID); |
wolfSSL | 16:8e0d178b1d1e | 225 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 226 | ret = wc_Shake256_Update(&sha, ed448Ctx, ED448CTX_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 227 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 228 | ret = wc_Shake256_Update(&sha, &type, sizeof(type)); |
wolfSSL | 16:8e0d178b1d1e | 229 | } |
wolfSSL | 16:8e0d178b1d1e | 230 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 231 | ret = wc_Shake256_Update(&sha, &contextLen, sizeof(contextLen)); |
wolfSSL | 16:8e0d178b1d1e | 232 | } |
wolfSSL | 16:8e0d178b1d1e | 233 | if (ret == 0 && context != NULL) { |
wolfSSL | 16:8e0d178b1d1e | 234 | ret = wc_Shake256_Update(&sha, context, contextLen); |
wolfSSL | 16:8e0d178b1d1e | 235 | } |
wolfSSL | 16:8e0d178b1d1e | 236 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 237 | ret = wc_Shake256_Update(&sha, out, ED448_SIG_SIZE/2); |
wolfSSL | 16:8e0d178b1d1e | 238 | } |
wolfSSL | 16:8e0d178b1d1e | 239 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 240 | ret = wc_Shake256_Update(&sha, key->p, ED448_PUB_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 241 | } |
wolfSSL | 16:8e0d178b1d1e | 242 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 243 | ret = wc_Shake256_Update(&sha, in, inLen); |
wolfSSL | 16:8e0d178b1d1e | 244 | } |
wolfSSL | 16:8e0d178b1d1e | 245 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 246 | ret = wc_Shake256_Final(&sha, hram, sizeof(hram)); |
wolfSSL | 16:8e0d178b1d1e | 247 | } |
wolfSSL | 16:8e0d178b1d1e | 248 | wc_Shake256_Free(&sha); |
wolfSSL | 16:8e0d178b1d1e | 249 | } |
wolfSSL | 16:8e0d178b1d1e | 250 | } |
wolfSSL | 16:8e0d178b1d1e | 251 | |
wolfSSL | 16:8e0d178b1d1e | 252 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 253 | sc448_reduce(hram); |
wolfSSL | 16:8e0d178b1d1e | 254 | sc448_muladd(out + (ED448_SIG_SIZE/2), hram, az, nonce); |
wolfSSL | 16:8e0d178b1d1e | 255 | } |
wolfSSL | 16:8e0d178b1d1e | 256 | |
wolfSSL | 16:8e0d178b1d1e | 257 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 258 | } |
wolfSSL | 16:8e0d178b1d1e | 259 | |
wolfSSL | 16:8e0d178b1d1e | 260 | /* Sign the message using the ed448 private key. |
wolfSSL | 16:8e0d178b1d1e | 261 | * Signature type is Ed448. |
wolfSSL | 16:8e0d178b1d1e | 262 | * |
wolfSSL | 16:8e0d178b1d1e | 263 | * in [in] Message to sign. |
wolfSSL | 16:8e0d178b1d1e | 264 | * inLen [in] Length of the message in bytes. |
wolfSSL | 16:8e0d178b1d1e | 265 | * out [in] Buffer to write signature into. |
wolfSSL | 16:8e0d178b1d1e | 266 | * outLen [in/out] On in, size of buffer. |
wolfSSL | 16:8e0d178b1d1e | 267 | * On out, the length of the signature in bytes. |
wolfSSL | 16:8e0d178b1d1e | 268 | * key [in] Ed448 key to use when signing |
wolfSSL | 16:8e0d178b1d1e | 269 | * context [in] Context of signing. |
wolfSSL | 16:8e0d178b1d1e | 270 | * contextLen [in] Length of context in bytes. |
wolfSSL | 16:8e0d178b1d1e | 271 | * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and |
wolfSSL | 16:8e0d178b1d1e | 272 | * context is not NULL or public key not set, |
wolfSSL | 16:8e0d178b1d1e | 273 | * BUFFER_E when outLen is less than ED448_SIG_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 274 | * other -ve values when hash fails, |
wolfSSL | 16:8e0d178b1d1e | 275 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 276 | */ |
wolfSSL | 16:8e0d178b1d1e | 277 | int wc_ed448_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen, |
wolfSSL | 16:8e0d178b1d1e | 278 | ed448_key* key, const byte* context, byte contextLen) |
wolfSSL | 16:8e0d178b1d1e | 279 | { |
wolfSSL | 16:8e0d178b1d1e | 280 | return ed448_sign_msg(in, inLen, out, outLen, key, Ed448, context, |
wolfSSL | 16:8e0d178b1d1e | 281 | contextLen); |
wolfSSL | 16:8e0d178b1d1e | 282 | } |
wolfSSL | 16:8e0d178b1d1e | 283 | |
wolfSSL | 16:8e0d178b1d1e | 284 | /* Sign the hash using the ed448 private key. |
wolfSSL | 16:8e0d178b1d1e | 285 | * Signature type is Ed448ph. |
wolfSSL | 16:8e0d178b1d1e | 286 | * |
wolfSSL | 16:8e0d178b1d1e | 287 | * hash [in] Hash of message to sign. |
wolfSSL | 16:8e0d178b1d1e | 288 | * hashLen [in] Length of hash of message in bytes. |
wolfSSL | 16:8e0d178b1d1e | 289 | * out [in] Buffer to write signature into. |
wolfSSL | 16:8e0d178b1d1e | 290 | * outLen [in/out] On in, size of buffer. |
wolfSSL | 16:8e0d178b1d1e | 291 | * On out, the length of the signature in bytes. |
wolfSSL | 16:8e0d178b1d1e | 292 | * key [in] Ed448 key to use when signing |
wolfSSL | 16:8e0d178b1d1e | 293 | * context [in] Context of signing. |
wolfSSL | 16:8e0d178b1d1e | 294 | * contextLen [in] Length of context in bytes. |
wolfSSL | 16:8e0d178b1d1e | 295 | * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and |
wolfSSL | 16:8e0d178b1d1e | 296 | * context is not NULL or public key not set, |
wolfSSL | 16:8e0d178b1d1e | 297 | * BUFFER_E when outLen is less than ED448_SIG_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 298 | * other -ve values when hash fails, |
wolfSSL | 16:8e0d178b1d1e | 299 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 300 | */ |
wolfSSL | 16:8e0d178b1d1e | 301 | int wc_ed448ph_sign_hash(const byte* hash, word32 hashLen, byte* out, |
wolfSSL | 16:8e0d178b1d1e | 302 | word32 *outLen, ed448_key* key, |
wolfSSL | 16:8e0d178b1d1e | 303 | const byte* context, byte contextLen) |
wolfSSL | 16:8e0d178b1d1e | 304 | { |
wolfSSL | 16:8e0d178b1d1e | 305 | return ed448_sign_msg(hash, hashLen, out, outLen, key, Ed448ph, context, |
wolfSSL | 16:8e0d178b1d1e | 306 | contextLen); |
wolfSSL | 16:8e0d178b1d1e | 307 | } |
wolfSSL | 16:8e0d178b1d1e | 308 | |
wolfSSL | 16:8e0d178b1d1e | 309 | /* Sign the message using the ed448 private key. |
wolfSSL | 16:8e0d178b1d1e | 310 | * Signature type is Ed448ph. |
wolfSSL | 16:8e0d178b1d1e | 311 | * |
wolfSSL | 16:8e0d178b1d1e | 312 | * in [in] Message to sign. |
wolfSSL | 16:8e0d178b1d1e | 313 | * inLen [in] Length of the message to sign in bytes. |
wolfSSL | 16:8e0d178b1d1e | 314 | * out [in] Buffer to write signature into. |
wolfSSL | 16:8e0d178b1d1e | 315 | * outLen [in/out] On in, size of buffer. |
wolfSSL | 16:8e0d178b1d1e | 316 | * On out, the length of the signature in bytes. |
wolfSSL | 16:8e0d178b1d1e | 317 | * key [in] Ed448 key to use when signing |
wolfSSL | 16:8e0d178b1d1e | 318 | * context [in] Context of signing. |
wolfSSL | 16:8e0d178b1d1e | 319 | * contextLen [in] Length of context in bytes. |
wolfSSL | 16:8e0d178b1d1e | 320 | * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and |
wolfSSL | 16:8e0d178b1d1e | 321 | * context is not NULL or public key not set, |
wolfSSL | 16:8e0d178b1d1e | 322 | * BUFFER_E when outLen is less than ED448_SIG_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 323 | * other -ve values when hash fails, |
wolfSSL | 16:8e0d178b1d1e | 324 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 325 | */ |
wolfSSL | 16:8e0d178b1d1e | 326 | int wc_ed448ph_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen, |
wolfSSL | 16:8e0d178b1d1e | 327 | ed448_key* key, const byte* context, byte contextLen) |
wolfSSL | 16:8e0d178b1d1e | 328 | { |
wolfSSL | 16:8e0d178b1d1e | 329 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 330 | byte hash[64]; |
wolfSSL | 16:8e0d178b1d1e | 331 | |
wolfSSL | 16:8e0d178b1d1e | 332 | ret = wc_Shake256Hash(in, inLen, hash, sizeof(hash)); |
wolfSSL | 16:8e0d178b1d1e | 333 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 334 | ret = wc_ed448ph_sign_hash(hash, sizeof(hash), out, outLen, key, |
wolfSSL | 16:8e0d178b1d1e | 335 | context, contextLen); |
wolfSSL | 16:8e0d178b1d1e | 336 | } |
wolfSSL | 16:8e0d178b1d1e | 337 | |
wolfSSL | 16:8e0d178b1d1e | 338 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 339 | } |
wolfSSL | 16:8e0d178b1d1e | 340 | #endif /* HAVE_ED448_SIGN */ |
wolfSSL | 16:8e0d178b1d1e | 341 | |
wolfSSL | 16:8e0d178b1d1e | 342 | #ifdef HAVE_ED448_VERIFY |
wolfSSL | 16:8e0d178b1d1e | 343 | |
wolfSSL | 16:8e0d178b1d1e | 344 | /* Verify the message using the ed448 public key. |
wolfSSL | 16:8e0d178b1d1e | 345 | * |
wolfSSL | 16:8e0d178b1d1e | 346 | * sig [in] Signature to verify. |
wolfSSL | 16:8e0d178b1d1e | 347 | * sigLen [in] Size of signature in bytes. |
wolfSSL | 16:8e0d178b1d1e | 348 | * msg [in] Message to verify. |
wolfSSL | 16:8e0d178b1d1e | 349 | * msgLen [in] Length of the message in bytes. |
wolfSSL | 16:8e0d178b1d1e | 350 | * key [in] Ed448 key to use to verify. |
wolfSSL | 16:8e0d178b1d1e | 351 | * type [in] Type of signature to verify: Ed448 or Ed448ph |
wolfSSL | 16:8e0d178b1d1e | 352 | * context [in] Context of verification. |
wolfSSL | 16:8e0d178b1d1e | 353 | * contextLen [in] Length of context in bytes. |
wolfSSL | 16:8e0d178b1d1e | 354 | * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and |
wolfSSL | 16:8e0d178b1d1e | 355 | * context is not NULL or public key not set, |
wolfSSL | 16:8e0d178b1d1e | 356 | * BUFFER_E when sigLen is less than ED448_SIG_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 357 | * other -ve values when hash fails, |
wolfSSL | 16:8e0d178b1d1e | 358 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 359 | */ |
wolfSSL | 16:8e0d178b1d1e | 360 | static int ed448_verify_msg(const byte* sig, word32 sigLen, const byte* msg, |
wolfSSL | 16:8e0d178b1d1e | 361 | word32 msgLen, int* res, ed448_key* key, |
wolfSSL | 16:8e0d178b1d1e | 362 | byte type, const byte* context, byte contextLen) |
wolfSSL | 16:8e0d178b1d1e | 363 | { |
wolfSSL | 16:8e0d178b1d1e | 364 | byte rcheck[ED448_KEY_SIZE]; |
wolfSSL | 16:8e0d178b1d1e | 365 | byte h[ED448_SIG_SIZE]; |
wolfSSL | 16:8e0d178b1d1e | 366 | ge448_p2 A; |
wolfSSL | 16:8e0d178b1d1e | 367 | ge448_p2 R; |
wolfSSL | 16:8e0d178b1d1e | 368 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 369 | wc_Shake sha; |
wolfSSL | 16:8e0d178b1d1e | 370 | |
wolfSSL | 16:8e0d178b1d1e | 371 | /* sanity check on arguments */ |
wolfSSL | 16:8e0d178b1d1e | 372 | if ((sig == NULL) || (msg == NULL) || (res == NULL) || (key == NULL) || |
wolfSSL | 16:8e0d178b1d1e | 373 | ((context == NULL) && (contextLen != 0))) { |
wolfSSL | 16:8e0d178b1d1e | 374 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 375 | } |
wolfSSL | 16:8e0d178b1d1e | 376 | |
wolfSSL | 16:8e0d178b1d1e | 377 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 378 | /* set verification failed by default */ |
wolfSSL | 16:8e0d178b1d1e | 379 | *res = 0; |
wolfSSL | 16:8e0d178b1d1e | 380 | |
wolfSSL | 16:8e0d178b1d1e | 381 | /* check on basics needed to verify signature */ |
wolfSSL | 16:8e0d178b1d1e | 382 | if (sigLen < ED448_SIG_SIZE) { |
wolfSSL | 16:8e0d178b1d1e | 383 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 384 | } |
wolfSSL | 16:8e0d178b1d1e | 385 | } |
wolfSSL | 16:8e0d178b1d1e | 386 | |
wolfSSL | 16:8e0d178b1d1e | 387 | /* uncompress A (public key), test if valid, and negate it */ |
wolfSSL | 16:8e0d178b1d1e | 388 | if ((ret == 0) && (ge448_from_bytes_negate_vartime(&A, key->p) != 0)) { |
wolfSSL | 16:8e0d178b1d1e | 389 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 390 | } |
wolfSSL | 16:8e0d178b1d1e | 391 | |
wolfSSL | 16:8e0d178b1d1e | 392 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 393 | /* find H(R,A,M) and store it as h */ |
wolfSSL | 16:8e0d178b1d1e | 394 | ret = wc_InitShake256(&sha, NULL, INVALID_DEVID); |
wolfSSL | 16:8e0d178b1d1e | 395 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 396 | ret = wc_Shake256_Update(&sha, ed448Ctx, ED448CTX_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 397 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 398 | ret = wc_Shake256_Update(&sha, &type, sizeof(type)); |
wolfSSL | 16:8e0d178b1d1e | 399 | } |
wolfSSL | 16:8e0d178b1d1e | 400 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 401 | ret = wc_Shake256_Update(&sha, &contextLen, sizeof(contextLen)); |
wolfSSL | 16:8e0d178b1d1e | 402 | } |
wolfSSL | 16:8e0d178b1d1e | 403 | if (ret == 0 && context != NULL) { |
wolfSSL | 16:8e0d178b1d1e | 404 | ret = wc_Shake256_Update(&sha, context, contextLen); |
wolfSSL | 16:8e0d178b1d1e | 405 | } |
wolfSSL | 16:8e0d178b1d1e | 406 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 407 | ret = wc_Shake256_Update(&sha, sig, ED448_SIG_SIZE/2); |
wolfSSL | 16:8e0d178b1d1e | 408 | } |
wolfSSL | 16:8e0d178b1d1e | 409 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 410 | ret = wc_Shake256_Update(&sha, key->p, ED448_PUB_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 411 | } |
wolfSSL | 16:8e0d178b1d1e | 412 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 413 | ret = wc_Shake256_Update(&sha, msg, msgLen); |
wolfSSL | 16:8e0d178b1d1e | 414 | } |
wolfSSL | 16:8e0d178b1d1e | 415 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 416 | ret = wc_Shake256_Final(&sha, h, sizeof(h)); |
wolfSSL | 16:8e0d178b1d1e | 417 | } |
wolfSSL | 16:8e0d178b1d1e | 418 | wc_Shake256_Free(&sha); |
wolfSSL | 16:8e0d178b1d1e | 419 | } |
wolfSSL | 16:8e0d178b1d1e | 420 | } |
wolfSSL | 16:8e0d178b1d1e | 421 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 422 | sc448_reduce(h); |
wolfSSL | 16:8e0d178b1d1e | 423 | |
wolfSSL | 16:8e0d178b1d1e | 424 | /* Uses a fast single-signature verification SB = R + H(R,A,M)A becomes |
wolfSSL | 16:8e0d178b1d1e | 425 | * SB - H(R,A,M)A saving decompression of R |
wolfSSL | 16:8e0d178b1d1e | 426 | */ |
wolfSSL | 16:8e0d178b1d1e | 427 | ret = ge448_double_scalarmult_vartime(&R, h, &A, |
wolfSSL | 16:8e0d178b1d1e | 428 | sig + (ED448_SIG_SIZE/2)); |
wolfSSL | 16:8e0d178b1d1e | 429 | } |
wolfSSL | 16:8e0d178b1d1e | 430 | |
wolfSSL | 16:8e0d178b1d1e | 431 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 432 | ge448_to_bytes(rcheck, &R); |
wolfSSL | 16:8e0d178b1d1e | 433 | |
wolfSSL | 16:8e0d178b1d1e | 434 | /* comparison of R created to R in sig */ |
wolfSSL | 16:8e0d178b1d1e | 435 | if (ConstantCompare(rcheck, sig, ED448_SIG_SIZE/2) != 0) { |
wolfSSL | 16:8e0d178b1d1e | 436 | ret = SIG_VERIFY_E; |
wolfSSL | 16:8e0d178b1d1e | 437 | } |
wolfSSL | 16:8e0d178b1d1e | 438 | else { |
wolfSSL | 16:8e0d178b1d1e | 439 | /* set the verification status */ |
wolfSSL | 16:8e0d178b1d1e | 440 | *res = 1; |
wolfSSL | 16:8e0d178b1d1e | 441 | } |
wolfSSL | 16:8e0d178b1d1e | 442 | } |
wolfSSL | 16:8e0d178b1d1e | 443 | |
wolfSSL | 16:8e0d178b1d1e | 444 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 445 | } |
wolfSSL | 16:8e0d178b1d1e | 446 | |
wolfSSL | 16:8e0d178b1d1e | 447 | /* Verify the message using the ed448 public key. |
wolfSSL | 16:8e0d178b1d1e | 448 | * Signature type is Ed448. |
wolfSSL | 16:8e0d178b1d1e | 449 | * |
wolfSSL | 16:8e0d178b1d1e | 450 | * sig [in] Signature to verify. |
wolfSSL | 16:8e0d178b1d1e | 451 | * sigLen [in] Size of signature in bytes. |
wolfSSL | 16:8e0d178b1d1e | 452 | * msg [in] Message to verify. |
wolfSSL | 16:8e0d178b1d1e | 453 | * msgLen [in] Length of the message in bytes. |
wolfSSL | 16:8e0d178b1d1e | 454 | * key [in] Ed448 key to use to verify. |
wolfSSL | 16:8e0d178b1d1e | 455 | * context [in] Context of verification. |
wolfSSL | 16:8e0d178b1d1e | 456 | * contextLen [in] Length of context in bytes. |
wolfSSL | 16:8e0d178b1d1e | 457 | * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and |
wolfSSL | 16:8e0d178b1d1e | 458 | * context is not NULL or public key not set, |
wolfSSL | 16:8e0d178b1d1e | 459 | * BUFFER_E when sigLen is less than ED448_SIG_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 460 | * other -ve values when hash fails, |
wolfSSL | 16:8e0d178b1d1e | 461 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 462 | */ |
wolfSSL | 16:8e0d178b1d1e | 463 | int wc_ed448_verify_msg(const byte* sig, word32 sigLen, const byte* msg, |
wolfSSL | 16:8e0d178b1d1e | 464 | word32 msgLen, int* res, ed448_key* key, |
wolfSSL | 16:8e0d178b1d1e | 465 | const byte* context, byte contextLen) |
wolfSSL | 16:8e0d178b1d1e | 466 | { |
wolfSSL | 16:8e0d178b1d1e | 467 | return ed448_verify_msg(sig, sigLen, msg, msgLen, res, key, Ed448, |
wolfSSL | 16:8e0d178b1d1e | 468 | context, contextLen); |
wolfSSL | 16:8e0d178b1d1e | 469 | } |
wolfSSL | 16:8e0d178b1d1e | 470 | |
wolfSSL | 16:8e0d178b1d1e | 471 | /* Verify the hash using the ed448 public key. |
wolfSSL | 16:8e0d178b1d1e | 472 | * Signature type is Ed448ph. |
wolfSSL | 16:8e0d178b1d1e | 473 | * |
wolfSSL | 16:8e0d178b1d1e | 474 | * sig [in] Signature to verify. |
wolfSSL | 16:8e0d178b1d1e | 475 | * sigLen [in] Size of signature in bytes. |
wolfSSL | 16:8e0d178b1d1e | 476 | * hash [in] Hash of message to verify. |
wolfSSL | 16:8e0d178b1d1e | 477 | * hashLen [in] Length of the hash in bytes. |
wolfSSL | 16:8e0d178b1d1e | 478 | * key [in] Ed448 key to use to verify. |
wolfSSL | 16:8e0d178b1d1e | 479 | * context [in] Context of verification. |
wolfSSL | 16:8e0d178b1d1e | 480 | * contextLen [in] Length of context in bytes. |
wolfSSL | 16:8e0d178b1d1e | 481 | * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and |
wolfSSL | 16:8e0d178b1d1e | 482 | * context is not NULL or public key not set, |
wolfSSL | 16:8e0d178b1d1e | 483 | * BUFFER_E when sigLen is less than ED448_SIG_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 484 | * other -ve values when hash fails, |
wolfSSL | 16:8e0d178b1d1e | 485 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 486 | */ |
wolfSSL | 16:8e0d178b1d1e | 487 | int wc_ed448ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash, |
wolfSSL | 16:8e0d178b1d1e | 488 | word32 hashLen, int* res, ed448_key* key, |
wolfSSL | 16:8e0d178b1d1e | 489 | const byte* context, byte contextLen) |
wolfSSL | 16:8e0d178b1d1e | 490 | { |
wolfSSL | 16:8e0d178b1d1e | 491 | return ed448_verify_msg(sig, sigLen, hash, hashLen, res, key, Ed448ph, |
wolfSSL | 16:8e0d178b1d1e | 492 | context, contextLen); |
wolfSSL | 16:8e0d178b1d1e | 493 | } |
wolfSSL | 16:8e0d178b1d1e | 494 | |
wolfSSL | 16:8e0d178b1d1e | 495 | /* Verify the message using the ed448 public key. |
wolfSSL | 16:8e0d178b1d1e | 496 | * Signature type is Ed448ph. |
wolfSSL | 16:8e0d178b1d1e | 497 | * |
wolfSSL | 16:8e0d178b1d1e | 498 | * sig [in] Signature to verify. |
wolfSSL | 16:8e0d178b1d1e | 499 | * sigLen [in] Size of signature in bytes. |
wolfSSL | 16:8e0d178b1d1e | 500 | * msg [in] Message to verify. |
wolfSSL | 16:8e0d178b1d1e | 501 | * msgLen [in] Length of the message in bytes. |
wolfSSL | 16:8e0d178b1d1e | 502 | * key [in] Ed448 key to use to verify. |
wolfSSL | 16:8e0d178b1d1e | 503 | * context [in] Context of verification. |
wolfSSL | 16:8e0d178b1d1e | 504 | * contextLen [in] Length of context in bytes. |
wolfSSL | 16:8e0d178b1d1e | 505 | * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and |
wolfSSL | 16:8e0d178b1d1e | 506 | * context is not NULL or public key not set, |
wolfSSL | 16:8e0d178b1d1e | 507 | * BUFFER_E when sigLen is less than ED448_SIG_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 508 | * other -ve values when hash fails, |
wolfSSL | 16:8e0d178b1d1e | 509 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 510 | */ |
wolfSSL | 16:8e0d178b1d1e | 511 | int wc_ed448ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg, |
wolfSSL | 16:8e0d178b1d1e | 512 | word32 msgLen, int* res, ed448_key* key, |
wolfSSL | 16:8e0d178b1d1e | 513 | const byte* context, byte contextLen) |
wolfSSL | 16:8e0d178b1d1e | 514 | { |
wolfSSL | 16:8e0d178b1d1e | 515 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 516 | byte hash[64]; |
wolfSSL | 16:8e0d178b1d1e | 517 | |
wolfSSL | 16:8e0d178b1d1e | 518 | ret = wc_Shake256Hash(msg, msgLen, hash, sizeof(hash)); |
wolfSSL | 16:8e0d178b1d1e | 519 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 520 | ret = wc_ed448ph_verify_hash(sig, sigLen, hash, sizeof(hash), res, key, |
wolfSSL | 16:8e0d178b1d1e | 521 | context, contextLen); |
wolfSSL | 16:8e0d178b1d1e | 522 | } |
wolfSSL | 16:8e0d178b1d1e | 523 | |
wolfSSL | 16:8e0d178b1d1e | 524 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 525 | } |
wolfSSL | 16:8e0d178b1d1e | 526 | #endif /* HAVE_ED448_VERIFY */ |
wolfSSL | 16:8e0d178b1d1e | 527 | |
wolfSSL | 16:8e0d178b1d1e | 528 | /* Initialize the ed448 private/public key. |
wolfSSL | 16:8e0d178b1d1e | 529 | * |
wolfSSL | 16:8e0d178b1d1e | 530 | * key [in] Ed448 key. |
wolfSSL | 16:8e0d178b1d1e | 531 | * returns BAD_FUNC_ARG when key is NULL |
wolfSSL | 16:8e0d178b1d1e | 532 | */ |
wolfSSL | 16:8e0d178b1d1e | 533 | int wc_ed448_init(ed448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 534 | { |
wolfSSL | 16:8e0d178b1d1e | 535 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 536 | |
wolfSSL | 16:8e0d178b1d1e | 537 | if (key == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 538 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 539 | } |
wolfSSL | 16:8e0d178b1d1e | 540 | else { |
wolfSSL | 16:8e0d178b1d1e | 541 | XMEMSET(key, 0, sizeof(ed448_key)); |
wolfSSL | 16:8e0d178b1d1e | 542 | |
wolfSSL | 16:8e0d178b1d1e | 543 | fe448_init(); |
wolfSSL | 16:8e0d178b1d1e | 544 | } |
wolfSSL | 16:8e0d178b1d1e | 545 | |
wolfSSL | 16:8e0d178b1d1e | 546 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 547 | } |
wolfSSL | 16:8e0d178b1d1e | 548 | |
wolfSSL | 16:8e0d178b1d1e | 549 | |
wolfSSL | 16:8e0d178b1d1e | 550 | /* Clears the ed448 key data |
wolfSSL | 16:8e0d178b1d1e | 551 | * |
wolfSSL | 16:8e0d178b1d1e | 552 | * key [in] Ed448 key. |
wolfSSL | 16:8e0d178b1d1e | 553 | */ |
wolfSSL | 16:8e0d178b1d1e | 554 | void wc_ed448_free(ed448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 555 | { |
wolfSSL | 16:8e0d178b1d1e | 556 | if (key != NULL) { |
wolfSSL | 16:8e0d178b1d1e | 557 | ForceZero(key, sizeof(ed448_key)); |
wolfSSL | 16:8e0d178b1d1e | 558 | } |
wolfSSL | 16:8e0d178b1d1e | 559 | } |
wolfSSL | 16:8e0d178b1d1e | 560 | |
wolfSSL | 16:8e0d178b1d1e | 561 | |
wolfSSL | 16:8e0d178b1d1e | 562 | #ifdef HAVE_ED448_KEY_EXPORT |
wolfSSL | 16:8e0d178b1d1e | 563 | |
wolfSSL | 16:8e0d178b1d1e | 564 | /* Export the ed448 public key. |
wolfSSL | 16:8e0d178b1d1e | 565 | * |
wolfSSL | 16:8e0d178b1d1e | 566 | * key [in] Ed448 public key. |
wolfSSL | 16:8e0d178b1d1e | 567 | * out [in] Array to hold public key. |
wolfSSL | 16:8e0d178b1d1e | 568 | * outLen [in/out] On in, the number of bytes in array. |
wolfSSL | 16:8e0d178b1d1e | 569 | * On out, the number bytes put into array. |
wolfSSL | 16:8e0d178b1d1e | 570 | * returns BAD_FUNC_ARG when a parameter is NULL, |
wolfSSL | 16:8e0d178b1d1e | 571 | * ECC_BAD_ARG_E when outLen is less than ED448_PUB_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 572 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 573 | */ |
wolfSSL | 16:8e0d178b1d1e | 574 | int wc_ed448_export_public(ed448_key* key, byte* out, word32* outLen) |
wolfSSL | 16:8e0d178b1d1e | 575 | { |
wolfSSL | 16:8e0d178b1d1e | 576 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 577 | |
wolfSSL | 16:8e0d178b1d1e | 578 | /* sanity check on arguments */ |
wolfSSL | 16:8e0d178b1d1e | 579 | if ((key == NULL) || (out == NULL) || (outLen == NULL)) { |
wolfSSL | 16:8e0d178b1d1e | 580 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 581 | } |
wolfSSL | 16:8e0d178b1d1e | 582 | |
wolfSSL | 16:8e0d178b1d1e | 583 | if ((ret == 0) && (*outLen < ED448_PUB_KEY_SIZE)) { |
wolfSSL | 16:8e0d178b1d1e | 584 | *outLen = ED448_PUB_KEY_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 585 | ret = BUFFER_E; |
wolfSSL | 16:8e0d178b1d1e | 586 | } |
wolfSSL | 16:8e0d178b1d1e | 587 | |
wolfSSL | 16:8e0d178b1d1e | 588 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 589 | *outLen = ED448_PUB_KEY_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 590 | XMEMCPY(out, key->p, ED448_PUB_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 591 | } |
wolfSSL | 16:8e0d178b1d1e | 592 | |
wolfSSL | 16:8e0d178b1d1e | 593 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 594 | } |
wolfSSL | 16:8e0d178b1d1e | 595 | |
wolfSSL | 16:8e0d178b1d1e | 596 | #endif /* HAVE_ED448_KEY_EXPORT */ |
wolfSSL | 16:8e0d178b1d1e | 597 | |
wolfSSL | 16:8e0d178b1d1e | 598 | |
wolfSSL | 16:8e0d178b1d1e | 599 | #ifdef HAVE_ED448_KEY_IMPORT |
wolfSSL | 16:8e0d178b1d1e | 600 | /* Import a compressed or uncompressed ed448 public key from a byte array. |
wolfSSL | 16:8e0d178b1d1e | 601 | * Public key encoded in big-endian. |
wolfSSL | 16:8e0d178b1d1e | 602 | * |
wolfSSL | 16:8e0d178b1d1e | 603 | * in [in] Array holding public key. |
wolfSSL | 16:8e0d178b1d1e | 604 | * inLen [in] Number of bytes of data in array. |
wolfSSL | 16:8e0d178b1d1e | 605 | * key [in] Ed448 public key. |
wolfSSL | 16:8e0d178b1d1e | 606 | * returns BAD_FUNC_ARG when a parameter is NULL or key format is not supported, |
wolfSSL | 16:8e0d178b1d1e | 607 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 608 | */ |
wolfSSL | 16:8e0d178b1d1e | 609 | int wc_ed448_import_public(const byte* in, word32 inLen, ed448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 610 | { |
wolfSSL | 16:8e0d178b1d1e | 611 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 612 | |
wolfSSL | 16:8e0d178b1d1e | 613 | /* sanity check on arguments */ |
wolfSSL | 16:8e0d178b1d1e | 614 | if ((in == NULL) || (key == NULL)) { |
wolfSSL | 16:8e0d178b1d1e | 615 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 616 | } |
wolfSSL | 16:8e0d178b1d1e | 617 | |
wolfSSL | 16:8e0d178b1d1e | 618 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 619 | /* compressed prefix according to draft |
wolfSSL | 16:8e0d178b1d1e | 620 | * https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-06 */ |
wolfSSL | 16:8e0d178b1d1e | 621 | if (in[0] == 0x40 && inLen > ED448_PUB_KEY_SIZE) { |
wolfSSL | 16:8e0d178b1d1e | 622 | /* key is stored in compressed format so just copy in */ |
wolfSSL | 16:8e0d178b1d1e | 623 | XMEMCPY(key->p, (in + 1), ED448_PUB_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 624 | key->pubKeySet = 1; |
wolfSSL | 16:8e0d178b1d1e | 625 | } |
wolfSSL | 16:8e0d178b1d1e | 626 | /* importing uncompressed public key */ |
wolfSSL | 16:8e0d178b1d1e | 627 | else if (in[0] == 0x04 && inLen > 2*ED448_PUB_KEY_SIZE) { |
wolfSSL | 16:8e0d178b1d1e | 628 | /* pass in (x,y) and store compressed key */ |
wolfSSL | 16:8e0d178b1d1e | 629 | ret = ge448_compress_key(key->p, in+1, in+1+ED448_PUB_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 630 | if (ret == 0) |
wolfSSL | 16:8e0d178b1d1e | 631 | key->pubKeySet = 1; |
wolfSSL | 16:8e0d178b1d1e | 632 | } |
wolfSSL | 16:8e0d178b1d1e | 633 | else if (inLen == ED448_PUB_KEY_SIZE) { |
wolfSSL | 16:8e0d178b1d1e | 634 | /* if not specified compressed or uncompressed check key size |
wolfSSL | 16:8e0d178b1d1e | 635 | * if key size is equal to compressed key size copy in key */ |
wolfSSL | 16:8e0d178b1d1e | 636 | XMEMCPY(key->p, in, ED448_PUB_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 637 | key->pubKeySet = 1; |
wolfSSL | 16:8e0d178b1d1e | 638 | } |
wolfSSL | 16:8e0d178b1d1e | 639 | else { |
wolfSSL | 16:8e0d178b1d1e | 640 | /* bad public key format */ |
wolfSSL | 16:8e0d178b1d1e | 641 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 642 | } |
wolfSSL | 16:8e0d178b1d1e | 643 | } |
wolfSSL | 16:8e0d178b1d1e | 644 | |
wolfSSL | 16:8e0d178b1d1e | 645 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 646 | } |
wolfSSL | 16:8e0d178b1d1e | 647 | |
wolfSSL | 16:8e0d178b1d1e | 648 | |
wolfSSL | 16:8e0d178b1d1e | 649 | /* Import an ed448 private key from a byte array. |
wolfSSL | 16:8e0d178b1d1e | 650 | * |
wolfSSL | 16:8e0d178b1d1e | 651 | * priv [in] Array holding private key. |
wolfSSL | 16:8e0d178b1d1e | 652 | * privSz [in] Number of bytes of data in array. |
wolfSSL | 16:8e0d178b1d1e | 653 | * key [in] Ed448 private key. |
wolfSSL | 16:8e0d178b1d1e | 654 | * returns BAD_FUNC_ARG when a parameter is NULL or privSz is less than |
wolfSSL | 16:8e0d178b1d1e | 655 | * ED448_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 656 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 657 | */ |
wolfSSL | 16:8e0d178b1d1e | 658 | int wc_ed448_import_private_only(const byte* priv, word32 privSz, |
wolfSSL | 16:8e0d178b1d1e | 659 | ed448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 660 | { |
wolfSSL | 16:8e0d178b1d1e | 661 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 662 | |
wolfSSL | 16:8e0d178b1d1e | 663 | /* sanity check on arguments */ |
wolfSSL | 16:8e0d178b1d1e | 664 | if ((priv == NULL) || (key == NULL)) { |
wolfSSL | 16:8e0d178b1d1e | 665 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 666 | } |
wolfSSL | 16:8e0d178b1d1e | 667 | |
wolfSSL | 16:8e0d178b1d1e | 668 | /* key size check */ |
wolfSSL | 16:8e0d178b1d1e | 669 | if ((ret == 0) && (privSz < ED448_KEY_SIZE)) { |
wolfSSL | 16:8e0d178b1d1e | 670 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 671 | } |
wolfSSL | 16:8e0d178b1d1e | 672 | |
wolfSSL | 16:8e0d178b1d1e | 673 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 674 | XMEMCPY(key->k, priv, ED448_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 675 | } |
wolfSSL | 16:8e0d178b1d1e | 676 | |
wolfSSL | 16:8e0d178b1d1e | 677 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 678 | } |
wolfSSL | 16:8e0d178b1d1e | 679 | |
wolfSSL | 16:8e0d178b1d1e | 680 | /* Import an ed448 private and public keys from a byte arrays. |
wolfSSL | 16:8e0d178b1d1e | 681 | * |
wolfSSL | 16:8e0d178b1d1e | 682 | * priv [in] Array holding private key. |
wolfSSL | 16:8e0d178b1d1e | 683 | * privSz [in] Number of bytes of data in private key array. |
wolfSSL | 16:8e0d178b1d1e | 684 | * pub [in] Array holding private key. |
wolfSSL | 16:8e0d178b1d1e | 685 | * pubSz [in] Number of bytes of data in public key array. |
wolfSSL | 16:8e0d178b1d1e | 686 | * key [in] Ed448 private/public key. |
wolfSSL | 16:8e0d178b1d1e | 687 | * returns BAD_FUNC_ARG when a parameter is NULL or privSz is less than |
wolfSSL | 16:8e0d178b1d1e | 688 | * ED448_KEY_SIZE or pubSz is less than ED448_PUB_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 689 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 690 | */ |
wolfSSL | 16:8e0d178b1d1e | 691 | int wc_ed448_import_private_key(const byte* priv, word32 privSz, |
wolfSSL | 16:8e0d178b1d1e | 692 | const byte* pub, word32 pubSz, ed448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 693 | { |
wolfSSL | 16:8e0d178b1d1e | 694 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 695 | |
wolfSSL | 16:8e0d178b1d1e | 696 | /* sanity check on arguments */ |
wolfSSL | 16:8e0d178b1d1e | 697 | if ((priv == NULL) || (pub == NULL) || (key == NULL)) { |
wolfSSL | 16:8e0d178b1d1e | 698 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 699 | } |
wolfSSL | 16:8e0d178b1d1e | 700 | |
wolfSSL | 16:8e0d178b1d1e | 701 | /* key size check */ |
wolfSSL | 16:8e0d178b1d1e | 702 | if ((ret == 0) && (privSz < ED448_KEY_SIZE || pubSz < ED448_PUB_KEY_SIZE)) { |
wolfSSL | 16:8e0d178b1d1e | 703 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 704 | } |
wolfSSL | 16:8e0d178b1d1e | 705 | |
wolfSSL | 16:8e0d178b1d1e | 706 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 707 | /* import public key */ |
wolfSSL | 16:8e0d178b1d1e | 708 | ret = wc_ed448_import_public(pub, pubSz, key); |
wolfSSL | 16:8e0d178b1d1e | 709 | } |
wolfSSL | 16:8e0d178b1d1e | 710 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 711 | /* make the private key (priv + pub) */ |
wolfSSL | 16:8e0d178b1d1e | 712 | XMEMCPY(key->k, priv, ED448_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 713 | XMEMCPY(key->k + ED448_KEY_SIZE, key->p, ED448_PUB_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 714 | } |
wolfSSL | 16:8e0d178b1d1e | 715 | |
wolfSSL | 16:8e0d178b1d1e | 716 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 717 | } |
wolfSSL | 16:8e0d178b1d1e | 718 | |
wolfSSL | 16:8e0d178b1d1e | 719 | #endif /* HAVE_ED448_KEY_IMPORT */ |
wolfSSL | 16:8e0d178b1d1e | 720 | |
wolfSSL | 16:8e0d178b1d1e | 721 | |
wolfSSL | 16:8e0d178b1d1e | 722 | #ifdef HAVE_ED448_KEY_EXPORT |
wolfSSL | 16:8e0d178b1d1e | 723 | |
wolfSSL | 16:8e0d178b1d1e | 724 | /* Export the ed448 private key. |
wolfSSL | 16:8e0d178b1d1e | 725 | * |
wolfSSL | 16:8e0d178b1d1e | 726 | * key [in] Ed448 private key. |
wolfSSL | 16:8e0d178b1d1e | 727 | * out [in] Array to hold private key. |
wolfSSL | 16:8e0d178b1d1e | 728 | * outLen [in/out] On in, the number of bytes in array. |
wolfSSL | 16:8e0d178b1d1e | 729 | * On out, the number bytes put into array. |
wolfSSL | 16:8e0d178b1d1e | 730 | * returns BAD_FUNC_ARG when a parameter is NULL, |
wolfSSL | 16:8e0d178b1d1e | 731 | * ECC_BAD_ARG_E when outLen is less than ED448_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 732 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 733 | */ |
wolfSSL | 16:8e0d178b1d1e | 734 | int wc_ed448_export_private_only(ed448_key* key, byte* out, word32* outLen) |
wolfSSL | 16:8e0d178b1d1e | 735 | { |
wolfSSL | 16:8e0d178b1d1e | 736 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 737 | |
wolfSSL | 16:8e0d178b1d1e | 738 | /* sanity checks on arguments */ |
wolfSSL | 16:8e0d178b1d1e | 739 | if ((key == NULL) || (out == NULL) || (outLen == NULL)) { |
wolfSSL | 16:8e0d178b1d1e | 740 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 741 | } |
wolfSSL | 16:8e0d178b1d1e | 742 | |
wolfSSL | 16:8e0d178b1d1e | 743 | if ((ret == 0) && (*outLen < ED448_KEY_SIZE)) { |
wolfSSL | 16:8e0d178b1d1e | 744 | *outLen = ED448_KEY_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 745 | ret = BUFFER_E; |
wolfSSL | 16:8e0d178b1d1e | 746 | } |
wolfSSL | 16:8e0d178b1d1e | 747 | |
wolfSSL | 16:8e0d178b1d1e | 748 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 749 | *outLen = ED448_KEY_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 750 | XMEMCPY(out, key->k, ED448_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 751 | } |
wolfSSL | 16:8e0d178b1d1e | 752 | |
wolfSSL | 16:8e0d178b1d1e | 753 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 754 | } |
wolfSSL | 16:8e0d178b1d1e | 755 | |
wolfSSL | 16:8e0d178b1d1e | 756 | /* Export the ed448 private and public key. |
wolfSSL | 16:8e0d178b1d1e | 757 | * |
wolfSSL | 16:8e0d178b1d1e | 758 | * key [in] Ed448 private/public key. |
wolfSSL | 16:8e0d178b1d1e | 759 | * out [in] Array to hold private and public key. |
wolfSSL | 16:8e0d178b1d1e | 760 | * outLen [in/out] On in, the number of bytes in array. |
wolfSSL | 16:8e0d178b1d1e | 761 | * On out, the number bytes put into array. |
wolfSSL | 16:8e0d178b1d1e | 762 | * returns BAD_FUNC_ARG when a parameter is NULL, |
wolfSSL | 16:8e0d178b1d1e | 763 | * BUFFER_E when outLen is less than ED448_PRV_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 764 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 765 | */ |
wolfSSL | 16:8e0d178b1d1e | 766 | int wc_ed448_export_private(ed448_key* key, byte* out, word32* outLen) |
wolfSSL | 16:8e0d178b1d1e | 767 | { |
wolfSSL | 16:8e0d178b1d1e | 768 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 769 | |
wolfSSL | 16:8e0d178b1d1e | 770 | /* sanity checks on arguments */ |
wolfSSL | 16:8e0d178b1d1e | 771 | if ((key == NULL) || (out == NULL) || (outLen == NULL)) { |
wolfSSL | 16:8e0d178b1d1e | 772 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 773 | } |
wolfSSL | 16:8e0d178b1d1e | 774 | |
wolfSSL | 16:8e0d178b1d1e | 775 | if ((ret == 0) && (*outLen < ED448_PRV_KEY_SIZE)) { |
wolfSSL | 16:8e0d178b1d1e | 776 | *outLen = ED448_PRV_KEY_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 777 | ret = BUFFER_E; |
wolfSSL | 16:8e0d178b1d1e | 778 | } |
wolfSSL | 16:8e0d178b1d1e | 779 | |
wolfSSL | 16:8e0d178b1d1e | 780 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 781 | *outLen = ED448_PRV_KEY_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 782 | XMEMCPY(out, key->k, ED448_PRV_KEY_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 783 | } |
wolfSSL | 16:8e0d178b1d1e | 784 | |
wolfSSL | 16:8e0d178b1d1e | 785 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 786 | } |
wolfSSL | 16:8e0d178b1d1e | 787 | |
wolfSSL | 16:8e0d178b1d1e | 788 | /* Export the ed448 private and public key. |
wolfSSL | 16:8e0d178b1d1e | 789 | * |
wolfSSL | 16:8e0d178b1d1e | 790 | * key [in] Ed448 private/public key. |
wolfSSL | 16:8e0d178b1d1e | 791 | * priv [in] Array to hold private key. |
wolfSSL | 16:8e0d178b1d1e | 792 | * privSz [in/out] On in, the number of bytes in private key array. |
wolfSSL | 16:8e0d178b1d1e | 793 | * pub [in] Array to hold public key. |
wolfSSL | 16:8e0d178b1d1e | 794 | * pubSz [in/out] On in, the number of bytes in public key array. |
wolfSSL | 16:8e0d178b1d1e | 795 | * On out, the number bytes put into array. |
wolfSSL | 16:8e0d178b1d1e | 796 | * returns BAD_FUNC_ARG when a parameter is NULL, |
wolfSSL | 16:8e0d178b1d1e | 797 | * BUFFER_E when privSz is less than ED448_PRV_KEY_SIZE or pubSz is less |
wolfSSL | 16:8e0d178b1d1e | 798 | * than ED448_PUB_KEY_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 799 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 800 | */ |
wolfSSL | 16:8e0d178b1d1e | 801 | int wc_ed448_export_key(ed448_key* key, byte* priv, word32 *privSz, |
wolfSSL | 16:8e0d178b1d1e | 802 | byte* pub, word32 *pubSz) |
wolfSSL | 16:8e0d178b1d1e | 803 | { |
wolfSSL | 16:8e0d178b1d1e | 804 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 805 | |
wolfSSL | 16:8e0d178b1d1e | 806 | /* export 'full' private part */ |
wolfSSL | 16:8e0d178b1d1e | 807 | ret = wc_ed448_export_private(key, priv, privSz); |
wolfSSL | 16:8e0d178b1d1e | 808 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 809 | /* export public part */ |
wolfSSL | 16:8e0d178b1d1e | 810 | ret = wc_ed448_export_public(key, pub, pubSz); |
wolfSSL | 16:8e0d178b1d1e | 811 | } |
wolfSSL | 16:8e0d178b1d1e | 812 | |
wolfSSL | 16:8e0d178b1d1e | 813 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 814 | } |
wolfSSL | 16:8e0d178b1d1e | 815 | |
wolfSSL | 16:8e0d178b1d1e | 816 | #endif /* HAVE_ED448_KEY_EXPORT */ |
wolfSSL | 16:8e0d178b1d1e | 817 | |
wolfSSL | 16:8e0d178b1d1e | 818 | /* Check the public key of the ed448 key matches the private key. |
wolfSSL | 16:8e0d178b1d1e | 819 | * |
wolfSSL | 16:8e0d178b1d1e | 820 | * key [in] Ed448 private/public key. |
wolfSSL | 16:8e0d178b1d1e | 821 | * returns BAD_FUNC_ARG when key is NULL, |
wolfSSL | 16:8e0d178b1d1e | 822 | * PUBLIC_KEY_E when the public key is not set or doesn't match, |
wolfSSL | 16:8e0d178b1d1e | 823 | * other -ve value on hash failure, |
wolfSSL | 16:8e0d178b1d1e | 824 | * 0 otherwise. |
wolfSSL | 16:8e0d178b1d1e | 825 | */ |
wolfSSL | 16:8e0d178b1d1e | 826 | int wc_ed448_check_key(ed448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 827 | { |
wolfSSL | 16:8e0d178b1d1e | 828 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 829 | unsigned char pubKey[ED448_PUB_KEY_SIZE]; |
wolfSSL | 16:8e0d178b1d1e | 830 | |
wolfSSL | 16:8e0d178b1d1e | 831 | if (key == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 832 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 833 | } |
wolfSSL | 16:8e0d178b1d1e | 834 | |
wolfSSL | 16:8e0d178b1d1e | 835 | if (!key->pubKeySet) { |
wolfSSL | 16:8e0d178b1d1e | 836 | ret = PUBLIC_KEY_E; |
wolfSSL | 16:8e0d178b1d1e | 837 | } |
wolfSSL | 16:8e0d178b1d1e | 838 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 839 | ret = wc_ed448_make_public(key, pubKey, sizeof(pubKey)); |
wolfSSL | 16:8e0d178b1d1e | 840 | } |
wolfSSL | 16:8e0d178b1d1e | 841 | if ((ret == 0) && (XMEMCMP(pubKey, key->p, ED448_PUB_KEY_SIZE) != 0)) { |
wolfSSL | 16:8e0d178b1d1e | 842 | ret = PUBLIC_KEY_E; |
wolfSSL | 16:8e0d178b1d1e | 843 | } |
wolfSSL | 16:8e0d178b1d1e | 844 | |
wolfSSL | 16:8e0d178b1d1e | 845 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 846 | } |
wolfSSL | 16:8e0d178b1d1e | 847 | |
wolfSSL | 16:8e0d178b1d1e | 848 | /* Returns the size of an ed448 private key. |
wolfSSL | 16:8e0d178b1d1e | 849 | * |
wolfSSL | 16:8e0d178b1d1e | 850 | * key [in] Ed448 private/public key. |
wolfSSL | 16:8e0d178b1d1e | 851 | * returns BAD_FUNC_ARG when key is NULL, |
wolfSSL | 16:8e0d178b1d1e | 852 | * ED448_KEY_SIZE otherwise. |
wolfSSL | 16:8e0d178b1d1e | 853 | */ |
wolfSSL | 16:8e0d178b1d1e | 854 | int wc_ed448_size(ed448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 855 | { |
wolfSSL | 16:8e0d178b1d1e | 856 | int ret = ED448_KEY_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 857 | |
wolfSSL | 16:8e0d178b1d1e | 858 | if (key == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 859 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 860 | } |
wolfSSL | 16:8e0d178b1d1e | 861 | |
wolfSSL | 16:8e0d178b1d1e | 862 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 863 | } |
wolfSSL | 16:8e0d178b1d1e | 864 | |
wolfSSL | 16:8e0d178b1d1e | 865 | /* Returns the size of an ed448 private plus public key. |
wolfSSL | 16:8e0d178b1d1e | 866 | * |
wolfSSL | 16:8e0d178b1d1e | 867 | * key [in] Ed448 private/public key. |
wolfSSL | 16:8e0d178b1d1e | 868 | * returns BAD_FUNC_ARG when key is NULL, |
wolfSSL | 16:8e0d178b1d1e | 869 | * ED448_PRV_KEY_SIZE otherwise. |
wolfSSL | 16:8e0d178b1d1e | 870 | */ |
wolfSSL | 16:8e0d178b1d1e | 871 | int wc_ed448_priv_size(ed448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 872 | { |
wolfSSL | 16:8e0d178b1d1e | 873 | int ret = ED448_PRV_KEY_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 874 | |
wolfSSL | 16:8e0d178b1d1e | 875 | if (key == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 876 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 877 | } |
wolfSSL | 16:8e0d178b1d1e | 878 | |
wolfSSL | 16:8e0d178b1d1e | 879 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 880 | } |
wolfSSL | 16:8e0d178b1d1e | 881 | |
wolfSSL | 16:8e0d178b1d1e | 882 | /* Returns the size of an ed448 public key. |
wolfSSL | 16:8e0d178b1d1e | 883 | * |
wolfSSL | 16:8e0d178b1d1e | 884 | * key [in] Ed448 private/public key. |
wolfSSL | 16:8e0d178b1d1e | 885 | * returns BAD_FUNC_ARG when key is NULL, |
wolfSSL | 16:8e0d178b1d1e | 886 | * ED448_PUB_KEY_SIZE otherwise. |
wolfSSL | 16:8e0d178b1d1e | 887 | */ |
wolfSSL | 16:8e0d178b1d1e | 888 | int wc_ed448_pub_size(ed448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 889 | { |
wolfSSL | 16:8e0d178b1d1e | 890 | int ret = ED448_PUB_KEY_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 891 | |
wolfSSL | 16:8e0d178b1d1e | 892 | if (key == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 893 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 894 | } |
wolfSSL | 16:8e0d178b1d1e | 895 | |
wolfSSL | 16:8e0d178b1d1e | 896 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 897 | } |
wolfSSL | 16:8e0d178b1d1e | 898 | |
wolfSSL | 16:8e0d178b1d1e | 899 | /* Returns the size of an ed448 signature. |
wolfSSL | 16:8e0d178b1d1e | 900 | * |
wolfSSL | 16:8e0d178b1d1e | 901 | * key [in] Ed448 private/public key. |
wolfSSL | 16:8e0d178b1d1e | 902 | * returns BAD_FUNC_ARG when key is NULL, |
wolfSSL | 16:8e0d178b1d1e | 903 | * ED448_SIG_SIZE otherwise. |
wolfSSL | 16:8e0d178b1d1e | 904 | */ |
wolfSSL | 16:8e0d178b1d1e | 905 | int wc_ed448_sig_size(ed448_key* key) |
wolfSSL | 16:8e0d178b1d1e | 906 | { |
wolfSSL | 16:8e0d178b1d1e | 907 | int ret = ED448_SIG_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 908 | |
wolfSSL | 16:8e0d178b1d1e | 909 | if (key == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 910 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 911 | } |
wolfSSL | 16:8e0d178b1d1e | 912 | |
wolfSSL | 16:8e0d178b1d1e | 913 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 914 | } |
wolfSSL | 16:8e0d178b1d1e | 915 | |
wolfSSL | 16:8e0d178b1d1e | 916 | #endif /* HAVE_ED448 */ |
wolfSSL | 16:8e0d178b1d1e | 917 | |
wolfSSL | 16:8e0d178b1d1e | 918 |