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.
signature.c
00001 /* signature.c 00002 * 00003 * Copyright (C) 2006-2017 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 #ifdef HAVE_CONFIG_H 00024 #include <config.h> 00025 #endif 00026 00027 #include <wolfcrypt/settings.h> 00028 #include <wolfcrypt/signature.h> 00029 #include <wolfcrypt/error-crypt.h> 00030 #include <wolfcrypt/logging.h> 00031 #ifndef NO_ASN 00032 #include <wolfcrypt/asn.h> 00033 #endif 00034 #ifdef HAVE_ECC 00035 #include <wolfcrypt/ecc.h> 00036 #endif 00037 #ifndef NO_RSA 00038 #include <wolfcrypt/rsa.h> 00039 #endif 00040 00041 /* If ECC and RSA are disabled then disable signature wrapper */ 00042 #if (!defined(HAVE_ECC) || (defined(HAVE_ECC) && !defined(HAVE_ECC_SIGN) \ 00043 && !defined(HAVE_ECC_VERIFY))) && defined(NO_RSA) 00044 #undef NO_SIG_WRAPPER 00045 #define NO_SIG_WRAPPER 00046 #endif 00047 00048 /* Signature wrapper disabled check */ 00049 #ifndef NO_SIG_WRAPPER 00050 00051 #if !defined(NO_RSA) && !defined(NO_ASN) 00052 static int wc_SignatureDerEncode(enum wc_HashType hash_type, byte** hash_data, 00053 word32* hash_len) 00054 { 00055 int ret = wc_HashGetOID(hash_type); 00056 if (ret > 0) { 00057 int oid = ret; 00058 00059 /* Allocate buffer for hash and max DER encoded */ 00060 word32 digest_len = *hash_len + MAX_DER_DIGEST_SZ; 00061 byte *digest_buf = (byte*)XMALLOC(digest_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00062 if (digest_buf) { 00063 ret = wc_EncodeSignature(digest_buf, *hash_data, *hash_len, oid); 00064 if (ret > 0) { 00065 digest_len = ret; 00066 ret = 0; 00067 00068 /* Replace hash with digest (DER encoding + hash) */ 00069 XFREE(*hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00070 *hash_data = digest_buf; 00071 *hash_len = digest_len; 00072 } 00073 else { 00074 XFREE(digest_buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00075 } 00076 } 00077 else { 00078 ret = MEMORY_E; 00079 } 00080 } 00081 return ret; 00082 } 00083 #endif /* !NO_RSA && !NO_ASN */ 00084 00085 int wc_SignatureGetSize(enum wc_SignatureType sig_type, 00086 const void* key, word32 key_len) 00087 { 00088 int sig_len = BAD_FUNC_ARG; 00089 00090 /* Suppress possible unused args if all signature types are disabled */ 00091 (void)key; 00092 (void)key_len; 00093 00094 switch(sig_type) { 00095 case WC_SIGNATURE_TYPE_ECC: 00096 #ifdef HAVE_ECC 00097 /* Sanity check that void* key is at least ecc_key in size */ 00098 if (key_len >= sizeof(ecc_key)) { 00099 sig_len = wc_ecc_sig_size((ecc_key*)key); 00100 } 00101 else { 00102 WOLFSSL_MSG("wc_SignatureGetSize: Invalid ECC key size"); 00103 } 00104 #else 00105 sig_len = SIG_TYPE_E; 00106 #endif 00107 break; 00108 00109 case WC_SIGNATURE_TYPE_RSA_W_ENC: 00110 case WC_SIGNATURE_TYPE_RSA: 00111 #ifndef NO_RSA 00112 /* Sanity check that void* key is at least RsaKey in size */ 00113 if (key_len >= sizeof(RsaKey)) { 00114 sig_len = wc_RsaEncryptSize((RsaKey*)key); 00115 } 00116 else { 00117 WOLFSSL_MSG("wc_SignatureGetSize: Invalid RsaKey key size"); 00118 } 00119 #else 00120 sig_len = SIG_TYPE_E; 00121 #endif 00122 break; 00123 00124 case WC_SIGNATURE_TYPE_NONE: 00125 default: 00126 sig_len = BAD_FUNC_ARG; 00127 break; 00128 } 00129 return sig_len; 00130 } 00131 00132 int wc_SignatureVerifyHash( 00133 enum wc_HashType hash_type, enum wc_SignatureType sig_type, 00134 const byte* hash_data, word32 hash_len, 00135 const byte* sig, word32 sig_len, 00136 const void* key, word32 key_len) 00137 { 00138 int ret; 00139 00140 /* Check arguments */ 00141 if (hash_data == NULL || hash_len <= 0 || 00142 sig == NULL || sig_len <= 0 || 00143 key == NULL || key_len <= 0) { 00144 return BAD_FUNC_ARG; 00145 } 00146 00147 /* Validate signature len (1 to max is okay) */ 00148 if ((int)sig_len > wc_SignatureGetSize(sig_type, key, key_len)) { 00149 WOLFSSL_MSG("wc_SignatureVerify: Invalid sig type/len"); 00150 return BAD_FUNC_ARG; 00151 } 00152 00153 /* Validate hash size */ 00154 ret = wc_HashGetDigestSize(hash_type); 00155 if (ret < 0) { 00156 WOLFSSL_MSG("wc_SignatureVerify: Invalid hash type/len"); 00157 return ret; 00158 } 00159 ret = 0; 00160 00161 /* Verify signature using hash */ 00162 switch (sig_type) { 00163 case WC_SIGNATURE_TYPE_ECC: 00164 { 00165 #if defined(HAVE_ECC) && defined(HAVE_ECC_VERIFY) 00166 int is_valid_sig = 0; 00167 00168 /* Perform verification of signature using provided ECC key */ 00169 do { 00170 #ifdef WOLFSSL_ASYNC_CRYPT 00171 ret = wc_AsyncWait(ret, &((ecc_key*)key)->asyncDev, 00172 WC_ASYNC_FLAG_CALL_AGAIN); 00173 #endif 00174 if (ret >= 0) 00175 ret = wc_ecc_verify_hash(sig, sig_len, hash_data, hash_len, 00176 &is_valid_sig, (ecc_key*)key); 00177 } while (ret == WC_PENDING_E); 00178 if (ret != 0 || is_valid_sig != 1) { 00179 ret = SIG_VERIFY_E; 00180 } 00181 #else 00182 ret = SIG_TYPE_E; 00183 #endif 00184 break; 00185 } 00186 00187 case WC_SIGNATURE_TYPE_RSA_W_ENC: 00188 case WC_SIGNATURE_TYPE_RSA: 00189 { 00190 #ifndef NO_RSA 00191 word32 plain_len = hash_len; 00192 byte *plain_data; 00193 00194 /* Make sure the plain text output is at least key size */ 00195 if (plain_len < sig_len) { 00196 plain_len = sig_len; 00197 } 00198 plain_data = (byte*)XMALLOC(plain_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00199 if (plain_data) { 00200 /* Perform verification of signature using provided RSA key */ 00201 do { 00202 #ifdef WOLFSSL_ASYNC_CRYPT 00203 ret = wc_AsyncWait(ret, &((RsaKey*)key)->asyncDev, 00204 WC_ASYNC_FLAG_CALL_AGAIN); 00205 #endif 00206 if (ret >= 0) 00207 ret = wc_RsaSSL_Verify(sig, sig_len, plain_data, 00208 plain_len, (RsaKey*)key); 00209 } while (ret == WC_PENDING_E); 00210 if (ret >= 0) { 00211 if ((word32)ret == hash_len && 00212 XMEMCMP(plain_data, hash_data, hash_len) == 0) { 00213 ret = 0; /* Success */ 00214 } 00215 else { 00216 WOLFSSL_MSG("RSA Signature Verify difference!"); 00217 ret = SIG_VERIFY_E; 00218 } 00219 } 00220 XFREE(plain_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00221 } 00222 else { 00223 ret = MEMORY_E; 00224 } 00225 #else 00226 ret = SIG_TYPE_E; 00227 #endif 00228 break; 00229 } 00230 00231 case WC_SIGNATURE_TYPE_NONE: 00232 default: 00233 ret = BAD_FUNC_ARG; 00234 break; 00235 } 00236 00237 return ret; 00238 } 00239 00240 int wc_SignatureVerify( 00241 enum wc_HashType hash_type, enum wc_SignatureType sig_type, 00242 const byte* data, word32 data_len, 00243 const byte* sig, word32 sig_len, 00244 const void* key, word32 key_len) 00245 { 00246 int ret; 00247 word32 hash_len; 00248 byte *hash_data = NULL; 00249 00250 /* Check arguments */ 00251 if (data == NULL || data_len <= 0 || 00252 sig == NULL || sig_len <= 0 || 00253 key == NULL || key_len <= 0) { 00254 return BAD_FUNC_ARG; 00255 } 00256 00257 /* Validate signature len (1 to max is okay) */ 00258 if ((int)sig_len > wc_SignatureGetSize(sig_type, key, key_len)) { 00259 WOLFSSL_MSG("wc_SignatureVerify: Invalid sig type/len"); 00260 return BAD_FUNC_ARG; 00261 } 00262 00263 /* Validate hash size */ 00264 ret = wc_HashGetDigestSize(hash_type); 00265 if (ret < 0) { 00266 WOLFSSL_MSG("wc_SignatureVerify: Invalid hash type/len"); 00267 return ret; 00268 } 00269 hash_len = ret; 00270 00271 /* Allocate temporary buffer for hash data */ 00272 hash_data = (byte*)XMALLOC(hash_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00273 if (hash_data == NULL) { 00274 return MEMORY_E; 00275 } 00276 00277 /* Perform hash of data */ 00278 ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len); 00279 if (ret == 0) { 00280 /* Handle RSA with DER encoding */ 00281 if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) { 00282 #if defined(NO_RSA) || defined(NO_ASN) 00283 ret = SIG_TYPE_E; 00284 #else 00285 ret = wc_SignatureDerEncode(hash_type, &hash_data, &hash_len); 00286 #endif 00287 } 00288 00289 if (ret == 0) { 00290 /* Verify signature using hash */ 00291 ret = wc_SignatureVerifyHash(hash_type, sig_type, 00292 hash_data, hash_len, sig, sig_len, key, key_len); 00293 } 00294 } 00295 00296 if (hash_data) { 00297 XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00298 } 00299 00300 return ret; 00301 } 00302 00303 00304 int wc_SignatureGenerateHash( 00305 enum wc_HashType hash_type, enum wc_SignatureType sig_type, 00306 const byte* hash_data, word32 hash_len, 00307 byte* sig, word32 *sig_len, 00308 const void* key, word32 key_len, WC_RNG* rng) 00309 { 00310 int ret; 00311 00312 /* Suppress possible unused arg if all signature types are disabled */ 00313 (void)rng; 00314 00315 /* Check arguments */ 00316 if (hash_data == NULL || hash_len <= 0 || 00317 sig == NULL || sig_len == NULL || *sig_len <= 0 || 00318 key == NULL || key_len <= 0) { 00319 return BAD_FUNC_ARG; 00320 } 00321 00322 /* Validate signature len (needs to be at least max) */ 00323 if ((int)*sig_len < wc_SignatureGetSize(sig_type, key, key_len)) { 00324 WOLFSSL_MSG("wc_SignatureGenerate: Invalid sig type/len"); 00325 return BAD_FUNC_ARG; 00326 } 00327 00328 /* Validate hash size */ 00329 ret = wc_HashGetDigestSize(hash_type); 00330 if (ret < 0) { 00331 WOLFSSL_MSG("wc_SignatureGenerate: Invalid hash type/len"); 00332 return ret; 00333 } 00334 ret = 0; 00335 00336 /* Create signature using hash as data */ 00337 switch (sig_type) { 00338 case WC_SIGNATURE_TYPE_ECC: 00339 #if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN) 00340 /* Create signature using provided ECC key */ 00341 do { 00342 #ifdef WOLFSSL_ASYNC_CRYPT 00343 ret = wc_AsyncWait(ret, &((ecc_key*)key)->asyncDev, 00344 WC_ASYNC_FLAG_CALL_AGAIN); 00345 #endif 00346 if (ret >= 0) 00347 ret = wc_ecc_sign_hash(hash_data, hash_len, sig, sig_len, 00348 rng, (ecc_key*)key); 00349 } while (ret == WC_PENDING_E); 00350 #else 00351 ret = SIG_TYPE_E; 00352 #endif 00353 break; 00354 00355 case WC_SIGNATURE_TYPE_RSA_W_ENC: 00356 case WC_SIGNATURE_TYPE_RSA: 00357 #ifndef NO_RSA 00358 /* Create signature using provided RSA key */ 00359 do { 00360 #ifdef WOLFSSL_ASYNC_CRYPT 00361 ret = wc_AsyncWait(ret, &((RsaKey*)key)->asyncDev, 00362 WC_ASYNC_FLAG_CALL_AGAIN); 00363 #endif 00364 if (ret >= 0) 00365 ret = wc_RsaSSL_Sign(hash_data, hash_len, sig, *sig_len, 00366 (RsaKey*)key, rng); 00367 } while (ret == WC_PENDING_E); 00368 if (ret >= 0) { 00369 *sig_len = ret; 00370 ret = 0; /* Success */ 00371 } 00372 #else 00373 ret = SIG_TYPE_E; 00374 #endif 00375 break; 00376 00377 case WC_SIGNATURE_TYPE_NONE: 00378 default: 00379 ret = BAD_FUNC_ARG; 00380 break; 00381 } 00382 00383 return ret; 00384 } 00385 00386 int wc_SignatureGenerate( 00387 enum wc_HashType hash_type, enum wc_SignatureType sig_type, 00388 const byte* data, word32 data_len, 00389 byte* sig, word32 *sig_len, 00390 const void* key, word32 key_len, WC_RNG* rng) 00391 { 00392 int ret; 00393 word32 hash_len; 00394 byte *hash_data = NULL; 00395 00396 /* Check arguments */ 00397 if (data == NULL || data_len <= 0 || 00398 sig == NULL || sig_len == NULL || *sig_len <= 0 || 00399 key == NULL || key_len <= 0) { 00400 return BAD_FUNC_ARG; 00401 } 00402 00403 /* Validate signature len (needs to be at least max) */ 00404 if ((int)*sig_len < wc_SignatureGetSize(sig_type, key, key_len)) { 00405 WOLFSSL_MSG("wc_SignatureGenerate: Invalid sig type/len"); 00406 return BAD_FUNC_ARG; 00407 } 00408 00409 /* Validate hash size */ 00410 ret = wc_HashGetDigestSize(hash_type); 00411 if (ret < 0) { 00412 WOLFSSL_MSG("wc_SignatureGenerate: Invalid hash type/len"); 00413 return ret; 00414 } 00415 hash_len = ret; 00416 00417 /* Allocate temporary buffer for hash data */ 00418 hash_data = (byte*)XMALLOC(hash_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00419 if (hash_data == NULL) { 00420 return MEMORY_E; 00421 } 00422 00423 /* Perform hash of data */ 00424 ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len); 00425 if (ret == 0) { 00426 /* Handle RSA with DER encoding */ 00427 if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) { 00428 #if defined(NO_RSA) || defined(NO_ASN) 00429 ret = SIG_TYPE_E; 00430 #else 00431 ret = wc_SignatureDerEncode(hash_type, &hash_data, &hash_len); 00432 #endif 00433 } 00434 00435 if (ret == 0) { 00436 /* Generate signature using hash */ 00437 ret = wc_SignatureGenerateHash(hash_type, sig_type, 00438 hash_data, hash_len, sig, sig_len, key, key_len, rng); 00439 } 00440 } 00441 00442 if (hash_data) { 00443 XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00444 } 00445 00446 return ret; 00447 } 00448 00449 #endif /* NO_SIG_WRAPPER */ 00450
Generated on Tue Jul 12 2022 16:58:07 by
1.7.2