int main(int argc, char** argv) { int ret = 0; int fileLen; byte* fileBuf = NULL; int verifyFileLen; byte* verifyFileBuf = NULL; const char* verify_file = NULL; enum wc_SignatureType sig_type = WC_SIGNATURE_TYPE_NONE; enum wc_HashType hash_type = WC_HASH_TYPE_NONE; sig_type = WC_SIGNATURE_TYPE_ECC; hash_type = WC_HASH_TYPE_SHA256; #if 0 wolfSSL_Debugging_ON(); #endif /* Check arguments */ if (argc < 2) { printf("Usage: eccsiglentest <filename>\n"); return 1; } /* Verify hash type is supported */ if (wc_HashGetDigestSize(hash_type) <= 0) { printf("Hash type %d not supported!\n", hash_type); return 1; } printf("Signature Length Test: Loops %d\n", ECC_LOOP_COUNT); /* Load input file */ ret = load_file_to_buffer(argv[1], &fileBuf, &fileLen); if (ret < 0) { goto exit; } /* Load verify signature file (optional) */ if (verify_file) { ret = load_file_to_buffer(verify_file, &verifyFileBuf, &verifyFileLen); if (ret < 0) { goto exit; } } /* Perform sign and verify */ switch(sig_type) { #ifdef HAVE_ECC case WC_SIGNATURE_TYPE_ECC: { int curveId; int sigSz = verifyFileLen; #if 1 for (curveId=ECC_SECP192R1; curveId<=ECC_BRAINPOOLP512R1; curveId++) #else curveId = ECC_SECP521R1; #endif { int keySz = wc_ecc_get_curve_size_from_id(curveId); if (keySz > 0) { int maxSigSz = 0; int maxCurveSigSz = 0; int tries = ECC_LOOP_COUNT; while (--tries > 0) { ret = ecc_sign_verify_test(hash_type, sig_type, fileBuf, fileLen, verifyFileBuf, &sigSz, &maxSigSz, &maxCurveSigSz, curveId, keySz); } /* print max */ printf("ECC Curve %s, KeySz %d, Sig: CurveMax %d, ActMax %d, CalcMax %d\n", wc_ecc_get_name(curveId), keySz, maxCurveSigSz, maxSigSz, wc_ecc_sig_size_calc(keySz)); } } } break; #endif default: ret = EXIT_FAILURE; printf("Signature type %d, not supported!\n", sig_type); } exit: /* Free */ if (fileBuf) { free(fileBuf); } return ret; }
/* Generic Hashing Wrapper */ int wc_Hash(enum wc_HashType hash_type, const byte* data, word32 data_len, byte* hash, word32 hash_len) { int ret = HASH_TYPE_E; /* Default to hash type error */ word32 dig_size; /* Validate hash buffer size */ dig_size = wc_HashGetDigestSize(hash_type); if (hash_len < dig_size) { return BUFFER_E; } /* Suppress possible unused arg if all hashing is disabled */ (void)data; (void)data_len; (void)hash; (void)hash_len; switch(hash_type) { case WC_HASH_TYPE_MD5: #ifndef NO_MD5 ret = wc_Md5Hash(data, data_len, hash); #endif break; case WC_HASH_TYPE_SHA: #ifndef NO_SHA ret = wc_ShaHash(data, data_len, hash); #endif break; case WC_HASH_TYPE_SHA224: #ifdef WOLFSSL_SHA224 ret = wc_Sha224Hash(data, data_len, hash); #endif break; case WC_HASH_TYPE_SHA256: #ifndef NO_SHA256 ret = wc_Sha256Hash(data, data_len, hash); #endif break; case WC_HASH_TYPE_SHA384: #if defined(WOLFSSL_SHA512) && defined(WOLFSSL_SHA384) ret = wc_Sha384Hash(data, data_len, hash); #endif break; case WC_HASH_TYPE_SHA512: #ifdef WOLFSSL_SHA512 ret = wc_Sha512Hash(data, data_len, hash); #endif break; case WC_HASH_TYPE_MD5_SHA: #if !defined(NO_MD5) && !defined(NO_SHA) ret = wc_Md5Hash(data, data_len, hash); if (ret == 0) { ret = wc_ShaHash(data, data_len, &hash[MD5_DIGEST_SIZE]); } #endif break; /* Not Supported */ case WC_HASH_TYPE_MD2: case WC_HASH_TYPE_MD4: case WC_HASH_TYPE_NONE: default: ret = BAD_FUNC_ARG; break; } return ret; }
int wc_SignatureVerify( enum wc_HashType hash_type, enum wc_SignatureType sig_type, const byte* data, word32 data_len, const byte* sig, word32 sig_len, const void* key, word32 key_len) { int ret, hash_len; byte *hash_data = NULL; /* Check arguments */ if (data == NULL || data_len <= 0 || sig == NULL || sig_len <= 0 || key == NULL || key_len <= 0) { return BAD_FUNC_ARG; } /* Validate signature len (1 to max is okay) */ if ((int)sig_len > wc_SignatureGetSize(sig_type, key, key_len)) { WOLFSSL_MSG("wc_SignatureVerify: Invalid sig type/len"); return BAD_FUNC_ARG; } /* Validate hash size */ hash_len = wc_HashGetDigestSize(hash_type); if (hash_len <= 0) { WOLFSSL_MSG("wc_SignatureVerify: Invalid hash type/len"); return BAD_FUNC_ARG; } /* Allocate temporary buffer for hash data */ hash_data = XMALLOC(hash_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (hash_data == NULL) { return MEMORY_E; } /* Perform hash of data */ ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len); if(ret == 0) { /* Verify signature using hash as data */ switch(sig_type) { #ifdef HAVE_ECC case WC_SIGNATURE_TYPE_ECC: { int is_valid_sig = 0; /* Perform verification of signature using provided ECC key */ ret = wc_ecc_verify_hash(sig, sig_len, hash_data, hash_len, &is_valid_sig, (ecc_key*)key); if (ret != 0 || is_valid_sig != 1) { ret = SIG_VERIFY_E; } break; } #endif #ifndef NO_RSA case WC_SIGNATURE_TYPE_RSA: { byte *plain_data = XMALLOC(hash_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (plain_data) { /* Perform verification of signature using provided RSA key */ ret = wc_RsaSSL_Verify(sig, sig_len, plain_data, hash_len, (RsaKey*)key); if (ret != hash_len || XMEMCMP(plain_data, hash_data, hash_len) != 0) { ret = SIG_VERIFY_E; } XFREE(plain_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); } else { ret = MEMORY_E; } break; } #endif case WC_SIGNATURE_TYPE_NONE: default: ret = BAD_FUNC_ARG; break; } } if (hash_data) { XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); } return ret; }
/* Generic Hashing Wrapper */ int wc_Hash(enum wc_HashType hash_type, const byte* data, word32 data_len, byte* hash, word32 hash_len) { int ret = BAD_FUNC_ARG; word32 dig_size; /* Validate hash buffer size */ dig_size = wc_HashGetDigestSize(hash_type); if (hash_len < dig_size) { return BUFFER_E; } /* Supress possible unused arg if all hashing is disabled */ (void)data; (void)data_len; (void)hash; (void)hash_len; switch(hash_type) { #ifndef NO_MD5 case WC_HASH_TYPE_MD5: ret = wc_Md5Hash(data, data_len, hash); break; #endif #ifndef NO_SHA case WC_HASH_TYPE_SHA: ret = wc_ShaHash(data, data_len, hash); break; #endif #ifndef NO_SHA256 case WC_HASH_TYPE_SHA256: ret = wc_Sha256Hash(data, data_len, hash); break; #endif #ifdef WOLFSSL_SHA512 #ifdef WOLFSSL_SHA384 case WC_HASH_TYPE_SHA384: ret = wc_Sha384Hash(data, data_len, hash); break; #endif /* WOLFSSL_SHA384 */ case WC_HASH_TYPE_SHA512: ret = wc_Sha512Hash(data, data_len, hash); break; #endif /* WOLFSSL_SHA512 */ /* Not Supported */ #ifdef WOLFSSL_MD2 case WC_HASH_TYPE_MD2: #endif #ifndef NO_MD4 case WC_HASH_TYPE_MD4: #endif case WC_HASH_TYPE_NONE: default: WOLFSSL_MSG("wc_Hash: Bad hash type"); ret = BAD_FUNC_ARG; break; } return ret; }
int wc_SignatureGenerate( enum wc_HashType hash_type, enum wc_SignatureType sig_type, const byte* data, word32 data_len, byte* sig, word32 *sig_len, const void* key, word32 key_len, RNG* rng) { int ret, hash_len; byte *hash_data = NULL; /* Supress possible unused arg if all signature types are disabled */ (void)rng; /* Check arguments */ if (data == NULL || data_len <= 0 || sig == NULL || sig_len == NULL || *sig_len <= 0 || key == NULL || key_len <= 0) { return BAD_FUNC_ARG; } /* Validate signature len (needs to be at least max) */ if ((int)*sig_len < wc_SignatureGetSize(sig_type, key, key_len)) { WOLFSSL_MSG("wc_SignatureGenerate: Invalid sig type/len"); return BAD_FUNC_ARG; } /* Validate hash size */ hash_len = wc_HashGetDigestSize(hash_type); if (hash_len <= 0) { WOLFSSL_MSG("wc_SignatureGenerate: Invalid hash type/len"); return BAD_FUNC_ARG; } /* Allocate temporary buffer for hash data */ hash_data = XMALLOC(hash_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (hash_data == NULL) { return MEMORY_E; } /* Perform hash of data */ ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len); if (ret == 0) { /* Create signature using hash as data */ switch(sig_type) { #ifdef HAVE_ECC case WC_SIGNATURE_TYPE_ECC: { /* Create signature using provided ECC key */ ret = wc_ecc_sign_hash(hash_data, hash_len, sig, sig_len, rng, (ecc_key*)key); break; } #endif #ifndef NO_RSA case WC_SIGNATURE_TYPE_RSA: /* Create signature using provided RSA key */ ret = wc_RsaSSL_Sign(hash_data, hash_len, sig, *sig_len, (RsaKey*)key, rng); if (ret > 0) { *sig_len = ret; } break; #endif case WC_SIGNATURE_TYPE_NONE: default: ret = BAD_FUNC_ARG; break; } } if (hash_data) { XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); } return ret; }