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.
Fork of wolfSSL by
signature.c
00001 /* signature.c 00002 * 00003 * Copyright (C) 2006-2016 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 <wolfssl/wolfcrypt/settings.h> 00028 #include <wolfssl/wolfcrypt/signature.h> 00029 #include <wolfssl/wolfcrypt/error-crypt.h> 00030 #include <wolfssl/wolfcrypt/logging.h> 00031 #ifndef NO_ASN 00032 #include <wolfssl/wolfcrypt/asn.h> 00033 #endif 00034 #ifdef HAVE_ECC 00035 #include <wolfssl/wolfcrypt/ecc.h> 00036 #endif 00037 #ifndef NO_RSA 00038 #include <wolfssl/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 00067 /* Replace hash with digest (DER encoding + hash) */ 00068 XFREE(*hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00069 *hash_data = digest_buf; 00070 *hash_len = digest_len; 00071 } 00072 else { 00073 XFREE(digest_buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00074 } 00075 } 00076 else { 00077 ret = MEMORY_E; 00078 } 00079 } 00080 return ret; 00081 } 00082 #endif /* !NO_RSA && !NO_ASN */ 00083 00084 int wc_SignatureGetSize(enum wc_SignatureType sig_type, 00085 const void* key, word32 key_len) 00086 { 00087 int sig_len = BAD_FUNC_ARG; 00088 00089 /* Suppress possible unused args if all signature types are disabled */ 00090 (void)key; 00091 (void)key_len; 00092 00093 switch(sig_type) { 00094 case WC_SIGNATURE_TYPE_ECC: 00095 #ifdef HAVE_ECC 00096 /* Santity check that void* key is at least ecc_key in size */ 00097 if (key_len >= sizeof(ecc_key)) { 00098 sig_len = wc_ecc_sig_size((ecc_key*)key); 00099 } 00100 else { 00101 WOLFSSL_MSG("wc_SignatureGetSize: Invalid ECC key size"); 00102 } 00103 #else 00104 sig_len = SIG_TYPE_E; 00105 #endif 00106 break; 00107 00108 case WC_SIGNATURE_TYPE_RSA_W_ENC: 00109 case WC_SIGNATURE_TYPE_RSA: 00110 #ifndef NO_RSA 00111 /* Santity check that void* key is at least RsaKey in size */ 00112 if (key_len >= sizeof(RsaKey)) { 00113 sig_len = wc_RsaEncryptSize((RsaKey*)key); 00114 } 00115 else { 00116 WOLFSSL_MSG("wc_SignatureGetSize: Invalid RsaKey key size"); 00117 } 00118 #else 00119 sig_len = SIG_TYPE_E; 00120 #endif 00121 break; 00122 00123 case WC_SIGNATURE_TYPE_NONE: 00124 default: 00125 sig_len = BAD_FUNC_ARG; 00126 break; 00127 } 00128 return sig_len; 00129 } 00130 00131 int wc_SignatureVerify( 00132 enum wc_HashType hash_type, enum wc_SignatureType sig_type, 00133 const byte* data, word32 data_len, 00134 const byte* sig, word32 sig_len, 00135 const void* key, word32 key_len) 00136 { 00137 int ret; 00138 word32 hash_len; 00139 byte *hash_data = NULL; 00140 00141 /* Check arguments */ 00142 if (data == NULL || data_len <= 0 || 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 hash_len = ret; 00160 00161 /* Allocate temporary buffer for hash data */ 00162 hash_data = (byte*)XMALLOC(hash_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00163 if (hash_data == NULL) { 00164 return MEMORY_E; 00165 } 00166 00167 /* Perform hash of data */ 00168 ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len); 00169 if(ret == 0) { 00170 /* Verify signature using hash as data */ 00171 switch(sig_type) { 00172 case WC_SIGNATURE_TYPE_ECC: 00173 { 00174 #if defined(HAVE_ECC) && defined(HAVE_ECC_VERIFY) 00175 int is_valid_sig = 0; 00176 00177 /* Perform verification of signature using provided ECC key */ 00178 do { 00179 #ifdef WOLFSSL_ASYNC_CRYPT 00180 ret = wc_AsyncWait(ret, &((ecc_key*)key)->asyncDev, 00181 WC_ASYNC_FLAG_CALL_AGAIN); 00182 #endif 00183 if (ret >= 0) 00184 ret = wc_ecc_verify_hash(sig, sig_len, hash_data, hash_len, 00185 &is_valid_sig, (ecc_key*)key); 00186 } while (ret == WC_PENDING_E); 00187 if (ret != 0 || is_valid_sig != 1) { 00188 ret = SIG_VERIFY_E; 00189 } 00190 #else 00191 ret = SIG_TYPE_E; 00192 #endif 00193 break; 00194 } 00195 00196 case WC_SIGNATURE_TYPE_RSA_W_ENC: 00197 #if defined(NO_RSA) || defined(NO_ASN) 00198 ret = SIG_TYPE_E; 00199 break; 00200 #else 00201 ret = wc_SignatureDerEncode(hash_type, &hash_data, &hash_len); 00202 /* Check for error */ 00203 if (ret < 0) { 00204 break; 00205 } 00206 /* Otherwise fall-through and perform normal RSA verify against updated 00207 * DER encoding + hash */ 00208 #endif 00209 00210 case WC_SIGNATURE_TYPE_RSA: 00211 { 00212 #ifndef NO_RSA 00213 word32 plain_len = hash_len; 00214 byte *plain_data; 00215 00216 /* Make sure the plain text output is at least key size */ 00217 if (plain_len < sig_len) { 00218 plain_len = sig_len; 00219 } 00220 plain_data = (byte*)XMALLOC(plain_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00221 if (plain_data) { 00222 /* Perform verification of signature using provided RSA key */ 00223 do { 00224 #ifdef WOLFSSL_ASYNC_CRYPT 00225 ret = wc_AsyncWait(ret, &((RsaKey*)key)->asyncDev, 00226 WC_ASYNC_FLAG_CALL_AGAIN); 00227 #endif 00228 if (ret >= 0) 00229 ret = wc_RsaSSL_Verify(sig, sig_len, plain_data, 00230 plain_len, (RsaKey*)key); 00231 } while (ret == WC_PENDING_E); 00232 if (ret >= 0) { 00233 if ((word32)ret == hash_len && 00234 XMEMCMP(plain_data, hash_data, hash_len) == 0) { 00235 ret = 0; /* Success */ 00236 } 00237 else { 00238 WOLFSSL_MSG("RSA Signature Verify difference!"); 00239 ret = SIG_VERIFY_E; 00240 } 00241 } 00242 XFREE(plain_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00243 } 00244 else { 00245 ret = MEMORY_E; 00246 } 00247 #else 00248 ret = SIG_TYPE_E; 00249 #endif 00250 break; 00251 } 00252 00253 case WC_SIGNATURE_TYPE_NONE: 00254 default: 00255 ret = BAD_FUNC_ARG; 00256 break; 00257 } 00258 } 00259 00260 if (hash_data) { 00261 XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00262 } 00263 00264 return ret; 00265 } 00266 00267 int wc_SignatureGenerate( 00268 enum wc_HashType hash_type, enum wc_SignatureType sig_type, 00269 const byte* data, word32 data_len, 00270 byte* sig, word32 *sig_len, 00271 const void* key, word32 key_len, WC_RNG* rng) 00272 { 00273 int ret; 00274 word32 hash_len; 00275 byte *hash_data = NULL; 00276 00277 /* Suppress possible unused arg if all signature types are disabled */ 00278 (void)rng; 00279 00280 /* Check arguments */ 00281 if (data == NULL || data_len <= 0 || sig == NULL || sig_len == NULL || 00282 *sig_len <= 0 || key == NULL || key_len <= 0) { 00283 return BAD_FUNC_ARG; 00284 } 00285 00286 /* Validate signature len (needs to be at least max) */ 00287 if ((int)*sig_len < wc_SignatureGetSize(sig_type, key, key_len)) { 00288 WOLFSSL_MSG("wc_SignatureGenerate: Invalid sig type/len"); 00289 return BAD_FUNC_ARG; 00290 } 00291 00292 /* Validate hash size */ 00293 ret = wc_HashGetDigestSize(hash_type); 00294 if (ret < 0) { 00295 WOLFSSL_MSG("wc_SignatureGenerate: Invalid hash type/len"); 00296 return ret; 00297 } 00298 hash_len = ret; 00299 00300 /* Allocate temporary buffer for hash data */ 00301 hash_data = (byte*)XMALLOC(hash_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00302 if (hash_data == NULL) { 00303 return MEMORY_E; 00304 } 00305 00306 /* Perform hash of data */ 00307 ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len); 00308 if (ret == 0) { 00309 /* Create signature using hash as data */ 00310 switch(sig_type) { 00311 case WC_SIGNATURE_TYPE_ECC: 00312 #if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN) 00313 /* Create signature using provided ECC key */ 00314 do { 00315 #ifdef WOLFSSL_ASYNC_CRYPT 00316 ret = wc_AsyncWait(ret, &((ecc_key*)key)->asyncDev, 00317 WC_ASYNC_FLAG_CALL_AGAIN); 00318 #endif 00319 if (ret >= 0) 00320 ret = wc_ecc_sign_hash(hash_data, hash_len, sig, sig_len, 00321 rng, (ecc_key*)key); 00322 } while (ret == WC_PENDING_E); 00323 #else 00324 ret = SIG_TYPE_E; 00325 #endif 00326 break; 00327 00328 case WC_SIGNATURE_TYPE_RSA_W_ENC: 00329 #if defined(NO_RSA) || defined(NO_ASN) 00330 ret = SIG_TYPE_E; 00331 break; 00332 #else 00333 ret = wc_SignatureDerEncode(hash_type, &hash_data, &hash_len); 00334 /* Check for error */ 00335 if (ret < 0) { 00336 break; 00337 } 00338 /* Otherwise fall-through and perform normal RSA sign against updated 00339 * DER encoding + hash */ 00340 #endif 00341 00342 case WC_SIGNATURE_TYPE_RSA: 00343 #ifndef NO_RSA 00344 /* Create signature using provided RSA key */ 00345 do { 00346 #ifdef WOLFSSL_ASYNC_CRYPT 00347 ret = wc_AsyncWait(ret, &((RsaKey*)key)->asyncDev, 00348 WC_ASYNC_FLAG_CALL_AGAIN); 00349 #endif 00350 if (ret >= 0) 00351 ret = wc_RsaSSL_Sign(hash_data, hash_len, sig, *sig_len, 00352 (RsaKey*)key, rng); 00353 } while (ret == WC_PENDING_E); 00354 if (ret >= 0) { 00355 *sig_len = ret; 00356 ret = 0; /* Success */ 00357 } 00358 #else 00359 ret = SIG_TYPE_E; 00360 #endif 00361 break; 00362 00363 case WC_SIGNATURE_TYPE_NONE: 00364 default: 00365 ret = BAD_FUNC_ARG; 00366 break; 00367 } 00368 } 00369 00370 if (hash_data) { 00371 XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00372 } 00373 00374 return ret; 00375 } 00376 00377 #endif /* NO_SIG_WRAPPER */ 00378
Generated on Tue Jul 12 2022 23:30:59 by
1.7.2
