Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
wolfcrypt/src/signature.c@15:117db924cf7c, 2018-08-18 (annotated)
- Committer:
- wolfSSL
- Date:
- Sat Aug 18 22:20:43 2018 +0000
- Revision:
- 15:117db924cf7c
wolfSSL 3.15.3
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wolfSSL | 15:117db924cf7c | 1 | /* signature.c |
wolfSSL | 15:117db924cf7c | 2 | * |
wolfSSL | 15:117db924cf7c | 3 | * Copyright (C) 2006-2017 wolfSSL Inc. |
wolfSSL | 15:117db924cf7c | 4 | * |
wolfSSL | 15:117db924cf7c | 5 | * This file is part of wolfSSL. |
wolfSSL | 15:117db924cf7c | 6 | * |
wolfSSL | 15:117db924cf7c | 7 | * wolfSSL is free software; you can redistribute it and/or modify |
wolfSSL | 15:117db924cf7c | 8 | * it under the terms of the GNU General Public License as published by |
wolfSSL | 15:117db924cf7c | 9 | * the Free Software Foundation; either version 2 of the License, or |
wolfSSL | 15:117db924cf7c | 10 | * (at your option) any later version. |
wolfSSL | 15:117db924cf7c | 11 | * |
wolfSSL | 15:117db924cf7c | 12 | * wolfSSL is distributed in the hope that it will be useful, |
wolfSSL | 15:117db924cf7c | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
wolfSSL | 15:117db924cf7c | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
wolfSSL | 15:117db924cf7c | 15 | * GNU General Public License for more details. |
wolfSSL | 15:117db924cf7c | 16 | * |
wolfSSL | 15:117db924cf7c | 17 | * You should have received a copy of the GNU General Public License |
wolfSSL | 15:117db924cf7c | 18 | * along with this program; if not, write to the Free Software |
wolfSSL | 15:117db924cf7c | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA |
wolfSSL | 15:117db924cf7c | 20 | */ |
wolfSSL | 15:117db924cf7c | 21 | |
wolfSSL | 15:117db924cf7c | 22 | |
wolfSSL | 15:117db924cf7c | 23 | #ifdef HAVE_CONFIG_H |
wolfSSL | 15:117db924cf7c | 24 | #include <config.h> |
wolfSSL | 15:117db924cf7c | 25 | #endif |
wolfSSL | 15:117db924cf7c | 26 | |
wolfSSL | 15:117db924cf7c | 27 | #include <wolfssl/wolfcrypt/settings.h> |
wolfSSL | 15:117db924cf7c | 28 | #include <wolfssl/wolfcrypt/signature.h> |
wolfSSL | 15:117db924cf7c | 29 | #include <wolfssl/wolfcrypt/error-crypt.h> |
wolfSSL | 15:117db924cf7c | 30 | #include <wolfssl/wolfcrypt/logging.h> |
wolfSSL | 15:117db924cf7c | 31 | #ifndef NO_ASN |
wolfSSL | 15:117db924cf7c | 32 | #include <wolfssl/wolfcrypt/asn.h> |
wolfSSL | 15:117db924cf7c | 33 | #endif |
wolfSSL | 15:117db924cf7c | 34 | #ifdef HAVE_ECC |
wolfSSL | 15:117db924cf7c | 35 | #include <wolfssl/wolfcrypt/ecc.h> |
wolfSSL | 15:117db924cf7c | 36 | #endif |
wolfSSL | 15:117db924cf7c | 37 | #ifndef NO_RSA |
wolfSSL | 15:117db924cf7c | 38 | #include <wolfssl/wolfcrypt/rsa.h> |
wolfSSL | 15:117db924cf7c | 39 | #endif |
wolfSSL | 15:117db924cf7c | 40 | |
wolfSSL | 15:117db924cf7c | 41 | /* If ECC and RSA are disabled then disable signature wrapper */ |
wolfSSL | 15:117db924cf7c | 42 | #if (!defined(HAVE_ECC) || (defined(HAVE_ECC) && !defined(HAVE_ECC_SIGN) \ |
wolfSSL | 15:117db924cf7c | 43 | && !defined(HAVE_ECC_VERIFY))) && defined(NO_RSA) |
wolfSSL | 15:117db924cf7c | 44 | #undef NO_SIG_WRAPPER |
wolfSSL | 15:117db924cf7c | 45 | #define NO_SIG_WRAPPER |
wolfSSL | 15:117db924cf7c | 46 | #endif |
wolfSSL | 15:117db924cf7c | 47 | |
wolfSSL | 15:117db924cf7c | 48 | /* Signature wrapper disabled check */ |
wolfSSL | 15:117db924cf7c | 49 | #ifndef NO_SIG_WRAPPER |
wolfSSL | 15:117db924cf7c | 50 | |
wolfSSL | 15:117db924cf7c | 51 | #if !defined(NO_RSA) && !defined(NO_ASN) |
wolfSSL | 15:117db924cf7c | 52 | static int wc_SignatureDerEncode(enum wc_HashType hash_type, byte** hash_data, |
wolfSSL | 15:117db924cf7c | 53 | word32* hash_len) |
wolfSSL | 15:117db924cf7c | 54 | { |
wolfSSL | 15:117db924cf7c | 55 | int ret = wc_HashGetOID(hash_type); |
wolfSSL | 15:117db924cf7c | 56 | if (ret > 0) { |
wolfSSL | 15:117db924cf7c | 57 | int oid = ret; |
wolfSSL | 15:117db924cf7c | 58 | |
wolfSSL | 15:117db924cf7c | 59 | /* Allocate buffer for hash and max DER encoded */ |
wolfSSL | 15:117db924cf7c | 60 | word32 digest_len = *hash_len + MAX_DER_DIGEST_SZ; |
wolfSSL | 15:117db924cf7c | 61 | byte *digest_buf = (byte*)XMALLOC(digest_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 15:117db924cf7c | 62 | if (digest_buf) { |
wolfSSL | 15:117db924cf7c | 63 | ret = wc_EncodeSignature(digest_buf, *hash_data, *hash_len, oid); |
wolfSSL | 15:117db924cf7c | 64 | if (ret > 0) { |
wolfSSL | 15:117db924cf7c | 65 | digest_len = ret; |
wolfSSL | 15:117db924cf7c | 66 | ret = 0; |
wolfSSL | 15:117db924cf7c | 67 | |
wolfSSL | 15:117db924cf7c | 68 | /* Replace hash with digest (DER encoding + hash) */ |
wolfSSL | 15:117db924cf7c | 69 | XFREE(*hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 15:117db924cf7c | 70 | *hash_data = digest_buf; |
wolfSSL | 15:117db924cf7c | 71 | *hash_len = digest_len; |
wolfSSL | 15:117db924cf7c | 72 | } |
wolfSSL | 15:117db924cf7c | 73 | else { |
wolfSSL | 15:117db924cf7c | 74 | XFREE(digest_buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 15:117db924cf7c | 75 | } |
wolfSSL | 15:117db924cf7c | 76 | } |
wolfSSL | 15:117db924cf7c | 77 | else { |
wolfSSL | 15:117db924cf7c | 78 | ret = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 79 | } |
wolfSSL | 15:117db924cf7c | 80 | } |
wolfSSL | 15:117db924cf7c | 81 | return ret; |
wolfSSL | 15:117db924cf7c | 82 | } |
wolfSSL | 15:117db924cf7c | 83 | #endif /* !NO_RSA && !NO_ASN */ |
wolfSSL | 15:117db924cf7c | 84 | |
wolfSSL | 15:117db924cf7c | 85 | int wc_SignatureGetSize(enum wc_SignatureType sig_type, |
wolfSSL | 15:117db924cf7c | 86 | const void* key, word32 key_len) |
wolfSSL | 15:117db924cf7c | 87 | { |
wolfSSL | 15:117db924cf7c | 88 | int sig_len = BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 89 | |
wolfSSL | 15:117db924cf7c | 90 | /* Suppress possible unused args if all signature types are disabled */ |
wolfSSL | 15:117db924cf7c | 91 | (void)key; |
wolfSSL | 15:117db924cf7c | 92 | (void)key_len; |
wolfSSL | 15:117db924cf7c | 93 | |
wolfSSL | 15:117db924cf7c | 94 | switch(sig_type) { |
wolfSSL | 15:117db924cf7c | 95 | case WC_SIGNATURE_TYPE_ECC: |
wolfSSL | 15:117db924cf7c | 96 | #ifdef HAVE_ECC |
wolfSSL | 15:117db924cf7c | 97 | /* Sanity check that void* key is at least ecc_key in size */ |
wolfSSL | 15:117db924cf7c | 98 | if (key_len >= sizeof(ecc_key)) { |
wolfSSL | 15:117db924cf7c | 99 | sig_len = wc_ecc_sig_size((ecc_key*)key); |
wolfSSL | 15:117db924cf7c | 100 | } |
wolfSSL | 15:117db924cf7c | 101 | else { |
wolfSSL | 15:117db924cf7c | 102 | WOLFSSL_MSG("wc_SignatureGetSize: Invalid ECC key size"); |
wolfSSL | 15:117db924cf7c | 103 | } |
wolfSSL | 15:117db924cf7c | 104 | #else |
wolfSSL | 15:117db924cf7c | 105 | sig_len = SIG_TYPE_E; |
wolfSSL | 15:117db924cf7c | 106 | #endif |
wolfSSL | 15:117db924cf7c | 107 | break; |
wolfSSL | 15:117db924cf7c | 108 | |
wolfSSL | 15:117db924cf7c | 109 | case WC_SIGNATURE_TYPE_RSA_W_ENC: |
wolfSSL | 15:117db924cf7c | 110 | case WC_SIGNATURE_TYPE_RSA: |
wolfSSL | 15:117db924cf7c | 111 | #ifndef NO_RSA |
wolfSSL | 15:117db924cf7c | 112 | /* Sanity check that void* key is at least RsaKey in size */ |
wolfSSL | 15:117db924cf7c | 113 | if (key_len >= sizeof(RsaKey)) { |
wolfSSL | 15:117db924cf7c | 114 | sig_len = wc_RsaEncryptSize((RsaKey*)key); |
wolfSSL | 15:117db924cf7c | 115 | } |
wolfSSL | 15:117db924cf7c | 116 | else { |
wolfSSL | 15:117db924cf7c | 117 | WOLFSSL_MSG("wc_SignatureGetSize: Invalid RsaKey key size"); |
wolfSSL | 15:117db924cf7c | 118 | } |
wolfSSL | 15:117db924cf7c | 119 | #else |
wolfSSL | 15:117db924cf7c | 120 | sig_len = SIG_TYPE_E; |
wolfSSL | 15:117db924cf7c | 121 | #endif |
wolfSSL | 15:117db924cf7c | 122 | break; |
wolfSSL | 15:117db924cf7c | 123 | |
wolfSSL | 15:117db924cf7c | 124 | case WC_SIGNATURE_TYPE_NONE: |
wolfSSL | 15:117db924cf7c | 125 | default: |
wolfSSL | 15:117db924cf7c | 126 | sig_len = BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 127 | break; |
wolfSSL | 15:117db924cf7c | 128 | } |
wolfSSL | 15:117db924cf7c | 129 | return sig_len; |
wolfSSL | 15:117db924cf7c | 130 | } |
wolfSSL | 15:117db924cf7c | 131 | |
wolfSSL | 15:117db924cf7c | 132 | int wc_SignatureVerifyHash( |
wolfSSL | 15:117db924cf7c | 133 | enum wc_HashType hash_type, enum wc_SignatureType sig_type, |
wolfSSL | 15:117db924cf7c | 134 | const byte* hash_data, word32 hash_len, |
wolfSSL | 15:117db924cf7c | 135 | const byte* sig, word32 sig_len, |
wolfSSL | 15:117db924cf7c | 136 | const void* key, word32 key_len) |
wolfSSL | 15:117db924cf7c | 137 | { |
wolfSSL | 15:117db924cf7c | 138 | int ret; |
wolfSSL | 15:117db924cf7c | 139 | |
wolfSSL | 15:117db924cf7c | 140 | /* Check arguments */ |
wolfSSL | 15:117db924cf7c | 141 | if (hash_data == NULL || hash_len <= 0 || |
wolfSSL | 15:117db924cf7c | 142 | sig == NULL || sig_len <= 0 || |
wolfSSL | 15:117db924cf7c | 143 | key == NULL || key_len <= 0) { |
wolfSSL | 15:117db924cf7c | 144 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 145 | } |
wolfSSL | 15:117db924cf7c | 146 | |
wolfSSL | 15:117db924cf7c | 147 | /* Validate signature len (1 to max is okay) */ |
wolfSSL | 15:117db924cf7c | 148 | if ((int)sig_len > wc_SignatureGetSize(sig_type, key, key_len)) { |
wolfSSL | 15:117db924cf7c | 149 | WOLFSSL_MSG("wc_SignatureVerify: Invalid sig type/len"); |
wolfSSL | 15:117db924cf7c | 150 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 151 | } |
wolfSSL | 15:117db924cf7c | 152 | |
wolfSSL | 15:117db924cf7c | 153 | /* Validate hash size */ |
wolfSSL | 15:117db924cf7c | 154 | ret = wc_HashGetDigestSize(hash_type); |
wolfSSL | 15:117db924cf7c | 155 | if (ret < 0) { |
wolfSSL | 15:117db924cf7c | 156 | WOLFSSL_MSG("wc_SignatureVerify: Invalid hash type/len"); |
wolfSSL | 15:117db924cf7c | 157 | return ret; |
wolfSSL | 15:117db924cf7c | 158 | } |
wolfSSL | 15:117db924cf7c | 159 | ret = 0; |
wolfSSL | 15:117db924cf7c | 160 | |
wolfSSL | 15:117db924cf7c | 161 | /* Verify signature using hash */ |
wolfSSL | 15:117db924cf7c | 162 | switch (sig_type) { |
wolfSSL | 15:117db924cf7c | 163 | case WC_SIGNATURE_TYPE_ECC: |
wolfSSL | 15:117db924cf7c | 164 | { |
wolfSSL | 15:117db924cf7c | 165 | #if defined(HAVE_ECC) && defined(HAVE_ECC_VERIFY) |
wolfSSL | 15:117db924cf7c | 166 | int is_valid_sig = 0; |
wolfSSL | 15:117db924cf7c | 167 | |
wolfSSL | 15:117db924cf7c | 168 | /* Perform verification of signature using provided ECC key */ |
wolfSSL | 15:117db924cf7c | 169 | do { |
wolfSSL | 15:117db924cf7c | 170 | #ifdef WOLFSSL_ASYNC_CRYPT |
wolfSSL | 15:117db924cf7c | 171 | ret = wc_AsyncWait(ret, &((ecc_key*)key)->asyncDev, |
wolfSSL | 15:117db924cf7c | 172 | WC_ASYNC_FLAG_CALL_AGAIN); |
wolfSSL | 15:117db924cf7c | 173 | #endif |
wolfSSL | 15:117db924cf7c | 174 | if (ret >= 0) |
wolfSSL | 15:117db924cf7c | 175 | ret = wc_ecc_verify_hash(sig, sig_len, hash_data, hash_len, |
wolfSSL | 15:117db924cf7c | 176 | &is_valid_sig, (ecc_key*)key); |
wolfSSL | 15:117db924cf7c | 177 | } while (ret == WC_PENDING_E); |
wolfSSL | 15:117db924cf7c | 178 | if (ret != 0 || is_valid_sig != 1) { |
wolfSSL | 15:117db924cf7c | 179 | ret = SIG_VERIFY_E; |
wolfSSL | 15:117db924cf7c | 180 | } |
wolfSSL | 15:117db924cf7c | 181 | #else |
wolfSSL | 15:117db924cf7c | 182 | ret = SIG_TYPE_E; |
wolfSSL | 15:117db924cf7c | 183 | #endif |
wolfSSL | 15:117db924cf7c | 184 | break; |
wolfSSL | 15:117db924cf7c | 185 | } |
wolfSSL | 15:117db924cf7c | 186 | |
wolfSSL | 15:117db924cf7c | 187 | case WC_SIGNATURE_TYPE_RSA_W_ENC: |
wolfSSL | 15:117db924cf7c | 188 | case WC_SIGNATURE_TYPE_RSA: |
wolfSSL | 15:117db924cf7c | 189 | { |
wolfSSL | 15:117db924cf7c | 190 | #ifndef NO_RSA |
wolfSSL | 15:117db924cf7c | 191 | word32 plain_len = hash_len; |
wolfSSL | 15:117db924cf7c | 192 | byte *plain_data; |
wolfSSL | 15:117db924cf7c | 193 | |
wolfSSL | 15:117db924cf7c | 194 | /* Make sure the plain text output is at least key size */ |
wolfSSL | 15:117db924cf7c | 195 | if (plain_len < sig_len) { |
wolfSSL | 15:117db924cf7c | 196 | plain_len = sig_len; |
wolfSSL | 15:117db924cf7c | 197 | } |
wolfSSL | 15:117db924cf7c | 198 | plain_data = (byte*)XMALLOC(plain_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 15:117db924cf7c | 199 | if (plain_data) { |
wolfSSL | 15:117db924cf7c | 200 | /* Perform verification of signature using provided RSA key */ |
wolfSSL | 15:117db924cf7c | 201 | do { |
wolfSSL | 15:117db924cf7c | 202 | #ifdef WOLFSSL_ASYNC_CRYPT |
wolfSSL | 15:117db924cf7c | 203 | ret = wc_AsyncWait(ret, &((RsaKey*)key)->asyncDev, |
wolfSSL | 15:117db924cf7c | 204 | WC_ASYNC_FLAG_CALL_AGAIN); |
wolfSSL | 15:117db924cf7c | 205 | #endif |
wolfSSL | 15:117db924cf7c | 206 | if (ret >= 0) |
wolfSSL | 15:117db924cf7c | 207 | ret = wc_RsaSSL_Verify(sig, sig_len, plain_data, |
wolfSSL | 15:117db924cf7c | 208 | plain_len, (RsaKey*)key); |
wolfSSL | 15:117db924cf7c | 209 | } while (ret == WC_PENDING_E); |
wolfSSL | 15:117db924cf7c | 210 | if (ret >= 0) { |
wolfSSL | 15:117db924cf7c | 211 | if ((word32)ret == hash_len && |
wolfSSL | 15:117db924cf7c | 212 | XMEMCMP(plain_data, hash_data, hash_len) == 0) { |
wolfSSL | 15:117db924cf7c | 213 | ret = 0; /* Success */ |
wolfSSL | 15:117db924cf7c | 214 | } |
wolfSSL | 15:117db924cf7c | 215 | else { |
wolfSSL | 15:117db924cf7c | 216 | WOLFSSL_MSG("RSA Signature Verify difference!"); |
wolfSSL | 15:117db924cf7c | 217 | ret = SIG_VERIFY_E; |
wolfSSL | 15:117db924cf7c | 218 | } |
wolfSSL | 15:117db924cf7c | 219 | } |
wolfSSL | 15:117db924cf7c | 220 | XFREE(plain_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 15:117db924cf7c | 221 | } |
wolfSSL | 15:117db924cf7c | 222 | else { |
wolfSSL | 15:117db924cf7c | 223 | ret = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 224 | } |
wolfSSL | 15:117db924cf7c | 225 | #else |
wolfSSL | 15:117db924cf7c | 226 | ret = SIG_TYPE_E; |
wolfSSL | 15:117db924cf7c | 227 | #endif |
wolfSSL | 15:117db924cf7c | 228 | break; |
wolfSSL | 15:117db924cf7c | 229 | } |
wolfSSL | 15:117db924cf7c | 230 | |
wolfSSL | 15:117db924cf7c | 231 | case WC_SIGNATURE_TYPE_NONE: |
wolfSSL | 15:117db924cf7c | 232 | default: |
wolfSSL | 15:117db924cf7c | 233 | ret = BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 234 | break; |
wolfSSL | 15:117db924cf7c | 235 | } |
wolfSSL | 15:117db924cf7c | 236 | |
wolfSSL | 15:117db924cf7c | 237 | return ret; |
wolfSSL | 15:117db924cf7c | 238 | } |
wolfSSL | 15:117db924cf7c | 239 | |
wolfSSL | 15:117db924cf7c | 240 | int wc_SignatureVerify( |
wolfSSL | 15:117db924cf7c | 241 | enum wc_HashType hash_type, enum wc_SignatureType sig_type, |
wolfSSL | 15:117db924cf7c | 242 | const byte* data, word32 data_len, |
wolfSSL | 15:117db924cf7c | 243 | const byte* sig, word32 sig_len, |
wolfSSL | 15:117db924cf7c | 244 | const void* key, word32 key_len) |
wolfSSL | 15:117db924cf7c | 245 | { |
wolfSSL | 15:117db924cf7c | 246 | int ret; |
wolfSSL | 15:117db924cf7c | 247 | word32 hash_len; |
wolfSSL | 15:117db924cf7c | 248 | byte *hash_data = NULL; |
wolfSSL | 15:117db924cf7c | 249 | |
wolfSSL | 15:117db924cf7c | 250 | /* Check arguments */ |
wolfSSL | 15:117db924cf7c | 251 | if (data == NULL || data_len <= 0 || |
wolfSSL | 15:117db924cf7c | 252 | sig == NULL || sig_len <= 0 || |
wolfSSL | 15:117db924cf7c | 253 | key == NULL || key_len <= 0) { |
wolfSSL | 15:117db924cf7c | 254 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 255 | } |
wolfSSL | 15:117db924cf7c | 256 | |
wolfSSL | 15:117db924cf7c | 257 | /* Validate signature len (1 to max is okay) */ |
wolfSSL | 15:117db924cf7c | 258 | if ((int)sig_len > wc_SignatureGetSize(sig_type, key, key_len)) { |
wolfSSL | 15:117db924cf7c | 259 | WOLFSSL_MSG("wc_SignatureVerify: Invalid sig type/len"); |
wolfSSL | 15:117db924cf7c | 260 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 261 | } |
wolfSSL | 15:117db924cf7c | 262 | |
wolfSSL | 15:117db924cf7c | 263 | /* Validate hash size */ |
wolfSSL | 15:117db924cf7c | 264 | ret = wc_HashGetDigestSize(hash_type); |
wolfSSL | 15:117db924cf7c | 265 | if (ret < 0) { |
wolfSSL | 15:117db924cf7c | 266 | WOLFSSL_MSG("wc_SignatureVerify: Invalid hash type/len"); |
wolfSSL | 15:117db924cf7c | 267 | return ret; |
wolfSSL | 15:117db924cf7c | 268 | } |
wolfSSL | 15:117db924cf7c | 269 | hash_len = ret; |
wolfSSL | 15:117db924cf7c | 270 | |
wolfSSL | 15:117db924cf7c | 271 | /* Allocate temporary buffer for hash data */ |
wolfSSL | 15:117db924cf7c | 272 | hash_data = (byte*)XMALLOC(hash_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 15:117db924cf7c | 273 | if (hash_data == NULL) { |
wolfSSL | 15:117db924cf7c | 274 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 275 | } |
wolfSSL | 15:117db924cf7c | 276 | |
wolfSSL | 15:117db924cf7c | 277 | /* Perform hash of data */ |
wolfSSL | 15:117db924cf7c | 278 | ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len); |
wolfSSL | 15:117db924cf7c | 279 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 280 | /* Handle RSA with DER encoding */ |
wolfSSL | 15:117db924cf7c | 281 | if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) { |
wolfSSL | 15:117db924cf7c | 282 | #if defined(NO_RSA) || defined(NO_ASN) |
wolfSSL | 15:117db924cf7c | 283 | ret = SIG_TYPE_E; |
wolfSSL | 15:117db924cf7c | 284 | #else |
wolfSSL | 15:117db924cf7c | 285 | ret = wc_SignatureDerEncode(hash_type, &hash_data, &hash_len); |
wolfSSL | 15:117db924cf7c | 286 | #endif |
wolfSSL | 15:117db924cf7c | 287 | } |
wolfSSL | 15:117db924cf7c | 288 | |
wolfSSL | 15:117db924cf7c | 289 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 290 | /* Verify signature using hash */ |
wolfSSL | 15:117db924cf7c | 291 | ret = wc_SignatureVerifyHash(hash_type, sig_type, |
wolfSSL | 15:117db924cf7c | 292 | hash_data, hash_len, sig, sig_len, key, key_len); |
wolfSSL | 15:117db924cf7c | 293 | } |
wolfSSL | 15:117db924cf7c | 294 | } |
wolfSSL | 15:117db924cf7c | 295 | |
wolfSSL | 15:117db924cf7c | 296 | if (hash_data) { |
wolfSSL | 15:117db924cf7c | 297 | XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 15:117db924cf7c | 298 | } |
wolfSSL | 15:117db924cf7c | 299 | |
wolfSSL | 15:117db924cf7c | 300 | return ret; |
wolfSSL | 15:117db924cf7c | 301 | } |
wolfSSL | 15:117db924cf7c | 302 | |
wolfSSL | 15:117db924cf7c | 303 | |
wolfSSL | 15:117db924cf7c | 304 | int wc_SignatureGenerateHash( |
wolfSSL | 15:117db924cf7c | 305 | enum wc_HashType hash_type, enum wc_SignatureType sig_type, |
wolfSSL | 15:117db924cf7c | 306 | const byte* hash_data, word32 hash_len, |
wolfSSL | 15:117db924cf7c | 307 | byte* sig, word32 *sig_len, |
wolfSSL | 15:117db924cf7c | 308 | const void* key, word32 key_len, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 309 | { |
wolfSSL | 15:117db924cf7c | 310 | int ret; |
wolfSSL | 15:117db924cf7c | 311 | |
wolfSSL | 15:117db924cf7c | 312 | /* Suppress possible unused arg if all signature types are disabled */ |
wolfSSL | 15:117db924cf7c | 313 | (void)rng; |
wolfSSL | 15:117db924cf7c | 314 | |
wolfSSL | 15:117db924cf7c | 315 | /* Check arguments */ |
wolfSSL | 15:117db924cf7c | 316 | if (hash_data == NULL || hash_len <= 0 || |
wolfSSL | 15:117db924cf7c | 317 | sig == NULL || sig_len == NULL || *sig_len <= 0 || |
wolfSSL | 15:117db924cf7c | 318 | key == NULL || key_len <= 0) { |
wolfSSL | 15:117db924cf7c | 319 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 320 | } |
wolfSSL | 15:117db924cf7c | 321 | |
wolfSSL | 15:117db924cf7c | 322 | /* Validate signature len (needs to be at least max) */ |
wolfSSL | 15:117db924cf7c | 323 | if ((int)*sig_len < wc_SignatureGetSize(sig_type, key, key_len)) { |
wolfSSL | 15:117db924cf7c | 324 | WOLFSSL_MSG("wc_SignatureGenerate: Invalid sig type/len"); |
wolfSSL | 15:117db924cf7c | 325 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 326 | } |
wolfSSL | 15:117db924cf7c | 327 | |
wolfSSL | 15:117db924cf7c | 328 | /* Validate hash size */ |
wolfSSL | 15:117db924cf7c | 329 | ret = wc_HashGetDigestSize(hash_type); |
wolfSSL | 15:117db924cf7c | 330 | if (ret < 0) { |
wolfSSL | 15:117db924cf7c | 331 | WOLFSSL_MSG("wc_SignatureGenerate: Invalid hash type/len"); |
wolfSSL | 15:117db924cf7c | 332 | return ret; |
wolfSSL | 15:117db924cf7c | 333 | } |
wolfSSL | 15:117db924cf7c | 334 | ret = 0; |
wolfSSL | 15:117db924cf7c | 335 | |
wolfSSL | 15:117db924cf7c | 336 | /* Create signature using hash as data */ |
wolfSSL | 15:117db924cf7c | 337 | switch (sig_type) { |
wolfSSL | 15:117db924cf7c | 338 | case WC_SIGNATURE_TYPE_ECC: |
wolfSSL | 15:117db924cf7c | 339 | #if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN) |
wolfSSL | 15:117db924cf7c | 340 | /* Create signature using provided ECC key */ |
wolfSSL | 15:117db924cf7c | 341 | do { |
wolfSSL | 15:117db924cf7c | 342 | #ifdef WOLFSSL_ASYNC_CRYPT |
wolfSSL | 15:117db924cf7c | 343 | ret = wc_AsyncWait(ret, &((ecc_key*)key)->asyncDev, |
wolfSSL | 15:117db924cf7c | 344 | WC_ASYNC_FLAG_CALL_AGAIN); |
wolfSSL | 15:117db924cf7c | 345 | #endif |
wolfSSL | 15:117db924cf7c | 346 | if (ret >= 0) |
wolfSSL | 15:117db924cf7c | 347 | ret = wc_ecc_sign_hash(hash_data, hash_len, sig, sig_len, |
wolfSSL | 15:117db924cf7c | 348 | rng, (ecc_key*)key); |
wolfSSL | 15:117db924cf7c | 349 | } while (ret == WC_PENDING_E); |
wolfSSL | 15:117db924cf7c | 350 | #else |
wolfSSL | 15:117db924cf7c | 351 | ret = SIG_TYPE_E; |
wolfSSL | 15:117db924cf7c | 352 | #endif |
wolfSSL | 15:117db924cf7c | 353 | break; |
wolfSSL | 15:117db924cf7c | 354 | |
wolfSSL | 15:117db924cf7c | 355 | case WC_SIGNATURE_TYPE_RSA_W_ENC: |
wolfSSL | 15:117db924cf7c | 356 | case WC_SIGNATURE_TYPE_RSA: |
wolfSSL | 15:117db924cf7c | 357 | #ifndef NO_RSA |
wolfSSL | 15:117db924cf7c | 358 | /* Create signature using provided RSA key */ |
wolfSSL | 15:117db924cf7c | 359 | do { |
wolfSSL | 15:117db924cf7c | 360 | #ifdef WOLFSSL_ASYNC_CRYPT |
wolfSSL | 15:117db924cf7c | 361 | ret = wc_AsyncWait(ret, &((RsaKey*)key)->asyncDev, |
wolfSSL | 15:117db924cf7c | 362 | WC_ASYNC_FLAG_CALL_AGAIN); |
wolfSSL | 15:117db924cf7c | 363 | #endif |
wolfSSL | 15:117db924cf7c | 364 | if (ret >= 0) |
wolfSSL | 15:117db924cf7c | 365 | ret = wc_RsaSSL_Sign(hash_data, hash_len, sig, *sig_len, |
wolfSSL | 15:117db924cf7c | 366 | (RsaKey*)key, rng); |
wolfSSL | 15:117db924cf7c | 367 | } while (ret == WC_PENDING_E); |
wolfSSL | 15:117db924cf7c | 368 | if (ret >= 0) { |
wolfSSL | 15:117db924cf7c | 369 | *sig_len = ret; |
wolfSSL | 15:117db924cf7c | 370 | ret = 0; /* Success */ |
wolfSSL | 15:117db924cf7c | 371 | } |
wolfSSL | 15:117db924cf7c | 372 | #else |
wolfSSL | 15:117db924cf7c | 373 | ret = SIG_TYPE_E; |
wolfSSL | 15:117db924cf7c | 374 | #endif |
wolfSSL | 15:117db924cf7c | 375 | break; |
wolfSSL | 15:117db924cf7c | 376 | |
wolfSSL | 15:117db924cf7c | 377 | case WC_SIGNATURE_TYPE_NONE: |
wolfSSL | 15:117db924cf7c | 378 | default: |
wolfSSL | 15:117db924cf7c | 379 | ret = BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 380 | break; |
wolfSSL | 15:117db924cf7c | 381 | } |
wolfSSL | 15:117db924cf7c | 382 | |
wolfSSL | 15:117db924cf7c | 383 | return ret; |
wolfSSL | 15:117db924cf7c | 384 | } |
wolfSSL | 15:117db924cf7c | 385 | |
wolfSSL | 15:117db924cf7c | 386 | int wc_SignatureGenerate( |
wolfSSL | 15:117db924cf7c | 387 | enum wc_HashType hash_type, enum wc_SignatureType sig_type, |
wolfSSL | 15:117db924cf7c | 388 | const byte* data, word32 data_len, |
wolfSSL | 15:117db924cf7c | 389 | byte* sig, word32 *sig_len, |
wolfSSL | 15:117db924cf7c | 390 | const void* key, word32 key_len, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 391 | { |
wolfSSL | 15:117db924cf7c | 392 | int ret; |
wolfSSL | 15:117db924cf7c | 393 | word32 hash_len; |
wolfSSL | 15:117db924cf7c | 394 | byte *hash_data = NULL; |
wolfSSL | 15:117db924cf7c | 395 | |
wolfSSL | 15:117db924cf7c | 396 | /* Check arguments */ |
wolfSSL | 15:117db924cf7c | 397 | if (data == NULL || data_len <= 0 || |
wolfSSL | 15:117db924cf7c | 398 | sig == NULL || sig_len == NULL || *sig_len <= 0 || |
wolfSSL | 15:117db924cf7c | 399 | key == NULL || key_len <= 0) { |
wolfSSL | 15:117db924cf7c | 400 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 401 | } |
wolfSSL | 15:117db924cf7c | 402 | |
wolfSSL | 15:117db924cf7c | 403 | /* Validate signature len (needs to be at least max) */ |
wolfSSL | 15:117db924cf7c | 404 | if ((int)*sig_len < wc_SignatureGetSize(sig_type, key, key_len)) { |
wolfSSL | 15:117db924cf7c | 405 | WOLFSSL_MSG("wc_SignatureGenerate: Invalid sig type/len"); |
wolfSSL | 15:117db924cf7c | 406 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 407 | } |
wolfSSL | 15:117db924cf7c | 408 | |
wolfSSL | 15:117db924cf7c | 409 | /* Validate hash size */ |
wolfSSL | 15:117db924cf7c | 410 | ret = wc_HashGetDigestSize(hash_type); |
wolfSSL | 15:117db924cf7c | 411 | if (ret < 0) { |
wolfSSL | 15:117db924cf7c | 412 | WOLFSSL_MSG("wc_SignatureGenerate: Invalid hash type/len"); |
wolfSSL | 15:117db924cf7c | 413 | return ret; |
wolfSSL | 15:117db924cf7c | 414 | } |
wolfSSL | 15:117db924cf7c | 415 | hash_len = ret; |
wolfSSL | 15:117db924cf7c | 416 | |
wolfSSL | 15:117db924cf7c | 417 | /* Allocate temporary buffer for hash data */ |
wolfSSL | 15:117db924cf7c | 418 | hash_data = (byte*)XMALLOC(hash_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 15:117db924cf7c | 419 | if (hash_data == NULL) { |
wolfSSL | 15:117db924cf7c | 420 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 421 | } |
wolfSSL | 15:117db924cf7c | 422 | |
wolfSSL | 15:117db924cf7c | 423 | /* Perform hash of data */ |
wolfSSL | 15:117db924cf7c | 424 | ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len); |
wolfSSL | 15:117db924cf7c | 425 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 426 | /* Handle RSA with DER encoding */ |
wolfSSL | 15:117db924cf7c | 427 | if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) { |
wolfSSL | 15:117db924cf7c | 428 | #if defined(NO_RSA) || defined(NO_ASN) |
wolfSSL | 15:117db924cf7c | 429 | ret = SIG_TYPE_E; |
wolfSSL | 15:117db924cf7c | 430 | #else |
wolfSSL | 15:117db924cf7c | 431 | ret = wc_SignatureDerEncode(hash_type, &hash_data, &hash_len); |
wolfSSL | 15:117db924cf7c | 432 | #endif |
wolfSSL | 15:117db924cf7c | 433 | } |
wolfSSL | 15:117db924cf7c | 434 | |
wolfSSL | 15:117db924cf7c | 435 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 436 | /* Generate signature using hash */ |
wolfSSL | 15:117db924cf7c | 437 | ret = wc_SignatureGenerateHash(hash_type, sig_type, |
wolfSSL | 15:117db924cf7c | 438 | hash_data, hash_len, sig, sig_len, key, key_len, rng); |
wolfSSL | 15:117db924cf7c | 439 | } |
wolfSSL | 15:117db924cf7c | 440 | } |
wolfSSL | 15:117db924cf7c | 441 | |
wolfSSL | 15:117db924cf7c | 442 | if (hash_data) { |
wolfSSL | 15:117db924cf7c | 443 | XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 15:117db924cf7c | 444 | } |
wolfSSL | 15:117db924cf7c | 445 | |
wolfSSL | 15:117db924cf7c | 446 | return ret; |
wolfSSL | 15:117db924cf7c | 447 | } |
wolfSSL | 15:117db924cf7c | 448 | |
wolfSSL | 15:117db924cf7c | 449 | #endif /* NO_SIG_WRAPPER */ |
wolfSSL | 15:117db924cf7c | 450 |