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-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 ret = wc_ecc_verify_hash(sig, sig_len, hash_data, hash_len, &is_valid_sig, (ecc_key*)key); 00179 if (ret != 0 || is_valid_sig != 1) { 00180 ret = SIG_VERIFY_E; 00181 } 00182 #else 00183 ret = SIG_TYPE_E; 00184 #endif 00185 break; 00186 } 00187 00188 case WC_SIGNATURE_TYPE_RSA_W_ENC: 00189 #if defined(NO_RSA) || defined(NO_ASN) 00190 ret = SIG_TYPE_E; 00191 break; 00192 #else 00193 ret = wc_SignatureDerEncode(hash_type, &hash_data, &hash_len); 00194 /* Check for error */ 00195 if (ret < 0) { 00196 break; 00197 } 00198 /* Otherwise fall-through and perform normal RSA verify against updated 00199 * DER encoding + hash */ 00200 #endif 00201 00202 case WC_SIGNATURE_TYPE_RSA: 00203 { 00204 #ifndef NO_RSA 00205 word32 plain_len = hash_len; 00206 byte *plain_data; 00207 00208 /* Make sure the plain text output is at least key size */ 00209 if (plain_len < sig_len) { 00210 plain_len = sig_len; 00211 } 00212 plain_data = (byte*)XMALLOC(hash_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00213 if (plain_data) { 00214 /* Perform verification of signature using provided RSA key */ 00215 ret = wc_RsaSSL_Verify(sig, sig_len, plain_data, plain_len, 00216 (RsaKey*)key); 00217 if (ret >= 0) { 00218 if ((word32)ret == hash_len && 00219 XMEMCMP(plain_data, hash_data, hash_len) == 0) { 00220 ret = 0; /* Success */ 00221 } 00222 else { 00223 WOLFSSL_MSG("RSA Signature Verify difference!"); 00224 ret = SIG_VERIFY_E; 00225 } 00226 } 00227 XFREE(plain_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00228 } 00229 else { 00230 ret = MEMORY_E; 00231 } 00232 #else 00233 ret = SIG_TYPE_E; 00234 #endif 00235 break; 00236 } 00237 00238 case WC_SIGNATURE_TYPE_NONE: 00239 default: 00240 ret = BAD_FUNC_ARG; 00241 break; 00242 } 00243 } 00244 00245 if (hash_data) { 00246 XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00247 } 00248 00249 return ret; 00250 } 00251 00252 int wc_SignatureGenerate( 00253 enum wc_HashType hash_type, enum wc_SignatureType sig_type, 00254 const byte* data, word32 data_len, 00255 byte* sig, word32 *sig_len, 00256 const void* key, word32 key_len, WC_RNG* rng) 00257 { 00258 int ret; 00259 word32 hash_len; 00260 byte *hash_data = NULL; 00261 00262 /* Suppress possible unused arg if all signature types are disabled */ 00263 (void)rng; 00264 00265 /* Check arguments */ 00266 if (data == NULL || data_len <= 0 || sig == NULL || sig_len == NULL || 00267 *sig_len <= 0 || key == NULL || key_len <= 0) { 00268 return BAD_FUNC_ARG; 00269 } 00270 00271 /* Validate signature len (needs to be at least max) */ 00272 if ((int)*sig_len < wc_SignatureGetSize(sig_type, key, key_len)) { 00273 WOLFSSL_MSG("wc_SignatureGenerate: Invalid sig type/len"); 00274 return BAD_FUNC_ARG; 00275 } 00276 00277 /* Validate hash size */ 00278 ret = wc_HashGetDigestSize(hash_type); 00279 if (ret < 0) { 00280 WOLFSSL_MSG("wc_SignatureGenerate: Invalid hash type/len"); 00281 return ret; 00282 } 00283 hash_len = ret; 00284 00285 /* Allocate temporary buffer for hash data */ 00286 hash_data = (byte*)XMALLOC(hash_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00287 if (hash_data == NULL) { 00288 return MEMORY_E; 00289 } 00290 00291 /* Perform hash of data */ 00292 ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len); 00293 if (ret == 0) { 00294 /* Create signature using hash as data */ 00295 switch(sig_type) { 00296 case WC_SIGNATURE_TYPE_ECC: 00297 #if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN) 00298 /* Create signature using provided ECC key */ 00299 ret = wc_ecc_sign_hash(hash_data, hash_len, sig, sig_len, rng, (ecc_key*)key); 00300 #else 00301 ret = SIG_TYPE_E; 00302 #endif 00303 break; 00304 00305 case WC_SIGNATURE_TYPE_RSA_W_ENC: 00306 #if defined(NO_RSA) || defined(NO_ASN) 00307 ret = SIG_TYPE_E; 00308 break; 00309 #else 00310 ret = wc_SignatureDerEncode(hash_type, &hash_data, &hash_len); 00311 /* Check for error */ 00312 if (ret < 0) { 00313 break; 00314 } 00315 /* Otherwise fall-through and perform normal RSA sign against updated 00316 * DER encoding + hash */ 00317 #endif 00318 00319 case WC_SIGNATURE_TYPE_RSA: 00320 #ifndef NO_RSA 00321 /* Create signature using provided RSA key */ 00322 ret = wc_RsaSSL_Sign(hash_data, hash_len, sig, *sig_len, (RsaKey*)key, rng); 00323 if (ret >= 0) { 00324 *sig_len = ret; 00325 ret = 0; /* Success */ 00326 } 00327 #else 00328 ret = SIG_TYPE_E; 00329 #endif 00330 break; 00331 00332 case WC_SIGNATURE_TYPE_NONE: 00333 default: 00334 ret = BAD_FUNC_ARG; 00335 break; 00336 } 00337 } 00338 00339 if (hash_data) { 00340 XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00341 } 00342 00343 return ret; 00344 } 00345 00346 #endif /* NO_SIG_WRAPPER */ 00347
Generated on Tue Jul 12 2022 15:55:20 by
1.7.2