X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=FreeRTOS-Plus%2FSource%2FCyaSSL%2Fctaocrypt%2Ftest%2Ftest.c;h=7f7191cb02a75c5640a35ea68da382b8fe604bbc;hb=00f677e0ada95522edf37c288392d92b4d6e18c5;hp=ddb3e0149635aef1ceabefc984e014f6740d21a4;hpb=14c3bded7a00a2833d54febe3b8442e75e52c89c;p=freertos diff --git a/FreeRTOS-Plus/Source/CyaSSL/ctaocrypt/test/test.c b/FreeRTOS-Plus/Source/CyaSSL/ctaocrypt/test/test.c index ddb3e0149..7f7191cb0 100644 --- a/FreeRTOS-Plus/Source/CyaSSL/ctaocrypt/test/test.c +++ b/FreeRTOS-Plus/Source/CyaSSL/ctaocrypt/test/test.c @@ -1,6 +1,6 @@ /* test.c * - * Copyright (C) 2006-2012 Sawtooth Consulting Ltd. + * Copyright (C) 2006-2014 wolfSSL Inc. * * This file is part of CyaSSL. * @@ -16,16 +16,20 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifdef HAVE_CONFIG_H #include #endif -#include -#include -#include +#include + +#ifdef XMALLOC_USER + #include /* we're using malloc / free direct here */ +#endif + +#ifndef NO_CRYPT_TEST #ifdef CYASSL_TEST_CERT #include @@ -44,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -53,7 +58,16 @@ #include #ifdef HAVE_ECC #include -#endif +#endif +#ifdef HAVE_BLAKE2 + #include +#endif +#ifdef HAVE_LIBZ + #include +#endif +#ifdef HAVE_PKCS7 + #include +#endif #ifdef _MSC_VER /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */ @@ -67,8 +81,40 @@ #include #endif + +#if defined(USE_CERT_BUFFERS_1024) || defined(USE_CERT_BUFFERS_2048) + /* include test cert and key buffers for use with NO_FILESYSTEM */ + #if defined(CYASSL_MDK_ARM) + #include "cert_data.h" + /* use certs_test.c for initial data, so other + commands can share the data. */ + #else + #include + #endif +#endif + +#if defined(CYASSL_MDK_ARM) + #include + #include + extern FILE * CyaSSL_fopen(const char *fname, const char *mode) ; + #define fopen CyaSSL_fopen +#endif + #ifdef HAVE_NTRU - #include "crypto_ntru.h" + #include "ntru_crypto.h" +#endif +#ifdef HAVE_CAVIUM + #include "cavium_sysdep.h" + #include "cavium_common.h" + #include "cavium_ioctl.h" +#endif + +#ifdef FREESCALE_MQX + #include + #include + #include +#else + #include #endif @@ -79,49 +125,77 @@ #define printf dc_log_printf #endif +#include "ctaocrypt/test/test.h" + typedef struct testVector { - char* input; - char* output; + const char* input; + const char* output; size_t inLen; size_t outLen; } testVector; -int md2_test(); -int md5_test(); -int md4_test(); -int sha_test(); -int sha256_test(); -int sha512_test(); -int sha384_test(); -int hmac_test(); -int arc4_test(); -int hc128_test(); -int rabbit_test(); -int des_test(); -int des3_test(); -int aes_test(); -int aesgcm_test(); -int rsa_test(); -int dh_test(); -int dsa_test(); -int random_test(); -int pwdbased_test(); -int ripemd_test(); -int openssl_test(); /* test mini api */ +int md2_test(void); +int md5_test(void); +int md4_test(void); +int sha_test(void); +int sha256_test(void); +int sha512_test(void); +int sha384_test(void); +int hmac_md5_test(void); +int hmac_sha_test(void); +int hmac_sha256_test(void); +int hmac_sha384_test(void); +int hmac_sha512_test(void); +int hmac_blake2b_test(void); +int hkdf_test(void); +int arc4_test(void); +int hc128_test(void); +int rabbit_test(void); +int des_test(void); +int des3_test(void); +int aes_test(void); +int aesgcm_test(void); +int gmac_test(void); +int aesccm_test(void); +int camellia_test(void); +int rsa_test(void); +int dh_test(void); +int dsa_test(void); +int random_test(void); +int pwdbased_test(void); +int ripemd_test(void); +int openssl_test(void); /* test mini api */ +int pbkdf1_test(void); +int pkcs12_test(void); +int pbkdf2_test(void); #ifdef HAVE_ECC - int ecc_test(); + int ecc_test(void); + #ifdef HAVE_ECC_ENCRYPT + int ecc_encrypt_test(void); + #endif +#endif +#ifdef HAVE_BLAKE2 + int blake2b_test(void); +#endif +#ifdef HAVE_LIBZ + int compress_test(void); +#endif +#ifdef HAVE_PKCS7 + int pkcs7enveloped_test(void); + int pkcs7signed_test(void); #endif -int PemToDer(const char* inName, const char* outName); -void err_sys(const char* msg, int es) +static void err_sys(const char* msg, int es) { printf("%s error = %d\n", msg, es); -#ifndef THREADX - exit(es); -#endif + #if !defined(THREADX) && !defined(CYASSL_MDK_ARM) + if (msg) + exit(es); + #endif + return; } /* func_args from test.h, so don't have to pull in other junk */ @@ -132,186 +206,333 @@ typedef struct func_args { } func_args; + void ctaocrypt_test(void* args) { int ret = 0; ((func_args*)args)->return_code = -1; /* error state */ +#if !defined(NO_BIG_INT) if (CheckCtcSettings() != 1) err_sys("Build vs runtime math mismatch\n", -1234); #ifdef USE_FAST_MATH if (CheckFastMathSettings() != 1) err_sys("Build vs runtime fastmath FP_MAX_BITS mismatch\n", -1235); -#endif - - if ( (ret = md5_test()) ) +#endif /* USE_FAST_MATH */ +#endif /* !NO_BIG_INT */ + + +#ifndef NO_MD5 + if ( (ret = md5_test()) != 0) err_sys("MD5 test failed!\n", ret); else printf( "MD5 test passed!\n"); +#endif #ifdef CYASSL_MD2 - if ( (ret = md2_test()) ) + if ( (ret = md2_test()) != 0) err_sys("MD2 test failed!\n", ret); else printf( "MD2 test passed!\n"); #endif #ifndef NO_MD4 - if ( (ret = md4_test()) ) + if ( (ret = md4_test()) != 0) err_sys("MD4 test failed!\n", ret); else printf( "MD4 test passed!\n"); #endif - if ( (ret = sha_test()) ) +#ifndef NO_SHA + if ( (ret = sha_test()) != 0) err_sys("SHA test failed!\n", ret); else printf( "SHA test passed!\n"); +#endif #ifndef NO_SHA256 - if ( (ret = sha256_test()) ) + if ( (ret = sha256_test()) != 0) err_sys("SHA-256 test failed!\n", ret); else printf( "SHA-256 test passed!\n"); #endif #ifdef CYASSL_SHA384 - if ( (ret = sha384_test()) ) + if ( (ret = sha384_test()) != 0) err_sys("SHA-384 test failed!\n", ret); else printf( "SHA-384 test passed!\n"); #endif #ifdef CYASSL_SHA512 - if ( (ret = sha512_test()) ) + if ( (ret = sha512_test()) != 0) err_sys("SHA-512 test failed!\n", ret); else printf( "SHA-512 test passed!\n"); #endif #ifdef CYASSL_RIPEMD - if ( (ret = ripemd_test()) ) + if ( (ret = ripemd_test()) != 0) err_sys("RIPEMD test failed!\n", ret); else printf( "RIPEMD test passed!\n"); #endif +#ifdef HAVE_BLAKE2 + if ( (ret = blake2b_test()) != 0) + err_sys("BLAKE2b test failed!\n", ret); + else + printf( "BLAKE2b test passed!\n"); +#endif + #ifndef NO_HMAC - if ( (ret = hmac_test()) ) - err_sys("HMAC test failed!\n", ret); + #ifndef NO_MD5 + if ( (ret = hmac_md5_test()) != 0) + err_sys("HMAC-MD5 test failed!\n", ret); + else + printf( "HMAC-MD5 test passed!\n"); + #endif + + #ifndef NO_SHA + if ( (ret = hmac_sha_test()) != 0) + err_sys("HMAC-SHA test failed!\n", ret); else - printf( "HMAC test passed!\n"); + printf( "HMAC-SHA test passed!\n"); + #endif + + #ifndef NO_SHA256 + if ( (ret = hmac_sha256_test()) != 0) + err_sys("HMAC-SHA256 test failed!\n", ret); + else + printf( "HMAC-SHA256 test passed!\n"); + #endif + + #ifdef CYASSL_SHA384 + if ( (ret = hmac_sha384_test()) != 0) + err_sys("HMAC-SHA384 test failed!\n", ret); + else + printf( "HMAC-SHA384 test passed!\n"); + #endif + + #ifdef CYASSL_SHA512 + if ( (ret = hmac_sha512_test()) != 0) + err_sys("HMAC-SHA512 test failed!\n", ret); + else + printf( "HMAC-SHA512 test passed!\n"); + #endif + + #ifdef HAVE_BLAKE2 + if ( (ret = hmac_blake2b_test()) != 0) + err_sys("HMAC-BLAKE2 test failed!\n", ret); + else + printf( "HMAC-BLAKE2 test passed!\n"); + #endif + + #ifdef HAVE_HKDF + if ( (ret = hkdf_test()) != 0) + err_sys("HMAC-KDF test failed!\n", ret); + else + printf( "HMAC-KDF test passed!\n"); + #endif + +#endif + +#ifdef HAVE_AESGCM + if ( (ret = gmac_test()) != 0) + err_sys("GMAC test passed!\n", ret); + else + printf( "GMAC test passed!\n"); #endif - if ( (ret = arc4_test()) ) +#ifndef NO_RC4 + if ( (ret = arc4_test()) != 0) err_sys("ARC4 test failed!\n", ret); else printf( "ARC4 test passed!\n"); +#endif #ifndef NO_HC128 - if ( (ret = hc128_test()) ) + if ( (ret = hc128_test()) != 0) err_sys("HC-128 test failed!\n", ret); else printf( "HC-128 test passed!\n"); #endif #ifndef NO_RABBIT - if ( (ret = rabbit_test()) ) + if ( (ret = rabbit_test()) != 0) err_sys("Rabbit test failed!\n", ret); else printf( "Rabbit test passed!\n"); #endif #ifndef NO_DES3 - if ( (ret = des_test()) ) + if ( (ret = des_test()) != 0) err_sys("DES test failed!\n", ret); else printf( "DES test passed!\n"); #endif #ifndef NO_DES3 - if ( (ret = des3_test()) ) + if ( (ret = des3_test()) != 0) err_sys("DES3 test failed!\n", ret); else printf( "DES3 test passed!\n"); #endif #ifndef NO_AES - if ( (ret = aes_test()) ) + if ( (ret = aes_test()) != 0) err_sys("AES test failed!\n", ret); else printf( "AES test passed!\n"); #ifdef HAVE_AESGCM - if ( (ret = aesgcm_test()) ) + if ( (ret = aesgcm_test()) != 0) err_sys("AES-GCM test failed!\n", ret); else printf( "AES-GCM test passed!\n"); #endif + +#ifdef HAVE_AESCCM + if ( (ret = aesccm_test()) != 0) + err_sys("AES-CCM test failed!\n", ret); + else + printf( "AES-CCM test passed!\n"); +#endif +#endif + +#ifdef HAVE_CAMELLIA + if ( (ret = camellia_test()) != 0) + err_sys("CAMELLIA test failed!\n", ret); + else + printf( "CAMELLIA test passed!\n"); #endif - if ( (ret = random_test()) ) + if ( (ret = random_test()) != 0) err_sys("RANDOM test failed!\n", ret); else printf( "RANDOM test passed!\n"); - if ( (ret = rsa_test()) ) +#ifndef NO_RSA + if ( (ret = rsa_test()) != 0) err_sys("RSA test failed!\n", ret); else printf( "RSA test passed!\n"); +#endif #ifndef NO_DH - if ( (ret = dh_test()) ) + if ( (ret = dh_test()) != 0) err_sys("DH test failed!\n", ret); else printf( "DH test passed!\n"); #endif #ifndef NO_DSA - if ( (ret = dsa_test()) ) + if ( (ret = dsa_test()) != 0) err_sys("DSA test failed!\n", ret); else printf( "DSA test passed!\n"); #endif - + #ifndef NO_PWDBASED - if ( (ret = pwdbased_test()) ) + if ( (ret = pwdbased_test()) != 0) err_sys("PWDBASED test failed!\n", ret); else printf( "PWDBASED test passed!\n"); #endif - + #ifdef OPENSSL_EXTRA - if ( (ret = openssl_test()) ) + if ( (ret = openssl_test()) != 0) err_sys("OPENSSL test failed!\n", ret); else printf( "OPENSSL test passed!\n"); #endif #ifdef HAVE_ECC - if ( (ret = ecc_test()) ) + if ( (ret = ecc_test()) != 0) err_sys("ECC test failed!\n", ret); else printf( "ECC test passed!\n"); + #ifdef HAVE_ECC_ENCRYPT + if ( (ret = ecc_encrypt_test()) != 0) + err_sys("ECC Enc test failed!\n", ret); + else + printf( "ECC Enc test passed!\n"); + #endif +#endif + +#ifdef HAVE_LIBZ + if ( (ret = compress_test()) != 0) + err_sys("COMPRESS test failed!\n", ret); + else + printf( "COMPRESS test passed!\n"); +#endif + +#ifdef HAVE_PKCS7 + if ( (ret = pkcs7enveloped_test()) != 0) + err_sys("PKCS7enveloped test failed!\n", ret); + else + printf( "PKCS7enveloped test passed!\n"); + + if ( (ret = pkcs7signed_test()) != 0) + err_sys("PKCS7signed test failed!\n", ret); + else + printf( "PKCS7signed test passed!\n"); #endif ((func_args*)args)->return_code = ret; } -/* so overall tests can pull in test function */ #ifndef NO_MAIN_DRIVER +#ifdef HAVE_CAVIUM + +static int OpenNitroxDevice(int dma_mode,int dev_id) +{ + Csp1CoreAssignment core_assign; + Uint32 device; + + if (CspInitialize(CAVIUM_DIRECT,CAVIUM_DEV_ID)) + return -1; + if (Csp1GetDevType(&device)) + return -1; + if (device != NPX_DEVICE) { + if (ioctl(gpkpdev_hdlr[CAVIUM_DEV_ID], IOCTL_CSP1_GET_CORE_ASSIGNMENT, + (Uint32 *)&core_assign)!= 0) + return -1; + } + CspShutdown(CAVIUM_DEV_ID); + + return CspInitialize(dma_mode, dev_id); +} + +#endif /* HAVE_CAVIUM */ + + /* so overall tests can pull in test function */ + int main(int argc, char** argv) { + func_args args; + +#ifdef HAVE_CAVIUM + int ret = OpenNitroxDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID); + if (ret != 0) + err_sys("Cavium OpenNitroxDevice failed", -1236); +#endif /* HAVE_CAVIUM */ + args.argc = argc; args.argv = argv; ctaocrypt_test(&args); + +#ifdef HAVE_CAVIUM + CspShutdown(CAVIUM_DEV_ID); +#endif + return args.return_code; } @@ -332,45 +553,45 @@ int md2_test() a.output = "\x83\x50\xe5\xa3\xe2\x4c\x15\x3d\xf2\x27\x5c\x9f\x80\x69" "\x27\x73"; a.inLen = strlen(a.input); - a.outLen = strlen(a.output); + a.outLen = MD2_DIGEST_SIZE; b.input = "a"; b.output = "\x32\xec\x01\xec\x4a\x6d\xac\x72\xc0\xab\x96\xfb\x34\xc0" "\xb5\xd1"; b.inLen = strlen(b.input); - b.outLen = strlen(b.output); + b.outLen = MD2_DIGEST_SIZE; c.input = "abc"; c.output = "\xda\x85\x3b\x0d\x3f\x88\xd9\x9b\x30\x28\x3a\x69\xe6\xde" "\xd6\xbb"; c.inLen = strlen(c.input); - c.outLen = strlen(c.output); + c.outLen = MD2_DIGEST_SIZE; d.input = "message digest"; d.output = "\xab\x4f\x49\x6b\xfb\x2a\x53\x0b\x21\x9f\xf3\x30\x31\xfe" "\x06\xb0"; d.inLen = strlen(d.input); - d.outLen = strlen(d.output); + d.outLen = MD2_DIGEST_SIZE; e.input = "abcdefghijklmnopqrstuvwxyz"; e.output = "\x4e\x8d\xdf\xf3\x65\x02\x92\xab\x5a\x41\x08\xc3\xaa\x47" "\x94\x0b"; e.inLen = strlen(e.input); - e.outLen = strlen(e.output); + e.outLen = MD2_DIGEST_SIZE; f.input = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345" "6789"; f.output = "\xda\x33\xde\xf2\xa4\x2d\xf1\x39\x75\x35\x28\x46\xc3\x03" "\x38\xcd"; f.inLen = strlen(f.input); - f.outLen = strlen(f.output); + f.outLen = MD2_DIGEST_SIZE; g.input = "1234567890123456789012345678901234567890123456789012345678" "9012345678901234567890"; g.output = "\xd5\x97\x6f\x79\xd8\x3d\x3a\x0d\xc9\x80\x6c\x3c\x66\xf3" "\xef\xd8"; g.inLen = strlen(g.input); - g.outLen = strlen(g.output); + g.outLen = MD2_DIGEST_SIZE; test_md2[0] = a; test_md2[1] = b; @@ -392,10 +613,10 @@ int md2_test() return 0; } -#endif - +#endif -int md5_test() +#ifndef NO_MD5 +int md5_test(void) { Md5 md5; byte hash[MD5_DIGEST_SIZE]; @@ -408,33 +629,33 @@ int md5_test() a.output = "\x90\x01\x50\x98\x3c\xd2\x4f\xb0\xd6\x96\x3f\x7d\x28\xe1\x7f" "\x72"; a.inLen = strlen(a.input); - a.outLen = strlen(a.output); + a.outLen = MD5_DIGEST_SIZE; b.input = "message digest"; b.output = "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d\x52\x5a\x2f\x31\xaa\xf1\x61" "\xd0"; b.inLen = strlen(b.input); - b.outLen = strlen(b.output); + b.outLen = MD5_DIGEST_SIZE; c.input = "abcdefghijklmnopqrstuvwxyz"; c.output = "\xc3\xfc\xd3\xd7\x61\x92\xe4\x00\x7d\xfb\x49\x6c\xca\x67\xe1" "\x3b"; c.inLen = strlen(c.input); - c.outLen = strlen(c.output); + c.outLen = MD5_DIGEST_SIZE; d.input = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345" "6789"; d.output = "\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d" "\x9f"; d.inLen = strlen(d.input); - d.outLen = strlen(d.output); + d.outLen = MD5_DIGEST_SIZE; e.input = "1234567890123456789012345678901234567890123456789012345678" "9012345678901234567890"; e.output = "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55\xac\x49\xda\x2e\x21\x07\xb6" "\x7a"; e.inLen = strlen(e.input); - e.outLen = strlen(e.output); + e.outLen = MD5_DIGEST_SIZE; test_md5[0] = a; test_md5[1] = b; @@ -454,11 +675,12 @@ int md5_test() return 0; } +#endif /* NO_MD5 */ #ifndef NO_MD4 -int md4_test() +int md4_test(void) { Md4 md4; byte hash[MD4_DIGEST_SIZE]; @@ -468,48 +690,48 @@ int md4_test() int times = sizeof(test_md4) / sizeof(testVector), i; a.input = ""; - a.output = "\x31\xd6\xcf\xe0\xd1\x6a\xe9\x31\xb7\x3c\x59\xd7\xe0\xc0\x89" + a.output = "\x31\xd6\xcf\xe0\xd1\x6a\xe9\x31\xb7\x3c\x59\xd7\xe0\xc0\x89" "\xc0"; a.inLen = strlen(a.input); - a.outLen = strlen(a.output); + a.outLen = MD4_DIGEST_SIZE; b.input = "a"; - b.output = "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46\x24\x5e\x05\xfb\xdb\xd6\xfb" + b.output = "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46\x24\x5e\x05\xfb\xdb\xd6\xfb" "\x24"; b.inLen = strlen(b.input); - b.outLen = strlen(b.output); + b.outLen = MD4_DIGEST_SIZE; c.input = "abc"; - c.output = "\xa4\x48\x01\x7a\xaf\x21\xd8\x52\x5f\xc1\x0a\xe8\x7a\xa6\x72" + c.output = "\xa4\x48\x01\x7a\xaf\x21\xd8\x52\x5f\xc1\x0a\xe8\x7a\xa6\x72" "\x9d"; c.inLen = strlen(c.input); - c.outLen = strlen(c.output); + c.outLen = MD4_DIGEST_SIZE; d.input = "message digest"; - d.output = "\xd9\x13\x0a\x81\x64\x54\x9f\xe8\x18\x87\x48\x06\xe1\xc7\x01" + d.output = "\xd9\x13\x0a\x81\x64\x54\x9f\xe8\x18\x87\x48\x06\xe1\xc7\x01" "\x4b"; d.inLen = strlen(d.input); - d.outLen = strlen(d.output); + d.outLen = MD4_DIGEST_SIZE; e.input = "abcdefghijklmnopqrstuvwxyz"; - e.output = "\xd7\x9e\x1c\x30\x8a\xa5\xbb\xcd\xee\xa8\xed\x63\xdf\x41\x2d" + e.output = "\xd7\x9e\x1c\x30\x8a\xa5\xbb\xcd\xee\xa8\xed\x63\xdf\x41\x2d" "\xa9"; e.inLen = strlen(e.input); - e.outLen = strlen(e.output); + e.outLen = MD4_DIGEST_SIZE; f.input = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345" "6789"; - f.output = "\x04\x3f\x85\x82\xf2\x41\xdb\x35\x1c\xe6\x27\xe1\x53\xe7\xf0" + f.output = "\x04\x3f\x85\x82\xf2\x41\xdb\x35\x1c\xe6\x27\xe1\x53\xe7\xf0" "\xe4"; f.inLen = strlen(f.input); - f.outLen = strlen(f.output); + f.outLen = MD4_DIGEST_SIZE; g.input = "1234567890123456789012345678901234567890123456789012345678" "9012345678901234567890"; - g.output = "\xe3\x3b\x4d\xdc\x9c\x38\xf2\x19\x9c\x3e\x7b\x16\x4f\xcc\x05" + g.output = "\xe3\x3b\x4d\xdc\x9c\x38\xf2\x19\x9c\x3e\x7b\x16\x4f\xcc\x05" "\x36"; g.inLen = strlen(g.input); - g.outLen = strlen(g.output); + g.outLen = MD4_DIGEST_SIZE; test_md4[0] = a; test_md4[1] = b; @@ -534,33 +756,36 @@ int md4_test() #endif /* NO_MD4 */ -int sha_test() +#ifndef NO_SHA + +int sha_test(void) { Sha sha; byte hash[SHA_DIGEST_SIZE]; testVector a, b, c, d; testVector test_sha[4]; + int ret; int times = sizeof(test_sha) / sizeof(struct testVector), i; a.input = "abc"; a.output = "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2" "\x6C\x9C\xD0\xD8\x9D"; a.inLen = strlen(a.input); - a.outLen = strlen(a.output); + a.outLen = SHA_DIGEST_SIZE; b.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; b.output = "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29" "\xE5\xE5\x46\x70\xF1"; b.inLen = strlen(b.input); - b.outLen = strlen(b.output); + b.outLen = SHA_DIGEST_SIZE; c.input = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaa"; c.output = "\x00\x98\xBA\x82\x4B\x5C\x16\x42\x7B\xD7\xA1\x12\x2A\x5A\x44" "\x2A\x25\xEC\x64\x4D"; c.inLen = strlen(c.input); - c.outLen = strlen(c.output); + c.outLen = SHA_DIGEST_SIZE; d.input = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" @@ -568,14 +793,16 @@ int sha_test() d.output = "\xAD\x5B\x3F\xDB\xCB\x52\x67\x78\xC2\x83\x9D\x2F\x15\x1E\xA7" "\x53\x99\x5E\x26\xA0"; d.inLen = strlen(d.input); - d.outLen = strlen(d.output); + d.outLen = SHA_DIGEST_SIZE; test_sha[0] = a; test_sha[1] = b; test_sha[2] = c; test_sha[3] = d; - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return -4001; for (i = 0; i < times; ++i) { ShaUpdate(&sha, (byte*)test_sha[i].input, (word32)test_sha[i].inLen); @@ -588,9 +815,10 @@ int sha_test() return 0; } +#endif /* NO_SHA */ #ifdef CYASSL_RIPEMD -int ripemd_test() +int ripemd_test(void) { RipeMd ripemd; byte hash[RIPEMD_DIGEST_SIZE]; @@ -603,26 +831,26 @@ int ripemd_test() a.output = "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04\x4a\x8e\x98\xc6" "\xb0\x87\xf1\x5a\x0b\xfc"; a.inLen = strlen(a.input); - a.outLen = strlen(a.output); + a.outLen = RIPEMD_DIGEST_SIZE; b.input = "message digest"; b.output = "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8\x81\xb1\x23\xa8" "\x5f\xfa\x21\x59\x5f\x36"; b.inLen = strlen(b.input); - b.outLen = strlen(b.output); + b.outLen = RIPEMD_DIGEST_SIZE; - c.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + c.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; c.output = "\x12\xa0\x53\x38\x4a\x9c\x0c\x88\xe4\x05\xa0\x6c\x27\xdc" "\xf4\x9a\xda\x62\xeb\x2b"; c.inLen = strlen(c.input); - c.outLen = strlen(c.output); + c.outLen = RIPEMD_DIGEST_SIZE; d.input = "12345678901234567890123456789012345678901234567890123456" "789012345678901234567890"; d.output = "\x9b\x75\x2e\x45\x57\x3d\x4b\x39\xf4\xdb\xd3\x32\x3c\xab" - "\x82\xbf\x63\x32\x6b\xfb"; + "\x82\xbf\x63\x32\x6b\xfb"; d.inLen = strlen(d.input); - d.outLen = strlen(d.output); + d.outLen = RIPEMD_DIGEST_SIZE; test_ripemd[0] = a; test_ripemd[1] = b; @@ -645,14 +873,89 @@ int ripemd_test() #endif /* CYASSL_RIPEMD */ +#ifdef HAVE_BLAKE2 + + +#define BLAKE2_TESTS 3 + +static const byte blake2b_vec[BLAKE2_TESTS][BLAKE2B_OUTBYTES] = +{ + { + 0x78, 0x6A, 0x02, 0xF7, 0x42, 0x01, 0x59, 0x03, + 0xC6, 0xC6, 0xFD, 0x85, 0x25, 0x52, 0xD2, 0x72, + 0x91, 0x2F, 0x47, 0x40, 0xE1, 0x58, 0x47, 0x61, + 0x8A, 0x86, 0xE2, 0x17, 0xF7, 0x1F, 0x54, 0x19, + 0xD2, 0x5E, 0x10, 0x31, 0xAF, 0xEE, 0x58, 0x53, + 0x13, 0x89, 0x64, 0x44, 0x93, 0x4E, 0xB0, 0x4B, + 0x90, 0x3A, 0x68, 0x5B, 0x14, 0x48, 0xB7, 0x55, + 0xD5, 0x6F, 0x70, 0x1A, 0xFE, 0x9B, 0xE2, 0xCE + }, + { + 0x2F, 0xA3, 0xF6, 0x86, 0xDF, 0x87, 0x69, 0x95, + 0x16, 0x7E, 0x7C, 0x2E, 0x5D, 0x74, 0xC4, 0xC7, + 0xB6, 0xE4, 0x8F, 0x80, 0x68, 0xFE, 0x0E, 0x44, + 0x20, 0x83, 0x44, 0xD4, 0x80, 0xF7, 0x90, 0x4C, + 0x36, 0x96, 0x3E, 0x44, 0x11, 0x5F, 0xE3, 0xEB, + 0x2A, 0x3A, 0xC8, 0x69, 0x4C, 0x28, 0xBC, 0xB4, + 0xF5, 0xA0, 0xF3, 0x27, 0x6F, 0x2E, 0x79, 0x48, + 0x7D, 0x82, 0x19, 0x05, 0x7A, 0x50, 0x6E, 0x4B + }, + { + 0x1C, 0x08, 0x79, 0x8D, 0xC6, 0x41, 0xAB, 0xA9, + 0xDE, 0xE4, 0x35, 0xE2, 0x25, 0x19, 0xA4, 0x72, + 0x9A, 0x09, 0xB2, 0xBF, 0xE0, 0xFF, 0x00, 0xEF, + 0x2D, 0xCD, 0x8E, 0xD6, 0xF8, 0xA0, 0x7D, 0x15, + 0xEA, 0xF4, 0xAE, 0xE5, 0x2B, 0xBF, 0x18, 0xAB, + 0x56, 0x08, 0xA6, 0x19, 0x0F, 0x70, 0xB9, 0x04, + 0x86, 0xC8, 0xA7, 0xD4, 0x87, 0x37, 0x10, 0xB1, + 0x11, 0x5D, 0x3D, 0xEB, 0xBB, 0x43, 0x27, 0xB5 + } +}; + + + +int blake2b_test(void) +{ + Blake2b b2b; + byte digest[64]; + byte input[64]; + int i, ret; + + for (i = 0; i < (int)sizeof(input); i++) + input[i] = (byte)i; + + for (i = 0; i < BLAKE2_TESTS; i++) { + ret = InitBlake2b(&b2b, 64); + if (ret != 0) + return -4002; + + ret = Blake2bUpdate(&b2b, input, i); + if (ret != 0) + return -4003; + + ret = Blake2bFinal(&b2b, digest, 64); + if (ret != 0) + return -4004; + + if (memcmp(digest, blake2b_vec[i], 64) != 0) { + return -300 - i; + } + } + + return 0; +} +#endif /* HAVE_BLAKE2 */ + + #ifndef NO_SHA256 -int sha256_test() +int sha256_test(void) { Sha256 sha; byte hash[SHA256_DIGEST_SIZE]; testVector a, b; testVector test_sha[2]; + int ret; int times = sizeof(test_sha) / sizeof(struct testVector), i; a.input = "abc"; @@ -660,23 +963,29 @@ int sha256_test() "\x23\xB0\x03\x61\xA3\x96\x17\x7A\x9C\xB4\x10\xFF\x61\xF2\x00" "\x15\xAD"; a.inLen = strlen(a.input); - a.outLen = strlen(a.output); + a.outLen = SHA256_DIGEST_SIZE; b.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; b.output = "\x24\x8D\x6A\x61\xD2\x06\x38\xB8\xE5\xC0\x26\x93\x0C\x3E\x60" "\x39\xA3\x3C\xE4\x59\x64\xFF\x21\x67\xF6\xEC\xED\xD4\x19\xDB" "\x06\xC1"; b.inLen = strlen(b.input); - b.outLen = strlen(b.output); + b.outLen = SHA256_DIGEST_SIZE; test_sha[0] = a; test_sha[1] = b; - InitSha256(&sha); + ret = InitSha256(&sha); + if (ret != 0) + return -4005; for (i = 0; i < times; ++i) { - Sha256Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen); - Sha256Final(&sha, hash); + ret = Sha256Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen); + if (ret != 0) + return -4006; + ret = Sha256Final(&sha, hash); + if (ret != 0) + return -4007; if (memcmp(hash, test_sha[i].output, SHA256_DIGEST_SIZE) != 0) return -10 - i; @@ -688,10 +997,11 @@ int sha256_test() #ifdef CYASSL_SHA512 -int sha512_test() +int sha512_test(void) { Sha512 sha; byte hash[SHA512_DIGEST_SIZE]; + int ret; testVector a, b; testVector test_sha[2]; @@ -704,7 +1014,7 @@ int sha512_test() "\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f" "\xa5\x4c\xa4\x9f"; a.inLen = strlen(a.input); - a.outLen = strlen(a.output); + a.outLen = SHA512_DIGEST_SIZE; b.input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; @@ -712,18 +1022,25 @@ int sha512_test() "\x3f\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88" "\x90\x18\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4" "\xb5\x43\x3a\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b" - "\x87\x4b\xe9\x09"; + "\x87\x4b\xe9\x09"; b.inLen = strlen(b.input); - b.outLen = strlen(b.output); + b.outLen = SHA512_DIGEST_SIZE; test_sha[0] = a; test_sha[1] = b; - InitSha512(&sha); + ret = InitSha512(&sha); + if (ret != 0) + return -4009; for (i = 0; i < times; ++i) { - Sha512Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen); - Sha512Final(&sha, hash); + ret = Sha512Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen); + if (ret != 0) + return -4010; + + ret = Sha512Final(&sha, hash); + if (ret != 0) + return -4011; if (memcmp(hash, test_sha[i].output, SHA512_DIGEST_SIZE) != 0) return -10 - i; @@ -735,10 +1052,11 @@ int sha512_test() #ifdef CYASSL_SHA384 -int sha384_test() +int sha384_test(void) { Sha384 sha; byte hash[SHA384_DIGEST_SIZE]; + int ret; testVector a, b; testVector test_sha[2]; @@ -750,7 +1068,7 @@ int sha384_test() "\x5b\xed\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34" "\xc8\x25\xa7"; a.inLen = strlen(a.input); - a.outLen = strlen(a.output); + a.outLen = SHA384_DIGEST_SIZE; b.input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; @@ -759,16 +1077,23 @@ int sha384_test() "\xf7\x12\xfc\xc7\xc7\x1a\x55\x7e\x2d\xb9\x66\xc3\xe9\xfa\x91" "\x74\x60\x39"; b.inLen = strlen(b.input); - b.outLen = strlen(b.output); + b.outLen = SHA384_DIGEST_SIZE; test_sha[0] = a; test_sha[1] = b; - InitSha384(&sha); + ret = InitSha384(&sha); + if (ret != 0) + return -4012; for (i = 0; i < times; ++i) { - Sha384Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen); - Sha384Final(&sha, hash); + ret = Sha384Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen); + if (ret != 0) + return -4013; + + ret = Sha384Final(&sha, hash); + if (ret != 0) + return -4014; if (memcmp(hash, test_sha[i].output, SHA384_DIGEST_SIZE) != 0) return -10 - i; @@ -779,8 +1104,8 @@ int sha384_test() #endif /* CYASSL_SHA384 */ -#ifndef NO_HMAC -int hmac_test() +#if !defined(NO_HMAC) && !defined(NO_MD5) +int hmac_md5_test(void) { Hmac hmac; byte hash[MD5_DIGEST_SIZE]; @@ -795,19 +1120,20 @@ int hmac_test() testVector a, b, c; testVector test_hmac[3]; + int ret; int times = sizeof(test_hmac) / sizeof(testVector), i; a.input = "Hi There"; a.output = "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc" "\x9d"; a.inLen = strlen(a.input); - a.outLen = strlen(a.output); + a.outLen = MD5_DIGEST_SIZE; b.input = "what do ya want for nothing?"; b.output = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7" "\x38"; b.inLen = strlen(b.input); - b.outLen = strlen(b.output); + b.outLen = MD5_DIGEST_SIZE; c.input = "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" @@ -816,178 +1142,614 @@ int hmac_test() c.output = "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3" "\xf6"; c.inLen = strlen(c.input); - c.outLen = strlen(c.output); + c.outLen = MD5_DIGEST_SIZE; test_hmac[0] = a; test_hmac[1] = b; test_hmac[2] = c; for (i = 0; i < times; ++i) { - HmacSetKey(&hmac, MD5, (byte*)keys[i], (word32)strlen(keys[i])); - HmacUpdate(&hmac, (byte*)test_hmac[i].input, +#if defined(HAVE_FIPS) || defined(HAVE_CAVIUM) + if (i == 1) + continue; /* cavium can't handle short keys, fips not allowed */ +#endif +#ifdef HAVE_CAVIUM + if (HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) + return -20009; +#endif + ret = HmacSetKey(&hmac, MD5, (byte*)keys[i], (word32)strlen(keys[i])); + if (ret != 0) + return -4015; + ret = HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); - HmacFinal(&hmac, hash); + if (ret != 0) + return -4016; + ret = HmacFinal(&hmac, hash); + if (ret != 0) + return -4017; if (memcmp(hash, test_hmac[i].output, MD5_DIGEST_SIZE) != 0) return -20 - i; +#ifdef HAVE_CAVIUM + HmacFreeCavium(&hmac); +#endif } return 0; } -#endif - +#endif /* NO_HMAC && NO_MD5 */ -int arc4_test() +#if !defined(NO_HMAC) && !defined(NO_SHA) +int hmac_sha_test(void) { - byte cipher[16]; - byte plain[16]; + Hmac hmac; + byte hash[SHA_DIGEST_SIZE]; - const char* keys[] = - { - "\x01\x23\x45\x67\x89\xab\xcd\xef", - "\x01\x23\x45\x67\x89\xab\xcd\xef", - "\x00\x00\x00\x00\x00\x00\x00\x00", - "\xef\x01\x23\x45" + const char* keys[]= + { + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b", + "Jefe", + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA" }; - testVector a, b, c, d; - testVector test_arc4[4]; + testVector a, b, c; + testVector test_hmac[3]; - int times = sizeof(test_arc4) / sizeof(testVector), i; + int ret; + int times = sizeof(test_hmac) / sizeof(testVector), i; - a.input = "\x01\x23\x45\x67\x89\xab\xcd\xef"; - a.output = "\x75\xb7\x87\x80\x99\xe0\xc5\x96"; + a.input = "Hi There"; + a.output = "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c" + "\x8e\xf1\x46\xbe\x00"; a.inLen = strlen(a.input); - a.outLen = strlen(a.output); + a.outLen = SHA_DIGEST_SIZE; - b.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; - b.output = "\x74\x94\xc2\xe7\x10\x4b\x08\x79"; + b.input = "what do ya want for nothing?"; + b.output = "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf" + "\x9c\x25\x9a\x7c\x79"; b.inLen = strlen(b.input); - b.outLen = strlen(b.output); + b.outLen = SHA_DIGEST_SIZE; - c.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; - c.output = "\xde\x18\x89\x41\xa3\x37\x5d\x3a"; + c.input = "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD"; + c.output = "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b" + "\x4f\x63\xf1\x75\xd3"; c.inLen = strlen(c.input); - c.outLen = strlen(c.output); - - d.input = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; - d.output = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf\xbd\x61"; - d.inLen = strlen(d.input); - d.outLen = strlen(d.output); + c.outLen = SHA_DIGEST_SIZE; - test_arc4[0] = a; - test_arc4[1] = b; - test_arc4[2] = c; - test_arc4[3] = d; + test_hmac[0] = a; + test_hmac[1] = b; + test_hmac[2] = c; for (i = 0; i < times; ++i) { - Arc4 enc; - Arc4 dec; - - Arc4SetKey(&enc, (byte*)keys[i], (word32)strlen(keys[i])); - Arc4SetKey(&dec, (byte*)keys[i], (word32)strlen(keys[i])); - - Arc4Process(&enc, cipher, (byte*)test_arc4[i].input, - (word32)test_arc4[i].outLen); - Arc4Process(&dec, plain, cipher, (word32)test_arc4[i].outLen); +#if defined(HAVE_FIPS) || defined(HAVE_CAVIUM) + if (i == 1) + continue; /* cavium can't handle short keys, fips not allowed */ +#endif +#ifdef HAVE_CAVIUM + if (HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) + return -20010; +#endif + ret = HmacSetKey(&hmac, SHA, (byte*)keys[i], (word32)strlen(keys[i])); + if (ret != 0) + return -4018; + ret = HmacUpdate(&hmac, (byte*)test_hmac[i].input, + (word32)test_hmac[i].inLen); + if (ret != 0) + return -4019; + ret = HmacFinal(&hmac, hash); + if (ret != 0) + return -4020; - if (memcmp(plain, test_arc4[i].input, test_arc4[i].outLen)) + if (memcmp(hash, test_hmac[i].output, SHA_DIGEST_SIZE) != 0) return -20 - i; - - if (memcmp(cipher, test_arc4[i].output, test_arc4[i].outLen)) - return -20 - 5 - i; +#ifdef HAVE_CAVIUM + HmacFreeCavium(&hmac); +#endif } return 0; } +#endif -int hc128_test() +#if !defined(NO_HMAC) && !defined(NO_SHA256) +int hmac_sha256_test(void) { -#ifdef HAVE_HC128 - byte cipher[16]; - byte plain[16]; - - const char* keys[] = - { - "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", - "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD", - "\x0F\x62\xB5\x08\x5B\xAE\x01\x54\xA7\xFA\x4D\xA0\xF3\x46\x99\xEC" - }; + Hmac hmac; + byte hash[SHA256_DIGEST_SIZE]; - const char* ivs[] = + const char* keys[]= { - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", - "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", - "\x0D\x74\xDB\x42\xA9\x10\x77\xDE\x45\xAC\x13\x7A\xE1\x48\xAF\x16", - "\x28\x8F\xF6\x5D\xC4\x2B\x92\xF9\x60\xC7\x2E\x95\xFC\x63\xCA\x31" + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b", + "Jefe", + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA" }; + testVector a, b, c; + testVector test_hmac[3]; - testVector a, b, c, d; - testVector test_hc128[4]; - - int times = sizeof(test_hc128) / sizeof(testVector), i; + int ret; + int times = sizeof(test_hmac) / sizeof(testVector), i; - a.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; - a.output = "\x37\x86\x02\xB9\x8F\x32\xA7\x48"; + a.input = "Hi There"; + a.output = "\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1" + "\x2b\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32" + "\xcf\xf7"; a.inLen = strlen(a.input); - a.outLen = strlen(a.output); + a.outLen = SHA256_DIGEST_SIZE; - b.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; - b.output = "\x33\x7F\x86\x11\xC6\xED\x61\x5F"; + b.input = "what do ya want for nothing?"; + b.output = "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75" + "\xc7\x5a\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec" + "\x38\x43"; b.inLen = strlen(b.input); - b.outLen = strlen(b.output); + b.outLen = SHA256_DIGEST_SIZE; - c.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; - c.output = "\x2E\x1E\xD1\x2A\x85\x51\xC0\x5A"; + c.input = "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD"; + c.output = "\x77\x3e\xa9\x1e\x36\x80\x0e\x46\x85\x4d\xb8\xeb\xd0\x91\x81" + "\xa7\x29\x59\x09\x8b\x3e\xf8\xc1\x22\xd9\x63\x55\x14\xce\xd5" + "\x65\xfe"; c.inLen = strlen(c.input); - c.outLen = strlen(c.output); - - d.input = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; - d.output = "\x1C\xD8\xAE\xDD\xFE\x52\xE2\x17\xE8\x35\xD0\xB7\xE8\x4E\x29"; - d.inLen = strlen(d.input); - d.outLen = strlen(d.output); + c.outLen = SHA256_DIGEST_SIZE; - test_hc128[0] = a; - test_hc128[1] = b; - test_hc128[2] = c; - test_hc128[3] = d; + test_hmac[0] = a; + test_hmac[1] = b; + test_hmac[2] = c; for (i = 0; i < times; ++i) { - HC128 enc; - HC128 dec; - - Hc128_SetKey(&enc, (byte*)keys[i], (byte*)ivs[i]); - Hc128_SetKey(&dec, (byte*)keys[i], (byte*)ivs[i]); - - Hc128_Process(&enc, cipher, (byte*)test_hc128[i].input, - (word32)test_hc128[i].outLen); - Hc128_Process(&dec, plain, cipher, (word32)test_hc128[i].outLen); - - if (memcmp(plain, test_hc128[i].input, test_hc128[i].outLen)) - return -120 - i; +#if defined(HAVE_FIPS) || defined(HAVE_CAVIUM) + if (i == 1) + continue; /* cavium can't handle short keys, fips not allowed */ +#endif +#ifdef HAVE_CAVIUM + if (HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) + return -20011; +#endif + ret = HmacSetKey(&hmac, SHA256, (byte*)keys[i],(word32)strlen(keys[i])); + if (ret != 0) + return -4021; + ret = HmacUpdate(&hmac, (byte*)test_hmac[i].input, + (word32)test_hmac[i].inLen); + if (ret != 0) + return -4022; + ret = HmacFinal(&hmac, hash); + if (ret != 0) + return -4023; - if (memcmp(cipher, test_hc128[i].output, test_hc128[i].outLen)) - return -120 - 5 - i; + if (memcmp(hash, test_hmac[i].output, SHA256_DIGEST_SIZE) != 0) + return -20 - i; +#ifdef HAVE_CAVIUM + HmacFreeCavium(&hmac); +#endif } -#endif /* HAVE_HC128 */ return 0; } +#endif -#ifndef NO_RABBIT -int rabbit_test() +#if !defined(NO_HMAC) && defined(HAVE_BLAKE2) +int hmac_blake2b_test(void) { - byte cipher[16]; - byte plain[16]; + Hmac hmac; + byte hash[BLAKE2B_256]; - const char* keys[] = - { - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + const char* keys[]= + { + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b", + "Jefe", + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA" + }; + + testVector a, b, c; + testVector test_hmac[3]; + + int ret; + int times = sizeof(test_hmac) / sizeof(testVector), i; + + a.input = "Hi There"; + a.output = "\x72\x93\x0d\xdd\xf5\xf7\xe1\x78\x38\x07\x44\x18\x0b\x3f\x51" + "\x37\x25\xb5\x82\xc2\x08\x83\x2f\x1c\x99\xfd\x03\xa0\x16\x75" + "\xac\xfd"; + a.inLen = strlen(a.input); + a.outLen = BLAKE2B_256; + + b.input = "what do ya want for nothing?"; + b.output = "\x3d\x20\x50\x71\x05\xc0\x8c\x0c\x38\x44\x1e\xf7\xf9\xd1\x67" + "\x21\xff\x64\xf5\x94\x00\xcf\xf9\x75\x41\xda\x88\x61\x9d\x7c" + "\xda\x2b"; + b.inLen = strlen(b.input); + b.outLen = BLAKE2B_256; + + c.input = "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD"; + c.output = "\xda\xfe\x2a\x24\xfc\xe7\xea\x36\x34\xbe\x41\x92\xc7\x11\xa7" + "\x00\xae\x53\x9c\x11\x9c\x80\x74\x55\x22\x25\x4a\xb9\x55\xd3" + "\x0f\x87"; + c.inLen = strlen(c.input); + c.outLen = BLAKE2B_256; + + test_hmac[0] = a; + test_hmac[1] = b; + test_hmac[2] = c; + + for (i = 0; i < times; ++i) { +#if defined(HAVE_FIPS) || defined(HAVE_CAVIUM) + if (i == 1) + continue; /* cavium can't handle short keys, fips not allowed */ +#endif +#ifdef HAVE_CAVIUM + if (HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) + return -20011; +#endif + ret = HmacSetKey(&hmac, BLAKE2B_ID, (byte*)keys[i], + (word32)strlen(keys[i])); + if (ret != 0) + return -4024; + ret = HmacUpdate(&hmac, (byte*)test_hmac[i].input, + (word32)test_hmac[i].inLen); + if (ret != 0) + return -4025; + ret = HmacFinal(&hmac, hash); + if (ret != 0) + return -4026; + + if (memcmp(hash, test_hmac[i].output, BLAKE2B_256) != 0) + return -20 - i; +#ifdef HAVE_CAVIUM + HmacFreeCavium(&hmac); +#endif + } + + return 0; +} +#endif + + +#if !defined(NO_HMAC) && defined(CYASSL_SHA384) +int hmac_sha384_test(void) +{ + Hmac hmac; + byte hash[SHA384_DIGEST_SIZE]; + + const char* keys[]= + { + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b", + "Jefe", + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA" + }; + + testVector a, b, c; + testVector test_hmac[3]; + + int ret; + int times = sizeof(test_hmac) / sizeof(testVector), i; + + a.input = "Hi There"; + a.output = "\xaf\xd0\x39\x44\xd8\x48\x95\x62\x6b\x08\x25\xf4\xab\x46\x90" + "\x7f\x15\xf9\xda\xdb\xe4\x10\x1e\xc6\x82\xaa\x03\x4c\x7c\xeb" + "\xc5\x9c\xfa\xea\x9e\xa9\x07\x6e\xde\x7f\x4a\xf1\x52\xe8\xb2" + "\xfa\x9c\xb6"; + a.inLen = strlen(a.input); + a.outLen = SHA384_DIGEST_SIZE; + + b.input = "what do ya want for nothing?"; + b.output = "\xaf\x45\xd2\xe3\x76\x48\x40\x31\x61\x7f\x78\xd2\xb5\x8a\x6b" + "\x1b\x9c\x7e\xf4\x64\xf5\xa0\x1b\x47\xe4\x2e\xc3\x73\x63\x22" + "\x44\x5e\x8e\x22\x40\xca\x5e\x69\xe2\xc7\x8b\x32\x39\xec\xfa" + "\xb2\x16\x49"; + b.inLen = strlen(b.input); + b.outLen = SHA384_DIGEST_SIZE; + + c.input = "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD"; + c.output = "\x88\x06\x26\x08\xd3\xe6\xad\x8a\x0a\xa2\xac\xe0\x14\xc8\xa8" + "\x6f\x0a\xa6\x35\xd9\x47\xac\x9f\xeb\xe8\x3e\xf4\xe5\x59\x66" + "\x14\x4b\x2a\x5a\xb3\x9d\xc1\x38\x14\xb9\x4e\x3a\xb6\xe1\x01" + "\xa3\x4f\x27"; + c.inLen = strlen(c.input); + c.outLen = SHA384_DIGEST_SIZE; + + test_hmac[0] = a; + test_hmac[1] = b; + test_hmac[2] = c; + + for (i = 0; i < times; ++i) { +#if defined(HAVE_FIPS) + if (i == 1) + continue; /* fips not allowed */ +#endif + ret = HmacSetKey(&hmac, SHA384, (byte*)keys[i],(word32)strlen(keys[i])); + if (ret != 0) + return -4027; + ret = HmacUpdate(&hmac, (byte*)test_hmac[i].input, + (word32)test_hmac[i].inLen); + if (ret != 0) + return -4028; + ret = HmacFinal(&hmac, hash); + if (ret != 0) + return -4029; + + if (memcmp(hash, test_hmac[i].output, SHA384_DIGEST_SIZE) != 0) + return -20 - i; + } + + return 0; +} +#endif + + +#if !defined(NO_HMAC) && defined(CYASSL_SHA512) +int hmac_sha512_test(void) +{ + Hmac hmac; + byte hash[SHA512_DIGEST_SIZE]; + + const char* keys[]= + { + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b", + "Jefe", + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA" + }; + + testVector a, b, c; + testVector test_hmac[3]; + + int ret; + int times = sizeof(test_hmac) / sizeof(testVector), i; + + a.input = "Hi There"; + a.output = "\x87\xaa\x7c\xde\xa5\xef\x61\x9d\x4f\xf0\xb4\x24\x1a\x1d\x6c" + "\xb0\x23\x79\xf4\xe2\xce\x4e\xc2\x78\x7a\xd0\xb3\x05\x45\xe1" + "\x7c\xde\xda\xa8\x33\xb7\xd6\xb8\xa7\x02\x03\x8b\x27\x4e\xae" + "\xa3\xf4\xe4\xbe\x9d\x91\x4e\xeb\x61\xf1\x70\x2e\x69\x6c\x20" + "\x3a\x12\x68\x54"; + a.inLen = strlen(a.input); + a.outLen = SHA512_DIGEST_SIZE; + + b.input = "what do ya want for nothing?"; + b.output = "\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2\xe3\x95\xfb\xe7\x3b\x56\xe0" + "\xa3\x87\xbd\x64\x22\x2e\x83\x1f\xd6\x10\x27\x0c\xd7\xea\x25" + "\x05\x54\x97\x58\xbf\x75\xc0\x5a\x99\x4a\x6d\x03\x4f\x65\xf8" + "\xf0\xe6\xfd\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b\x63\x6e\x07\x0a" + "\x38\xbc\xe7\x37"; + b.inLen = strlen(b.input); + b.outLen = SHA512_DIGEST_SIZE; + + c.input = "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD"; + c.output = "\xfa\x73\xb0\x08\x9d\x56\xa2\x84\xef\xb0\xf0\x75\x6c\x89\x0b" + "\xe9\xb1\xb5\xdb\xdd\x8e\xe8\x1a\x36\x55\xf8\x3e\x33\xb2\x27" + "\x9d\x39\xbf\x3e\x84\x82\x79\xa7\x22\xc8\x06\xb4\x85\xa4\x7e" + "\x67\xc8\x07\xb9\x46\xa3\x37\xbe\xe8\x94\x26\x74\x27\x88\x59" + "\xe1\x32\x92\xfb"; + c.inLen = strlen(c.input); + c.outLen = SHA512_DIGEST_SIZE; + + test_hmac[0] = a; + test_hmac[1] = b; + test_hmac[2] = c; + + for (i = 0; i < times; ++i) { +#if defined(HAVE_FIPS) + if (i == 1) + continue; /* fips not allowed */ +#endif + ret = HmacSetKey(&hmac, SHA512, (byte*)keys[i],(word32)strlen(keys[i])); + if (ret != 0) + return -4030; + ret = HmacUpdate(&hmac, (byte*)test_hmac[i].input, + (word32)test_hmac[i].inLen); + if (ret != 0) + return -4031; + ret = HmacFinal(&hmac, hash); + if (ret != 0) + return -4032; + + if (memcmp(hash, test_hmac[i].output, SHA512_DIGEST_SIZE) != 0) + return -20 - i; + } + + return 0; +} +#endif + + +#ifndef NO_RC4 +int arc4_test(void) +{ + byte cipher[16]; + byte plain[16]; + + const char* keys[] = + { + "\x01\x23\x45\x67\x89\xab\xcd\xef", + "\x01\x23\x45\x67\x89\xab\xcd\xef", + "\x00\x00\x00\x00\x00\x00\x00\x00", + "\xef\x01\x23\x45" + }; + + testVector a, b, c, d; + testVector test_arc4[4]; + + int times = sizeof(test_arc4) / sizeof(testVector), i; + + a.input = "\x01\x23\x45\x67\x89\xab\xcd\xef"; + a.output = "\x75\xb7\x87\x80\x99\xe0\xc5\x96"; + a.inLen = 8; + a.outLen = 8; + + b.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; + b.output = "\x74\x94\xc2\xe7\x10\x4b\x08\x79"; + b.inLen = 8; + b.outLen = 8; + + c.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; + c.output = "\xde\x18\x89\x41\xa3\x37\x5d\x3a"; + c.inLen = 8; + c.outLen = 8; + + d.input = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + d.output = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf\xbd\x61"; + d.inLen = 10; + d.outLen = 10; + + test_arc4[0] = a; + test_arc4[1] = b; + test_arc4[2] = c; + test_arc4[3] = d; + + for (i = 0; i < times; ++i) { + Arc4 enc; + Arc4 dec; + int keylen = 8; /* strlen with key 0x00 not good */ + if (i == 3) + keylen = 4; + +#ifdef HAVE_CAVIUM + if (Arc4InitCavium(&enc, CAVIUM_DEV_ID) != 0) + return -20001; + if (Arc4InitCavium(&dec, CAVIUM_DEV_ID) != 0) + return -20002; +#endif + + Arc4SetKey(&enc, (byte*)keys[i], keylen); + Arc4SetKey(&dec, (byte*)keys[i], keylen); + + Arc4Process(&enc, cipher, (byte*)test_arc4[i].input, + (word32)test_arc4[i].outLen); + Arc4Process(&dec, plain, cipher, (word32)test_arc4[i].outLen); + + if (memcmp(plain, test_arc4[i].input, test_arc4[i].outLen)) + return -20 - i; + + if (memcmp(cipher, test_arc4[i].output, test_arc4[i].outLen)) + return -20 - 5 - i; + +#ifdef HAVE_CAVIUM + Arc4FreeCavium(&enc); + Arc4FreeCavium(&dec); +#endif + } + + return 0; +} +#endif + + +int hc128_test(void) +{ +#ifdef HAVE_HC128 + byte cipher[16]; + byte plain[16]; + + const char* keys[] = + { + "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD", + "\x0F\x62\xB5\x08\x5B\xAE\x01\x54\xA7\xFA\x4D\xA0\xF3\x46\x99\xEC" + }; + + const char* ivs[] = + { + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x0D\x74\xDB\x42\xA9\x10\x77\xDE\x45\xAC\x13\x7A\xE1\x48\xAF\x16", + "\x28\x8F\xF6\x5D\xC4\x2B\x92\xF9\x60\xC7\x2E\x95\xFC\x63\xCA\x31" + }; + + + testVector a, b, c, d; + testVector test_hc128[4]; + + int times = sizeof(test_hc128) / sizeof(testVector), i; + + a.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; + a.output = "\x37\x86\x02\xB9\x8F\x32\xA7\x48"; + a.inLen = 8; + a.outLen = 8; + + b.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; + b.output = "\x33\x7F\x86\x11\xC6\xED\x61\x5F"; + b.inLen = 8; + b.outLen = 8; + + c.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; + c.output = "\x2E\x1E\xD1\x2A\x85\x51\xC0\x5A"; + c.inLen = 8; + c.outLen = 8; + + d.input = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + d.output = "\x1C\xD8\xAE\xDD\xFE\x52\xE2\x17\xE8\x35\xD0\xB7\xE8\x4E\x29"; + d.inLen = 15; + d.outLen = 15; + + test_hc128[0] = a; + test_hc128[1] = b; + test_hc128[2] = c; + test_hc128[3] = d; + + for (i = 0; i < times; ++i) { + HC128 enc; + HC128 dec; + + /* align keys/ivs in plain/cipher buffers */ + memcpy(plain, keys[i], 16); + memcpy(cipher, ivs[i], 16); + + Hc128_SetKey(&enc, plain, cipher); + Hc128_SetKey(&dec, plain, cipher); + + /* align input */ + memcpy(plain, test_hc128[i].input, test_hc128[i].outLen); + Hc128_Process(&enc, cipher, plain, (word32)test_hc128[i].outLen); + Hc128_Process(&dec, plain, cipher, (word32)test_hc128[i].outLen); + + if (memcmp(plain, test_hc128[i].input, test_hc128[i].outLen)) + return -120 - i; + + if (memcmp(cipher, test_hc128[i].output, test_hc128[i].outLen)) + return -120 - 5 - i; + } + +#endif /* HAVE_HC128 */ + return 0; +} + + +#ifndef NO_RABBIT +int rabbit_test(void) +{ + byte cipher[16]; + byte plain[16]; + + const char* keys[] = + { + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\xAC\xC3\x51\xDC\xF1\x62\xFC\x3B\xFE\x36\x3D\x2E\x29\x13\x28\x91" }; @@ -998,7 +1760,6 @@ int rabbit_test() 0 }; - testVector a, b, c; testVector test_rabbit[3]; @@ -1006,18 +1767,18 @@ int rabbit_test() a.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; a.output = "\xED\xB7\x05\x67\x37\x5D\xCD\x7C"; - a.inLen = strlen(a.input); - a.outLen = strlen(a.output); + a.inLen = 8; + a.outLen = 8; b.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; b.output = "\x6D\x7D\x01\x22\x92\xCC\xDC\xE0"; - b.inLen = strlen(b.input); - b.outLen = strlen(b.output); + b.inLen = 8; + b.outLen = 8; c.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; - c.output = "\x9C\x51\xE2\x87\x84\xC3\x7F\xE9"; - c.inLen = strlen(c.input); - c.outLen = strlen(c.output); + c.output = "\x04\xCE\xCA\x7A\x1A\x86\x6E\x77"; + c.inLen = 8; + c.outLen = 8; test_rabbit[0] = a; test_rabbit[1] = b; @@ -1026,12 +1787,21 @@ int rabbit_test() for (i = 0; i < times; ++i) { Rabbit enc; Rabbit dec; - - RabbitSetKey(&enc, (byte*)keys[i], (byte*)ivs[i]); - RabbitSetKey(&dec, (byte*)keys[i], (byte*)ivs[i]); - - RabbitProcess(&enc, cipher, (byte*)test_rabbit[i].input, - (word32)test_rabbit[i].outLen); + byte* iv; + + /* align keys/ivs in plain/cipher buffers */ + memcpy(plain, keys[i], 16); + if (ivs[i]) { + memcpy(cipher, ivs[i], 8); + iv = cipher; + } else + iv = NULL; + RabbitSetKey(&enc, plain, iv); + RabbitSetKey(&dec, plain, iv); + + /* align input */ + memcpy(plain, test_rabbit[i].input, test_rabbit[i].outLen); + RabbitProcess(&enc, cipher, plain, (word32)test_rabbit[i].outLen); RabbitProcess(&dec, plain, cipher, (word32)test_rabbit[i].outLen); if (memcmp(plain, test_rabbit[i].input, test_rabbit[i].outLen)) @@ -1047,7 +1817,7 @@ int rabbit_test() #ifndef NO_DES3 -int des_test() +int des_test(void) { const byte vector[] = { /* "now is the time for all " w/o trailing 0 */ 0x6e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, @@ -1061,34 +1831,40 @@ int des_test() Des enc; Des dec; - const byte key[] = + const byte key[] = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef }; - const byte iv[] = + const byte iv[] = { 0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef }; - const byte verify[] = + const byte verify[] = { 0x8b,0x7c,0x52,0xb0,0x01,0x2b,0x6c,0xb8, 0x4f,0x0f,0xeb,0xf3,0xfb,0x5f,0x86,0x73, 0x15,0x85,0xb3,0x22,0x4b,0x86,0x2b,0x4b }; + int ret; + + ret = Des_SetKey(&enc, key, iv, DES_ENCRYPTION); + if (ret != 0) + return -31; - Des_SetKey(&enc, key, iv, DES_ENCRYPTION); Des_CbcEncrypt(&enc, cipher, vector, sizeof(vector)); - Des_SetKey(&dec, key, iv, DES_DECRYPTION); + ret = Des_SetKey(&dec, key, iv, DES_DECRYPTION); + if (ret != 0) + return -32; Des_CbcDecrypt(&dec, plain, cipher, sizeof(cipher)); if (memcmp(plain, vector, sizeof(plain))) - return -31; + return -33; if (memcmp(cipher, verify, sizeof(cipher))) - return -32; + return -34; return 0; } @@ -1096,7 +1872,7 @@ int des_test() #ifndef NO_DES3 -int des3_test() +int des3_test(void) { const byte vector[] = { /* "Now is the time for all " w/o trailing 0 */ 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, @@ -1110,46 +1886,66 @@ int des3_test() Des3 enc; Des3 dec; - const byte key3[] = + const byte key3[] = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10, 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 }; - const byte iv3[] = + const byte iv3[] = { 0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81 - + }; - const byte verify3[] = + const byte verify3[] = { 0x43,0xa0,0x29,0x7e,0xd1,0x84,0xf8,0x0e, 0x89,0x64,0x84,0x32,0x12,0xd5,0x08,0x98, 0x18,0x94,0x15,0x74,0x87,0x12,0x7d,0xb0 }; + int ret; - Des3_SetKey(&enc, key3, iv3, DES_ENCRYPTION); - Des3_CbcEncrypt(&enc, cipher, vector, sizeof(vector)); - Des3_SetKey(&dec, key3, iv3, DES_DECRYPTION); - Des3_CbcDecrypt(&dec, plain, cipher, sizeof(cipher)); - if (memcmp(plain, vector, sizeof(plain))) +#ifdef HAVE_CAVIUM + if (Des3_InitCavium(&enc, CAVIUM_DEV_ID) != 0) + return -20005; + if (Des3_InitCavium(&dec, CAVIUM_DEV_ID) != 0) + return -20006; +#endif + ret = Des3_SetKey(&enc, key3, iv3, DES_ENCRYPTION); + if (ret != 0) + return -31; + ret = Des3_SetKey(&dec, key3, iv3, DES_DECRYPTION); + if (ret != 0) + return -32; + ret = Des3_CbcEncrypt(&enc, cipher, vector, sizeof(vector)); + if (ret != 0) return -33; + ret = Des3_CbcDecrypt(&dec, plain, cipher, sizeof(cipher)); + if (ret != 0) + return -34; + + if (memcmp(plain, vector, sizeof(plain))) + return -35; if (memcmp(cipher, verify3, sizeof(cipher))) - return -34; + return -36; +#ifdef HAVE_CAVIUM + Des3_FreeCavium(&enc); + Des3_FreeCavium(&dec); +#endif return 0; } #endif /* NO_DES */ #ifndef NO_AES -int aes_test() +int aes_test(void) { Aes enc; Aes dec; @@ -1160,7 +1956,7 @@ int aes_test() 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20 }; - const byte verify[] = + const byte verify[] = { 0x95,0x94,0x92,0x57,0x5f,0x42,0x81,0x53, 0x2c,0xcc,0x9d,0x46,0x77,0xa2,0x33,0xcb @@ -1171,12 +1967,27 @@ int aes_test() byte cipher[AES_BLOCK_SIZE * 4]; byte plain [AES_BLOCK_SIZE * 4]; + int ret; - AesSetKey(&enc, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); - AesSetKey(&dec, key, AES_BLOCK_SIZE, iv, AES_DECRYPTION); +#ifdef HAVE_CAVIUM + if (AesInitCavium(&enc, CAVIUM_DEV_ID) != 0) + return -20003; + if (AesInitCavium(&dec, CAVIUM_DEV_ID) != 0) + return -20004; +#endif + ret = AesSetKey(&enc, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); + if (ret != 0) + return -1001; + ret = AesSetKey(&dec, key, AES_BLOCK_SIZE, iv, AES_DECRYPTION); + if (ret != 0) + return -1002; - AesCbcEncrypt(&enc, cipher, msg, AES_BLOCK_SIZE); - AesCbcDecrypt(&dec, plain, cipher, AES_BLOCK_SIZE); + ret = AesCbcEncrypt(&enc, cipher, msg, AES_BLOCK_SIZE); + if (ret != 0) + return -1005; + ret = AesCbcDecrypt(&dec, plain, cipher, AES_BLOCK_SIZE); + if (ret != 0) + return -1006; if (memcmp(plain, msg, AES_BLOCK_SIZE)) return -60; @@ -1184,9 +1995,13 @@ int aes_test() if (memcmp(cipher, verify, AES_BLOCK_SIZE)) return -61; +#ifdef HAVE_CAVIUM + AesFreeCavium(&enc); + AesFreeCavium(&dec); +#endif #ifdef CYASSL_AES_COUNTER { - const byte ctrKey[] = + const byte ctrKey[] = { 0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6, 0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c @@ -1223,9 +2038,15 @@ int aes_test() 0x79,0x21,0x70,0xa0,0xf3,0x00,0x9c,0xee }; - AesSetKey(&enc, ctrKey, AES_BLOCK_SIZE, ctrIv, AES_ENCRYPTION); + const byte oddCipher[] = + { + 0xb9,0xd7,0xcb,0x08,0xb0,0xe1,0x7b,0xa0, + 0xc2 + }; + + AesSetKeyDirect(&enc, ctrKey, AES_BLOCK_SIZE, ctrIv, AES_ENCRYPTION); /* Ctr only uses encrypt, even on key setup */ - AesSetKey(&dec, ctrKey, AES_BLOCK_SIZE, ctrIv, AES_ENCRYPTION); + AesSetKeyDirect(&dec, ctrKey, AES_BLOCK_SIZE, ctrIv, AES_ENCRYPTION); AesCtrEncrypt(&enc, cipher, ctrPlain, AES_BLOCK_SIZE*4); AesCtrEncrypt(&dec, plain, cipher, AES_BLOCK_SIZE*4); @@ -1235,14 +2056,78 @@ int aes_test() if (memcmp(cipher, ctrCipher, AES_BLOCK_SIZE*4)) return -67; + + /* let's try with just 9 bytes, non block size test */ + AesSetKeyDirect(&enc, ctrKey, AES_BLOCK_SIZE, ctrIv, AES_ENCRYPTION); + /* Ctr only uses encrypt, even on key setup */ + AesSetKeyDirect(&dec, ctrKey, AES_BLOCK_SIZE, ctrIv, AES_ENCRYPTION); + + AesCtrEncrypt(&enc, cipher, ctrPlain, 9); + AesCtrEncrypt(&dec, plain, cipher, 9); + + if (memcmp(plain, ctrPlain, 9)) + return -68; + + if (memcmp(cipher, ctrCipher, 9)) + return -69; + + /* and an additional 9 bytes to reuse tmp left buffer */ + AesCtrEncrypt(&enc, cipher, ctrPlain, 9); + AesCtrEncrypt(&dec, plain, cipher, 9); + + if (memcmp(plain, ctrPlain, 9)) + return -70; + + if (memcmp(cipher, oddCipher, 9)) + return -71; } #endif /* CYASSL_AES_COUNTER */ +#if defined(CYASSL_AESNI) && defined(CYASSL_AES_DIRECT) + { + const byte niPlain[] = + { + 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a + }; + + const byte niCipher[] = + { + 0xf3,0xee,0xd1,0xbd,0xb5,0xd2,0xa0,0x3c, + 0x06,0x4b,0x5a,0x7e,0x3d,0xb1,0x81,0xf8 + }; + + const byte niKey[] = + { + 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe, + 0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, + 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7, + 0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 + }; + + XMEMSET(cipher, 0, AES_BLOCK_SIZE); + ret = AesSetKey(&enc, niKey, sizeof(niKey), cipher, AES_ENCRYPTION); + if (ret != 0) + return -1003; + AesEncryptDirect(&enc, cipher, niPlain); + if (XMEMCMP(cipher, niCipher, AES_BLOCK_SIZE) != 0) + return -20006; + + XMEMSET(plain, 0, AES_BLOCK_SIZE); + ret = AesSetKey(&dec, niKey, sizeof(niKey), plain, AES_DECRYPTION); + if (ret != 0) + return -1004; + AesDecryptDirect(&dec, plain, niCipher); + if (XMEMCMP(plain, niPlain, AES_BLOCK_SIZE) != 0) + return -20007; + } +#endif /* CYASSL_AESNI && CYASSL_AES_DIRECT */ + return 0; } #ifdef HAVE_AESGCM -int aesgcm_test() +int aesgcm_test(void) { Aes enc; @@ -1262,9 +2147,9 @@ int aesgcm_test() const byte iv[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88, 0x00, 0x00, 0x00, 0x00 + 0xde, 0xca, 0xf8, 0x88 }; - + const byte p[] = { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, @@ -1276,14 +2161,14 @@ int aesgcm_test() 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39 }; - + const byte a[] = { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2 }; - + const byte c[] = { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, @@ -1302,27 +2187,27 @@ int aesgcm_test() 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b }; - byte t2[16]; - byte p2[60]; - byte c2[60]; + byte t2[sizeof(t)]; + byte p2[sizeof(c)]; + byte c2[sizeof(p)]; int result; - memset(t2, 0, 16); - memset(c2, 0, 60); - memset(p2, 0, 60); + memset(t2, 0, sizeof(t2)); + memset(c2, 0, sizeof(c2)); + memset(p2, 0, sizeof(p2)); - AesGcmSetKey(&enc, k, sizeof(k), iv); - AesGcmSetExpIV(&enc, iv + /*AES_GCM_IMP_IV_SZ*/ 4); + AesGcmSetKey(&enc, k, sizeof(k)); /* AES-GCM encrypt and decrypt both use AES encrypt internally */ - AesGcmEncrypt(&enc, c2, p, sizeof(c2), t2, sizeof(t2), a, sizeof(a)); + AesGcmEncrypt(&enc, c2, p, sizeof(c2), iv, sizeof(iv), + t2, sizeof(t2), a, sizeof(a)); if (memcmp(c, c2, sizeof(c2))) return -68; if (memcmp(t, t2, sizeof(t2))) return -69; - result = AesGcmDecrypt(&enc, - p2, c2, sizeof(p2), t2, sizeof(t2), a, sizeof(a)); + result = AesGcmDecrypt(&enc, p2, c2, sizeof(p2), iv, sizeof(iv), + t2, sizeof(t2), a, sizeof(a)); if (result != 0) return -70; if (memcmp(p, p2, sizeof(p2))) @@ -1330,54 +2215,494 @@ int aesgcm_test() return 0; } + +int gmac_test(void) +{ + Gmac gmac; + + const byte k1[] = + { + 0x89, 0xc9, 0x49, 0xe9, 0xc8, 0x04, 0xaf, 0x01, + 0x4d, 0x56, 0x04, 0xb3, 0x94, 0x59, 0xf2, 0xc8 + }; + const byte iv1[] = + { + 0xd1, 0xb1, 0x04, 0xc8, 0x15, 0xbf, 0x1e, 0x94, + 0xe2, 0x8c, 0x8f, 0x16 + }; + const byte a1[] = + { + 0x82, 0xad, 0xcd, 0x63, 0x8d, 0x3f, 0xa9, 0xd9, + 0xf3, 0xe8, 0x41, 0x00, 0xd6, 0x1e, 0x07, 0x77 + }; + const byte t1[] = + { + 0x88, 0xdb, 0x9d, 0x62, 0x17, 0x2e, 0xd0, 0x43, + 0xaa, 0x10, 0xf1, 0x6d, 0x22, 0x7d, 0xc4, 0x1b + }; + + const byte k2[] = + { + 0x40, 0xf7, 0xec, 0xb2, 0x52, 0x6d, 0xaa, 0xd4, + 0x74, 0x25, 0x1d, 0xf4, 0x88, 0x9e, 0xf6, 0x5b + }; + const byte iv2[] = + { + 0xee, 0x9c, 0x6e, 0x06, 0x15, 0x45, 0x45, 0x03, + 0x1a, 0x60, 0x24, 0xa7 + }; + const byte a2[] = + { + 0x94, 0x81, 0x2c, 0x87, 0x07, 0x4e, 0x15, 0x18, + 0x34, 0xb8, 0x35, 0xaf, 0x1c, 0xa5, 0x7e, 0x56 + }; + const byte t2[] = + { + 0xc6, 0x81, 0x79, 0x8e, 0x3d, 0xda, 0xb0, 0x9f, + 0x8d, 0x83, 0xb0, 0xbb, 0x14, 0xb6, 0x91 + }; + + const byte k3[] = + { + 0xb8, 0xe4, 0x9a, 0x5e, 0x37, 0xf9, 0x98, 0x2b, + 0xb9, 0x6d, 0xd0, 0xc9, 0xb6, 0xab, 0x26, 0xac + }; + const byte iv3[] = + { + 0xe4, 0x4a, 0x42, 0x18, 0x8c, 0xae, 0x94, 0x92, + 0x6a, 0x9c, 0x26, 0xb0 + }; + const byte a3[] = + { + 0x9d, 0xb9, 0x61, 0x68, 0xa6, 0x76, 0x7a, 0x31, + 0xf8, 0x29, 0xe4, 0x72, 0x61, 0x68, 0x3f, 0x8a + }; + const byte t3[] = + { + 0x23, 0xe2, 0x9f, 0x66, 0xe4, 0xc6, 0x52, 0x48 + }; + + byte tag[16]; + + memset(tag, 0, sizeof(tag)); + GmacSetKey(&gmac, k1, sizeof(k1)); + GmacUpdate(&gmac, iv1, sizeof(iv1), a1, sizeof(a1), tag, sizeof(t1)); + if (memcmp(t1, tag, sizeof(t1)) != 0) + return -126; + + memset(tag, 0, sizeof(tag)); + GmacSetKey(&gmac, k2, sizeof(k2)); + GmacUpdate(&gmac, iv2, sizeof(iv2), a2, sizeof(a2), tag, sizeof(t2)); + if (memcmp(t2, tag, sizeof(t2)) != 0) + return -127; + + memset(tag, 0, sizeof(tag)); + GmacSetKey(&gmac, k3, sizeof(k3)); + GmacUpdate(&gmac, iv3, sizeof(iv3), a3, sizeof(a3), tag, sizeof(t3)); + if (memcmp(t3, tag, sizeof(t3)) != 0) + return -128; + + return 0; +} #endif /* HAVE_AESGCM */ +#ifdef HAVE_AESCCM +int aesccm_test(void) +{ + Aes enc; + + /* key */ + const byte k[] = + { + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf + }; + + /* nonce */ + const byte iv[] = + { + 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xa0, + 0xa1, 0xa2, 0xa3, 0xa4, 0xa5 + }; + + /* plaintext */ + const byte p[] = + { + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e + }; + + const byte a[] = + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }; + + const byte c[] = + { + 0x58, 0x8c, 0x97, 0x9a, 0x61, 0xc6, 0x63, 0xd2, + 0xf0, 0x66, 0xd0, 0xc2, 0xc0, 0xf9, 0x89, 0x80, + 0x6d, 0x5f, 0x6b, 0x61, 0xda, 0xc3, 0x84 + }; + + const byte t[] = + { + 0x17, 0xe8, 0xd1, 0x2c, 0xfd, 0xf9, 0x26, 0xe0 + }; + + byte t2[sizeof(t)]; + byte p2[sizeof(p)]; + byte c2[sizeof(c)]; + + int result; + + memset(t2, 0, sizeof(t2)); + memset(c2, 0, sizeof(c2)); + memset(p2, 0, sizeof(p2)); + + AesCcmSetKey(&enc, k, sizeof(k)); + /* AES-CCM encrypt and decrypt both use AES encrypt internally */ + AesCcmEncrypt(&enc, c2, p, sizeof(c2), iv, sizeof(iv), + t2, sizeof(t2), a, sizeof(a)); + if (memcmp(c, c2, sizeof(c2))) + return -107; + if (memcmp(t, t2, sizeof(t2))) + return -108; + + result = AesCcmDecrypt(&enc, p2, c2, sizeof(p2), iv, sizeof(iv), + t2, sizeof(t2), a, sizeof(a)); + if (result != 0) + return -109; + if (memcmp(p, p2, sizeof(p2))) + return -110; + + /* Test the authentication failure */ + t2[0]++; /* Corrupt the authentication tag. */ + result = AesCcmDecrypt(&enc, p2, c, sizeof(p2), iv, sizeof(iv), + t2, sizeof(t2), a, sizeof(a)); + if (result == 0) + return -111; + + /* Clear c2 to compare against p2. p2 should be set to zero in case of + * authentication fail. */ + memset(c2, 0, sizeof(c2)); + if (memcmp(p2, c2, sizeof(p2))) + return -112; + + return 0; +} +#endif /* HAVE_AESCCM */ + #endif /* NO_AES */ -int random_test() +#ifdef HAVE_CAMELLIA + +enum { + CAM_ECB_ENC, CAM_ECB_DEC, CAM_CBC_ENC, CAM_CBC_DEC +}; + +typedef struct { + int type; + const byte* plaintext; + const byte* iv; + const byte* ciphertext; + const byte* key; + word32 keySz; + int errorCode; +} test_vector_t; + +int camellia_test(void) { - RNG rng; - byte block[32]; - int ret = InitRng(&rng); + /* Camellia ECB Test Plaintext */ + static const byte pte[] = + { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 + }; + + /* Camellia ECB Test Initialization Vector */ + static const byte ive[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + + /* Test 1: Camellia ECB 128-bit key */ + static const byte k1[] = + { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 + }; + static const byte c1[] = + { + 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, + 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 + }; + + /* Test 2: Camellia ECB 192-bit key */ + static const byte k2[] = + { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 + }; + static const byte c2[] = + { + 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8, + 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 + }; + + /* Test 3: Camellia ECB 256-bit key */ + static const byte k3[] = + { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff + }; + static const byte c3[] = + { + 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, + 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 + }; + + /* Camellia CBC Test Plaintext */ + static const byte ptc[] = + { + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A + }; + + /* Camellia CBC Test Initialization Vector */ + static const byte ivc[] = + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }; + + /* Test 4: Camellia-CBC 128-bit key */ + static const byte k4[] = + { + 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C + }; + static const byte c4[] = + { + 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0, + 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB + }; + + /* Test 5: Camellia-CBC 192-bit key */ + static const byte k5[] = + { + 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, + 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, + 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B + }; + static const byte c5[] = + { + 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2, + 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 + }; + + /* Test 6: CBC 256-bit key */ + static const byte k6[] = + { + 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 + }; + static const byte c6[] = + { + 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A, + 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA + }; + + byte out[CAMELLIA_BLOCK_SIZE]; + Camellia cam; + int i, testsSz; + const test_vector_t testVectors[] = + { + {CAM_ECB_ENC, pte, ive, c1, k1, sizeof(k1), -114}, + {CAM_ECB_ENC, pte, ive, c2, k2, sizeof(k2), -115}, + {CAM_ECB_ENC, pte, ive, c3, k3, sizeof(k3), -116}, + {CAM_ECB_DEC, pte, ive, c1, k1, sizeof(k1), -117}, + {CAM_ECB_DEC, pte, ive, c2, k2, sizeof(k2), -118}, + {CAM_ECB_DEC, pte, ive, c3, k3, sizeof(k3), -119}, + {CAM_CBC_ENC, ptc, ivc, c4, k4, sizeof(k4), -120}, + {CAM_CBC_ENC, ptc, ivc, c5, k5, sizeof(k5), -121}, + {CAM_CBC_ENC, ptc, ivc, c6, k6, sizeof(k6), -122}, + {CAM_CBC_DEC, ptc, ivc, c4, k4, sizeof(k4), -123}, + {CAM_CBC_DEC, ptc, ivc, c5, k5, sizeof(k5), -124}, + {CAM_CBC_DEC, ptc, ivc, c6, k6, sizeof(k6), -125} + }; + + testsSz = sizeof(testVectors)/sizeof(test_vector_t); + for (i = 0; i < testsSz; i++) { + if (CamelliaSetKey(&cam, testVectors[i].key, testVectors[i].keySz, + testVectors[i].iv) != 0) + return testVectors[i].errorCode; + + switch (testVectors[i].type) { + case CAM_ECB_ENC: + CamelliaEncryptDirect(&cam, out, testVectors[i].plaintext); + if (memcmp(out, testVectors[i].ciphertext, CAMELLIA_BLOCK_SIZE)) + return testVectors[i].errorCode; + break; + case CAM_ECB_DEC: + CamelliaDecryptDirect(&cam, out, testVectors[i].ciphertext); + if (memcmp(out, testVectors[i].plaintext, CAMELLIA_BLOCK_SIZE)) + return testVectors[i].errorCode; + break; + case CAM_CBC_ENC: + CamelliaCbcEncrypt(&cam, out, testVectors[i].plaintext, + CAMELLIA_BLOCK_SIZE); + if (memcmp(out, testVectors[i].ciphertext, CAMELLIA_BLOCK_SIZE)) + return testVectors[i].errorCode; + break; + case CAM_CBC_DEC: + CamelliaCbcDecrypt(&cam, out, testVectors[i].ciphertext, + CAMELLIA_BLOCK_SIZE); + if (memcmp(out, testVectors[i].plaintext, CAMELLIA_BLOCK_SIZE)) + return testVectors[i].errorCode; + break; + default: + break; + } + } + + /* Setting the IV and checking it was actually set. */ + CamelliaSetIV(&cam, ivc); + if (XMEMCMP(cam.reg, ivc, CAMELLIA_BLOCK_SIZE)) + return -1; + + /* Setting the IV to NULL should be same as all zeros IV */ + if (CamelliaSetIV(&cam, NULL) != 0 || + XMEMCMP(cam.reg, ive, CAMELLIA_BLOCK_SIZE)) + return -1; + + /* First parameter should never be null */ + if (CamelliaSetIV(NULL, NULL) == 0) + return -1; + + /* First parameter should never be null, check it fails */ + if (CamelliaSetKey(NULL, k1, sizeof(k1), NULL) == 0) + return -1; + + /* Key should have a size of 16, 24, or 32 */ + if (CamelliaSetKey(&cam, k1, 0, NULL) == 0) + return -1; + + return 0; +} +#endif /* HAVE_CAMELLIA */ + + +#if defined(HAVE_HASHDRBG) || defined(NO_RC4) + +int random_test(void) +{ + const byte test1Entropy[] = + { + 0xa6, 0x5a, 0xd0, 0xf3, 0x45, 0xdb, 0x4e, 0x0e, 0xff, 0xe8, 0x75, 0xc3, + 0xa2, 0xe7, 0x1f, 0x42, 0xc7, 0x12, 0x9d, 0x62, 0x0f, 0xf5, 0xc1, 0x19, + 0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, 0x85, 0x81, 0xf9, 0x31, + 0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d, 0xdb, 0xcb, 0xcc, 0x2e + }; + const byte test1Output[] = + { + 0xd3, 0xe1, 0x60, 0xc3, 0x5b, 0x99, 0xf3, 0x40, 0xb2, 0x62, 0x82, 0x64, + 0xd1, 0x75, 0x10, 0x60, 0xe0, 0x04, 0x5d, 0xa3, 0x83, 0xff, 0x57, 0xa5, + 0x7d, 0x73, 0xa6, 0x73, 0xd2, 0xb8, 0xd8, 0x0d, 0xaa, 0xf6, 0xa6, 0xc3, + 0x5a, 0x91, 0xbb, 0x45, 0x79, 0xd7, 0x3f, 0xd0, 0xc8, 0xfe, 0xd1, 0x11, + 0xb0, 0x39, 0x13, 0x06, 0x82, 0x8a, 0xdf, 0xed, 0x52, 0x8f, 0x01, 0x81, + 0x21, 0xb3, 0xfe, 0xbd, 0xc3, 0x43, 0xe7, 0x97, 0xb8, 0x7d, 0xbb, 0x63, + 0xdb, 0x13, 0x33, 0xde, 0xd9, 0xd1, 0xec, 0xe1, 0x77, 0xcf, 0xa6, 0xb7, + 0x1f, 0xe8, 0xab, 0x1d, 0xa4, 0x66, 0x24, 0xed, 0x64, 0x15, 0xe5, 0x1c, + 0xcd, 0xe2, 0xc7, 0xca, 0x86, 0xe2, 0x83, 0x99, 0x0e, 0xea, 0xeb, 0x91, + 0x12, 0x04, 0x15, 0x52, 0x8b, 0x22, 0x95, 0x91, 0x02, 0x81, 0xb0, 0x2d, + 0xd4, 0x31, 0xf4, 0xc9, 0xf7, 0x04, 0x27, 0xdf + }; + const byte test2EntropyA[] = + { + 0x63, 0x36, 0x33, 0x77, 0xe4, 0x1e, 0x86, 0x46, 0x8d, 0xeb, 0x0a, 0xb4, + 0xa8, 0xed, 0x68, 0x3f, 0x6a, 0x13, 0x4e, 0x47, 0xe0, 0x14, 0xc7, 0x00, + 0x45, 0x4e, 0x81, 0xe9, 0x53, 0x58, 0xa5, 0x69, 0x80, 0x8a, 0xa3, 0x8f, + 0x2a, 0x72, 0xa6, 0x23, 0x59, 0x91, 0x5a, 0x9f, 0x8a, 0x04, 0xca, 0x68 + }; + const byte test2EntropyB[] = + { + 0xe6, 0x2b, 0x8a, 0x8e, 0xe8, 0xf1, 0x41, 0xb6, 0x98, 0x05, 0x66, 0xe3, + 0xbf, 0xe3, 0xc0, 0x49, 0x03, 0xda, 0xd4, 0xac, 0x2c, 0xdf, 0x9f, 0x22, + 0x80, 0x01, 0x0a, 0x67, 0x39, 0xbc, 0x83, 0xd3 + }; + const byte test2Output[] = + { + 0x04, 0xee, 0xc6, 0x3b, 0xb2, 0x31, 0xdf, 0x2c, 0x63, 0x0a, 0x1a, 0xfb, + 0xe7, 0x24, 0x94, 0x9d, 0x00, 0x5a, 0x58, 0x78, 0x51, 0xe1, 0xaa, 0x79, + 0x5e, 0x47, 0x73, 0x47, 0xc8, 0xb0, 0x56, 0x62, 0x1c, 0x18, 0xbd, 0xdc, + 0xdd, 0x8d, 0x99, 0xfc, 0x5f, 0xc2, 0xb9, 0x20, 0x53, 0xd8, 0xcf, 0xac, + 0xfb, 0x0b, 0xb8, 0x83, 0x12, 0x05, 0xfa, 0xd1, 0xdd, 0xd6, 0xc0, 0x71, + 0x31, 0x8a, 0x60, 0x18, 0xf0, 0x3b, 0x73, 0xf5, 0xed, 0xe4, 0xd4, 0xd0, + 0x71, 0xf9, 0xde, 0x03, 0xfd, 0x7a, 0xea, 0x10, 0x5d, 0x92, 0x99, 0xb8, + 0xaf, 0x99, 0xaa, 0x07, 0x5b, 0xdb, 0x4d, 0xb9, 0xaa, 0x28, 0xc1, 0x8d, + 0x17, 0x4b, 0x56, 0xee, 0x2a, 0x01, 0x4d, 0x09, 0x88, 0x96, 0xff, 0x22, + 0x82, 0xc9, 0x55, 0xa8, 0x19, 0x69, 0xe0, 0x69, 0xfa, 0x8c, 0xe0, 0x07, + 0xa1, 0x80, 0x18, 0x3a, 0x07, 0xdf, 0xae, 0x17 + }; + int ret; + + ret = RNG_HealthTest(0, test1Entropy, sizeof(test1Entropy), NULL, 0, + test1Output, sizeof(test1Output)); if (ret != 0) return -39; - RNG_GenerateBlock(&rng, block, sizeof(block)); + ret = RNG_HealthTest(1, test2EntropyA, sizeof(test2EntropyA), + test2EntropyB, sizeof(test2EntropyB), + test2Output, sizeof(test2Output)); + if (ret != 0) return -40; return 0; } +#else /* HAVE_HASHDRBG || NO_RC4 */ -static const char* clientKey = "./certs/client-key.der"; -static const char* clientCert = "./certs/client-cert.der"; -#ifdef CYASSL_CERT_GEN - static const char* caKeyFile = "./certs/ca-key.der"; - static const char* caCertFile = "./certs/ca-cert.pem"; +int random_test(void) +{ + RNG rng; + byte block[32]; + int ret; + +#ifdef HAVE_CAVIUM + ret = InitRngCavium(&rng, CAVIUM_DEV_ID); + if (ret != 0) return -2007; #endif + ret = InitRng(&rng); + if (ret != 0) return -39; + + ret = RNG_GenerateBlock(&rng, block, sizeof(block)); + if (ret != 0) return -40; + + return 0; +} + +#endif /* HAVE_HASHDRBG || NO_RC4 */ #ifdef HAVE_NTRU -static byte GetEntropy(ENTROPY_CMD cmd, byte* out) +byte GetEntropy(ENTROPY_CMD cmd, byte* out); + +byte GetEntropy(ENTROPY_CMD cmd, byte* out) { static RNG rng; - if (cmd == INIT) { - int ret = InitRng(&rng); - if (ret == 0) - return 1; - else - return 0; - } + if (cmd == INIT) + return (InitRng(&rng) == 0) ? 1 : 0; if (out == NULL) return 0; - if (cmd == GET_BYTE_OF_ENTROPY) { - RNG_GenerateBlock(&rng, out, 1); - return 1; - } + if (cmd == GET_BYTE_OF_ENTROPY) + return (RNG_GenerateBlock(&rng, out, 1) == 0) ? 1 : 0; if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) { *out = 1; @@ -1389,10 +2714,59 @@ static byte GetEntropy(ENTROPY_CMD cmd, byte* out) #endif /* HAVE_NTRU */ -int rsa_test() +#ifndef NO_RSA + +#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) + #ifdef FREESCALE_MQX + static const char* clientKey = "a:\\certs\\client-key.der"; + static const char* clientCert = "a:\\certs\\client-cert.der"; + #ifdef CYASSL_CERT_GEN + static const char* caKeyFile = "a:\\certs\\ca-key.der"; + static const char* caCertFile = "a:\\certs\\ca-cert.pem"; + #ifdef HAVE_ECC + static const char* eccCaKeyFile = "a:\\certs\\ecc-key.der"; + static const char* eccCaCertFile = "a:\\certs\\server-ecc.pem"; + #endif + #endif + #elif defined(CYASSL_MKD_SHELL) + static char* clientKey = "certs/client-key.der"; + static char* clientCert = "certs/client-cert.der"; + void set_clientKey(char *key) { clientKey = key ; } + void set_clientCert(char *cert) { clientCert = cert ; } + #ifdef CYASSL_CERT_GEN + static char* caKeyFile = "certs/ca-key.der"; + static char* caCertFile = "certs/ca-cert.pem"; + void set_caKeyFile (char * key) { caKeyFile = key ; } + void set_caCertFile(char * cert) { caCertFile = cert ; } + #ifdef HAVE_ECC + static const char* eccCaKeyFile = "certs/ecc-key.der"; + static const char* eccCaCertFile = "certs/server-ecc.pem"; + void set_eccCaKeyFile (char * key) { eccCaKeyFile = key ; } + void set_eccCaCertFile(char * cert) { eccCaCertFile = cert ; } + #endif + #endif + #else + static const char* clientKey = "./certs/client-key.der"; + static const char* clientCert = "./certs/client-cert.der"; + #ifdef CYASSL_CERT_GEN + static const char* caKeyFile = "./certs/ca-key.der"; + static const char* caCertFile = "./certs/ca-cert.pem"; + #ifdef HAVE_ECC + static const char* eccCaKeyFile = "./certs/ecc-key.der"; + static const char* eccCaCertFile = "./certs/server-ecc.pem"; + #endif + #endif + #endif +#endif + + + +#define FOURK_BUF 4096 + +int rsa_test(void) { - byte tmp[2048], tmp2[2048]; - size_t bytes, bytes2; + byte* tmp; + size_t bytes; RsaKey key; RNG rng; word32 idx = 0; @@ -1401,19 +2775,39 @@ int rsa_test() word32 inLen = (word32)strlen((char*)in); byte out[256]; byte plain[256]; +#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) + FILE* file, * file2; +#endif #ifdef CYASSL_TEST_CERT DecodedCert cert; #endif - FILE* file = fopen(clientKey, "rb"), * file2; + tmp = (byte*)malloc(FOURK_BUF); + if (tmp == NULL) + return -40; + +#ifdef USE_CERT_BUFFERS_1024 + XMEMCPY(tmp, client_key_der_1024, sizeof_client_key_der_1024); + bytes = sizeof_client_key_der_1024; +#elif defined(USE_CERT_BUFFERS_2048) + XMEMCPY(tmp, client_key_der_2048, sizeof_client_key_der_2048); + bytes = sizeof_client_key_der_2048; +#else + file = fopen(clientKey, "rb"); if (!file) err_sys("can't open ./certs/client-key.der, " "Please run from CyaSSL home dir", -40); - bytes = fread(tmp, 1, sizeof(tmp), file); - - InitRsaKey(&key, 0); + bytes = fread(tmp, 1, FOURK_BUF, file); + fclose(file); +#endif /* USE_CERT_BUFFERS */ + +#ifdef HAVE_CAVIUM + RsaInitCavium(&key, CAVIUM_DEV_ID); +#endif + ret = InitRsaKey(&key, 0); + if (ret != 0) return -39; ret = RsaPrivateKeyDecode(tmp, &idx, &key, (word32)bytes); if (ret != 0) return -41; @@ -1437,68 +2831,139 @@ int rsa_test() if (memcmp(plain, in, ret)) return -48; +#if defined(CYASSL_MDK_ARM) + #define sizeof(s) strlen((char *)(s)) +#endif + +#ifdef USE_CERT_BUFFERS_1024 + XMEMCPY(tmp, client_cert_der_1024, sizeof_client_cert_der_1024); + bytes = sizeof_client_cert_der_1024; +#elif defined(USE_CERT_BUFFERS_2048) + XMEMCPY(tmp, client_cert_der_2048, sizeof_client_cert_der_2048); + bytes = sizeof_client_cert_der_2048; +#else file2 = fopen(clientCert, "rb"); if (!file2) return -49; - bytes2 = fread(tmp2, 1, sizeof(tmp2), file2); + bytes = fread(tmp, 1, FOURK_BUF, file2); + fclose(file2); +#endif + +#ifdef sizeof + #undef sizeof +#endif #ifdef CYASSL_TEST_CERT - InitDecodedCert(&cert, (byte*)&tmp2, (word32)bytes2, 0); + InitDecodedCert(&cert, tmp, (word32)bytes, 0); ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) return -491; FreeDecodedCert(&cert); +#else + (void)bytes; #endif - fclose(file2); - fclose(file); #ifdef CYASSL_KEY_GEN { - byte der[4096]; - byte pem[4096]; - word32 derSz = 0; - word32 pemSz = 0; + byte* der; + byte* pem; + int derSz = 0; + int pemSz = 0; RsaKey derIn; RsaKey genKey; - FILE* keyFile; - FILE* pemFile; + FILE* keyFile; + FILE* pemFile; - InitRsaKey(&genKey, 0); + ret = InitRsaKey(&genKey, 0); + if (ret != 0) + return -300; ret = MakeRsaKey(&genKey, 1024, 65537, &rng); if (ret != 0) return -301; - derSz = RsaKeyToDer(&genKey, der, sizeof(der)); - if (derSz < 0) + der = (byte*)malloc(FOURK_BUF); + if (der == NULL) { + FreeRsaKey(&genKey); + return -307; + } + pem = (byte*)malloc(FOURK_BUF); + if (pem == NULL) { + free(der); + FreeRsaKey(&genKey); + return -308; + } + + derSz = RsaKeyToDer(&genKey, der, FOURK_BUF); + if (derSz < 0) { + free(der); + free(pem); return -302; + } keyFile = fopen("./key.der", "wb"); - if (!keyFile) + if (!keyFile) { + free(der); + free(pem); + FreeRsaKey(&genKey); return -303; - ret = fwrite(der, derSz, 1, keyFile); + } + ret = (int)fwrite(der, 1, derSz, keyFile); fclose(keyFile); - - pemSz = DerToPem(der, derSz, pem, sizeof(pem), PRIVATEKEY_TYPE); - if (pemSz < 0) + if (ret != derSz) { + free(der); + free(pem); + FreeRsaKey(&genKey); + return -313; + } + + pemSz = DerToPem(der, derSz, pem, FOURK_BUF, PRIVATEKEY_TYPE); + if (pemSz < 0) { + free(der); + free(pem); + FreeRsaKey(&genKey); return -304; + } pemFile = fopen("./key.pem", "wb"); - if (!pemFile) + if (!pemFile) { + free(der); + free(pem); + FreeRsaKey(&genKey); return -305; - ret = fwrite(pem, pemSz, 1, pemFile); + } + ret = (int)fwrite(pem, 1, pemSz, pemFile); fclose(pemFile); - - InitRsaKey(&derIn, 0); + if (ret != pemSz) { + free(der); + free(pem); + FreeRsaKey(&genKey); + return -314; + } + + ret = InitRsaKey(&derIn, 0); + if (ret != 0) { + free(der); + free(pem); + FreeRsaKey(&genKey); + return -3060; + } idx = 0; ret = RsaPrivateKeyDecode(der, &idx, &derIn, derSz); - if (ret != 0) + if (ret != 0) { + free(der); + free(pem); + FreeRsaKey(&derIn); + FreeRsaKey(&genKey); return -306; + } FreeRsaKey(&derIn); FreeRsaKey(&genKey); + free(pem); + free(der); } #endif /* CYASSL_KEY_GEN */ @@ -1507,8 +2972,8 @@ int rsa_test() /* self signed */ { Cert myCert; - byte derCert[4096]; - byte pem[4096]; + byte* derCert; + byte* pem; FILE* derFile; FILE* pemFile; int certSz; @@ -1517,6 +2982,15 @@ int rsa_test() DecodedCert decode; #endif + derCert = (byte*)malloc(FOURK_BUF); + if (derCert == NULL) + return -309; + pem = (byte*)malloc(FOURK_BUF); + if (pem == NULL) { + free(derCert); + return -310; + } + InitCert(&myCert); strncpy(myCert.subject.country, "US", CTC_NAME_SIZE); @@ -1529,62 +3003,110 @@ int rsa_test() myCert.isCA = 1; myCert.sigType = CTC_SHA256wRSA; - certSz = MakeSelfCert(&myCert, derCert, sizeof(derCert), &key, &rng); - if (certSz < 0) + certSz = MakeSelfCert(&myCert, derCert, FOURK_BUF, &key, &rng); + if (certSz < 0) { + free(derCert); + free(pem); return -401; + } #ifdef CYASSL_TEST_CERT InitDecodedCert(&decode, derCert, certSz, 0); ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); - if (ret != 0) + if (ret != 0) { + free(derCert); + free(pem); return -402; + } FreeDecodedCert(&decode); #endif derFile = fopen("./cert.der", "wb"); - if (!derFile) + if (!derFile) { + free(derCert); + free(pem); return -403; - ret = fwrite(derCert, certSz, 1, derFile); + } + ret = (int)fwrite(derCert, 1, certSz, derFile); fclose(derFile); - - pemSz = DerToPem(derCert, certSz, pem, sizeof(pem), CERT_TYPE); - if (pemSz < 0) + if (ret != certSz) { + free(derCert); + free(pem); + return -414; + } + + pemSz = DerToPem(derCert, certSz, pem, FOURK_BUF, CERT_TYPE); + if (pemSz < 0) { + free(derCert); + free(pem); return -404; + } pemFile = fopen("./cert.pem", "wb"); - if (!pemFile) + if (!pemFile) { + free(derCert); + free(pem); return -405; - ret = fwrite(pem, pemSz, 1, pemFile); + } + ret = (int)fwrite(pem, 1, pemSz, pemFile); fclose(pemFile); - - + if (ret != pemSz) { + free(derCert); + free(pem); + return -406; + } + free(pem); + free(derCert); } /* CA style */ { RsaKey caKey; Cert myCert; - byte derCert[4096]; - byte pem[4096]; + byte* derCert; + byte* pem; FILE* derFile; FILE* pemFile; int certSz; int pemSz; - byte tmp[2048]; - size_t bytes; - word32 idx = 0; + size_t bytes3; + word32 idx3 = 0; + FILE* file3 ; #ifdef CYASSL_TEST_CERT DecodedCert decode; #endif - FILE* file = fopen(caKeyFile, "rb"); + derCert = (byte*)malloc(FOURK_BUF); + if (derCert == NULL) + return -311; + pem = (byte*)malloc(FOURK_BUF); + if (pem == NULL) { + free(derCert); + return -312; + } + + file3 = fopen(caKeyFile, "rb"); - if (!file) + if (!file3) { + free(derCert); + free(pem); return -412; + } - bytes = fread(tmp, 1, sizeof(tmp), file); - - InitRsaKey(&caKey, 0); - ret = RsaPrivateKeyDecode(tmp, &idx, &caKey, (word32)bytes); - if (ret != 0) return -413; + bytes3 = fread(tmp, 1, FOURK_BUF, file3); + fclose(file3); + + ret = InitRsaKey(&caKey, 0); + if (ret != 0) { + free(derCert); + free(pem); + return -411; + } + ret = RsaPrivateKeyDecode(tmp, &idx3, &caKey, (word32)bytes3); + if (ret != 0) { + free(derCert); + free(pem); + FreeRsaKey(&caKey); + return -413; + } InitCert(&myCert); @@ -1597,60 +3119,248 @@ int rsa_test() strncpy(myCert.subject.email, "info@yassl.com", CTC_NAME_SIZE); ret = SetIssuer(&myCert, caCertFile); - if (ret < 0) + if (ret < 0) { + free(derCert); + free(pem); + FreeRsaKey(&caKey); return -405; + } - certSz = MakeCert(&myCert, derCert, sizeof(derCert), &key, &rng); - if (certSz < 0) + certSz = MakeCert(&myCert, derCert, FOURK_BUF, &key, NULL, &rng); + if (certSz < 0) { + free(derCert); + free(pem); + FreeRsaKey(&caKey); return -407; - - certSz = SignCert(&myCert, derCert, sizeof(derCert), &caKey, &rng); - if (certSz < 0) + } + + certSz = SignCert(myCert.bodySz, myCert.sigType, derCert, FOURK_BUF, + &caKey, NULL, &rng); + if (certSz < 0) { + free(derCert); + free(pem); + FreeRsaKey(&caKey); return -408; + } #ifdef CYASSL_TEST_CERT InitDecodedCert(&decode, derCert, certSz, 0); ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); - if (ret != 0) + if (ret != 0) { + free(derCert); + free(pem); + FreeRsaKey(&caKey); return -409; + } FreeDecodedCert(&decode); #endif derFile = fopen("./othercert.der", "wb"); - if (!derFile) + if (!derFile) { + free(derCert); + free(pem); + FreeRsaKey(&caKey); return -410; - ret = fwrite(derCert, certSz, 1, derFile); + } + ret = (int)fwrite(derCert, 1, certSz, derFile); fclose(derFile); - - pemSz = DerToPem(derCert, certSz, pem, sizeof(pem), CERT_TYPE); - if (pemSz < 0) + if (ret != certSz) { + free(derCert); + free(pem); + FreeRsaKey(&caKey); + return -416; + } + + pemSz = DerToPem(derCert, certSz, pem, FOURK_BUF, CERT_TYPE); + if (pemSz < 0) { + free(derCert); + free(pem); + FreeRsaKey(&caKey); return -411; + } pemFile = fopen("./othercert.pem", "wb"); - if (!pemFile) + if (!pemFile) { + free(derCert); + free(pem); + FreeRsaKey(&caKey); return -412; - ret = fwrite(pem, pemSz, 1, pemFile); + } + ret = (int)fwrite(pem, 1, pemSz, pemFile); + if (ret != pemSz) { + free(derCert); + free(pem); + FreeRsaKey(&caKey); + return -415; + } + fclose(pemFile); + free(pem); + free(derCert); + FreeRsaKey(&caKey); + } +#ifdef HAVE_ECC + /* ECC CA style */ + { + ecc_key caKey; + Cert myCert; + byte* derCert; + byte* pem; + FILE* derFile; + FILE* pemFile; + int certSz; + int pemSz; + size_t bytes3; + word32 idx3 = 0; + FILE* file3; +#ifdef CYASSL_TEST_CERT + DecodedCert decode; +#endif + + derCert = (byte*)malloc(FOURK_BUF); + if (derCert == NULL) + return -5311; + pem = (byte*)malloc(FOURK_BUF); + if (pem == NULL) { + free(derCert); + return -5312; + } + + file3 = fopen(eccCaKeyFile, "rb"); + + if (!file3) { + free(derCert); + free(pem); + return -5412; + } + + bytes3 = fread(tmp, 1, FOURK_BUF, file3); + fclose(file3); + + ecc_init(&caKey); + ret = EccPrivateKeyDecode(tmp, &idx3, &caKey, (word32)bytes3); + if (ret != 0) { + free(derCert); + free(pem); + return -5413; + } + + InitCert(&myCert); + myCert.sigType = CTC_SHA256wECDSA; + + strncpy(myCert.subject.country, "US", CTC_NAME_SIZE); + strncpy(myCert.subject.state, "OR", CTC_NAME_SIZE); + strncpy(myCert.subject.locality, "Portland", CTC_NAME_SIZE); + strncpy(myCert.subject.org, "wolfSSL", CTC_NAME_SIZE); + strncpy(myCert.subject.unit, "Development", CTC_NAME_SIZE); + strncpy(myCert.subject.commonName, "www.wolfssl.com", CTC_NAME_SIZE); + strncpy(myCert.subject.email, "info@wolfssl.com", CTC_NAME_SIZE); + + ret = SetIssuer(&myCert, eccCaCertFile); + if (ret < 0) { + free(pem); + free(derCert); + ecc_free(&caKey); + return -5405; + } + + certSz = MakeCert(&myCert, derCert, FOURK_BUF, NULL, &caKey, &rng); + if (certSz < 0) { + free(pem); + free(derCert); + ecc_free(&caKey); + return -5407; + } + + certSz = SignCert(myCert.bodySz, myCert.sigType, derCert, FOURK_BUF, + NULL, &caKey, &rng); + if (certSz < 0) { + free(pem); + free(derCert); + ecc_free(&caKey); + return -5408; + } + +#ifdef CYASSL_TEST_CERT + InitDecodedCert(&decode, derCert, certSz, 0); + ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); + if (ret != 0) { + free(pem); + free(derCert); + ecc_free(&caKey); + return -5409; + } + FreeDecodedCert(&decode); +#endif + + derFile = fopen("./certecc.der", "wb"); + if (!derFile) { + free(pem); + free(derCert); + ecc_free(&caKey); + return -5410; + } + ret = (int)fwrite(derCert, 1, certSz, derFile); + fclose(derFile); + if (ret != certSz) { + free(pem); + free(derCert); + ecc_free(&caKey); + return -5414; + } + + pemSz = DerToPem(derCert, certSz, pem, FOURK_BUF, CERT_TYPE); + if (pemSz < 0) { + free(pem); + free(derCert); + ecc_free(&caKey); + return -5411; + } + + pemFile = fopen("./certecc.pem", "wb"); + if (!pemFile) { + free(pem); + free(derCert); + ecc_free(&caKey); + return -5412; + } + ret = (int)fwrite(pem, 1, pemSz, pemFile); + if (ret != pemSz) { + free(pem); + free(derCert); + ecc_free(&caKey); + return -5415; + } fclose(pemFile); + free(pem); + free(derCert); + ecc_free(&caKey); } +#endif /* HAVE_ECC */ #ifdef HAVE_NTRU { RsaKey caKey; Cert myCert; - byte derCert[4096]; - byte pem[4096]; + byte* derCert; + byte* pem; FILE* derFile; FILE* pemFile; FILE* caFile; FILE* ntruPrivFile; int certSz; int pemSz; - byte tmp[2048]; - size_t bytes; - word32 idx = 0; + word32 idx3; #ifdef CYASSL_TEST_CERT DecodedCert decode; #endif + derCert = (byte*)malloc(FOURK_BUF); + if (derCert == NULL) + return -311; + pem = (byte*)malloc(FOURK_BUF); + if (pem == NULL) { + free(derCert); + return -312; + } byte public_key[557]; /* sized for EES401EP2 */ word16 public_key_len; /* no. of octets in public key */ @@ -1660,34 +3370,63 @@ int rsa_test() static uint8_t const pers_str[] = { 'C', 'y', 'a', 'S', 'S', 'L', ' ', 't', 'e', 's', 't' }; - word32 rc = crypto_drbg_instantiate(112, pers_str, sizeof(pers_str), - GetEntropy, &drbg); - if (rc != DRBG_OK) + word32 rc = ntru_crypto_drbg_instantiate(112, pers_str, + sizeof(pers_str), GetEntropy, &drbg); + if (rc != DRBG_OK) { + free(derCert); + free(pem); + return -448; + } + + rc = ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, + &public_key_len, NULL, + &private_key_len, NULL); + if (rc != NTRU_OK) { + free(derCert); + free(pem); + return -449; + } + + rc = ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, + &public_key_len, public_key, + &private_key_len, private_key); + if (rc != NTRU_OK) { + free(derCert); + free(pem); return -450; + } - rc = crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, &public_key_len, - NULL, &private_key_len, NULL); - if (rc != NTRU_OK) + rc = ntru_crypto_drbg_uninstantiate(drbg); + + if (rc != NTRU_OK) { + free(derCert); + free(pem); return -451; + } - rc = crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, &public_key_len, - public_key, &private_key_len, private_key); - crypto_drbg_uninstantiate(drbg); + caFile = fopen(caKeyFile, "rb"); - if (rc != NTRU_OK) + if (!caFile) { + free(derCert); + free(pem); return -452; + } - caFile = fopen(caKeyFile, "rb"); + bytes = fread(tmp, 1, FOURK_BUF, caFile); + fclose(caFile); - if (!caFile) + ret = InitRsaKey(&caKey, 0); + if (ret != 0) { + free(derCert); + free(pem); return -453; - - bytes = fread(tmp, 1, sizeof(tmp), caFile); - fclose(caFile); - - InitRsaKey(&caKey, 0); - ret = RsaPrivateKeyDecode(tmp, &idx, &caKey, (word32)bytes); - if (ret != 0) return -454; + } + ret = RsaPrivateKeyDecode(tmp, &idx3, &caKey, (word32)bytes); + if (ret != 0) { + free(derCert); + free(pem); + return -454; + } InitCert(&myCert); @@ -1700,62 +3439,206 @@ int rsa_test() strncpy(myCert.subject.email, "info@yassl.com", CTC_NAME_SIZE); ret = SetIssuer(&myCert, caCertFile); - if (ret < 0) + if (ret < 0) { + free(derCert); + free(pem); + FreeRsaKey(&caKey); return -455; - - certSz = MakeNtruCert(&myCert, derCert, sizeof(derCert), public_key, - public_key_len, &rng); - if (certSz < 0) + } + + certSz = MakeNtruCert(&myCert, derCert, FOURK_BUF, public_key, + public_key_len, &rng); + if (certSz < 0) { + free(derCert); + free(pem); + FreeRsaKey(&caKey); return -456; - - certSz = SignCert(&myCert, derCert, sizeof(derCert), &caKey, &rng); - if (certSz < 0) + } + + certSz = SignCert(myCert.bodySz, myCert.sigType, derCert, FOURK_BUF, + &caKey, NULL, &rng); + FreeRsaKey(&caKey); + if (certSz < 0) { + free(derCert); + free(pem); return -457; + } #ifdef CYASSL_TEST_CERT InitDecodedCert(&decode, derCert, certSz, 0); ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); - if (ret != 0) + if (ret != 0) { + free(derCert); + free(pem); return -458; + } FreeDecodedCert(&decode); #endif derFile = fopen("./ntru-cert.der", "wb"); - if (!derFile) + if (!derFile) { + free(derCert); + free(pem); return -459; - ret = fwrite(derCert, certSz, 1, derFile); + } + ret = (int)fwrite(derCert, 1, certSz, derFile); fclose(derFile); - - pemSz = DerToPem(derCert, certSz, pem, sizeof(pem), CERT_TYPE); - if (pemSz < 0) + if (ret != certSz) { + free(derCert); + free(pem); + return -473; + } + + pemSz = DerToPem(derCert, certSz, pem, FOURK_BUF, CERT_TYPE); + if (pemSz < 0) { + free(derCert); + free(pem); return -460; + } pemFile = fopen("./ntru-cert.pem", "wb"); - if (!pemFile) + if (!pemFile) { + free(derCert); + free(pem); return -461; - ret = fwrite(pem, pemSz, 1, pemFile); + } + ret = (int)fwrite(pem, 1, pemSz, pemFile); fclose(pemFile); + if (ret != pemSz) { + free(derCert); + free(pem); + return -474; + } ntruPrivFile = fopen("./ntru-key.raw", "wb"); - if (!ntruPrivFile) + if (!ntruPrivFile) { + free(derCert); + free(pem); return -462; - ret = fwrite(private_key, private_key_len, 1, ntruPrivFile); + } + ret = (int)fwrite(private_key, 1, private_key_len, ntruPrivFile); fclose(ntruPrivFile); + if (ret != private_key_len) { + free(pem); + free(derCert); + return -475; + } + free(pem); + free(derCert); } #endif /* HAVE_NTRU */ +#ifdef CYASSL_CERT_REQ + { + Cert req; + byte* der; + byte* pem; + int derSz; + int pemSz; + FILE* reqFile; + + der = (byte*)malloc(FOURK_BUF); + if (der == NULL) + return -463; + pem = (byte*)malloc(FOURK_BUF); + if (pem == NULL) { + free(der); + return -464; + } + + InitCert(&req); + + req.version = 0; + req.isCA = 1; + strncpy(req.challengePw, "yassl123", CTC_NAME_SIZE); + strncpy(req.subject.country, "US", CTC_NAME_SIZE); + strncpy(req.subject.state, "OR", CTC_NAME_SIZE); + strncpy(req.subject.locality, "Portland", CTC_NAME_SIZE); + strncpy(req.subject.org, "yaSSL", CTC_NAME_SIZE); + strncpy(req.subject.unit, "Development", CTC_NAME_SIZE); + strncpy(req.subject.commonName, "www.yassl.com", CTC_NAME_SIZE); + strncpy(req.subject.email, "info@yassl.com", CTC_NAME_SIZE); + req.sigType = CTC_SHA256wRSA; + + derSz = MakeCertReq(&req, der, FOURK_BUF, &key, NULL); + if (derSz < 0) { + free(pem); + free(der); + return -465; + } + + derSz = SignCert(req.bodySz, req.sigType, der, FOURK_BUF, + &key, NULL, &rng); + if (derSz < 0) { + free(pem); + free(der); + return -466; + } + + pemSz = DerToPem(der, derSz, pem, FOURK_BUF, CERTREQ_TYPE); + if (pemSz < 0) { + free(pem); + free(der); + return -467; + } + + reqFile = fopen("./certreq.der", "wb"); + if (!reqFile) { + free(pem); + free(der); + return -468; + } + + ret = (int)fwrite(der, 1, derSz, reqFile); + fclose(reqFile); + if (ret != derSz) { + free(pem); + free(der); + return -471; + } + + reqFile = fopen("./certreq.pem", "wb"); + if (!reqFile) { + free(pem); + free(der); + return -469; + } + ret = (int)fwrite(pem, 1, pemSz, reqFile); + fclose(reqFile); + if (ret != pemSz) { + free(pem); + free(der); + return -470; + } + + free(pem); + free(der); + } +#endif /* CYASSL_CERT_REQ */ #endif /* CYASSL_CERT_GEN */ FreeRsaKey(&key); +#ifdef HAVE_CAVIUM + RsaFreeCavium(&key); +#endif + free(tmp); return 0; } +#endif -static const char* dhKey = "./certs/dh2048.der"; #ifndef NO_DH -int dh_test() +#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) + #ifdef FREESCALE_MQX + static const char* dhKey = "a:\certs\\dh2048.der"; + #else + static const char* dhKey = "./certs/dh2048.der"; + #endif +#endif + +int dh_test(void) { int ret; word32 bytes; @@ -1770,15 +3653,26 @@ int dh_test() DhKey key; DhKey key2; RNG rng; + + +#ifdef USE_CERT_BUFFERS_1024 + XMEMCPY(tmp, dh_key_der_1024, sizeof_dh_key_der_1024); + bytes = sizeof_dh_key_der_1024; +#elif defined(USE_CERT_BUFFERS_2048) + XMEMCPY(tmp, dh_key_der_2048, sizeof_dh_key_der_2048); + bytes = sizeof_dh_key_der_2048; +#else FILE* file = fopen(dhKey, "rb"); if (!file) return -50; bytes = (word32) fread(tmp, 1, sizeof(tmp), file); + fclose(file); +#endif /* USE_CERT_BUFFERS */ - InitDhKey(&key); - InitDhKey(&key2); + InitDhKey(&key); + InitDhKey(&key2); ret = DhKeyDecode(tmp, &idx, &key, bytes); if (ret != 0) return -51; @@ -1791,14 +3685,14 @@ int dh_test() ret = InitRng(&rng); if (ret != 0) return -53; - - ret = DhGenerateKeyPair(&key, &rng, priv, &privSz, pub, &pubSz); - ret = DhGenerateKeyPair(&key2, &rng, priv2, &privSz2, pub2, &pubSz2); + + ret = DhGenerateKeyPair(&key, &rng, priv, &privSz, pub, &pubSz); + ret += DhGenerateKeyPair(&key2, &rng, priv2, &privSz2, pub2, &pubSz2); if (ret != 0) return -54; - ret = DhAgree(&key, agree, &agreeSz, priv, privSz, pub2, pubSz2); - ret = DhAgree(&key2, agree2, &agreeSz2, priv2, privSz2, pub, pubSz); + ret = DhAgree(&key, agree, &agreeSz, priv, privSz, pub2, pubSz2); + ret += DhAgree(&key2, agree2, &agreeSz2, priv2, privSz2, pub, pubSz); if (ret != 0) return -55; @@ -1807,7 +3701,6 @@ int dh_test() FreeDhKey(&key); FreeDhKey(&key2); - fclose(file); return 0; } @@ -1815,11 +3708,17 @@ int dh_test() #endif /* NO_DH */ -static const char* dsaKey = "./certs/dsa2048.der"; - #ifndef NO_DSA -int dsa_test() +#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) + #ifdef FREESCALE_MQX + static const char* dsaKey = "a:\\certs\\dsa2048.der"; + #else + static const char* dsaKey = "./certs/dsa2048.der"; + #endif +#endif + +int dsa_test(void) { int ret, answer; word32 bytes; @@ -1827,17 +3726,30 @@ int dsa_test() byte tmp[1024]; DsaKey key; RNG rng; - FILE* file = fopen(dsaKey, "rb"); Sha sha; byte hash[SHA_DIGEST_SIZE]; byte signature[40]; + +#ifdef USE_CERT_BUFFERS_1024 + XMEMCPY(tmp, dsa_key_der_1024, sizeof_dsa_key_der_1024); + bytes = sizeof_dsa_key_der_1024; +#elif defined(USE_CERT_BUFFERS_2048) + XMEMCPY(tmp, dsa_key_der_2048, sizeof_dsa_key_der_2048); + bytes = sizeof_dsa_key_der_2048; +#else + FILE* file = fopen(dsaKey, "rb"); + if (!file) return -60; bytes = (word32) fread(tmp, 1, sizeof(tmp), file); - - InitSha(&sha); + fclose(file); +#endif /* USE_CERT_BUFFERS */ + + ret = InitSha(&sha); + if (ret != 0) + return -4002; ShaUpdate(&sha, tmp, bytes); ShaFinal(&sha, hash); @@ -1854,10 +3766,9 @@ int dsa_test() ret = DsaVerify(hash, signature, &key, &answer); if (ret != 0) return -64; if (answer != 1) return -65; - + FreeDsaKey(&key); - fclose(file); - + return 0; } @@ -1866,7 +3777,7 @@ int dsa_test() #ifdef OPENSSL_EXTRA -int openssl_test() +int openssl_test(void) { EVP_MD_CTX md_ctx; testVector a, b, c, d, e, f; @@ -1880,12 +3791,12 @@ int openssl_test() a.output = "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55\xac\x49\xda\x2e\x21\x07\xb6" "\x7a"; a.inLen = strlen(a.input); - a.outLen = strlen(a.output); + a.outLen = MD5_DIGEST_SIZE; EVP_MD_CTX_init(&md_ctx); EVP_DigestInit(&md_ctx, EVP_md5()); - EVP_DigestUpdate(&md_ctx, a.input, a.inLen); + EVP_DigestUpdate(&md_ctx, a.input, (unsigned long)a.inLen); EVP_DigestFinal(&md_ctx, hash, 0); if (memcmp(hash, a.output, MD5_DIGEST_SIZE) != 0) @@ -1897,12 +3808,12 @@ int openssl_test() b.output = "\xAD\x5B\x3F\xDB\xCB\x52\x67\x78\xC2\x83\x9D\x2F\x15\x1E\xA7" "\x53\x99\x5E\x26\xA0"; b.inLen = strlen(b.input); - b.outLen = strlen(b.output); + b.outLen = SHA_DIGEST_SIZE; EVP_MD_CTX_init(&md_ctx); EVP_DigestInit(&md_ctx, EVP_sha1()); - EVP_DigestUpdate(&md_ctx, b.input, b.inLen); + EVP_DigestUpdate(&md_ctx, b.input, (unsigned long)b.inLen); EVP_DigestFinal(&md_ctx, hash, 0); if (memcmp(hash, b.output, SHA_DIGEST_SIZE) != 0) @@ -1914,12 +3825,12 @@ int openssl_test() "\x39\xA3\x3C\xE4\x59\x64\xFF\x21\x67\xF6\xEC\xED\xD4\x19\xDB" "\x06\xC1"; d.inLen = strlen(d.input); - d.outLen = strlen(d.output); + d.outLen = SHA256_DIGEST_SIZE; EVP_MD_CTX_init(&md_ctx); EVP_DigestInit(&md_ctx, EVP_sha256()); - EVP_DigestUpdate(&md_ctx, d.input, d.inLen); + EVP_DigestUpdate(&md_ctx, d.input, (unsigned long)d.inLen); EVP_DigestFinal(&md_ctx, hash, 0); if (memcmp(hash, d.output, SHA256_DIGEST_SIZE) != 0) @@ -1932,9 +3843,9 @@ int openssl_test() e.output = "\x09\x33\x0c\x33\xf7\x11\x47\xe8\x3d\x19\x2f\xc7\x82\xcd\x1b" "\x47\x53\x11\x1b\x17\x3b\x3b\x05\xd2\x2f\xa0\x80\x86\xe3\xb0" "\xf7\x12\xfc\xc7\xc7\x1a\x55\x7e\x2d\xb9\x66\xc3\xe9\xfa\x91" - "\x74\x60\x39"; + "\x74\x60\x39"; e.inLen = strlen(e.input); - e.outLen = strlen(e.output); + e.outLen = SHA384_DIGEST_SIZE; EVP_MD_CTX_init(&md_ctx); EVP_DigestInit(&md_ctx, EVP_sha384()); @@ -1956,14 +3867,14 @@ int openssl_test() "\x3f\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88" "\x90\x18\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4" "\xb5\x43\x3a\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b" - "\x87\x4b\xe9\x09"; + "\x87\x4b\xe9\x09"; f.inLen = strlen(f.input); - f.outLen = strlen(f.output); + f.outLen = SHA512_DIGEST_SIZE; EVP_MD_CTX_init(&md_ctx); EVP_DigestInit(&md_ctx, EVP_sha512()); - EVP_DigestUpdate(&md_ctx, f.input, f.inLen); + EVP_DigestUpdate(&md_ctx, f.input, (unsigned long)f.inLen); EVP_DigestFinal(&md_ctx, hash, 0); if (memcmp(hash, f.output, SHA512_DIGEST_SIZE) != 0) @@ -1974,12 +3885,12 @@ int openssl_test() if (RAND_bytes(hash, sizeof(hash)) != 1) return -73; - + c.input = "what do ya want for nothing?"; c.output = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7" "\x38"; c.inLen = strlen(c.input); - c.outLen = strlen(c.output); + c.outLen = MD5_DIGEST_SIZE; HMAC(EVP_md5(), "Jefe", 4, (byte*)c.input, (int)c.inLen, hash, 0); @@ -1996,19 +3907,19 @@ int openssl_test() byte plain[24]; byte cipher[24]; - const_DES_cblock key = + const_DES_cblock key = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef }; - DES_cblock iv = + DES_cblock iv = { 0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef }; DES_key_schedule sched; - const byte verify[] = + const byte verify[] = { 0x8b,0x7c,0x52,0xb0,0x01,0x2b,0x6c,0xb8, 0x4f,0x0f,0xeb,0xf3,0xfb,0x5f,0x86,0x73, @@ -2045,7 +3956,7 @@ int openssl_test() 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20 }; - const byte verify[] = + const byte verify[] = { 0x95,0x94,0x92,0x57,0x5f,0x42,0x81,0x53, 0x2c,0xcc,0x9d,0x46,0x77,0xa2,0x33,0xcb @@ -2088,14 +3999,14 @@ int openssl_test() #ifndef NO_PWDBASED -int pkcs12_test() +int pkcs12_test(void) { const byte passwd[] = { 0x00, 0x73, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x67, - 0x00, 0x00 }; + 0x00, 0x00 }; const byte salt[] = { 0x0a, 0x58, 0xCF, 0x64, 0x53, 0x0d, 0x82, 0x3f }; const byte passwd2[] = { 0x00, 0x71, 0x00, 0x75, 0x00, 0x65, 0x00, 0x65, - 0x00, 0x67, 0x00, 0x00 }; + 0x00, 0x67, 0x00, 0x00 }; const byte salt2[] = { 0x16, 0x82, 0xC0, 0xfC, 0x5b, 0x3f, 0x7e, 0xc5 }; byte derived[64]; @@ -2117,20 +4028,26 @@ int pkcs12_test() int ret = PKCS12_PBKDF(derived, passwd, sizeof(passwd), salt, 8, iterations, kLen, SHA, id); - if ( (ret = memcmp(derived, verify, kLen)) != 0) + if (ret < 0) return -103; + if ( (ret = memcmp(derived, verify, kLen)) != 0) + return -104; + iterations = 1000; - ret = PKCS12_PBKDF(derived, passwd2, sizeof(passwd2), salt2, 8, iterations, + ret = PKCS12_PBKDF(derived, passwd2, sizeof(passwd2), salt2, 8, iterations, kLen, SHA, id); + if (ret < 0) + return -105; + if ( (ret = memcmp(derived, verify2, 24)) != 0) - return -104; + return -106; return 0; } -int pbkdf2_test() +int pbkdf2_test(void) { char passwd[] = "password"; const byte salt[] = { 0x78, 0x57, 0x8E, 0x5a, 0x5d, 0x63, 0xcb, 0x06 }; @@ -2144,8 +4061,10 @@ int pbkdf2_test() }; - PBKDF2(derived, (byte*)passwd, strlen(passwd), salt, 8, iterations, kLen, - SHA); + int ret = PBKDF2(derived, (byte*)passwd, (int)strlen(passwd), salt, 8, + iterations, kLen, SHA); + if (ret != 0) + return ret; if (memcmp(derived, verify, sizeof(verify)) != 0) return -102; @@ -2154,7 +4073,7 @@ int pbkdf2_test() } -int pbkdf1_test() +int pbkdf1_test(void) { char passwd[] = "password"; const byte salt[] = { 0x78, 0x57, 0x8E, 0x5a, 0x5d, 0x63, 0xcb, 0x06 }; @@ -2167,8 +4086,8 @@ int pbkdf1_test() 0x4A, 0x3D, 0x2A, 0x20 }; - PBKDF1(derived, (byte*)passwd, strlen(passwd), salt, 8, iterations, kLen, - SHA); + PBKDF1(derived, (byte*)passwd, (int)strlen(passwd), salt, 8, iterations, + kLen, SHA); if (memcmp(derived, verify, sizeof(verify)) != 0) return -101; @@ -2177,7 +4096,7 @@ int pbkdf1_test() } -int pwdbased_test() +int pwdbased_test(void) { int ret = pbkdf1_test(); ret += pbkdf2_test(); @@ -2187,10 +4106,99 @@ int pwdbased_test() #endif /* NO_PWDBASED */ +#if defined(HAVE_HKDF) && (!defined(NO_SHA) || !defined(NO_SHA256)) + +int hkdf_test(void) +{ + int ret; + int L = 42; + byte okm1[42]; + byte ikm1[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; + byte salt1[13] ={ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c }; + byte info1[10] ={ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9 }; + byte res1[42] = { 0x0a, 0xc1, 0xaf, 0x70, 0x02, 0xb3, 0xd7, 0x61, + 0xd1, 0xe5, 0x52, 0x98, 0xda, 0x9d, 0x05, 0x06, + 0xb9, 0xae, 0x52, 0x05, 0x72, 0x20, 0xa3, 0x06, + 0xe0, 0x7b, 0x6b, 0x87, 0xe8, 0xdf, 0x21, 0xd0, + 0xea, 0x00, 0x03, 0x3d, 0xe0, 0x39, 0x84, 0xd3, + 0x49, 0x18 }; + byte res2[42] = { 0x08, 0x5a, 0x01, 0xea, 0x1b, 0x10, 0xf3, 0x69, + 0x33, 0x06, 0x8b, 0x56, 0xef, 0xa5, 0xad, 0x81, + 0xa4, 0xf1, 0x4b, 0x82, 0x2f, 0x5b, 0x09, 0x15, + 0x68, 0xa9, 0xcd, 0xd4, 0xf1, 0x55, 0xfd, 0xa2, + 0xc2, 0x2e, 0x42, 0x24, 0x78, 0xd3, 0x05, 0xf3, + 0xf8, 0x96 }; + byte res3[42] = { 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, + 0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31, + 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e, + 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d, + 0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a, + 0x96, 0xc8 }; + byte res4[42] = { 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, + 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a, + 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c, + 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, + 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, + 0x58, 0x65 }; + + (void)res1; + (void)res2; + (void)res3; + (void)res4; + (void)salt1; + (void)info1; + +#ifndef NO_SHA + ret = HKDF(SHA, ikm1, 22, NULL, 0, NULL, 0, okm1, L); + if (ret != 0) + return -2001; + + if (memcmp(okm1, res1, L) != 0) + return -2002; + +#ifndef HAVE_FIPS + /* fips can't have key size under 14 bytes, salt is key too */ + ret = HKDF(SHA, ikm1, 11, salt1, 13, info1, 10, okm1, L); + if (ret != 0) + return -2003; + + if (memcmp(okm1, res2, L) != 0) + return -2004; +#endif /* HAVE_FIPS */ +#endif /* NO_SHA */ + +#ifndef NO_SHA256 + ret = HKDF(SHA256, ikm1, 22, NULL, 0, NULL, 0, okm1, L); + if (ret != 0) + return -2005; + + if (memcmp(okm1, res3, L) != 0) + return -2006; + +#ifndef HAVE_FIPS + /* fips can't have key size under 14 bytes, salt is key too */ + ret = HKDF(SHA256, ikm1, 22, salt1, 13, info1, 10, okm1, L); + if (ret != 0) + return -2007; + + if (memcmp(okm1, res4, L) != 0) + return -2007; +#endif /* HAVE_FIPS */ +#endif /* NO_SHA256 */ + + return 0; +} + +#endif /* HAVE_HKDF */ + #ifdef HAVE_ECC -int ecc_test() +int ecc_test(void) { RNG rng; byte sharedA[1024]; @@ -2211,6 +4219,10 @@ int ecc_test() ecc_init(&pubKey); ret = ecc_make_key(&rng, 32, &userA); + + if (ret != 0) + return -1014; + ret = ecc_make_key(&rng, 32, &userB); if (ret != 0) @@ -2218,10 +4230,13 @@ int ecc_test() x = sizeof(sharedA); ret = ecc_shared_secret(&userA, &userB, sharedA, &x); - + + if (ret != 0) + return -1015; + y = sizeof(sharedB); ret = ecc_shared_secret(&userB, &userA, sharedB, &y); - + if (ret != 0) return -1003; @@ -2238,12 +4253,12 @@ int ecc_test() ret = ecc_import_x963(exportBuf, x, &pubKey); - if (ret != 0) + if (ret != 0) return -1007; y = sizeof(sharedB); ret = ecc_shared_secret(&userB, &pubKey, sharedB, &y); - + if (ret != 0) return -1008; @@ -2251,12 +4266,15 @@ int ecc_test() return -1010; /* test DSA sign hash */ - for (i = 0; i < sizeof(digest); i++) - digest[i] = i; + for (i = 0; i < (int)sizeof(digest); i++) + digest[i] = (byte)i; x = sizeof(sig); ret = ecc_sign_hash(digest, sizeof(digest), sig, &x, &rng, &userA); - + + if (ret != 0) + return -1016; + verify = 0; ret = ecc_verify_hash(sig, x, digest, sizeof(digest), &verify, &userA); @@ -2266,6 +4284,11 @@ int ecc_test() if (verify != 1) return -1012; + x = sizeof(exportBuf); + ret = ecc_export_private_only(&userA, exportBuf, &x); + if (ret != 0) + return -1013; + ecc_free(&pubKey); ecc_free(&userB); ecc_free(&userA); @@ -2273,4 +4296,568 @@ int ecc_test() return 0; } +#ifdef HAVE_ECC_ENCRYPT + +int ecc_encrypt_test(void) +{ + RNG rng; + int ret; + ecc_key userA, userB; + byte msg[48]; + byte plain[48]; + byte out[80]; + word32 outSz = sizeof(out); + word32 plainSz = sizeof(plain); + int i; + + ret = InitRng(&rng); + if (ret != 0) + return -3001; + + ecc_init(&userA); + ecc_init(&userB); + + ret = ecc_make_key(&rng, 32, &userA); + ret += ecc_make_key(&rng, 32, &userB); + + if (ret != 0) + return -3002; + + for (i = 0; i < 48; i++) + msg[i] = i; + + /* encrypt msg to B */ + ret = ecc_encrypt(&userA, &userB, msg, sizeof(msg), out, &outSz, NULL); + if (ret != 0) + return -3003; + + /* decrypt msg from A */ + ret = ecc_decrypt(&userB, &userA, out, outSz, plain, &plainSz, NULL); + if (ret != 0) + return -3004; + + if (memcmp(plain, msg, sizeof(msg)) != 0) + return -3005; + + + { /* let's verify message exchange works, A is client, B is server */ + ecEncCtx* cliCtx = ecc_ctx_new(REQ_RESP_CLIENT, &rng); + ecEncCtx* srvCtx = ecc_ctx_new(REQ_RESP_SERVER, &rng); + + byte cliSalt[EXCHANGE_SALT_SZ]; + byte srvSalt[EXCHANGE_SALT_SZ]; + const byte* tmpSalt; + + if (cliCtx == NULL || srvCtx == NULL) + return -3006; + + /* get salt to send to peer */ + tmpSalt = ecc_ctx_get_own_salt(cliCtx); + if (tmpSalt == NULL) + return -3007; + memcpy(cliSalt, tmpSalt, EXCHANGE_SALT_SZ); + + tmpSalt = ecc_ctx_get_own_salt(srvCtx); + if (tmpSalt == NULL) + return -3007; + memcpy(srvSalt, tmpSalt, EXCHANGE_SALT_SZ); + + /* in actual use, we'd get the peer's salt over the transport */ + ret = ecc_ctx_set_peer_salt(cliCtx, srvSalt); + ret += ecc_ctx_set_peer_salt(srvCtx, cliSalt); + + ret += ecc_ctx_set_info(cliCtx, (byte*)"CyaSSL MSGE", 11); + ret += ecc_ctx_set_info(srvCtx, (byte*)"CyaSSL MSGE", 11); + + if (ret != 0) + return -3008; + + /* get encrypted msg (request) to send to B */ + outSz = sizeof(out); + ret = ecc_encrypt(&userA, &userB, msg, sizeof(msg), out, &outSz,cliCtx); + if (ret != 0) + return -3009; + + /* B decrypts msg (request) from A */ + plainSz = sizeof(plain); + ret = ecc_decrypt(&userB, &userA, out, outSz, plain, &plainSz, srvCtx); + if (ret != 0) + return -3010; + + if (memcmp(plain, msg, sizeof(msg)) != 0) + return -3011; + + { + /* msg2 (response) from B to A */ + byte msg2[48]; + byte plain2[48]; + byte out2[80]; + word32 outSz2 = sizeof(out2); + word32 plainSz2 = sizeof(plain2); + + for (i = 0; i < 48; i++) + msg2[i] = i+48; + + /* get encrypted msg (response) to send to B */ + ret = ecc_encrypt(&userB, &userA, msg2, sizeof(msg2), out2, + &outSz2, srvCtx); + if (ret != 0) + return -3012; + + /* A decrypts msg (response) from B */ + ret = ecc_decrypt(&userA, &userB, out2, outSz2, plain2, &plainSz2, + cliCtx); + if (ret != 0) + return -3013; + + if (memcmp(plain2, msg2, sizeof(msg2)) != 0) + return -3014; + } + + /* cleanup */ + ecc_ctx_free(srvCtx); + ecc_ctx_free(cliCtx); + } + + /* cleanup */ + ecc_free(&userB); + ecc_free(&userA); + + return 0; +} + +#endif /* HAVE_ECC_ENCRYPT */ #endif /* HAVE_ECC */ + +#ifdef HAVE_LIBZ + +const byte sample_text[] = + "Biodiesel cupidatat marfa, cliche aute put a bird on it incididunt elit\n" + "polaroid. Sunt tattooed bespoke reprehenderit. Sint twee organic id\n" + "marfa. Commodo veniam ad esse gastropub. 3 wolf moon sartorial vero,\n" + "plaid delectus biodiesel squid +1 vice. Post-ironic keffiyeh leggings\n" + "selfies cray fap hoodie, forage anim. Carles cupidatat shoreditch, VHS\n" + "small batch meggings kogi dolore food truck bespoke gastropub.\n" + "\n" + "Terry richardson adipisicing actually typewriter tumblr, twee whatever\n" + "four loko you probably haven't heard of them high life. Messenger bag\n" + "whatever tattooed deep v mlkshk. Brooklyn pinterest assumenda chillwave\n" + "et, banksy ullamco messenger bag umami pariatur direct trade forage.\n" + "Typewriter culpa try-hard, pariatur sint brooklyn meggings. Gentrify\n" + "food truck next level, tousled irony non semiotics PBR ethical anim cred\n" + "readymade. Mumblecore brunch lomo odd future, portland organic terry\n" + "richardson elit leggings adipisicing ennui raw denim banjo hella. Godard\n" + "mixtape polaroid, pork belly readymade organic cray typewriter helvetica\n" + "four loko whatever street art yr farm-to-table.\n" + "\n" + "Vinyl keytar vice tofu. Locavore you probably haven't heard of them pug\n" + "pickled, hella tonx labore truffaut DIY mlkshk elit cosby sweater sint\n" + "et mumblecore. Elit swag semiotics, reprehenderit DIY sartorial nisi ugh\n" + "nesciunt pug pork belly wayfarers selfies delectus. Ethical hoodie\n" + "seitan fingerstache kale chips. Terry richardson artisan williamsburg,\n" + "eiusmod fanny pack irony tonx ennui lo-fi incididunt tofu YOLO\n" + "readymade. 8-bit sed ethnic beard officia. Pour-over iphone DIY butcher,\n" + "ethnic art party qui letterpress nisi proident jean shorts mlkshk\n" + "locavore.\n" + "\n" + "Narwhal flexitarian letterpress, do gluten-free voluptate next level\n" + "banh mi tonx incididunt carles DIY. Odd future nulla 8-bit beard ut\n" + "cillum pickled velit, YOLO officia you probably haven't heard of them\n" + "trust fund gastropub. Nisi adipisicing tattooed, Austin mlkshk 90's\n" + "small batch american apparel. Put a bird on it cosby sweater before they\n" + "sold out pork belly kogi hella. Street art mollit sustainable polaroid,\n" + "DIY ethnic ea pug beard dreamcatcher cosby sweater magna scenester nisi.\n" + "Sed pork belly skateboard mollit, labore proident eiusmod. Sriracha\n" + "excepteur cosby sweater, anim deserunt laborum eu aliquip ethical et\n" + "neutra PBR selvage.\n" + "\n" + "Raw denim pork belly truffaut, irony plaid sustainable put a bird on it\n" + "next level jean shorts exercitation. Hashtag keytar whatever, nihil\n" + "authentic aliquip disrupt laborum. Tattooed selfies deserunt trust fund\n" + "wayfarers. 3 wolf moon synth church-key sartorial, gastropub leggings\n" + "tattooed. Labore high life commodo, meggings raw denim fingerstache pug\n" + "trust fund leggings seitan forage. Nostrud ullamco duis, reprehenderit\n" + "incididunt flannel sustainable helvetica pork belly pug banksy you\n" + "probably haven't heard of them nesciunt farm-to-table. Disrupt nostrud\n" + "mollit magna, sriracha sartorial helvetica.\n" + "\n" + "Nulla kogi reprehenderit, skateboard sustainable duis adipisicing viral\n" + "ad fanny pack salvia. Fanny pack trust fund you probably haven't heard\n" + "of them YOLO vice nihil. Keffiyeh cray lo-fi pinterest cardigan aliqua,\n" + "reprehenderit aute. Culpa tousled williamsburg, marfa lomo actually anim\n" + "skateboard. Iphone aliqua ugh, semiotics pariatur vero readymade\n" + "organic. Marfa squid nulla, in laborum disrupt laboris irure gastropub.\n" + "Veniam sunt food truck leggings, sint vinyl fap.\n" + "\n" + "Hella dolore pork belly, truffaut carles you probably haven't heard of\n" + "them PBR helvetica in sapiente. Fashion axe ugh bushwick american\n" + "apparel. Fingerstache sed iphone, jean shorts blue bottle nisi bushwick\n" + "flexitarian officia veniam plaid bespoke fap YOLO lo-fi. Blog\n" + "letterpress mumblecore, food truck id cray brooklyn cillum ad sed.\n" + "Assumenda chambray wayfarers vinyl mixtape sustainable. VHS vinyl\n" + "delectus, culpa williamsburg polaroid cliche swag church-key synth kogi\n" + "magna pop-up literally. Swag thundercats ennui shoreditch vegan\n" + "pitchfork neutra truffaut etsy, sed single-origin coffee craft beer.\n" + "\n" + "Odio letterpress brooklyn elit. Nulla single-origin coffee in occaecat\n" + "meggings. Irony meggings 8-bit, chillwave lo-fi adipisicing cred\n" + "dreamcatcher veniam. Put a bird on it irony umami, trust fund bushwick\n" + "locavore kale chips. Sriracha swag thundercats, chillwave disrupt\n" + "tousled beard mollit mustache leggings portland next level. Nihil esse\n" + "est, skateboard art party etsy thundercats sed dreamcatcher ut iphone\n" + "swag consectetur et. Irure skateboard banjo, nulla deserunt messenger\n" + "bag dolor terry richardson sapiente.\n"; + + +int compress_test(void) +{ + int ret = 0; + word32 dSz = sizeof(sample_text); + word32 cSz = (dSz + (word32)(dSz * 0.001) + 12); + byte *c = NULL; + byte *d = NULL; + + c = calloc(cSz, sizeof(byte)); + d = calloc(dSz, sizeof(byte)); + + if (c == NULL || d == NULL) + ret = -300; + + if (ret == 0 && (ret = Compress(c, cSz, sample_text, dSz, 0)) < 0) + ret = -301; + + if (ret > 0) { + cSz = (word32)ret; + ret = 0; + } + + if (ret == 0 && DeCompress(d, dSz, c, cSz) != (int)dSz) + ret = -302; + + if (ret == 0 && memcmp(d, sample_text, dSz)) + ret = -303; + + if (c) free(c); + if (d) free(d); + + return ret; +} + +#endif /* HAVE_LIBZ */ + +#ifdef HAVE_PKCS7 + +int pkcs7enveloped_test(void) +{ + int ret = 0; + + int cipher = DES3b; + int envelopedSz, decodedSz; + PKCS7 pkcs7; + byte* cert; + byte* privKey; + byte enveloped[2048]; + byte decoded[2048]; + + size_t certSz; + size_t privKeySz; + FILE* certFile; + FILE* keyFile; + FILE* pkcs7File; + const char* pkcs7OutFile = "pkcs7envelopedData.der"; + + const byte data[] = { /* Hello World */ + 0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f, + 0x72,0x6c,0x64 + }; + + /* read client cert and key in DER format */ + cert = (byte*)malloc(FOURK_BUF); + if (cert == NULL) + return -201; + + privKey = (byte*)malloc(FOURK_BUF); + if (privKey == NULL) { + free(cert); + return -202; + } + + certFile = fopen(clientCert, "rb"); + if (!certFile) { + free(cert); + free(privKey); + err_sys("can't open ./certs/client-cert.der, " + "Please run from CyaSSL home dir", -42); + } + + certSz = fread(cert, 1, FOURK_BUF, certFile); + fclose(certFile); + + keyFile = fopen(clientKey, "rb"); + if (!keyFile) { + free(cert); + free(privKey); + err_sys("can't open ./certs/client-key.der, " + "Please run from CyaSSL home dir", -43); + } + + privKeySz = fread(privKey, 1, FOURK_BUF, keyFile); + fclose(keyFile); + + PKCS7_InitWithCert(&pkcs7, cert, (word32)certSz); + pkcs7.content = (byte*)data; + pkcs7.contentSz = (word32)sizeof(data); + pkcs7.contentOID = DATA; + pkcs7.encryptOID = cipher; + pkcs7.privateKey = privKey; + pkcs7.privateKeySz = (word32)privKeySz; + + /* encode envelopedData */ + envelopedSz = PKCS7_EncodeEnvelopedData(&pkcs7, enveloped, + sizeof(enveloped)); + if (envelopedSz <= 0) { + free(cert); + free(privKey); + return -203; + } + + /* decode envelopedData */ + decodedSz = PKCS7_DecodeEnvelopedData(&pkcs7, enveloped, envelopedSz, + decoded, sizeof(decoded)); + if (decodedSz <= 0) { + free(cert); + free(privKey); + return -204; + } + + /* test decode result */ + if (memcmp(decoded, data, sizeof(data)) != 0) { + free(cert); + free(privKey); + return -205; + } + + /* output pkcs7 envelopedData for external testing */ + pkcs7File = fopen(pkcs7OutFile, "wb"); + if (!pkcs7File) { + free(cert); + free(privKey); + return -206; + } + + ret = (int)fwrite(enveloped, envelopedSz, 1, pkcs7File); + fclose(pkcs7File); + + free(cert); + free(privKey); + PKCS7_Free(&pkcs7); + + if (ret > 0) + return 0; + + return ret; +} + +int pkcs7signed_test(void) +{ + int ret = 0; + + FILE* file; + byte* certDer; + byte* keyDer; + byte* out; + char data[] = "Hello World"; + word32 dataSz, outSz, certDerSz, keyDerSz; + PKCS7 msg; + RNG rng; + + byte transIdOid[] = + { 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, + 0x09, 0x07 }; + byte messageTypeOid[] = + { 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, + 0x09, 0x02 }; + byte senderNonceOid[] = + { 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, + 0x09, 0x05 }; + byte transId[(SHA_DIGEST_SIZE + 1) * 2 + 1]; + byte messageType[] = { 0x13, 2, '1', '9' }; + byte senderNonce[PKCS7_NONCE_SZ + 2]; + + PKCS7Attrib attribs[] = + { + { transIdOid, sizeof(transIdOid), + transId, sizeof(transId) - 1 }, /* take off the null */ + { messageTypeOid, sizeof(messageTypeOid), + messageType, sizeof(messageType) }, + { senderNonceOid, sizeof(senderNonceOid), + senderNonce, sizeof(senderNonce) } + }; + + dataSz = (word32) strlen(data); + outSz = FOURK_BUF; + + certDer = (byte*)malloc(FOURK_BUF); + if (certDer == NULL) + return -207; + keyDer = (byte*)malloc(FOURK_BUF); + if (keyDer == NULL) { + free(certDer); + return -208; + } + out = (byte*)malloc(FOURK_BUF); + if (out == NULL) { + free(certDer); + free(keyDer); + return -209; + } + + /* read in DER cert of recipient, into cert of size certSz */ + file = fopen(clientCert, "rb"); + if (!file) { + free(certDer); + free(keyDer); + free(out); + err_sys("can't open ./certs/client-cert.der, " + "Please run from CyaSSL home dir", -44); + } + certDerSz = (word32)fread(certDer, 1, FOURK_BUF, file); + fclose(file); + + file = fopen(clientKey, "rb"); + if (!file) { + free(certDer); + free(keyDer); + free(out); + err_sys("can't open ./certs/client-key.der, " + "Please run from CyaSSL home dir", -45); + } + keyDerSz = (word32)fread(keyDer, 1, FOURK_BUF, file); + fclose(file); + + ret = InitRng(&rng); + if (ret != 0) { + free(certDer); + free(keyDer); + free(out); + return -210; + } + + senderNonce[0] = 0x04; + senderNonce[1] = PKCS7_NONCE_SZ; + + ret = RNG_GenerateBlock(&rng, &senderNonce[2], PKCS7_NONCE_SZ); + if (ret != 0) { + free(certDer); + free(keyDer); + free(out); + return -211; + } + + PKCS7_InitWithCert(&msg, certDer, certDerSz); + msg.privateKey = keyDer; + msg.privateKeySz = keyDerSz; + msg.content = (byte*)data; + msg.contentSz = dataSz; + msg.hashOID = SHAh; + msg.encryptOID = RSAk; + msg.signedAttribs = attribs; + msg.signedAttribsSz = sizeof(attribs)/sizeof(PKCS7Attrib); + msg.rng = &rng; + { + Sha sha; + byte digest[SHA_DIGEST_SIZE]; + int i,j; + + transId[0] = 0x13; + transId[1] = SHA_DIGEST_SIZE * 2; + + ret = InitSha(&sha); + if (ret != 0) { + free(certDer); + free(keyDer); + free(out); + return -4003; + } + ShaUpdate(&sha, msg.publicKey, msg.publicKeySz); + ShaFinal(&sha, digest); + + for (i = 0, j = 2; i < SHA_DIGEST_SIZE; i++, j += 2) { + snprintf((char*)&transId[j], 3, "%02x", digest[i]); + } + } + ret = PKCS7_EncodeSignedData(&msg, out, outSz); + if (ret < 0) { + free(certDer); + free(keyDer); + free(out); + PKCS7_Free(&msg); + return -212; + } + else + outSz = ret; + + /* write PKCS#7 to output file for more testing */ + file = fopen("./pkcs7signedData.der", "wb"); + if (!file) { + free(certDer); + free(keyDer); + free(out); + PKCS7_Free(&msg); + return -213; + } + ret = (int)fwrite(out, 1, outSz, file); + fclose(file); + if (ret != (int)outSz) { + free(certDer); + free(keyDer); + free(out); + PKCS7_Free(&msg); + return -218; + } + + PKCS7_Free(&msg); + PKCS7_InitWithCert(&msg, NULL, 0); + + ret = PKCS7_VerifySignedData(&msg, out, outSz); + if (ret < 0) { + free(certDer); + free(keyDer); + free(out); + PKCS7_Free(&msg); + return -214; + } + + if (msg.singleCert == NULL || msg.singleCertSz == 0) { + free(certDer); + free(keyDer); + free(out); + PKCS7_Free(&msg); + return -215; + } + + file = fopen("./pkcs7cert.der", "wb"); + if (!file) { + free(certDer); + free(keyDer); + free(out); + PKCS7_Free(&msg); + return -216; + } + ret = (int)fwrite(msg.singleCert, 1, msg.singleCertSz, file); + fclose(file); + + free(certDer); + free(keyDer); + free(out); + PKCS7_Free(&msg); + + if (ret > 0) + return 0; + + return ret; +} + +#endif /* HAVE_PKCS7 */ + +#endif /* NO_CRYPT_TEST */