int ecc_sign_verify_test(enum wc_HashType hash_type, enum wc_SignatureType sig_type, const byte* fileBuf, int fileLen, byte* verifyFileBuf, int* verifyFileLen, int* pmaxSigSz, int* pmaxCurveSigSz, int curveId, int keySz) { int ret; ecc_key eccKey; RNG rng; byte* sigBuf = NULL; word32 sigLen; byte eccPubKeyBuf[ECC_BUFSIZE], eccPrivKeyBuf[ECC_BUFSIZE]; word32 eccPubKeyLen, eccPrivKeyLen; word32 maxCurveSigSz; #ifdef DEBUG_SIG_TEST printf("ECC Signature: Curve %s, Size %d\n", wc_ecc_get_name(curveId), keySz); #endif /* Init */ wc_InitRng(&rng); /* Generate key */ wc_ecc_init(&eccKey); ret = wc_ecc_make_key_ex(&rng, keySz, &eccKey, curveId); if(ret != 0) { printf("ECC Make Key Failed! %d\n", ret); goto exit; } ret = wc_ecc_sig_size(&eccKey); if (ret < 0) { printf("ECC Sig SizeFailed! %d\n", ret); goto exit; } maxCurveSigSz = ret; /* Display public key data */ eccPubKeyLen = ECC_BUFSIZE; ret = wc_ecc_export_x963(&eccKey, eccPubKeyBuf, &eccPubKeyLen); if (ret != 0) { printf("ECC public key x963 export failed! %d\n", ret); ret = EXIT_FAILURE; goto exit; } #ifdef DEBUG_SIG_TEST printf("ECC Public Key: Len %d\n", eccPubKeyLen); hexdump(eccPubKeyBuf, eccPubKeyLen, 16); #endif /* Display private key data */ eccPrivKeyLen = ECC_BUFSIZE; ret = wc_ecc_export_private_only(&eccKey, eccPrivKeyBuf, &eccPrivKeyLen); if (ret != 0) { printf("ECC private key export failed! %d\n", ret); ret = EXIT_FAILURE; goto exit; } #ifdef DEBUG_SIG_TEST printf("ECC Private Key: Len %d\n", eccPrivKeyLen); hexdump(eccPrivKeyBuf, eccPrivKeyLen, 16); #endif if (verifyFileBuf) { sigLen = *verifyFileLen; sigBuf = verifyFileBuf; } else { /* Get signature length and allocate buffer */ sigLen = wc_SignatureGetSize(sig_type, &eccKey, sizeof(eccKey)); if(sigLen <= 0) { printf("ECC Signature type %d not supported!\n", sig_type); ret = EXIT_FAILURE; goto exit; } sigBuf = malloc(sigLen); if(!sigBuf) { printf("ECC Signature malloc failed!\n"); ret = EXIT_FAILURE; goto exit; } #ifdef DEBUG_SIG_TEST printf("ECC Signature Len: %d\n", sigLen); #endif /* Perform hash and sign to create signature */ ret = wc_SignatureGenerate( hash_type, sig_type, fileBuf, fileLen, sigBuf, &sigLen, &eccKey, sizeof(eccKey), &rng); *verifyFileLen = sigLen; #ifdef DEBUG_SIG_TEST printf("ECC Signature Generation: %s (%d)\n", (ret == 0) ? "Pass" : "Fail", ret); #endif if(ret < 0) { ret = EXIT_FAILURE; goto exit; } } #ifdef DEBUG_SIG_TEST printf("Signature Data:\n"); hexdump(sigBuf, sigLen, 16); #endif /* Perform signature verification */ /* Release and init new key */ wc_ecc_free(&eccKey); wc_ecc_init(&eccKey); /* Import the public key */ ret = wc_ecc_import_x963_ex(eccPubKeyBuf, eccPubKeyLen, &eccKey, curveId); if (ret != 0) { printf("ECC public key import failed! %d\n", ret); ret = EXIT_FAILURE; goto exit; } /* Perform signature verification using public key */ ret = wc_SignatureVerify( hash_type, sig_type, fileBuf, fileLen, sigBuf, sigLen, &eccKey, sizeof(eccKey)); #ifdef DEBUG_SIG_TEST printf("ECC Signature Verification: %s (%d)\n", (ret == 0) ? "Pass" : "Fail", ret); #endif if (ret < 0) { ret = EXIT_FAILURE; } if (pmaxSigSz && *pmaxSigSz < sigLen) { #ifdef DEBUG_SIG_TEST_MAX printf("Curve: Max %d->%d\n", *pmaxSigSz, sigLen); hexdump(sigBuf, sigLen, 16); #endif *pmaxSigSz = sigLen; } if (pmaxCurveSigSz && *pmaxCurveSigSz < maxCurveSigSz) { *pmaxCurveSigSz = maxCurveSigSz; } exit: /* Free */ if(sigBuf) { free(sigBuf); } wc_ecc_free(&eccKey); wc_FreeRng(&rng); return ret; }
int main(void) { board_init(); board_console_init(BOARD_DEBUG_BAUD); SysTick_Config(BOARD_SYSTICK_100MS); PRINTF("ubirch #1 r0.2 RSA/ECC encryption/signature benchmark\r\n"); if (init_ltc() != 0) PRINTF("No LTC, may crash\r\n"); if (init_trng() != 0) error("failed to initialize TRNG"); if (init_board_key(2048) != 0) error("failed to generate key pair"); if (init_recipient_public_key(recipient_pubkey, recipient_pubkey_length)) error("failed to load recipient public key"); byte cipher[256]; // 256 bytes is large enough to store 2048 bit RSA ciphertext word32 plaintextLength = strlen(plaintext); word32 cipherLength = sizeof(cipher); PRINTF("- signing message with board private key\r\n"); uint32_t total = 0; int signatureLength = 0; byte *signature = NULL; for (int i = 0; i < BENCHMARK_LOOPS; i++) { const uint32_t start = timer_read(); signatureLength = wc_SignatureGetSize(WC_SIGNATURE_TYPE_RSA, &board_rsa_key, sizeof(board_rsa_key)); signature = malloc((size_t) signatureLength); if (wc_SignatureGenerate( WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, (const byte *) plaintext, plaintextLength, signature, (word32 *) &signatureLength, &board_rsa_key, sizeof(board_rsa_key), &rng) != 0) error("failed to sign plain text message"); const uint32_t elapsed = timer_read() - start; total += elapsed; char loop_str[64]; sprintf(loop_str, "%d", i); timestamp(loop_str, elapsed); } timestamp("Average:", total / BENCHMARK_LOOPS); PRINTF("-- SIGNATURE\r\n"); PRINTF("- encrypting message\r\n"); total = 0; int r = -1; for (int i = 0; i < BENCHMARK_LOOPS; i++) { const uint32_t start = timer_read(); r = wc_RsaPublicEncrypt((const byte *) plaintext, plaintextLength, cipher, cipherLength, &recipient_public_key, &rng); if (r < 0) error("failed to encrypt message"); const uint32_t elapsed = timer_read() - start; total += elapsed; char loop_str[64]; sprintf(loop_str, "%d", i); timestamp(loop_str, elapsed); } timestamp("Average:", total / BENCHMARK_LOOPS); PRINTF("-- CIPHER (%d bytes)\r\n", r); wc_FreeRsaKey(&board_rsa_key); wc_FreeRsaKey(&recipient_public_key); PRINTF("THE END\r\n"); while (true) { uint8_t ch = (uint8_t) GETCHAR(); if (ch == '\r') PUTCHAR('\n'); PUTCHAR(ch); } }