diff --git a/certs/ca-cert.der b/certs/ca-cert.der new file mode 100644 index 000000000..5d7c48ade Binary files /dev/null and b/certs/ca-cert.der differ diff --git a/certs/include.am b/certs/include.am index 197ebc46c..32a2bfd0d 100644 --- a/certs/include.am +++ b/certs/include.am @@ -26,13 +26,15 @@ EXTRA_DIST += \ EXTRA_DIST += \ certs/ca-key.der \ + certs/ca-cert.der \ certs/client-cert.der \ certs/client-key.der \ certs/dh2048.der \ certs/rsa2048.der \ certs/dsa2048.der \ - certs/ecc-key.der - + certs/ecc-key.der \ + certs/server-key.der \ + certs/server-cert.der dist_doc_DATA+= certs/taoCert.txt diff --git a/certs/server-cert.der b/certs/server-cert.der new file mode 100644 index 000000000..5f845ca3b Binary files /dev/null and b/certs/server-cert.der differ diff --git a/certs/server-key.der b/certs/server-key.der new file mode 100644 index 000000000..868f0543c Binary files /dev/null and b/certs/server-key.der differ diff --git a/certs/taoCert.txt b/certs/taoCert.txt index 15a12c059..798660767 100644 --- a/certs/taoCert.txt +++ b/certs/taoCert.txt @@ -1,11 +1,11 @@ ***** Create a self signed cert ************ -1) openssl genrsa 512 > client-key.pem +1) openssl genrsa 1024 > client-key.pem -2) openssl req -new -x509 -nodes -md5 -days 1000 -key client-key.pem > client-cert.pem +2) openssl req -new -x509 -nodes -sha1 -days 1000 -key client-key.pem > client-cert.pem -3) note sha1 would be -sha1 +3) note md5 would be -md5 -- adding metadata to beginning @@ -21,13 +21,13 @@ same as self signed, use ca prefix instead of client ***** Create a cert signed by CA ************** -1) openssl req -newkey rsa:512 -md5 -days 1000 -nodes -keyout server-key.pem > server-req.pem +1) openssl req -newkey rsa:1024 -sha1 -days 1000 -nodes -keyout server-key.pem > server-req.pem * note if using exisitng key do: -new -key keyName 2) copy ca-key.pem ca-cert.srl (why ????) -3) openssl x509 -req -in server-req.pem -days 1000 -md5 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem +3) openssl x509 -req -in server-req.pem -days 1000 -sha1 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem ***** Adding Subject Key ID and Authentication Key ID extensions to a cert ***** diff --git a/certs/test/expired-ca.pem b/certs/test/expired-ca.pem new file mode 100644 index 000000000..6a0cf898e --- /dev/null +++ b/certs/test/expired-ca.pem @@ -0,0 +1,56 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 8a:37:22:65:73:f5:aa:e8 + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, ST=Montana, L=Bozeman, O=sawtooth, OU=consulting, CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com + Validity + Not Before: Jun 30 18:47:10 2010 GMT + Not After : Mar 26 18:47:10 2013 GMT + Subject: C=US, ST=Montana, L=Bozeman, O=sawtooth, OU=consulting, CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (512 bit) + Modulus (512 bit): + 00:97:30:b9:1a:92:ef:25:4f:ca:4c:11:31:95:1a: + e1:c0:10:19:0a:20:b9:37:80:1a:57:38:02:4e:1b: + c5:0f:28:4f:da:e3:c9:16:aa:50:bd:4a:fb:b7:71: + c7:35:cc:63:81:c1:dd:9d:33:f9:38:16:88:32:a0: + aa:56:23:03:a3 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 3B:66:FD:A0:40:C6:F4:E2:70:CF:21:1A:0C:4F:67:FE:B7:4B:42:09 + X509v3 Authority Key Identifier: + keyid:3B:66:FD:A0:40:C6:F4:E2:70:CF:21:1A:0C:4F:67:FE:B7:4B:42:09 + DirName:/C=US/ST=Montana/L=Bozeman/O=sawtooth/OU=consulting/CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com + serial:8A:37:22:65:73:F5:AA:E8 + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: md5WithRSAEncryption + 32:65:a2:b1:dc:6d:e0:8d:8b:c8:58:29:8e:b8:18:4b:62:88: + 13:67:f8:6c:75:46:75:8f:8a:19:a6:a3:d5:3c:fc:57:4e:7a: + 68:a9:fc:93:dc:ae:29:7d:bb:4e:ec:ea:55:fa:a4:e3:00:61: + f4:b0:34:6d:d1:d5:a4:64:24:f8 +-----BEGIN CERTIFICATE----- +MIIDQDCCAuqgAwIBAgIJAIo3ImVz9aroMA0GCSqGSIb3DQEBBAUAMIGeMQswCQYD +VQQGEwJVUzEQMA4GA1UECBMHTW9udGFuYTEQMA4GA1UEBxMHQm96ZW1hbjERMA8G +A1UEChMIc2F3dG9vdGgxEzARBgNVBAsTCmNvbnN1bHRpbmcxJDAiBgNVBAMTG3d3 +dy5zYXd0b290aC1jb25zdWx0aW5nLmNvbTEdMBsGCSqGSIb3DQEJARYOaW5mb0B5 +YXNzbC5jb20wHhcNMTAwNjMwMTg0NzEwWhcNMTMwMzI2MTg0NzEwWjCBnjELMAkG +A1UEBhMCVVMxEDAOBgNVBAgTB01vbnRhbmExEDAOBgNVBAcTB0JvemVtYW4xETAP +BgNVBAoTCHNhd3Rvb3RoMRMwEQYDVQQLEwpjb25zdWx0aW5nMSQwIgYDVQQDExt3 +d3cuc2F3dG9vdGgtY29uc3VsdGluZy5jb20xHTAbBgkqhkiG9w0BCQEWDmluZm9A +eWFzc2wuY29tMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJcwuRqS7yVPykwRMZUa +4cAQGQoguTeAGlc4Ak4bxQ8oT9rjyRaqUL1K+7dxxzXMY4HB3Z0z+TgWiDKgqlYj +A6MCAwEAAaOCAQcwggEDMB0GA1UdDgQWBBQ7Zv2gQMb04nDPIRoMT2f+t0tCCTCB +0wYDVR0jBIHLMIHIgBQ7Zv2gQMb04nDPIRoMT2f+t0tCCaGBpKSBoTCBnjELMAkG +A1UEBhMCVVMxEDAOBgNVBAgTB01vbnRhbmExEDAOBgNVBAcTB0JvemVtYW4xETAP +BgNVBAoTCHNhd3Rvb3RoMRMwEQYDVQQLEwpjb25zdWx0aW5nMSQwIgYDVQQDExt3 +d3cuc2F3dG9vdGgtY29uc3VsdGluZy5jb20xHTAbBgkqhkiG9w0BCQEWDmluZm9A +eWFzc2wuY29tggkAijciZXP1qugwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQF +AANBADJlorHcbeCNi8hYKY64GEtiiBNn+Gx1RnWPihmmo9U8/FdOemip/JPcril9 +u07s6lX6pOMAYfSwNG3R1aRkJPg= +-----END CERTIFICATE----- diff --git a/certs/test/expired-cert.pem b/certs/test/expired-cert.pem new file mode 100644 index 000000000..1ec53c026 --- /dev/null +++ b/certs/test/expired-cert.pem @@ -0,0 +1,39 @@ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, ST=Montana, L=Bozeman, O=sawtooth, OU=consulting, CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com + Validity + Not Before: Jun 30 18:52:17 2010 GMT + Not After : Mar 26 18:52:17 2013 GMT + Subject: C=US, ST=Montana, L=Bozeman, O=yaSSL, OU=support, CN=www.yassl.com/emailAddress=info@yassl.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (512 bit) + Modulus (512 bit): + 00:c6:7b:c0:68:81:2f:de:82:3f:f9:ac:c3:86:4a: + 66:b7:ec:d4:f1:f6:64:21:ff:f5:a2:34:42:d0:38: + 9f:c6:dd:3b:6e:26:65:6a:54:96:dd:d2:7b:eb:36: + a2:ae:7e:2a:9e:7e:56:a5:b6:87:9f:15:c7:18:66: + 7e:16:77:e2:a7 + Exponent: 65537 (0x10001) + Signature Algorithm: md5WithRSAEncryption + 58:a9:98:e7:16:52:4c:40:e7:e1:47:92:19:1b:3a:8f:97:6c: + 7b:b7:b0:cb:20:6d:ad:b5:d3:47:58:d8:e4:f2:3e:32:e9:ef: + 87:77:e5:54:36:f4:8d:50:8d:07:b4:77:45:ea:9d:a4:33:36: + 9b:0b:e0:74:58:11:c5:01:7b:4d +-----BEGIN CERTIFICATE----- +MIICFDCCAb4CAQEwDQYJKoZIhvcNAQEEBQAwgZ4xCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdNb250YW5hMRAwDgYDVQQHEwdCb3plbWFuMREwDwYDVQQKEwhzYXd0b290 +aDETMBEGA1UECxMKY29uc3VsdGluZzEkMCIGA1UEAxMbd3d3LnNhd3Rvb3RoLWNv +bnN1bHRpbmcuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQHlhc3NsLmNvbTAeFw0x +MDA2MzAxODUyMTdaFw0xMzAzMjYxODUyMTdaMIGKMQswCQYDVQQGEwJVUzEQMA4G +A1UECBMHTW9udGFuYTEQMA4GA1UEBxMHQm96ZW1hbjEOMAwGA1UEChMFeWFTU0wx +EDAOBgNVBAsTB3N1cHBvcnQxFjAUBgNVBAMTDXd3dy55YXNzbC5jb20xHTAbBgkq +hkiG9w0BCQEWDmluZm9AeWFzc2wuY29tMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJB +AMZ7wGiBL96CP/msw4ZKZrfs1PH2ZCH/9aI0QtA4n8bdO24mZWpUlt3Se+s2oq5+ +Kp5+VqW2h58VxxhmfhZ34qcCAwEAATANBgkqhkiG9w0BAQQFAANBAFipmOcWUkxA +5+FHkhkbOo+XbHu3sMsgba2100dY2OTyPjLp74d35VQ29I1QjQe0d0XqnaQzNpsL +4HRYEcUBe00= +-----END CERTIFICATE----- diff --git a/certs/test/expired-key.pem b/certs/test/expired-key.pem new file mode 100644 index 000000000..154d661b1 --- /dev/null +++ b/certs/test/expired-key.pem @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBOwIBAAJBAMZ7wGiBL96CP/msw4ZKZrfs1PH2ZCH/9aI0QtA4n8bdO24mZWpU +lt3Se+s2oq5+Kp5+VqW2h58VxxhmfhZ34qcCAwEAAQJBAJSbGxgjgV+rTZL2Ev58 +viN/IoB25cm/Bn4Heu7DNn2A2kpdGX2cCaf7rEQoIKCiHxvopvxOcd/7nLS/gNli +dCECIQD/cX/9fvB1Uajw0fmvwNON9+3P9uJSqpig90zL32pwjQIhAMbqee9TBMN4 +TxXbgWqA92PrCXe8WDZ3PwoJqdR6MRUDAiEAny+TDF1z6hiWiGTCDgXDkKBlwgjf +p5aKgR077XzwLu0CICVpWEGg1ZaF/CnaPP7w/pZ2UDOK4vRrfRnAM4bY7H5NAiBS +1eXJ/MCZ2uPfpl7XK2BU9P69KdKUk5WHxdRchVvcDg== +-----END RSA PRIVATE KEY----- diff --git a/configure.ac b/configure.ac index ba20a229d..f56ebb4fc 100644 --- a/configure.ac +++ b/configure.ac @@ -6,7 +6,7 @@ # # -AC_INIT([cyassl],[3.0.0],[https://github.com/cyassl/cyassl/issues],[cyassl],[http://www.wolfssl.com]) +AC_INIT([cyassl],[3.0.3],[https://github.com/cyassl/cyassl/issues],[cyassl],[http://www.wolfssl.com]) AC_CONFIG_AUX_DIR([build-aux]) @@ -81,6 +81,7 @@ AC_CHECK_HEADERS([errno.h]) AC_CHECK_LIB(network,socket) AC_CHECK_SIZEOF(long long, 8) AC_CHECK_SIZEOF(long, 4) +AC_CHECK_TYPES(__uint128_t) AC_C_BIGENDIAN # mktime check takes forever on some systems, if time supported it would be # highly unusual for mktime to be missing @@ -390,7 +391,10 @@ then then # GCC needs these flags, icc doesn't # opt levels greater than 2 may cause problems on systems w/o aesni - AM_CFLAGS="$AM_CFLAGS -maes -msse4" + if test "$CC" != "icc" + then + AM_CFLAGS="$AM_CFLAGS -maes -msse4" + fi fi fi @@ -783,9 +787,9 @@ AM_CONDITIONAL([BUILD_RSA], [test "x$ENABLED_RSA" = "xyes"]) # DH AC_ARG_ENABLE([dh], - [ --enable-dh Enable DH (default: enabled)], + [ --enable-dh Enable DH (default: disabled)], [ ENABLED_DH=$enableval ], - [ ENABLED_DH=yes ] + [ ENABLED_DH=no ] ) if test "$ENABLED_DH" = "no" @@ -1235,21 +1239,44 @@ AM_CONDITIONAL([BUILD_CRL_MONITOR], [test "x$ENABLED_CRL_MONITOR" = "xyes"]) # NTRU -ntruHome=`pwd`/NTRU_algorithm -ntruInclude=$ntruHome/cryptolib -ntruLib=$ntruHome -AC_ARG_ENABLE([ntru], - [ --enable-ntru Enable NTRU (default: disabled)], - [ ENABLED_NTRU=$enableval ], - [ ENABLED_NTRU=no ] - ) +ENABLED_NTRU="no" +tryntrudir="" +AC_ARG_WITH([ntru], + [ --with-ntru=PATH Path to NTRU install (default /usr/) ], + [ + AC_MSG_CHECKING([for NTRU]) + CPPFLAGS="$CPPFLAGS -DHAVE_NTRU" + LIBS="$LIBS -lNTRUEncrypt" -if test "$ENABLED_NTRU" = "yes" -then - AM_CFLAGS="$AM_CFLAGS -DHAVE_NTRU -I$ntruInclude" - AM_LDFLAGS="$AM_LDFLAGS -L$ntruLib" - LIBS="$LIBS -lntru_encrypt" -fi + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ ntru_crypto_drbg_instantiate(0, 0, 0, 0, 0); ]])], [ ntru_linked=yes ],[ ntru_linked=no ]) + + if test "x$ntru_linked" == "xno" ; then + if test "x$withval" != "xno" ; then + tryntrudir=$withval + fi + if test "x$withval" == "xyes" ; then + tryntrudir="/usr" + fi + + LDFLAGS="$AM_LDFLAGS -L$tryntrudir/lib" + CPPFLAGS="$CPPFLAGS -I$tryntrudir/include" + + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ ntru_crypto_drbg_instantiate(0, 0, 0, 0, 0); ]])], [ ntru_linked=yes ],[ ntru_linked=no ]) + + if test "x$ntru_linked" == "xno" ; then + AC_MSG_ERROR([NTRU isn't found. + If it's already installed, specify its path using --with-ntru=/dir/]) + fi + AC_MSG_RESULT([yes]) + AM_LDFLAGS="$AM_LDFLAGS -L$tryntrudir/lib" + else + AC_MSG_RESULT([yes]) + fi + + AM_CFLAGS="$AM_CFLAGS -DHAVE_NTRU" + ENABLED_NTRU="yes" + ] +) AM_CONDITIONAL([BUILD_NTRU], [test "x$ENABLED_NTRU" = "xyes"]) @@ -1665,6 +1692,13 @@ then fi fi +# ICC command line warning for non supported warning flags +if test "$CC" = "icc" +then + AM_CFLAGS="$AM_CFLAGS -wd10006" +fi + + LIB_SOCKET_NSL AX_HARDEN_CC_COMPILER_FLAGS diff --git a/ctaocrypt/benchmark/benchmark.c b/ctaocrypt/benchmark/benchmark.c index 500dcefa5..60eb4a41c 100644 --- a/ctaocrypt/benchmark/benchmark.c +++ b/ctaocrypt/benchmark/benchmark.c @@ -53,6 +53,9 @@ #include "cavium_common.h" #include "cavium_ioctl.h" #endif +#ifdef HAVE_NTRU + #include "ntru_crypto.h" +#endif #if defined(CYASSL_MDK_ARM) extern FILE * CyaSSL_fopen(const char *fname, const char *mode) ; @@ -105,6 +108,9 @@ void bench_dh(void); void bench_eccKeyGen(void); void bench_eccKeyAgree(void); #endif +#ifdef HAVE_NTRU +void bench_ntruKeyGen(void); +#endif double current_time(int); @@ -132,6 +138,9 @@ static int OpenNitroxDevice(int dma_mode,int dev_id) #endif +#if defined(DEBUG_CYASSL) && !defined(HAVE_VALGRIND) + CYASSL_API int CyaSSL_Debugging_ON(); +#endif /* so embedded projects can pull in tests on their own */ #if !defined(NO_MAIN_DRIVER) @@ -146,6 +155,10 @@ int benchmark_test(void *args) { #endif + #if defined(DEBUG_CYASSL) && !defined(HAVE_VALGRIND) + CyaSSL_Debugging_ON(); + #endif + #ifdef HAVE_CAVIUM int ret = OpenNitroxDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID); if (ret != 0) { @@ -225,6 +238,10 @@ int benchmark_test(void *args) bench_rsaKeyGen(); #endif +#ifdef HAVE_NTRU + bench_ntruKeyGen(); +#endif + #ifdef HAVE_ECC bench_eccKeyGen(); bench_eccKeyAgree(); @@ -850,15 +867,14 @@ static RNG rng; #ifndef NO_RSA -#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) && \ - defined(CYASSL_MDK_SHELL) -static char *certRSAname = "certs/rsa2048.der" ; -static void set_Bench_RSA_File(char * cert) { certRSAname = cert ; } - /* set by shell command */ -#elif defined(CYASSL_MDK_SHELL) - /* nothing */ -#else -static const char *certRSAname = "certs/rsa2048.der" ; +#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) + #if defined(CYASSL_MDK_SHELL) + static char *certRSAname = "certs/rsa2048.der"; + /* set by shell command */ + static void set_Bench_RSA_File(char * cert) { certRSAname = cert ; } + #else + static const char *certRSAname = "certs/rsa2048.der"; + #endif #endif void bench_rsa(void) @@ -955,20 +971,22 @@ void bench_rsa(void) #ifndef NO_DH -#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) && \ - defined(CYASSL_MDK_SHELL) -static char *certDHname = "certs/dh2048.der" ; -void set_Bench_DH_File(char * cert) { certDHname = cert ; } - /* set by shell command */ -#elif defined(CYASSL_MDK_SHELL) - /* nothing */ -#else -static const char *certDHname = "certs/dh2048.der" ; +#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) + #if defined(CYASSL_MDK_SHELL) + static char *certDHname = "certs/dh2048.der"; + /* set by shell command */ + void set_Bench_DH_File(char * cert) { certDHname = cert ; } + #else + static const char *certDHname = "certs/dh2048.der"; + #endif #endif void bench_dh(void) { - int i, ret; +#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) + int ret; +#endif + int i ; byte tmp[1024]; size_t bytes; word32 idx = 0, pubSz, privSz = 0, pubSz2, privSz2, agreeSz; @@ -1089,6 +1107,74 @@ void bench_rsaKeyGen(void) " iterations\n", milliEach, genTimes); } #endif /* CYASSL_KEY_GEN */ +#ifdef HAVE_NTRU +byte GetEntropy(ENTROPY_CMD cmd, byte* out); + +byte GetEntropy(ENTROPY_CMD cmd, byte* out) +{ + if (cmd == INIT) + return (InitRng(&rng) == 0) ? 1 : 0; + + if (out == NULL) + return 0; + + 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; + return 1; + } + + return 0; +} +void bench_ntruKeyGen(void) +{ + double start, total, each, milliEach; + int i; + + byte public_key[5951]; /* 2048 key equivalent to rsa */ + word16 public_key_len; + byte private_key[5951]; + word16 private_key_len = sizeof(private_key); + + DRBG_HANDLE drbg; + static uint8_t const pers_str[] = { + 'C', 'y', 'a', 'S', 'S', 'L', ' ', 't', 'e', 's', 't' + }; + + word32 rc = ntru_crypto_drbg_instantiate(112, pers_str, sizeof(pers_str), GetEntropy, &drbg); + + if(rc != DRBG_OK) { + printf("NTRU drbg instantiate failed\n"); + return; + } + + start = current_time(1); + + for(i = 0; i < genTimes; i++) { + ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, &public_key_len, + public_key, &private_key_len, private_key); + } + + total = current_time(0) - start; + + rc = ntru_crypto_drbg_uninstantiate(drbg); + + if (rc != NTRU_OK) { + printf("NTRU drbg uninstantiate failed\n"); + return; + } + + each = total / genTimes; + milliEach = each * 1000; + + printf("\n"); + printf("NTRU 112 key generation %6.3f milliseconds, avg over %d" + " iterations\n", milliEach, genTimes); + +} +#endif #ifdef HAVE_ECC void bench_eccKeyGen(void) @@ -1211,7 +1297,6 @@ void bench_eccKeyAgree(void) } #endif /* HAVE_ECC */ - #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN @@ -1238,10 +1323,10 @@ void bench_eccKeyAgree(void) #elif defined MICROCHIP_PIC32 #if defined(CYASSL_MICROCHIP_PIC32MZ) - #define CLOCK 8000000.0 + #define CLOCK 80000000.0 #else #include - #define CLOCK 4000000.0 + #define CLOCK 40000000.0 #endif double current_time(int reset) @@ -1259,10 +1344,10 @@ void bench_eccKeyAgree(void) return ( ns / CLOCK * 2.0); } -#elif defined CYASSL_MDK_ARM - - extern double current_time(int reset) ; - +#elif defined(CYASSL_IAR_ARM) || defined (CYASSL_MDK_ARM) + #warning "Write your current_time()" + double current_time(int reset) { return 0.0 ; } + #elif defined FREERTOS double current_time(int reset) diff --git a/ctaocrypt/src/aes.c b/ctaocrypt/src/aes.c index bc38012a4..e25b5d873 100644 --- a/ctaocrypt/src/aes.c +++ b/ctaocrypt/src/aes.c @@ -804,6 +804,11 @@ int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, iv = (byte*)aes->reg; enc_key = (byte*)aes->key; + if ((word)out % CYASSL_MMCAU_ALIGNMENT) { + CYASSL_MSG("Bad cau_aes_encrypt alignment"); + return BAD_ALIGN_E; + } + while (len > 0) { XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE); @@ -836,6 +841,11 @@ int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, iv = (byte*)aes->reg; dec_key = (byte*)aes->key; + if ((word)out % CYASSL_MMCAU_ALIGNMENT) { + CYASSL_MSG("Bad cau_aes_decrypt alignment"); + return BAD_ALIGN_E; + } + while (len > 0) { XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE); @@ -1541,31 +1551,34 @@ static const word32 Td[5][256] = { #ifdef CYASSL_AESNI +/* Each platform needs to query info type 1 from cpuid to see if aesni is + * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts + */ + #ifndef _MSC_VER - #define cpuid(func,ax,bx,cx,dx)\ + #define cpuid(reg, func)\ __asm__ __volatile__ ("cpuid":\ - "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func)); + "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3]) :\ + "a" (func)); + #define XASM_LINK(f) asm(f) #else - #define cpuid(func,ax,bx,cx,dx)\ - __asm mov eax, func \ - __asm cpuid \ - __asm mov ax, eax \ - __asm mov bx, ebx \ - __asm mov cx, ecx \ - __asm mov dx, edx + #include + #define cpuid(a,b) __cpuid((int*)a,b) + + #define XASM_LINK(f) #endif /* _MSC_VER */ static int Check_CPU_support_AES(void) { - unsigned int a,b,c,d; - cpuid(1,a,b,c,d); + unsigned int reg[4]; /* put a,b,c,d into 0,1,2,3 */ + cpuid(reg, 1); /* query info 1 */ - if (c & 0x2000000) + if (reg[2] & 0x2000000) return 1; return 0; @@ -1580,34 +1593,34 @@ static int haveAESNI = 0; void AES_CBC_encrypt(const unsigned char* in, unsigned char* out, unsigned char* ivec, unsigned long length, const unsigned char* KS, int nr) - asm ("AES_CBC_encrypt"); + XASM_LINK("AES_CBC_encrypt"); void AES_CBC_decrypt(const unsigned char* in, unsigned char* out, unsigned char* ivec, unsigned long length, const unsigned char* KS, int nr) - asm ("AES_CBC_decrypt"); + XASM_LINK("AES_CBC_decrypt"); void AES_ECB_encrypt(const unsigned char* in, unsigned char* out, unsigned long length, const unsigned char* KS, int nr) - asm ("AES_ECB_encrypt"); + XASM_LINK("AES_ECB_encrypt"); void AES_ECB_decrypt(const unsigned char* in, unsigned char* out, unsigned long length, const unsigned char* KS, int nr) - asm ("AES_ECB_decrypt"); + XASM_LINK("AES_ECB_decrypt"); void AES_128_Key_Expansion(const unsigned char* userkey, unsigned char* key_schedule) - asm ("AES_128_Key_Expansion"); + XASM_LINK("AES_128_Key_Expansion"); void AES_192_Key_Expansion(const unsigned char* userkey, unsigned char* key_schedule) - asm ("AES_192_Key_Expansion"); + XASM_LINK("AES_192_Key_Expansion"); void AES_256_Key_Expansion(const unsigned char* userkey, unsigned char* key_schedule) - asm ("AES_256_Key_Expansion"); + XASM_LINK("AES_256_Key_Expansion"); static int AES_set_encrypt_key(const unsigned char *userKey, const int bits, @@ -2228,6 +2241,7 @@ int AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) if ((word)in % 16) { #ifndef NO_CYASSL_ALLOC_ALIGN byte* tmp = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + CYASSL_MSG("AES-CBC encrypt with bad alignment"); if (tmp == NULL) return MEMORY_E; XMEMCPY(tmp, in, sz); diff --git a/ctaocrypt/src/aes_asm.s b/ctaocrypt/src/aes_asm.s index 382d9b313..b5f5bc9c1 100755 --- a/ctaocrypt/src/aes_asm.s +++ b/ctaocrypt/src/aes_asm.s @@ -24,6 +24,8 @@ * by Intel Mobility Group, Israel Development Center, Israel Shay Gueron */ +/* This file is in at&t asm syntax, see .asm for intel syntax */ + /* AES_CBC_encrypt (const unsigned char *in, diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index de4328df3..6d2d962e1 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -35,14 +35,11 @@ #include #include #include -#include -#include #include +#include #include #include #include -#include -#include #include #include @@ -53,7 +50,7 @@ #endif #ifdef HAVE_NTRU - #include "crypto_ntru.h" + #include "ntru_crypto.h" #endif #ifdef HAVE_ECC @@ -626,7 +623,7 @@ CYASSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid, if (b == ASN_TAG_NULL) { b = input[i++]; - if (b != 0) + if (b != 0) return ASN_EXPECT_0_E; } else @@ -838,11 +835,15 @@ static int DecryptKey(const char* password, int passwordSz, byte* salt, int saltSz, int iterations, int id, byte* input, int length, int version, byte* cbcIv) { - byte key[MAX_KEY_SIZE]; - int typeH; - int derivedLen; - int decryptionType; - int ret = 0; + int typeH; + int derivedLen; + int decryptionType; + int ret = 0; +#ifdef CYASSL_SMALL_STACK + byte* key; +#else + byte key[MAX_KEY_SIZE]; +#endif switch (id) { case PBE_MD5_DES: @@ -873,6 +874,12 @@ static int DecryptKey(const char* password, int passwordSz, byte* salt, return ALGO_ID_E; } +#ifdef CYASSL_SMALL_STACK + key = (byte*)XMALLOC(MAX_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (key == NULL) + return MEMORY_E; +#endif + if (version == PKCS5v2) ret = PBKDF2(key, (byte*)password, passwordSz, salt, saltSz, iterations, derivedLen, typeH); @@ -883,8 +890,12 @@ static int DecryptKey(const char* password, int passwordSz, byte* salt, int i, idx = 0; byte unicodePasswd[MAX_UNICODE_SZ]; - if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd)) + if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd)) { +#ifdef CYASSL_SMALL_STACK + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return UNICODE_SIZE_E; + } for (i = 0; i < passwordSz; i++) { unicodePasswd[idx++] = 0x00; @@ -900,11 +911,19 @@ static int DecryptKey(const char* password, int passwordSz, byte* salt, ret += PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz, iterations, 8, typeH, 2); } - else + else { +#ifdef CYASSL_SMALL_STACK + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ALGO_ID_E; + } - if (ret != 0) + if (ret != 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ret; + } switch (decryptionType) { #ifndef NO_DES3 @@ -917,8 +936,12 @@ static int DecryptKey(const char* password, int passwordSz, byte* salt, desIv = cbcIv; ret = Des_SetKey(&dec, key, desIv, DES_DECRYPTION); - if (ret != 0) + if (ret != 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ret; + } Des_CbcDecrypt(&dec, input, input, length); break; @@ -932,11 +955,19 @@ static int DecryptKey(const char* password, int passwordSz, byte* salt, if (version == PKCS5v2 || version == PKCS12) desIv = cbcIv; ret = Des3_SetKey(&dec, key, desIv, DES_DECRYPTION); - if (ret != 0) + if (ret != 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ret; + } ret = Des3_CbcDecrypt(&dec, input, input, length); - if (ret != 0) + if (ret != 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ret; + } break; } #endif @@ -952,9 +983,16 @@ static int DecryptKey(const char* password, int passwordSz, byte* salt, #endif default: +#ifdef CYASSL_SMALL_STACK + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ALGO_ID_E; } +#ifdef CYASSL_SMALL_STACK + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return 0; } @@ -966,8 +1004,13 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz) word32 inOutIdx = 0, oid; int first, second, length, version, saltSz, id; int iterations = 0; +#ifdef CYASSL_SMALL_STACK + byte* salt = NULL; + byte* cbcIv = NULL; +#else byte salt[MAX_SALT_SIZE]; byte cbcIv[MAX_IV_SIZE]; +#endif if (GetSequence(input, &inOutIdx, &length, sz) < 0) return ASN_PARSE_E; @@ -1005,39 +1048,97 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz) if (saltSz > MAX_SALT_SIZE) return ASN_PARSE_E; +#ifdef CYASSL_SMALL_STACK + salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (salt == NULL) + return MEMORY_E; +#endif + XMEMCPY(salt, &input[inOutIdx], saltSz); inOutIdx += saltSz; - if (GetShortInt(input, &inOutIdx, &iterations) < 0) + if (GetShortInt(input, &inOutIdx, &iterations) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; + } + +#ifdef CYASSL_SMALL_STACK + cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (cbcIv == NULL) { + XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } +#endif if (version == PKCS5v2) { /* get encryption algo */ - if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0) + if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; + } - if (CheckAlgoV2(oid, &id) < 0) + if (CheckAlgoV2(oid, &id) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; /* PKCS v2 algo id error */ + } - if (input[inOutIdx++] != ASN_OCTET_STRING) + if (input[inOutIdx++] != ASN_OCTET_STRING) { +#ifdef CYASSL_SMALL_STACK + XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; + } - if (GetLength(input, &inOutIdx, &length, sz) < 0) + if (GetLength(input, &inOutIdx, &length, sz) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; + } XMEMCPY(cbcIv, &input[inOutIdx], length); inOutIdx += length; } - if (input[inOutIdx++] != ASN_OCTET_STRING) + if (input[inOutIdx++] != ASN_OCTET_STRING) { +#ifdef CYASSL_SMALL_STACK + XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; - - if (GetLength(input, &inOutIdx, &length, sz) < 0) + } + + if (GetLength(input, &inOutIdx, &length, sz) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; + } if (DecryptKey(password, passwordSz, salt, saltSz, iterations, id, - input + inOutIdx, length, version, cbcIv) < 0) + input + inOutIdx, length, version, cbcIv) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_INPUT_E; /* decrypt failure */ + } + +#ifdef CYASSL_SMALL_STACK + XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif XMEMMOVE(input, input + inOutIdx, length); return ToTraditional(input, length); @@ -1163,8 +1264,6 @@ int DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz) } -#ifdef OPENSSL_EXTRA - int DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz, byte* g, word32* gInOutSz) { @@ -1213,7 +1312,6 @@ int DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz, return 0; } -#endif /* OPENSSL_EXTRA */ #endif /* NO_DH */ @@ -1270,6 +1368,7 @@ void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap) cert->signature = 0; cert->subjectCN = 0; cert->subjectCNLen = 0; + cert->subjectCNEnc = CTC_UTF8; cert->subjectCNStored = 0; cert->altNames = NULL; #ifndef IGNORE_NAME_CONSTRAINTS @@ -1308,16 +1407,22 @@ void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap) #ifdef CYASSL_CERT_GEN cert->subjectSN = 0; cert->subjectSNLen = 0; + cert->subjectSNEnc = CTC_UTF8; cert->subjectC = 0; cert->subjectCLen = 0; + cert->subjectCEnc = CTC_PRINTABLE; cert->subjectL = 0; cert->subjectLLen = 0; + cert->subjectLEnc = CTC_UTF8; cert->subjectST = 0; cert->subjectSTLen = 0; + cert->subjectSTEnc = CTC_UTF8; cert->subjectO = 0; cert->subjectOLen = 0; + cert->subjectOEnc = CTC_UTF8; cert->subjectOU = 0; cert->subjectOULen = 0; + cert->subjectOUEnc = CTC_UTF8; cert->subjectEmail = 0; cert->subjectEmailLen = 0; #endif /* CYASSL_CERT_GEN */ @@ -1429,9 +1534,14 @@ void FreeDecodedCert(DecodedCert* cert) static int GetCertHeader(DecodedCert* cert) { - int ret = 0, len; - byte serialTmp[EXTERNAL_SERIAL_SIZE]; - mp_int mpi; + int ret = 0, len; + byte serialTmp[EXTERNAL_SERIAL_SIZE]; +#if defined(CYASSL_SMALL_STACK) && defined(USE_FAST_MATH) + mp_int* mpi = NULL; +#else + mp_int stack_mpi; + mp_int* mpi = &stack_mpi; +#endif if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0) return ASN_PARSE_E; @@ -1445,17 +1555,32 @@ static int GetCertHeader(DecodedCert* cert) if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version) < 0) return ASN_PARSE_E; - if (GetInt(&mpi, cert->source, &cert->srcIdx, cert->maxIdx) < 0) - return ASN_PARSE_E; +#if defined(CYASSL_SMALL_STACK) && defined(USE_FAST_MATH) + mpi = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (mpi == NULL) + return MEMORY_E; +#endif - len = mp_unsigned_bin_size(&mpi); + if (GetInt(mpi, cert->source, &cert->srcIdx, cert->maxIdx) < 0) { +#if defined(CYASSL_SMALL_STACK) && defined(USE_FAST_MATH) + XFREE(mpi, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return ASN_PARSE_E; + } + + len = mp_unsigned_bin_size(mpi); if (len < (int)sizeof(serialTmp)) { - if ( (ret = mp_to_unsigned_bin(&mpi, serialTmp)) == MP_OKAY) { + if ( (ret = mp_to_unsigned_bin(mpi, serialTmp)) == MP_OKAY) { XMEMCPY(cert->serial, serialTmp, len); cert->serialSz = len; } } - mp_clear(&mpi); + mp_clear(mpi); + +#if defined(CYASSL_SMALL_STACK) && defined(USE_FAST_MATH) + XFREE(mpi, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return ret; } @@ -1536,34 +1661,61 @@ static int GetKey(DecodedCert* cert) const byte* key = &cert->source[tmpIdx]; byte* next = (byte*)key; word16 keyLen; + word32 rc; + word32 remaining = cert->maxIdx - cert->srcIdx; +#ifdef CYASSL_SMALL_STACK + byte* keyBlob = NULL; +#else byte keyBlob[MAX_NTRU_KEY_SZ]; - - word32 rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key, - &keyLen, NULL, &next); - +#endif + rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key, + &keyLen, NULL, &next, &remaining); if (rc != NTRU_OK) return ASN_NTRU_KEY_E; - if (keyLen > sizeof(keyBlob)) + if (keyLen > MAX_NTRU_KEY_SZ) return ASN_NTRU_KEY_E; - rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,&keyLen, - keyBlob, &next); - if (rc != NTRU_OK) - return ASN_NTRU_KEY_E; +#ifdef CYASSL_SMALL_STACK + keyBlob = (byte*)XMALLOC(MAX_NTRU_KEY_SZ, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (keyBlob == NULL) + return MEMORY_E; +#endif - if ( (next - key) < 0) + rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key, + &keyLen, keyBlob, &next, &remaining); + if (rc != NTRU_OK) { +#ifdef CYASSL_SMALL_STACK + XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_NTRU_KEY_E; + } + + if ( (next - key) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return ASN_NTRU_KEY_E; + } cert->srcIdx = tmpIdx + (int)(next - key); cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); - if (cert->publicKey == NULL) + if (cert->publicKey == NULL) { +#ifdef CYASSL_SMALL_STACK + XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return MEMORY_E; + } XMEMCPY(cert->publicKey, keyBlob, keyLen); cert->pubKeyStored = 1; cert->pubKeySize = keyLen; +#ifdef CYASSL_SMALL_STACK + XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return 0; } #endif /* HAVE_NTRU */ @@ -1707,8 +1859,7 @@ static int GetName(DecodedCert* cert, int nameType) cert->srcIdx += 2; id = cert->source[cert->srcIdx++]; - b = cert->source[cert->srcIdx++]; /* strType */ - (void)b; /* may want to validate? */ + b = cert->source[cert->srcIdx++]; /* encoding */ if (GetLength(cert->source, &cert->srcIdx, &strLen, cert->maxIdx) < 0) @@ -1724,6 +1875,7 @@ static int GetName(DecodedCert* cert, int nameType) if (nameType == SUBJECT) { cert->subjectCN = (char *)&cert->source[cert->srcIdx]; cert->subjectCNLen = strLen; + cert->subjectCNEnc = b; } if (!tooBig) { @@ -1746,6 +1898,7 @@ static int GetName(DecodedCert* cert, int nameType) if (nameType == SUBJECT) { cert->subjectSN = (char*)&cert->source[cert->srcIdx]; cert->subjectSNLen = strLen; + cert->subjectSNEnc = b; } #endif /* CYASSL_CERT_GEN */ #ifdef OPENSSL_EXTRA @@ -1763,6 +1916,7 @@ static int GetName(DecodedCert* cert, int nameType) if (nameType == SUBJECT) { cert->subjectC = (char*)&cert->source[cert->srcIdx]; cert->subjectCLen = strLen; + cert->subjectCEnc = b; } #endif /* CYASSL_CERT_GEN */ #ifdef OPENSSL_EXTRA @@ -1780,6 +1934,7 @@ static int GetName(DecodedCert* cert, int nameType) if (nameType == SUBJECT) { cert->subjectL = (char*)&cert->source[cert->srcIdx]; cert->subjectLLen = strLen; + cert->subjectLEnc = b; } #endif /* CYASSL_CERT_GEN */ #ifdef OPENSSL_EXTRA @@ -1797,6 +1952,7 @@ static int GetName(DecodedCert* cert, int nameType) if (nameType == SUBJECT) { cert->subjectST = (char*)&cert->source[cert->srcIdx]; cert->subjectSTLen = strLen; + cert->subjectSTEnc = b; } #endif /* CYASSL_CERT_GEN */ #ifdef OPENSSL_EXTRA @@ -1814,6 +1970,7 @@ static int GetName(DecodedCert* cert, int nameType) if (nameType == SUBJECT) { cert->subjectO = (char*)&cert->source[cert->srcIdx]; cert->subjectOLen = strLen; + cert->subjectOEnc = b; } #endif /* CYASSL_CERT_GEN */ #ifdef OPENSSL_EXTRA @@ -1831,6 +1988,7 @@ static int GetName(DecodedCert* cert, int nameType) if (nameType == SUBJECT) { cert->subjectOU = (char*)&cert->source[cert->srcIdx]; cert->subjectOULen = strLen; + cert->subjectOUEnc = b; } #endif /* CYASSL_CERT_GEN */ #ifdef OPENSSL_EXTRA @@ -2680,94 +2838,62 @@ word32 EncodeSignature(byte* out, const byte* digest, word32 digSz, int hashOID) } -/* return true (1) for Confirmation */ +/* return true (1) or false (0) for Confirmation */ static int ConfirmSignature(const byte* buf, word32 bufSz, const byte* key, word32 keySz, word32 keyOID, const byte* sig, word32 sigSz, word32 sigOID, void* heap) { -#ifdef CYASSL_SHA512 - byte digest[SHA512_DIGEST_SIZE]; /* max size */ -#elif !defined(NO_SHA256) - byte digest[SHA256_DIGEST_SIZE]; /* max size */ + int typeH = 0, digestSz = 0, ret = 0; +#ifdef CYASSL_SMALL_STACK + byte* digest; #else - byte digest[SHA_DIGEST_SIZE]; /* max size */ + byte digest[MAX_DIGEST_SIZE]; +#endif + +#ifdef CYASSL_SMALL_STACK + digest = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (digest == NULL) + return 0; /* not confirmed */ #endif - int typeH, digestSz, ret = 0; (void)key; (void)keySz; (void)sig; (void)sigSz; (void)heap; - (void)ret; switch (sigOID) { -#ifndef NO_MD5 + #ifndef NO_MD5 case CTC_MD5wRSA: - { - Md5 md5; - InitMd5(&md5); - Md5Update(&md5, buf, bufSz); - Md5Final(&md5, digest); + if (Md5Hash(buf, bufSz, digest) == 0) { typeH = MD5h; digestSz = MD5_DIGEST_SIZE; } break; -#endif + #endif #if defined(CYASSL_MD2) case CTC_MD2wRSA: - { - Md2 md2; - InitMd2(&md2); - Md2Update(&md2, buf, bufSz); - Md2Final(&md2, digest); + if (Md2Hash(buf, bufSz, digest) == 0) { typeH = MD2h; digestSz = MD2_DIGEST_SIZE; } break; #endif -#ifndef NO_SHA + #ifndef NO_SHA case CTC_SHAwRSA: case CTC_SHAwDSA: case CTC_SHAwECDSA: - { - Sha sha; - ret = InitSha(&sha); - if (ret != 0) { - CYASSL_MSG("InitSha failed"); - return 0; /* not confirmed */ - } - ShaUpdate(&sha, buf, bufSz); - ShaFinal(&sha, digest); + if (ShaHash(buf, bufSz, digest) == 0) { typeH = SHAh; - digestSz = SHA_DIGEST_SIZE; + digestSz = SHA_DIGEST_SIZE; } break; -#endif + #endif #ifndef NO_SHA256 case CTC_SHA256wRSA: case CTC_SHA256wECDSA: - { - Sha256 sha256; - ret = InitSha256(&sha256); - if (ret != 0) { - CYASSL_MSG("InitSha256 failed"); - return 0; /* not confirmed */ - } - - ret = Sha256Update(&sha256, buf, bufSz); - if (ret != 0) { - CYASSL_MSG("Sha256Update failed"); - return 0; /* not confirmed */ - } - - ret = Sha256Final(&sha256, digest); - if (ret != 0) { - CYASSL_MSG("Sha256Final failed"); - return 0; /* not confirmed */ - } - + if (Sha256Hash(buf, bufSz, digest) == 0) { typeH = SHA256h; digestSz = SHA256_DIGEST_SIZE; } @@ -2776,26 +2902,7 @@ static int ConfirmSignature(const byte* buf, word32 bufSz, #ifdef CYASSL_SHA512 case CTC_SHA512wRSA: case CTC_SHA512wECDSA: - { - Sha512 sha512; - ret = InitSha512(&sha512); - if (ret != 0) { - CYASSL_MSG("InitSha512 failed"); - return 0; /* not confirmed */ - } - - ret = Sha512Update(&sha512, buf, bufSz); - if (ret != 0) { - CYASSL_MSG("Sha512Update failed"); - return 0; /* not confirmed */ - } - - ret = Sha512Final(&sha512, digest); - if (ret != 0) { - CYASSL_MSG("Sha512Final failed"); - return 0; /* not confirmed */ - } - + if (Sha512Hash(buf, bufSz, digest) == 0) { typeH = SHA512h; digestSz = SHA512_DIGEST_SIZE; } @@ -2804,65 +2911,77 @@ static int ConfirmSignature(const byte* buf, word32 bufSz, #ifdef CYASSL_SHA384 case CTC_SHA384wRSA: case CTC_SHA384wECDSA: - { - Sha384 sha384; - ret = InitSha384(&sha384); - if (ret != 0) { - CYASSL_MSG("InitSha384 failed"); - return 0; /* not confirmed */ - } - - ret = Sha384Update(&sha384, buf, bufSz); - if (ret != 0) { - CYASSL_MSG("Sha384Update failed"); - return 0; /* not confirmed */ - } - - ret = Sha384Final(&sha384, digest); - if (ret != 0) { - CYASSL_MSG("Sha384Final failed"); - return 0; /* not confirmed */ - } - + if (Sha384Hash(buf, bufSz, digest) == 0) { typeH = SHA384h; digestSz = SHA384_DIGEST_SIZE; - } + } break; #endif default: CYASSL_MSG("Verify Signautre has unsupported type"); - return 0; } - (void)typeH; /* some builds won't read */ + + if (typeH == 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return 0; /* not confirmed */ + } switch (keyOID) { #ifndef NO_RSA case RSAk: { - RsaKey pubKey; - byte encodedSig[MAX_ENCODED_SIG_SZ]; - byte plain[MAX_ENCODED_SIG_SZ]; word32 idx = 0; int encodedSigSz, verifySz; byte* out; +#ifdef CYASSL_SMALL_STACK + RsaKey* pubKey; + byte* plain; + byte* encodedSig; +#else + RsaKey pubKey[1]; + byte plain[MAX_ENCODED_SIG_SZ]; + byte encodedSig[MAX_ENCODED_SIG_SZ]; +#endif + +#ifdef CYASSL_SMALL_STACK + pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + plain = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + + if (pubKey == NULL || plain == NULL || encodedSig == NULL) { + CYASSL_MSG("Failed to allocate memory at ConfirmSignature"); + + if (pubKey) + XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (plain) + XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (encodedSig) + XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + break; /* not confirmed */ + } +#endif if (sigSz > MAX_ENCODED_SIG_SZ) { CYASSL_MSG("Verify Signautre is too big"); - return 0; } - - ret = InitRsaKey(&pubKey, heap); - if (ret != 0) return ret; - if (RsaPublicKeyDecode(key, &idx, &pubKey, keySz) < 0) { + else if (InitRsaKey(pubKey, heap) != 0) { + CYASSL_MSG("InitRsaKey failed"); + } + else if (RsaPublicKeyDecode(key, &idx, pubKey, keySz) < 0) { CYASSL_MSG("ASN Key decode error RSA"); - ret = 0; } else { XMEMCPY(plain, sig, sigSz); - if ( (verifySz = RsaSSL_VerifyInline(plain, sigSz, &out, - &pubKey)) < 0) { + + if ((verifySz = RsaSSL_VerifyInline(plain, sigSz, &out, + pubKey)) < 0) { CYASSL_MSG("Rsa SSL verify error"); - ret = 0; } else { /* make sure we're right justified */ @@ -2871,61 +2990,97 @@ static int ConfirmSignature(const byte* buf, word32 bufSz, if (encodedSigSz != verifySz || XMEMCMP(out, encodedSig, encodedSigSz) != 0) { CYASSL_MSG("Rsa SSL verify match encode error"); - ret = 0; } else ret = 1; /* match */ #ifdef CYASSL_DEBUG_ENCODING { - int x; - printf("cyassl encodedSig:\n"); - for (x = 0; x < encodedSigSz; x++) { - printf("%02x ", encodedSig[x]); - if ( (x % 16) == 15) - printf("\n"); - } - printf("\n"); - printf("actual digest:\n"); - for (x = 0; x < verifySz; x++) { - printf("%02x ", out[x]); - if ( (x % 16) == 15) - printf("\n"); - } - printf("\n"); + int x; + + printf("cyassl encodedSig:\n"); + + for (x = 0; x < encodedSigSz; x++) { + printf("%02x ", encodedSig[x]); + if ( (x % 16) == 15) + printf("\n"); + } + + printf("\n"); + printf("actual digest:\n"); + + for (x = 0; x < verifySz; x++) { + printf("%02x ", out[x]); + if ( (x % 16) == 15) + printf("\n"); + } + + printf("\n"); } #endif /* CYASSL_DEBUG_ENCODING */ + } + } - FreeRsaKey(&pubKey); - return ret; + + FreeRsaKey(pubKey); + +#ifdef CYASSL_SMALL_STACK + XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif } #endif /* NO_RSA */ #ifdef HAVE_ECC case ECDSAk: { - ecc_key pubKey; - int verify = 0; - - if (ecc_import_x963(key, keySz, &pubKey) < 0) { - CYASSL_MSG("ASN Key import error ECC"); - return 0; - } - - ret = ecc_verify_hash(sig,sigSz,digest,digestSz,&verify,&pubKey); - ecc_free(&pubKey); - if (ret == 0 && verify == 1) - return 1; /* match */ + int verify = 0; +#ifdef CYASSL_SMALL_STACK + ecc_key* pubKey; +#else + ecc_key pubKey[1]; +#endif - CYASSL_MSG("ECC Verify didn't match"); - return 0; +#ifdef CYASSL_SMALL_STACK + pubKey = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (pubKey == NULL) { + CYASSL_MSG("Failed to allocate pubKey"); + break; /* not confirmed */ + } +#endif + + if (ecc_import_x963(key, keySz, pubKey) < 0) { + CYASSL_MSG("ASN Key import error ECC"); + } + else { + if (ecc_verify_hash(sig, sigSz, digest, digestSz, &verify, + pubKey) != 0) { + CYASSL_MSG("ECC verify hash error"); + } + else if (1 != verify) { + CYASSL_MSG("ECC Verify didn't match"); + } else + ret = 1; /* match */ + + ecc_free(pubKey); + } +#ifdef CYASSL_SMALL_STACK + XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif } #endif /* HAVE_ECC */ default: CYASSL_MSG("Verify Key type unknown"); - return 0; } + +#ifdef CYASSL_SMALL_STACK + XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; } @@ -3486,8 +3641,8 @@ static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert) } if (input[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) { - CYASSL_MSG("\tfail: wanted OPTIONAL item 0, not available\n"); - return ASN_PARSE_E; + CYASSL_MSG("\tinfo: OPTIONAL item 0, not available\n"); + return 0; } if (GetLength(input, &idx, &length, sz) < 0) { @@ -4221,11 +4376,16 @@ CYASSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output) int DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz, int type) { +#ifdef CYASSL_SMALL_STACK + char* header = NULL; + char* footer = NULL; +#else char header[80]; char footer[80]; +#endif - int headerLen; - int footerLen; + int headerLen = 80; + int footerLen = 80; int i; int err; int outLen; /* return length or error */ @@ -4233,56 +4393,99 @@ int DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz, if (der == output) /* no in place conversion */ return BAD_FUNC_ARG; +#ifdef CYASSL_SMALL_STACK + header = (char*)XMALLOC(headerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (header == NULL) + return MEMORY_E; + + footer = (char*)XMALLOC(footerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (footer == NULL) { + XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } +#endif + if (type == CERT_TYPE) { - XSTRNCPY(header, "-----BEGIN CERTIFICATE-----\n", sizeof(header)); - XSTRNCPY(footer, "-----END CERTIFICATE-----\n", sizeof(footer)); + XSTRNCPY(header, "-----BEGIN CERTIFICATE-----\n", headerLen); + XSTRNCPY(footer, "-----END CERTIFICATE-----\n", footerLen); } else if (type == PRIVATEKEY_TYPE) { - XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----\n", sizeof(header)); - XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----\n", sizeof(footer)); + XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----\n", headerLen); + XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----\n", footerLen); } #ifdef HAVE_ECC else if (type == ECC_PRIVATEKEY_TYPE) { - XSTRNCPY(header, "-----BEGIN EC PRIVATE KEY-----\n", sizeof(header)); - XSTRNCPY(footer, "-----END EC PRIVATE KEY-----\n", sizeof(footer)); + XSTRNCPY(header, "-----BEGIN EC PRIVATE KEY-----\n", headerLen); + XSTRNCPY(footer, "-----END EC PRIVATE KEY-----\n", footerLen); } #endif #ifdef CYASSL_CERT_REQ else if (type == CERTREQ_TYPE) { XSTRNCPY(header, - "-----BEGIN CERTIFICATE REQUEST-----\n", sizeof(header)); - XSTRNCPY(footer, "-----END CERTIFICATE REQUEST-----\n", sizeof(footer)); + "-----BEGIN CERTIFICATE REQUEST-----\n", headerLen); + XSTRNCPY(footer, "-----END CERTIFICATE REQUEST-----\n", footerLen); } #endif - else + else { +#ifdef CYASSL_SMALL_STACK + XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return BAD_FUNC_ARG; + } headerLen = (int)XSTRLEN(header); footerLen = (int)XSTRLEN(footer); - if (!der || !output) + if (!der || !output) { +#ifdef CYASSL_SMALL_STACK + XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return BAD_FUNC_ARG; + } /* don't even try if outSz too short */ - if (outSz < headerLen + footerLen + derSz) + if (outSz < headerLen + footerLen + derSz) { +#ifdef CYASSL_SMALL_STACK + XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return BAD_FUNC_ARG; + } /* header */ XMEMCPY(output, header, headerLen); i = headerLen; +#ifdef CYASSL_SMALL_STACK + XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + /* body */ outLen = outSz - (headerLen + footerLen); /* input to Base64_Encode */ - if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) + if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return err; + } i += outLen; /* footer */ - if ( (i + footerLen) > (int)outSz) + if ( (i + footerLen) > (int)outSz) { +#ifdef CYASSL_SMALL_STACK + XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return BAD_FUNC_ARG; + } XMEMCPY(output + i, footer, footerLen); +#ifdef CYASSL_SMALL_STACK + XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return outLen + headerLen + footerLen; } @@ -4450,21 +4653,35 @@ void InitCert(Cert* cert) XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE); cert->issuer.country[0] = '\0'; + cert->issuer.countryEnc = CTC_PRINTABLE; cert->issuer.state[0] = '\0'; + cert->issuer.stateEnc = CTC_UTF8; cert->issuer.locality[0] = '\0'; + cert->issuer.localityEnc = CTC_UTF8; cert->issuer.sur[0] = '\0'; + cert->issuer.surEnc = CTC_UTF8; cert->issuer.org[0] = '\0'; + cert->issuer.orgEnc = CTC_UTF8; cert->issuer.unit[0] = '\0'; + cert->issuer.unitEnc = CTC_UTF8; cert->issuer.commonName[0] = '\0'; + cert->issuer.commonNameEnc = CTC_UTF8; cert->issuer.email[0] = '\0'; cert->subject.country[0] = '\0'; + cert->subject.countryEnc = CTC_PRINTABLE; cert->subject.state[0] = '\0'; + cert->subject.stateEnc = CTC_UTF8; cert->subject.locality[0] = '\0'; + cert->subject.localityEnc = CTC_UTF8; cert->subject.sur[0] = '\0'; + cert->subject.surEnc = CTC_UTF8; cert->subject.org[0] = '\0'; + cert->subject.orgEnc = CTC_UTF8; cert->subject.unit[0] = '\0'; + cert->subject.unitEnc = CTC_UTF8; cert->subject.commonName[0] = '\0'; + cert->subject.commonNameEnc = CTC_UTF8; cert->subject.email[0] = '\0'; #ifdef CYASSL_CERT_REQ @@ -4535,22 +4752,62 @@ static int SetSerial(const byte* serial, byte* output) /* Write a public ECC key to output */ static int SetEccPublicKey(byte* output, ecc_key* key) { - byte algo[MAX_ALGO_SZ]; - byte curve[MAX_ALGO_SZ]; byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */ - byte pub[ECC_BUFSIZE]; int algoSz; int curveSz; int lenSz; int idx; - word32 pubSz = sizeof(pub); + word32 pubSz = ECC_BUFSIZE; +#ifdef CYASSL_SMALL_STACK + byte* algo = NULL; + byte* curve = NULL; + byte* pub = NULL; +#else + byte algo[MAX_ALGO_SZ]; + byte curve[MAX_ALGO_SZ]; + byte pub[ECC_BUFSIZE]; +#endif + +#ifdef CYASSL_SMALL_STACK + pub = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (pub == NULL) + return MEMORY_E; +#endif int ret = ecc_export_x963(key, pub, &pubSz); - if (ret != 0) return ret; + if (ret != 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return ret; + } + +#ifdef CYASSL_SMALL_STACK + curve = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (curve == NULL) { + XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } +#endif /* headers */ curveSz = SetCurve(key, curve); - if (curveSz <= 0) return curveSz; + if (curveSz <= 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return curveSz; + } + +#ifdef CYASSL_SMALL_STACK + algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (algo == NULL) { + XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } +#endif algoSz = SetAlgoID(ECDSAk, algo, keyType, curveSz); lenSz = SetLength(pubSz + 1, len); @@ -4574,6 +4831,12 @@ static int SetEccPublicKey(byte* output, ecc_key* key) XMEMCPY(output + idx, pub, pubSz); idx += pubSz; +#ifdef CYASSL_SMALL_STACK + XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return idx; } @@ -4584,9 +4847,15 @@ static int SetEccPublicKey(byte* output, ecc_key* key) /* Write a public RSA key to output */ static int SetRsaPublicKey(byte* output, RsaKey* key) { +#ifdef CYASSL_SMALL_STACK + byte* n = NULL; + byte* e = NULL; + byte* algo = NULL; +#else byte n[MAX_RSA_INT_SZ]; byte e[MAX_RSA_E_SZ]; byte algo[MAX_ALGO_SZ]; +#endif byte seq[MAX_SEQ_SZ]; byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */ int nSz; @@ -4600,40 +4869,83 @@ static int SetRsaPublicKey(byte* output, RsaKey* key) int err; /* n */ +#ifdef CYASSL_SMALL_STACK + n = (byte*)XMALLOC(MAX_RSA_INT_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (n == NULL) + return MEMORY_E; +#endif + leadingBit = mp_leading_bit(&key->n); rawLen = mp_unsigned_bin_size(&key->n) + leadingBit; n[0] = ASN_INTEGER; nSz = SetLength(rawLen, n + 1) + 1; /* int tag */ - if ( (nSz + rawLen) < (int)sizeof(n)) { + if ( (nSz + rawLen) < MAX_RSA_INT_SZ) { if (leadingBit) n[nSz] = 0; err = mp_to_unsigned_bin(&key->n, n + nSz + leadingBit); if (err == MP_OKAY) nSz += rawLen; - else + else { +#ifdef CYASSL_SMALL_STACK + XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return MP_TO_E; + } } - else + else { +#ifdef CYASSL_SMALL_STACK + XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return BUFFER_E; + } /* e */ +#ifdef CYASSL_SMALL_STACK + e = (byte*)XMALLOC(MAX_RSA_E_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (e == NULL) { +#ifdef CYASSL_SMALL_STACK + XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return MEMORY_E; + } +#endif + leadingBit = mp_leading_bit(&key->e); rawLen = mp_unsigned_bin_size(&key->e) + leadingBit; e[0] = ASN_INTEGER; eSz = SetLength(rawLen, e + 1) + 1; /* int tag */ - if ( (eSz + rawLen) < (int)sizeof(e)) { + if ( (eSz + rawLen) < MAX_RSA_E_SZ) { if (leadingBit) e[eSz] = 0; err = mp_to_unsigned_bin(&key->e, e + eSz + leadingBit); if (err == MP_OKAY) eSz += rawLen; - else + else { +#ifdef CYASSL_SMALL_STACK + XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return MP_TO_E; + } } - else + else { +#ifdef CYASSL_SMALL_STACK + XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return BUFFER_E; + } + +#ifdef CYASSL_SMALL_STACK + algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (algo == NULL) { + XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } +#endif /* headers */ algoSz = SetAlgoID(RSAk, algo, keyType, 0); @@ -4662,6 +4974,12 @@ static int SetRsaPublicKey(byte* output, RsaKey* key) XMEMCPY(output + idx, e, eSz); idx += eSz; +#ifdef CYASSL_SMALL_STACK + XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return idx; } @@ -4823,6 +5141,37 @@ static const char* GetOneName(CertName* name, int idx) } +/* Get Which Name Encoding from index */ +static char GetNameType(CertName* name, int idx) +{ + switch (idx) { + case 0: + return name->countryEnc; + + case 1: + return name->stateEnc; + + case 2: + return name->localityEnc; + + case 3: + return name->surEnc; + + case 4: + return name->orgEnc; + + case 5: + return name->unitEnc; + + case 6: + return name->commonNameEnc; + + default: + return 0; + } +} + + /* Get ASN Name from index */ static byte GetNameId(int idx) { @@ -4898,8 +5247,19 @@ static int SetCa(byte* output) /* encode CertName into output, return total bytes written */ static int SetName(byte* output, CertName* name) { - int totalBytes = 0, i, idx; - EncodedName names[NAME_ENTRIES]; + int totalBytes = 0, i, idx; +#ifdef CYASSL_SMALL_STACK + EncodedName* names = NULL; +#else + EncodedName names[NAME_ENTRIES]; +#endif + +#ifdef CYASSL_SMALL_STACK + names = (EncodedName*)XMALLOC(sizeof(EncodedName) * NAME_ENTRIES, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (names == NULL) + return MEMORY_E; +#endif for (i = 0; i < NAME_ENTRIES; i++) { const char* nameStr = GetOneName(name, i); @@ -4941,8 +5301,12 @@ static int SetName(byte* output, CertName* name) setSz = SetSet(thisLen, set); thisLen += setSz; - if (thisLen > (int)sizeof(names[i].encoded)) + if (thisLen > (int)sizeof(names[i].encoded)) { +#ifdef CYASSL_SMALL_STACK + XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return BUFFER_E; + } /* store it */ idx = 0; @@ -4972,10 +5336,7 @@ static int SetName(byte* output, CertName* name) /* id type */ names[i].encoded[idx++] = bType; /* str type */ - if (bType == ASN_COUNTRY_NAME) - names[i].encoded[idx++] = 0x13; /* printable */ - else - names[i].encoded[idx++] = 0x0c; /* utf8 */ + names[i].encoded[idx++] = GetNameType(name, i); } /* second length */ XMEMCPY(names[i].encoded + idx, secondLen, secondSz); @@ -4995,8 +5356,12 @@ static int SetName(byte* output, CertName* name) /* header */ idx = SetSequence(totalBytes, output); totalBytes += idx; - if (totalBytes > ASN_NAME_MAX) + if (totalBytes > ASN_NAME_MAX) { +#ifdef CYASSL_SMALL_STACK + XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return BUFFER_E; + } for (i = 0; i < NAME_ENTRIES; i++) { if (names[i].used) { @@ -5004,6 +5369,11 @@ static int SetName(byte* output, CertName* name) idx += names[i].totalLen; } } + +#ifdef CYASSL_SMALL_STACK + XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return totalBytes; } @@ -5060,15 +5430,15 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, word32 rc; word16 encodedSz; - rc = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz, - ntruKey, &encodedSz, NULL); + rc = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz, + ntruKey, &encodedSz, NULL); if (rc != NTRU_OK) return PUBLIC_KEY_E; if (encodedSz > MAX_PUBLIC_KEY_SZ) return PUBLIC_KEY_E; - rc = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz, - ntruKey, &encodedSz, der->publicKey); + rc = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz, + ntruKey, &encodedSz, der->publicKey); if (rc != NTRU_OK) return PUBLIC_KEY_E; @@ -5184,73 +5554,95 @@ static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz, RsaKey* rsaKey, ecc_key* eccKey, RNG* rng, int sigAlgoType) { - byte digest[SHA256_DIGEST_SIZE]; /* max size */ - byte encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ]; - int encSigSz, digestSz, typeH, ret = 0; + int encSigSz, digestSz, typeH = 0, ret = 0; + byte digest[SHA256_DIGEST_SIZE]; /* max size */ +#ifdef CYASSL_SMALL_STACK + byte* encSig; +#else + byte encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ]; +#endif + (void)digest; + (void)digestSz; + (void)encSig; + (void)encSigSz; + (void)typeH; + + (void)buffer; + (void)sz; + (void)sig; + (void)sigSz; + (void)rsaKey; (void)eccKey; + (void)rng; - if (sigAlgoType == CTC_MD5wRSA) { - Md5 md5; - - InitMd5(&md5); - Md5Update(&md5, buffer, sz); - Md5Final(&md5, digest); - - digestSz = MD5_DIGEST_SIZE; - typeH = MD5h; + switch (sigAlgoType) { + #ifndef NO_MD5 + case CTC_MD5wRSA: + if ((ret = Md5Hash(buffer, sz, digest)) == 0) { + typeH = MD5h; + digestSz = MD5_DIGEST_SIZE; + } + break; + #endif + #ifndef NO_SHA + case CTC_SHAwRSA: + case CTC_SHAwECDSA: + if ((ret = ShaHash(buffer, sz, digest)) == 0) { + typeH = SHAh; + digestSz = SHA_DIGEST_SIZE; + } + break; + #endif + #ifndef NO_SHA256 + case CTC_SHA256wRSA: + case CTC_SHA256wECDSA: + if ((ret = Sha256Hash(buffer, sz, digest)) == 0) { + typeH = SHA256h; + digestSz = SHA256_DIGEST_SIZE; + } + break; + #endif + default: + CYASSL_MSG("MakeSignautre called with unsupported type"); + ret = ALGO_ID_E; } - else if (sigAlgoType == CTC_SHAwRSA || sigAlgoType == CTC_SHAwECDSA) { - Sha sha; - - ret = InitSha(&sha); - if (ret != 0) - return ret; - - ShaUpdate(&sha, buffer, sz); - ShaFinal(&sha, digest); - - digestSz = SHA_DIGEST_SIZE; - typeH = SHAh; - } - else if (sigAlgoType == CTC_SHA256wRSA || sigAlgoType == CTC_SHA256wECDSA) { - Sha256 sha256; - - ret = InitSha256(&sha256); - if (ret != 0) - return ret; - - ret = Sha256Update(&sha256, buffer, sz); - if (ret != 0) - return ret; - - ret = Sha256Final(&sha256, digest); - if (ret != 0) - return ret; - - digestSz = SHA256_DIGEST_SIZE; - typeH = SHA256h; - } - else - return ALGO_ID_E; - + + if (ret != 0) + return ret; + +#ifdef CYASSL_SMALL_STACK + encSig = (byte*)XMALLOC(MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ, + NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (encSig == NULL) + return MEMORY_E; +#endif + + ret = ALGO_ID_E; + +#ifndef NO_RSA if (rsaKey) { /* signature */ encSigSz = EncodeSignature(encSig, digest, digestSz, typeH); - return RsaSSL_Sign(encSig, encSigSz, sig, sigSz, rsaKey, rng); + ret = RsaSSL_Sign(encSig, encSigSz, sig, sigSz, rsaKey, rng); } +#endif + #ifdef HAVE_ECC - else if (eccKey) { + if (!rsaKey && eccKey) { word32 outSz = sigSz; ret = ecc_sign_hash(digest, digestSz, sig, &outSz, rng, eccKey); - if (ret != 0) - return ret; - return outSz; + if (ret == 0) + ret = outSz; } -#endif /* HAVE_ECC */ +#endif - return ALGO_ID_E; +#ifdef CYASSL_SMALL_STACK + XFREE(encSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; } @@ -5287,21 +5679,35 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, ecc_key* eccKey, RNG* rng, const byte* ntruKey, word16 ntruSz) { - DerCert der; - int ret; + int ret; +#ifdef CYASSL_SMALL_STACK + DerCert* der; +#else + DerCert der[1]; +#endif - if (eccKey) - cert->keyType = ECC_KEY; - else - cert->keyType = rsaKey ? RSA_KEY : NTRU_KEY; - ret = EncodeCert(cert, &der, rsaKey, eccKey, rng, ntruKey, ntruSz); - if (ret != 0) - return ret; + cert->keyType = eccKey ? ECC_KEY : (rsaKey ? RSA_KEY : NTRU_KEY); - if (der.total + MAX_SEQ_SZ * 2 > (int)derSz) - return BUFFER_E; +#ifdef CYASSL_SMALL_STACK + der = (DerCert*)XMALLOC(sizeof(DerCert), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (der == NULL) + return MEMORY_E; +#endif - return cert->bodySz = WriteCertBody(&der, derBuffer); + ret = EncodeCert(cert, der, rsaKey, eccKey, rng, ntruKey, ntruSz); + + if (ret == 0) { + if (der->total + MAX_SEQ_SZ * 2 > (int)derSz) + ret = BUFFER_E; + else + ret = cert->bodySz = WriteCertBody(der, derBuffer); + } + +#ifdef CYASSL_SMALL_STACK + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; } @@ -5497,18 +5903,35 @@ static int WriteCertReqBody(DerCert* der, byte* buffer) int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, ecc_key* eccKey) { - DerCert der; - int ret; + int ret; +#ifdef CYASSL_SMALL_STACK + DerCert* der; +#else + DerCert der[1]; +#endif - cert->keyType = (eccKey != NULL) ? ECC_KEY : RSA_KEY; - ret = EncodeCertReq(cert, &der, rsaKey, eccKey); - if (ret != 0) - return ret; + cert->keyType = eccKey ? ECC_KEY : RSA_KEY; - if (der.total + MAX_SEQ_SZ * 2 > (int)derSz) - return BUFFER_E; +#ifdef CYASSL_SMALL_STACK + der = (DerCert*)XMALLOC(sizeof(DerCert), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (der == NULL) + return MEMORY_E; +#endif - return cert->bodySz = WriteCertReqBody(&der, derBuffer); + ret = EncodeCertReq(cert, der, rsaKey, eccKey); + + if (ret == 0) { + if (der->total + MAX_SEQ_SZ * 2 > (int)derSz) + ret = BUFFER_E; + else + ret = cert->bodySz = WriteCertReqBody(der, derBuffer); + } + +#ifdef CYASSL_SMALL_STACK + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; } #endif /* CYASSL_CERT_REQ */ @@ -5517,21 +5940,37 @@ int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, int SignCert(int requestSz, int sType, byte* buffer, word32 buffSz, RsaKey* rsaKey, ecc_key* eccKey, RNG* rng) { - byte sig[MAX_ENCODED_SIG_SZ]; - int sigSz; + int sigSz; +#ifdef CYASSL_SMALL_STACK + byte* sig; +#else + byte sig[MAX_ENCODED_SIG_SZ]; +#endif if (requestSz < 0) return requestSz; - sigSz = MakeSignature(buffer, requestSz, sig, sizeof(sig), rsaKey, eccKey, - rng, sType); - if (sigSz < 0) - return sigSz; +#ifdef CYASSL_SMALL_STACK + sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (sig == NULL) + return MEMORY_E; +#endif - if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz) - return BUFFER_E; + sigSz = MakeSignature(buffer, requestSz, sig, MAX_ENCODED_SIG_SZ, rsaKey, + eccKey, rng, sType); - return AddSignature(buffer, requestSz, sig, sigSz, sType); + if (sigSz >= 0) { + if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz) + sigSz = BUFFER_E; + else + sigSz = AddSignature(buffer, requestSz, sig, sigSz, sType); + } + +#ifdef CYASSL_SMALL_STACK + XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return sigSz; } @@ -5551,127 +5990,149 @@ int MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng) /* Set Alt Names from der cert, return 0 on success */ static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz) { - DecodedCert decoded; - int ret; + int ret; +#ifdef CYASSL_SMALL_STACK + DecodedCert* decoded; +#else + DecodedCert decoded[1]; +#endif if (derSz < 0) return derSz; - InitDecodedCert(&decoded, (byte*)der, derSz, 0); - ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0); +#ifdef CYASSL_SMALL_STACK + decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (decoded == NULL) + return MEMORY_E; +#endif + + InitDecodedCert(decoded, (byte*)der, derSz, 0); + ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0); if (ret < 0) { - FreeDecodedCert(&decoded); - return ret; + CYASSL_MSG("ParseCertRelative error"); } - - if (decoded.extensions) { + else if (decoded->extensions) { byte b; int length; word32 maxExtensionsIdx; - decoded.srcIdx = decoded.extensionsIdx; - b = decoded.source[decoded.srcIdx++]; + decoded->srcIdx = decoded->extensionsIdx; + b = decoded->source[decoded->srcIdx++]; + if (b != ASN_EXTENSIONS) { - FreeDecodedCert(&decoded); - return ASN_PARSE_E; + ret = ASN_PARSE_E; } - - if (GetLength(decoded.source, &decoded.srcIdx, &length, - decoded.maxIdx) < 0) { - FreeDecodedCert(&decoded); - return ASN_PARSE_E; + else if (GetLength(decoded->source, &decoded->srcIdx, &length, + decoded->maxIdx) < 0) { + ret = ASN_PARSE_E; } - - if (GetSequence(decoded.source, &decoded.srcIdx, &length, - decoded.maxIdx) < 0) { - FreeDecodedCert(&decoded); - return ASN_PARSE_E; + else if (GetSequence(decoded->source, &decoded->srcIdx, &length, + decoded->maxIdx) < 0) { + ret = ASN_PARSE_E; } + else { + maxExtensionsIdx = decoded->srcIdx + length; - maxExtensionsIdx = decoded.srcIdx + length; + while (decoded->srcIdx < maxExtensionsIdx) { + word32 oid; + word32 startIdx = decoded->srcIdx; + word32 tmpIdx; - while (decoded.srcIdx < maxExtensionsIdx) { - word32 oid; - word32 startIdx = decoded.srcIdx; - word32 tmpIdx; - - if (GetSequence(decoded.source, &decoded.srcIdx, &length, - decoded.maxIdx) < 0) { - FreeDecodedCert(&decoded); - return ASN_PARSE_E; - } - - tmpIdx = decoded.srcIdx; - decoded.srcIdx = startIdx; - - if (GetAlgoId(decoded.source, &decoded.srcIdx, &oid, - decoded.maxIdx) < 0) { - FreeDecodedCert(&decoded); - return ASN_PARSE_E; - } - - if (oid == ALT_NAMES_OID) { - cert->altNamesSz = length + (tmpIdx - startIdx); - - if (cert->altNamesSz < (int)sizeof(cert->altNames)) - XMEMCPY(cert->altNames, &decoded.source[startIdx], - cert->altNamesSz); - else { - cert->altNamesSz = 0; - CYASSL_MSG("AltNames extensions too big"); - FreeDecodedCert(&decoded); - return ALT_NAME_E; + if (GetSequence(decoded->source, &decoded->srcIdx, &length, + decoded->maxIdx) < 0) { + ret = ASN_PARSE_E; + break; } + + tmpIdx = decoded->srcIdx; + decoded->srcIdx = startIdx; + + if (GetAlgoId(decoded->source, &decoded->srcIdx, &oid, + decoded->maxIdx) < 0) { + ret = ASN_PARSE_E; + break; + } + + if (oid == ALT_NAMES_OID) { + cert->altNamesSz = length + (tmpIdx - startIdx); + + if (cert->altNamesSz < (int)sizeof(cert->altNames)) + XMEMCPY(cert->altNames, &decoded->source[startIdx], + cert->altNamesSz); + else { + cert->altNamesSz = 0; + CYASSL_MSG("AltNames extensions too big"); + ret = ALT_NAME_E; + break; + } + } + decoded->srcIdx = tmpIdx + length; } - decoded.srcIdx = tmpIdx + length; } } - FreeDecodedCert(&decoded); - return 0; + FreeDecodedCert(decoded); +#ifdef CYASSL_SMALL_STACK + XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret < 0 ? ret : 0; } /* Set Dates from der cert, return 0 on success */ static int SetDatesFromCert(Cert* cert, const byte* der, int derSz) { - DecodedCert decoded; - int ret; + int ret; +#ifdef CYASSL_SMALL_STACK + DecodedCert* decoded; +#else + DecodedCert decoded[1]; +#endif CYASSL_ENTER("SetDatesFromCert"); if (derSz < 0) return derSz; + +#ifdef CYASSL_SMALL_STACK + decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (decoded == NULL) + return MEMORY_E; +#endif - InitDecodedCert(&decoded, (byte*)der, derSz, 0); - ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0); + InitDecodedCert(decoded, (byte*)der, derSz, 0); + ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0); if (ret < 0) { CYASSL_MSG("ParseCertRelative error"); - FreeDecodedCert(&decoded); - return ret; } - - if (decoded.beforeDate == NULL || decoded.afterDate == NULL) { + else if (decoded->beforeDate == NULL || decoded->afterDate == NULL) { CYASSL_MSG("Couldn't extract dates"); - FreeDecodedCert(&decoded); - return -1; + ret = -1; } - - if (decoded.beforeDateLen > MAX_DATE_SIZE || decoded.afterDateLen > - MAX_DATE_SIZE) { + else if (decoded->beforeDateLen > MAX_DATE_SIZE || + decoded->afterDateLen > MAX_DATE_SIZE) { CYASSL_MSG("Bad date size"); - FreeDecodedCert(&decoded); - return -1; + ret = -1; + } + else { + XMEMCPY(cert->beforeDate, decoded->beforeDate, decoded->beforeDateLen); + XMEMCPY(cert->afterDate, decoded->afterDate, decoded->afterDateLen); + + cert->beforeDateSz = decoded->beforeDateLen; + cert->afterDateSz = decoded->afterDateLen; } - XMEMCPY(cert->beforeDate, decoded.beforeDate, decoded.beforeDateLen); - XMEMCPY(cert->afterDate, decoded.afterDate, decoded.afterDateLen); + FreeDecodedCert(decoded); - cert->beforeDateSz = decoded.beforeDateLen; - cert->afterDateSz = decoded.afterDateLen; +#ifdef CYASSL_SMALL_STACK + XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif - return 0; + return ret < 0 ? ret : 0; } @@ -5681,71 +6142,94 @@ static int SetDatesFromCert(Cert* cert, const byte* der, int derSz) /* Set cn name from der buffer, return 0 on success */ static int SetNameFromCert(CertName* cn, const byte* der, int derSz) { - DecodedCert decoded; - int ret; - int sz; + int ret, sz; +#ifdef CYASSL_SMALL_STACK + DecodedCert* decoded; +#else + DecodedCert decoded[1]; +#endif if (derSz < 0) return derSz; - InitDecodedCert(&decoded, (byte*)der, derSz, 0); - ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0); +#ifdef CYASSL_SMALL_STACK + decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (decoded == NULL) + return MEMORY_E; +#endif - if (ret < 0) - return ret; + InitDecodedCert(decoded, (byte*)der, derSz, 0); + ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0); - if (decoded.subjectCN) { - sz = (decoded.subjectCNLen < CTC_NAME_SIZE) ? decoded.subjectCNLen : - CTC_NAME_SIZE - 1; - strncpy(cn->commonName, decoded.subjectCN, CTC_NAME_SIZE); - cn->commonName[sz] = 0; + if (ret < 0) { + CYASSL_MSG("ParseCertRelative error"); } - if (decoded.subjectC) { - sz = (decoded.subjectCLen < CTC_NAME_SIZE) ? decoded.subjectCLen : - CTC_NAME_SIZE - 1; - strncpy(cn->country, decoded.subjectC, CTC_NAME_SIZE); - cn->country[sz] = 0; - } - if (decoded.subjectST) { - sz = (decoded.subjectSTLen < CTC_NAME_SIZE) ? decoded.subjectSTLen : - CTC_NAME_SIZE - 1; - strncpy(cn->state, decoded.subjectST, CTC_NAME_SIZE); - cn->state[sz] = 0; - } - if (decoded.subjectL) { - sz = (decoded.subjectLLen < CTC_NAME_SIZE) ? decoded.subjectLLen : - CTC_NAME_SIZE - 1; - strncpy(cn->locality, decoded.subjectL, CTC_NAME_SIZE); - cn->locality[sz] = 0; - } - if (decoded.subjectO) { - sz = (decoded.subjectOLen < CTC_NAME_SIZE) ? decoded.subjectOLen : - CTC_NAME_SIZE - 1; - strncpy(cn->org, decoded.subjectO, CTC_NAME_SIZE); - cn->org[sz] = 0; - } - if (decoded.subjectOU) { - sz = (decoded.subjectOULen < CTC_NAME_SIZE) ? decoded.subjectOULen : - CTC_NAME_SIZE - 1; - strncpy(cn->unit, decoded.subjectOU, CTC_NAME_SIZE); - cn->unit[sz] = 0; - } - if (decoded.subjectSN) { - sz = (decoded.subjectSNLen < CTC_NAME_SIZE) ? decoded.subjectSNLen : - CTC_NAME_SIZE - 1; - strncpy(cn->sur, decoded.subjectSN, CTC_NAME_SIZE); - cn->sur[sz] = 0; - } - if (decoded.subjectEmail) { - sz = (decoded.subjectEmailLen < CTC_NAME_SIZE) ? - decoded.subjectEmailLen : CTC_NAME_SIZE - 1; - strncpy(cn->email, decoded.subjectEmail, CTC_NAME_SIZE); - cn->email[sz] = 0; + else { + if (decoded->subjectCN) { + sz = (decoded->subjectCNLen < CTC_NAME_SIZE) ? decoded->subjectCNLen + : CTC_NAME_SIZE - 1; + strncpy(cn->commonName, decoded->subjectCN, CTC_NAME_SIZE); + cn->commonName[sz] = 0; + cn->commonNameEnc = decoded->subjectCNEnc; + } + if (decoded->subjectC) { + sz = (decoded->subjectCLen < CTC_NAME_SIZE) ? decoded->subjectCLen + : CTC_NAME_SIZE - 1; + strncpy(cn->country, decoded->subjectC, CTC_NAME_SIZE); + cn->country[sz] = 0; + cn->countryEnc = decoded->subjectCEnc; + } + if (decoded->subjectST) { + sz = (decoded->subjectSTLen < CTC_NAME_SIZE) ? decoded->subjectSTLen + : CTC_NAME_SIZE - 1; + strncpy(cn->state, decoded->subjectST, CTC_NAME_SIZE); + cn->state[sz] = 0; + cn->stateEnc = decoded->subjectSTEnc; + } + if (decoded->subjectL) { + sz = (decoded->subjectLLen < CTC_NAME_SIZE) ? decoded->subjectLLen + : CTC_NAME_SIZE - 1; + strncpy(cn->locality, decoded->subjectL, CTC_NAME_SIZE); + cn->locality[sz] = 0; + cn->localityEnc = decoded->subjectLEnc; + } + if (decoded->subjectO) { + sz = (decoded->subjectOLen < CTC_NAME_SIZE) ? decoded->subjectOLen + : CTC_NAME_SIZE - 1; + strncpy(cn->org, decoded->subjectO, CTC_NAME_SIZE); + cn->org[sz] = 0; + cn->orgEnc = decoded->subjectOEnc; + } + if (decoded->subjectOU) { + sz = (decoded->subjectOULen < CTC_NAME_SIZE) ? decoded->subjectOULen + : CTC_NAME_SIZE - 1; + strncpy(cn->unit, decoded->subjectOU, CTC_NAME_SIZE); + cn->unit[sz] = 0; + cn->unitEnc = decoded->subjectOUEnc; + } + if (decoded->subjectSN) { + sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen + : CTC_NAME_SIZE - 1; + strncpy(cn->sur, decoded->subjectSN, CTC_NAME_SIZE); + cn->sur[sz] = 0; + cn->surEnc = decoded->subjectSNEnc; + } + if (decoded->subjectEmail) { + sz = (decoded->subjectEmailLen < CTC_NAME_SIZE) + ? decoded->subjectEmailLen : CTC_NAME_SIZE - 1; + strncpy(cn->email, decoded->subjectEmail, CTC_NAME_SIZE); + cn->email[sz] = 0; + } } - FreeDecodedCert(&decoded); + FreeDecodedCert(decoded); - return 0; +#ifdef CYASSL_SMALL_STACK + XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret < 0 ? ret : 0; } @@ -5929,8 +6413,14 @@ int EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, int version, length; int privSz, pubSz; byte b; - byte priv[ECC_MAXSIZE]; - byte pub[ECC_MAXSIZE * 2 + 1]; /* public key has two parts plus header */ + int ret = 0; +#ifdef CYASSL_SMALL_STACK + byte* priv; + byte* pub; +#else + byte priv[ECC_MAXSIZE]; + byte pub[ECC_MAXSIZE * 2 + 1]; /* public key has two parts plus header */ +#endif if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) return BAD_FUNC_ARG; @@ -5951,6 +6441,18 @@ int EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, if (GetLength(input, inOutIdx, &length, inSz) < 0) return ASN_PARSE_E; +#ifdef CYASSL_SMALL_STACK + priv = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (priv == NULL) + return MEMORY_E; + + pub = (byte*)XMALLOC(ECC_MAXSIZE * 2 + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (pub == NULL) { + XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } +#endif + /* priv key */ privSz = length; XMEMCPY(priv, &input[*inOutIdx], privSz); @@ -5962,54 +6464,77 @@ int EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, *inOutIdx += 1; if (GetLength(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; + ret = ASN_PARSE_E; + else { + /* object id */ + b = input[*inOutIdx]; + *inOutIdx += 1; - /* object id */ + if (b != ASN_OBJECT_ID) { + ret = ASN_OBJECT_ID_E; + } + else if (GetLength(input, inOutIdx, &length, inSz) < 0) { + ret = ASN_PARSE_E; + } + else { + while(length--) { + oid += input[*inOutIdx]; + *inOutIdx += 1; + } + if (CheckCurve(oid) < 0) + ret = ECC_CURVE_OID_E; + } + } + } + + if (ret == 0) { + /* prefix 1 */ b = input[*inOutIdx]; *inOutIdx += 1; - - if (b != ASN_OBJECT_ID) - return ASN_OBJECT_ID_E; - if (GetLength(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - - while(length--) { - oid += input[*inOutIdx]; - *inOutIdx += 1; + if (b != ECC_PREFIX_1) { + ret = ASN_ECC_KEY_E; + } + else if (GetLength(input, inOutIdx, &length, inSz) < 0) { + ret = ASN_PARSE_E; + } + else { + /* key header */ + b = input[*inOutIdx]; + *inOutIdx += 1; + + if (b != ASN_BIT_STRING) { + ret = ASN_BITSTR_E; + } + else if (GetLength(input, inOutIdx, &length, inSz) < 0) { + ret = ASN_PARSE_E; + } + else { + b = input[*inOutIdx]; + *inOutIdx += 1; + + if (b != 0x00) { + ret = ASN_EXPECT_0_E; + } + else { + /* pub key */ + pubSz = length - 1; /* null prefix */ + XMEMCPY(pub, &input[*inOutIdx], pubSz); + + *inOutIdx += length; + + ret = ecc_import_private_key(priv, privSz, pub, pubSz, key); + } + } } - if (CheckCurve(oid) < 0) - return ECC_CURVE_OID_E; } - - /* prefix 1 */ - b = input[*inOutIdx]; - *inOutIdx += 1; - if (b != ECC_PREFIX_1) - return ASN_ECC_KEY_E; - if (GetLength(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; +#ifdef CYASSL_SMALL_STACK + XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif - /* key header */ - b = input[*inOutIdx]; - *inOutIdx += 1; - if (b != ASN_BIT_STRING) - return ASN_BITSTR_E; - - if (GetLength(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - b = input[*inOutIdx]; - *inOutIdx += 1; - if (b != 0x00) - return ASN_EXPECT_0_E; - - pubSz = length - 1; /* null prefix */ - XMEMCPY(pub, &input[*inOutIdx], pubSz); - - *inOutIdx += length; - - return ecc_import_private_key(priv, privSz, pub, pubSz, key); + return ret; } #endif /* HAVE_ECC */ diff --git a/ctaocrypt/src/des3.c b/ctaocrypt/src/des3.c index a704b7910..4cd2a63ca 100644 --- a/ctaocrypt/src/des3.c +++ b/ctaocrypt/src/des3.c @@ -34,6 +34,7 @@ #include #include +#include #ifdef NO_INLINE #include @@ -169,19 +170,22 @@ CRYP_Cmd(DISABLE); } - void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) + int Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) { DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_CBC); + return 0; } - void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) + int Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) { DesCrypt(des, out, in, sz, DES_DECRYPTION, DES_CBC); + return 0; } - void Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz) + int Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz) { DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_ECB); + return 0; } void Des3Crypt(Des3* des, byte* out, const byte* in, word32 sz, @@ -389,14 +393,16 @@ static void Des_Cbc(byte* out, const byte* in, word32 sz, } -void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) +int Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) { Des_Cbc(out, in, sz, (byte *)des->key, (byte *)des->reg, SEC_DESC_DES_CBC_ENCRYPT) ; + return 0; } -void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) +int Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) { Des_Cbc(out, in, sz, (byte *)des->key, (byte *)des->reg, SEC_DESC_DES_CBC_DECRYPT) ; + return 0; } int Des3_CbcEncrypt(Des3* des3, byte* out, const byte* in, word32 sz) @@ -556,7 +562,7 @@ int Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) return ret; } - void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) + int Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) { int i; int offset = 0; @@ -566,6 +572,11 @@ int Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) iv = (byte*)des->reg; + if ((word)out % CYASSL_MMCAU_ALIGNMENT) { + CYASSL_MSG("Bad cau_des_encrypt alignment"); + return BAD_ALIGN_E; + } + while (len > 0) { XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE); @@ -583,10 +594,10 @@ int Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE); } - return; + return 0; } - void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) + int Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) { int i; int offset = 0; @@ -596,6 +607,11 @@ int Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) iv = (byte*)des->reg; + if ((word)out % CYASSL_MMCAU_ALIGNMENT) { + CYASSL_MSG("Bad cau_des_decrypt alignment"); + return BAD_ALIGN_E; + } + while (len > 0) { XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE); @@ -613,7 +629,7 @@ int Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) offset += DES_BLOCK_SIZE; } - return; + return 0; } int Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz) @@ -627,6 +643,11 @@ int Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) iv = (byte*)des->reg; + if ((word)out % CYASSL_MMCAU_ALIGNMENT) { + CYASSL_MSG("Bad 3ede cau_des_encrypt alignment"); + return BAD_ALIGN_E; + } + while (len > 0) { XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE); @@ -660,6 +681,11 @@ int Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) iv = (byte*)des->reg; + if ((word)out % CYASSL_MMCAU_ALIGNMENT) { + CYASSL_MSG("Bad 3ede cau_des_decrypt alignment"); + return BAD_ALIGN_E; + } + while (len > 0) { XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE); @@ -761,9 +787,9 @@ int Des3_SetIV(Des3* des, const byte* iv); bd_p->BD_CTRL.LAST_BD = 1; bd_p->BD_CTRL.DESC_EN = 1; - bd_p->SA_ADDR = (unsigned int)KVA_TO_PA(&sa) ; // (unsigned int)sa_p ; - bd_p->SRCADDR = (unsigned int)KVA_TO_PA(in) ; // (unsigned int)in_p ; - bd_p->DSTADDR = (unsigned int)KVA_TO_PA(out); // (unsigned int)out_p ; + bd_p->SA_ADDR = (unsigned int)KVA_TO_PA(&sa) ; /* (unsigned int)sa_p; */ + bd_p->SRCADDR = (unsigned int)KVA_TO_PA(in) ; /* (unsigned int)in_p; */ + bd_p->DSTADDR = (unsigned int)KVA_TO_PA(out); /* (unsigned int)out_p; */ bd_p->NXTPTR = (unsigned int)KVA_TO_PA(&bd); bd_p->MSGLEN = sz ; @@ -772,7 +798,7 @@ int Des3_SetIV(Des3* des, const byte* iv); while (CECON); /* Run the engine */ - CEBDPADDR = (unsigned int)KVA_TO_PA(&bd) ; // (unsigned int)bd_p ; + CEBDPADDR = (unsigned int)KVA_TO_PA(&bd) ; /* (unsigned int)bd_p ; */ CEINTEN = 0x07; CECON = 0x27; @@ -793,16 +819,18 @@ int Des3_SetIV(Des3* des, const byte* iv); ByteReverseWords((word32*)out, (word32 *)KVA0_TO_KVA1(out), sz); } - void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) + int Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) { DesCrypt(des->key, des->reg, out, in, sz, PIC32_ENCRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC ); + return 0; } - void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) + int Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) { DesCrypt(des->key, des->reg, out, in, sz, PIC32_DECRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC); + return 0; } int Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz) @@ -1250,7 +1278,7 @@ static void Des3ProcessBlock(Des3* des, const byte* in, byte* out) } -void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) +int Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) { word32 blocks = sz / DES_BLOCK_SIZE; @@ -1262,10 +1290,11 @@ void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) out += DES_BLOCK_SIZE; in += DES_BLOCK_SIZE; } + return 0; } -void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) +int Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) { word32 blocks = sz / DES_BLOCK_SIZE; byte hold[DES_BLOCK_SIZE]; @@ -1282,6 +1311,7 @@ void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) out += DES_BLOCK_SIZE; in += DES_BLOCK_SIZE; } + return 0; } @@ -1332,7 +1362,7 @@ int Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz) #ifdef CYASSL_DES_ECB /* One block, compatibility only */ -void Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz) +int Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz) { word32 blocks = sz / DES_BLOCK_SIZE; @@ -1342,6 +1372,7 @@ void Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz) out += DES_BLOCK_SIZE; in += DES_BLOCK_SIZE; } + return 0; } #endif /* CYASSL_DES_ECB */ @@ -1370,7 +1401,6 @@ int Des3_SetIV(Des3* des, const byte* iv) #ifdef HAVE_CAVIUM -#include #include "cavium_common.h" /* Initiliaze Des3 for use with Nitrox device */ diff --git a/ctaocrypt/src/ecc.c b/ctaocrypt/src/ecc.c index 6d6da7346..8904f7289 100644 --- a/ctaocrypt/src/ecc.c +++ b/ctaocrypt/src/ecc.c @@ -3629,9 +3629,9 @@ enum ecSrvState { struct ecEncCtx { - byte* kdfSalt; /* optional salt for kdf */ - byte* kdfInfo; /* optional info for kdf */ - byte* macSalt; /* optional salt for mac */ + const byte* kdfSalt; /* optional salt for kdf */ + const byte* kdfInfo; /* optional info for kdf */ + const byte* macSalt; /* optional salt for mac */ word32 kdfSaltSz; /* size of kdfSalt */ word32 kdfInfoSz; /* size of kdfInfo */ word32 macSaltSz; /* size of macSalt */ @@ -3676,6 +3676,19 @@ const byte* ecc_ctx_get_own_salt(ecEncCtx* ctx) } +/* optional set info, can be called before or after set_peer_salt */ +int ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz) +{ + if (ctx == NULL || info == 0 || sz < 0) + return BAD_FUNC_ARG; + + ctx->kdfInfo = info; + ctx->kdfInfoSz = sz; + + return 0; +} + + static const char* exchange_info = "Secure Message Exchange"; int ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt) @@ -3717,8 +3730,11 @@ int ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt) ctx->macSalt = ctx->serverSalt; ctx->macSaltSz = EXCHANGE_SALT_SZ; - ctx->kdfInfo = (byte*)exchange_info; - ctx->kdfInfoSz = EXCHANGE_INFO_SZ; + if (ctx->kdfInfo == NULL) { + /* default info */ + ctx->kdfInfo = (const byte*)exchange_info; + ctx->kdfInfoSz = EXCHANGE_INFO_SZ; + } return 0; } diff --git a/ctaocrypt/src/error.c b/ctaocrypt/src/error.c index 3b629ae08..00bfe309b 100644 --- a/ctaocrypt/src/error.c +++ b/ctaocrypt/src/error.c @@ -22,7 +22,7 @@ #ifdef HAVE_CONFIG_H #include #endif - + #include #include @@ -32,334 +32,264 @@ #pragma warning(disable: 4996) #endif - -void CTaoCryptErrorString(int error, char* buffer) +const char* CTaoCryptGetErrorString(int error) { - const int max = CYASSL_MAX_ERROR_SZ; /* shorthand */ - #ifdef NO_ERROR_STRINGS (void)error; - XSTRNCPY(buffer, "no support for error strings built in", max); + return "no support for error strings built in"; #else switch (error) { - case OPEN_RAN_E : - XSTRNCPY(buffer, "opening random device error", max); - break; + case OPEN_RAN_E : + return "opening random device error"; case READ_RAN_E : - XSTRNCPY(buffer, "reading random device error", max); - break; + return "reading random device error"; case WINCRYPT_E : - XSTRNCPY(buffer, "windows crypt init error", max); - break; + return "windows crypt init error"; - case CRYPTGEN_E : - XSTRNCPY(buffer, "windows crypt generation error", max); - break; + case CRYPTGEN_E : + return "windows crypt generation error"; - case RAN_BLOCK_E : - XSTRNCPY(buffer, "random device read would block error", max); - break; + case RAN_BLOCK_E : + return "random device read would block error"; - case BAD_MUTEX_E : - XSTRNCPY(buffer, "Bad mutex, operation failed", max); - break; + case BAD_MUTEX_E : + return "Bad mutex, operation failed"; case MP_INIT_E : - XSTRNCPY(buffer, "mp_init error state", max); - break; + return "mp_init error state"; case MP_READ_E : - XSTRNCPY(buffer, "mp_read error state", max); - break; + return "mp_read error state"; case MP_EXPTMOD_E : - XSTRNCPY(buffer, "mp_exptmod error state", max); - break; + return "mp_exptmod error state"; case MP_TO_E : - XSTRNCPY(buffer, "mp_to_xxx error state, can't convert", max); - break; + return "mp_to_xxx error state, can't convert"; case MP_SUB_E : - XSTRNCPY(buffer, "mp_sub error state, can't subtract", max); - break; + return "mp_sub error state, can't subtract"; case MP_ADD_E : - XSTRNCPY(buffer, "mp_add error state, can't add", max); - break; + return "mp_add error state, can't add"; case MP_MUL_E : - XSTRNCPY(buffer, "mp_mul error state, can't multiply", max); - break; + return "mp_mul error state, can't multiply"; case MP_MULMOD_E : - XSTRNCPY(buffer, "mp_mulmod error state, can't multiply mod", max); - break; + return "mp_mulmod error state, can't multiply mod"; case MP_MOD_E : - XSTRNCPY(buffer, "mp_mod error state, can't mod", max); - break; + return "mp_mod error state, can't mod"; case MP_INVMOD_E : - XSTRNCPY(buffer, "mp_invmod error state, can't inv mod", max); - break; - + return "mp_invmod error state, can't inv mod"; + case MP_CMP_E : - XSTRNCPY(buffer, "mp_cmp error state", max); - break; - + return "mp_cmp error state"; + case MP_ZERO_E : - XSTRNCPY(buffer, "mp zero result, not expected", max); - break; - + return "mp zero result, not expected"; + case MEMORY_E : - XSTRNCPY(buffer, "out of memory error", max); - break; + return "out of memory error"; case RSA_WRONG_TYPE_E : - XSTRNCPY(buffer, "RSA wrong block type for RSA function", max); - break; + return "RSA wrong block type for RSA function"; case RSA_BUFFER_E : - XSTRNCPY(buffer, "RSA buffer error, output too small or input too big", - max); - break; + return "RSA buffer error, output too small or input too big"; case BUFFER_E : - XSTRNCPY(buffer, "Buffer error, output too small or input too big",max); - break; + return "Buffer error, output too small or input too big"; case ALGO_ID_E : - XSTRNCPY(buffer, "Setting Cert AlogID error", max); - break; + return "Setting Cert AlogID error"; case PUBLIC_KEY_E : - XSTRNCPY(buffer, "Setting Cert Public Key error", max); - break; + return "Setting Cert Public Key error"; case DATE_E : - XSTRNCPY(buffer, "Setting Cert Date validity error", max); - break; + return "Setting Cert Date validity error"; case SUBJECT_E : - XSTRNCPY(buffer, "Setting Cert Subject name error", max); - break; + return "Setting Cert Subject name error"; case ISSUER_E : - XSTRNCPY(buffer, "Setting Cert Issuer name error", max); - break; + return "Setting Cert Issuer name error"; case CA_TRUE_E : - XSTRNCPY(buffer, "Setting basic constraint CA true error", max); - break; + return "Setting basic constraint CA true error"; case EXTENSIONS_E : - XSTRNCPY(buffer, "Setting extensions error", max); - break; + return "Setting extensions error"; case ASN_PARSE_E : - XSTRNCPY(buffer, "ASN parsing error, invalid input", max); - break; + return "ASN parsing error, invalid input"; case ASN_VERSION_E : - XSTRNCPY(buffer, "ASN version error, invalid number", max); - break; + return "ASN version error, invalid number"; case ASN_GETINT_E : - XSTRNCPY(buffer, "ASN get big int error, invalid data", max); - break; + return "ASN get big int error, invalid data"; case ASN_RSA_KEY_E : - XSTRNCPY(buffer, "ASN key init error, invalid input", max); - break; + return "ASN key init error, invalid input"; case ASN_OBJECT_ID_E : - XSTRNCPY(buffer, "ASN object id error, invalid id", max); - break; + return "ASN object id error, invalid id"; case ASN_TAG_NULL_E : - XSTRNCPY(buffer, "ASN tag error, not null", max); - break; + return "ASN tag error, not null"; case ASN_EXPECT_0_E : - XSTRNCPY(buffer, "ASN expect error, not zero", max); - break; + return "ASN expect error, not zero"; case ASN_BITSTR_E : - XSTRNCPY(buffer, "ASN bit string error, wrong id", max); - break; + return "ASN bit string error, wrong id"; case ASN_UNKNOWN_OID_E : - XSTRNCPY(buffer, "ASN oid error, unknown sum id", max); - break; + return "ASN oid error, unknown sum id"; case ASN_DATE_SZ_E : - XSTRNCPY(buffer, "ASN date error, bad size", max); - break; + return "ASN date error, bad size"; case ASN_BEFORE_DATE_E : - XSTRNCPY(buffer, "ASN date error, current date before", max); - break; + return "ASN date error, current date before"; case ASN_AFTER_DATE_E : - XSTRNCPY(buffer, "ASN date error, current date after", max); - break; + return "ASN date error, current date after"; case ASN_SIG_OID_E : - XSTRNCPY(buffer, "ASN signature error, mismatched oid", max); - break; + return "ASN signature error, mismatched oid"; case ASN_TIME_E : - XSTRNCPY(buffer, "ASN time error, unkown time type", max); - break; + return "ASN time error, unkown time type"; case ASN_INPUT_E : - XSTRNCPY(buffer, "ASN input error, not enough data", max); - break; + return "ASN input error, not enough data"; case ASN_SIG_CONFIRM_E : - XSTRNCPY(buffer, "ASN sig error, confirm failure", max); - break; + return "ASN sig error, confirm failure"; case ASN_SIG_HASH_E : - XSTRNCPY(buffer, "ASN sig error, unsupported hash type", max); - break; + return "ASN sig error, unsupported hash type"; case ASN_SIG_KEY_E : - XSTRNCPY(buffer, "ASN sig error, unsupported key type", max); - break; + return "ASN sig error, unsupported key type"; case ASN_DH_KEY_E : - XSTRNCPY(buffer, "ASN key init error, invalid input", max); - break; + return "ASN key init error, invalid input"; case ASN_NTRU_KEY_E : - XSTRNCPY(buffer, "ASN NTRU key decode error, invalid input", max); - break; + return "ASN NTRU key decode error, invalid input"; case ASN_CRIT_EXT_E: - XSTRNCPY(buffer, "X.509 Critical extension ignored", max); - break; + return "X.509 Critical extension ignored"; case ECC_BAD_ARG_E : - XSTRNCPY(buffer, "ECC input argument wrong type, invalid input", max); - break; + return "ECC input argument wrong type, invalid input"; case ASN_ECC_KEY_E : - XSTRNCPY(buffer, "ECC ASN1 bad key data, invalid input", max); - break; + return "ECC ASN1 bad key data, invalid input"; case ECC_CURVE_OID_E : - XSTRNCPY(buffer, "ECC curve sum OID unsupported, invalid input", max); - break; + return "ECC curve sum OID unsupported, invalid input"; case BAD_FUNC_ARG : - XSTRNCPY(buffer, "Bad function argument", max); - break; + return "Bad function argument"; case NOT_COMPILED_IN : - XSTRNCPY(buffer, "Feature not compiled in", max); - break; + return "Feature not compiled in"; case UNICODE_SIZE_E : - XSTRNCPY(buffer, "Unicode password too big", max); - break; + return "Unicode password too big"; case NO_PASSWORD : - XSTRNCPY(buffer, "No password provided by user", max); - break; + return "No password provided by user"; case ALT_NAME_E : - XSTRNCPY(buffer, "Alt Name problem, too big", max); - break; + return "Alt Name problem, too big"; case AES_GCM_AUTH_E: - XSTRNCPY(buffer, "AES-GCM Authentication check fail", max); - break; + return "AES-GCM Authentication check fail"; case AES_CCM_AUTH_E: - XSTRNCPY(buffer, "AES-CCM Authentication check fail", max); - break; + return "AES-CCM Authentication check fail"; case CAVIUM_INIT_E: - XSTRNCPY(buffer, "Cavium Init type error", max); - break; + return "Cavium Init type error"; case COMPRESS_INIT_E: - XSTRNCPY(buffer, "Compress Init error", max); - break; + return "Compress Init error"; case COMPRESS_E: - XSTRNCPY(buffer, "Compress error", max); - break; + return "Compress error"; case DECOMPRESS_INIT_E: - XSTRNCPY(buffer, "DeCompress Init error", max); - break; + return "DeCompress Init error"; case DECOMPRESS_E: - XSTRNCPY(buffer, "DeCompress error", max); - break; + return "DeCompress error"; case BAD_ALIGN_E: - XSTRNCPY(buffer, "Bad alignment error, no alloc help", max); - break; + return "Bad alignment error, no alloc help"; case ASN_NO_SIGNER_E : - XSTRNCPY(buffer, "ASN no signer error to confirm failure", max); - break; + return "ASN no signer error to confirm failure"; case ASN_CRL_CONFIRM_E : - XSTRNCPY(buffer, "ASN CRL sig error, confirm failure", max); - break; + return "ASN CRL sig error, confirm failure"; case ASN_CRL_NO_SIGNER_E : - XSTRNCPY(buffer, "ASN CRL no signer error to confirm failure", max); - break; + return "ASN CRL no signer error to confirm failure"; case ASN_OCSP_CONFIRM_E : - XSTRNCPY(buffer, "ASN OCSP sig error, confirm failure", max); - break; + return "ASN OCSP sig error, confirm failure"; case BAD_ENC_STATE_E: - XSTRNCPY(buffer, "Bad ecc encrypt state operation", max); - break; + return "Bad ecc encrypt state operation"; case BAD_PADDING_E: - XSTRNCPY(buffer, "Bad padding, message wrong length", max); - break; + return "Bad padding, message wrong length"; case REQ_ATTRIBUTE_E: - XSTRNCPY(buffer, "Setting cert request attributes error", max); - break; + return "Setting cert request attributes error"; case PKCS7_OID_E: - XSTRNCPY(buffer, "PKCS#7 error: mismatched OID value", max); - break; + return "PKCS#7 error: mismatched OID value"; case PKCS7_RECIP_E: - XSTRNCPY(buffer, "PKCS#7 error: no matching recipient found", max); - break; + return "PKCS#7 error: no matching recipient found"; case FIPS_NOT_ALLOWED_E: - XSTRNCPY(buffer, "FIPS mode not allowed error", max); - break; + return "FIPS mode not allowed error"; case ASN_NAME_INVALID_E: - XSTRNCPY(buffer, "Name Constraint error", max); - break; + return "Name Constraint error"; + + case RNG_FAILURE_E: + return "Random Number Generator failed"; + + case HMAC_MIN_KEYLEN_E: + return "FIPS Mode HMAC Minimum Key Length error"; default: - XSTRNCPY(buffer, "unknown error number", max); + return "unknown error number"; } #endif /* NO_ERROR_STRINGS */ } + +void CTaoCryptErrorString(int error, char* buffer) +{ + XSTRNCPY(buffer, CTaoCryptGetErrorString(error), CYASSL_MAX_ERROR_SZ); +} diff --git a/ctaocrypt/src/hmac.c b/ctaocrypt/src/hmac.c index 0bd1c41d1..c5362db55 100644 --- a/ctaocrypt/src/hmac.c +++ b/ctaocrypt/src/hmac.c @@ -131,6 +131,11 @@ int HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) if (ret != 0) return ret; +#ifdef HAVE_FIPS + if (length < HMAC_FIPS_MIN_KEY) + return HMAC_MIN_KEYLEN_E; +#endif + switch (hmac->macType) { #ifndef NO_MD5 case MD5: diff --git a/ctaocrypt/src/include.am b/ctaocrypt/src/include.am index 580d3f553..6664dab22 100644 --- a/ctaocrypt/src/include.am +++ b/ctaocrypt/src/include.am @@ -2,7 +2,8 @@ # All paths should be given relative to the root EXTRA_DIST += ctaocrypt/src/misc.c -EXTRA_DIST += ctaocrypt/src/asm.c +EXTRA_DIST += ctaocrypt/src/asm.c +EXTRA_DIST += ctaocrypt/src/aes_asm.asm EXTRA_DIST += \ ctaocrypt/src/ecc_fp.c \ diff --git a/ctaocrypt/src/integer.c b/ctaocrypt/src/integer.c index e885ca04b..b39a36f9f 100644 --- a/ctaocrypt/src/integer.c +++ b/ctaocrypt/src/integer.c @@ -1854,15 +1854,15 @@ int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, } /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times*/ - if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + if ((err = mp_copy (&M[1], &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) { goto LBL_RES; } for (x = 0; x < (winsize - 1); x++) { - if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { + if ((err = mp_sqr (&M[(mp_digit)(1 << (winsize - 1))], &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) { goto LBL_RES; } - if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { + if ((err = redux (&M[(mp_digit)(1 << (winsize - 1))], P, mp)) != MP_OKAY) { goto LBL_RES; } } @@ -3250,19 +3250,19 @@ int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) /* compute the value at M[1<<(winsize-1)] by squaring * M[1] (winsize-1) times */ - if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + if ((err = mp_copy (&M[1], &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) { goto LBL_MU; } for (x = 0; x < (winsize - 1); x++) { /* square it */ - if ((err = mp_sqr (&M[1 << (winsize - 1)], - &M[1 << (winsize - 1)])) != MP_OKAY) { + if ((err = mp_sqr (&M[(mp_digit)(1 << (winsize - 1))], + &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) { goto LBL_MU; } /* reduce modulo P */ - if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { + if ((err = redux (&M[(mp_digit)(1 << (winsize - 1))], P, &mu)) != MP_OKAY) { goto LBL_MU; } } @@ -3765,7 +3765,7 @@ int mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) #endif -#if defined(HAVE_ECC) || !defined(NO_PWDBASED) || defined(CYASSL_SNIFFER) || defined(CYASSL_HAVE_WOLFSCEP) +#if defined(HAVE_ECC) || !defined(NO_PWDBASED) || defined(CYASSL_SNIFFER) || defined(CYASSL_HAVE_WOLFSCEP) || defined(CYASSL_KEY_GEN) /* single digit addition */ int mp_add_d (mp_int* a, mp_digit b, mp_int* c) diff --git a/ctaocrypt/src/md2.c b/ctaocrypt/src/md2.c index 178287eec..e129cf73c 100644 --- a/ctaocrypt/src/md2.c +++ b/ctaocrypt/src/md2.c @@ -29,6 +29,8 @@ #ifdef CYASSL_MD2 #include +#include + #ifdef NO_INLINE #include #else @@ -128,4 +130,30 @@ void Md2Final(Md2* md2, byte* hash) } +int Md2Hash(const byte* data, word32 len, byte* hash) +{ +#ifdef CYASSL_SMALL_STACK + Md2* md2; +#else + Md2 md2[1]; +#endif + +#ifdef CYASSL_SMALL_STACK + md2 = (Md2*)XMALLOC(sizeof(Md2), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (md2 == NULL) + return MEMORY_E; +#endif + + InitMd2(md2); + Md2Update(md2, data, len); + Md2Final(md2, hash); + +#ifdef CYASSL_SMALL_STACK + XFREE(md2, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return 0; +} + + #endif /* CYASSL_MD2 */ diff --git a/ctaocrypt/src/md5.c b/ctaocrypt/src/md5.c index 3da4cc6b6..4a375391d 100644 --- a/ctaocrypt/src/md5.c +++ b/ctaocrypt/src/md5.c @@ -35,6 +35,7 @@ #endif #include +#include #ifdef NO_INLINE #include @@ -361,4 +362,30 @@ void Md5Final(Md5* md5, byte* hash) #endif /* STM32F2_HASH */ + +int Md5Hash(const byte* data, word32 len, byte* hash) +{ +#ifdef CYASSL_SMALL_STACK + Md5* md5; +#else + Md5 md5[1]; +#endif + +#ifdef CYASSL_SMALL_STACK + md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (md5 == NULL) + return MEMORY_E; +#endif + + InitMd5(md5); + Md5Update(md5, data, len); + Md5Final(md5, hash); + +#ifdef CYASSL_SMALL_STACK + XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return 0; +} + #endif /* NO_MD5 */ diff --git a/ctaocrypt/src/misc.c b/ctaocrypt/src/misc.c index 69fd4a449..7d4d33594 100644 --- a/ctaocrypt/src/misc.c +++ b/ctaocrypt/src/misc.c @@ -45,6 +45,8 @@ #include /* get intrinsic definitions */ + /* for non visual studio probably need no long version, 32 bit only + * i.e., _rotl and _rotr */ #pragma intrinsic(_lrotl, _lrotr) STATIC INLINE word32 rotlFixed(word32 x, word32 y) diff --git a/ctaocrypt/src/pkcs7.c b/ctaocrypt/src/pkcs7.c index 1b0092797..9e3706da0 100644 --- a/ctaocrypt/src/pkcs7.c +++ b/ctaocrypt/src/pkcs7.c @@ -153,25 +153,43 @@ int PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz) XMEMSET(pkcs7, 0, sizeof(PKCS7)); if (cert != NULL && certSz > 0) { - DecodedCert dCert; +#ifdef CYASSL_SMALL_STACK + DecodedCert* dCert; + + dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (dCert == NULL) + return MEMORY_E; +#else + DecodedCert stack_dCert; + DecodedCert* dCert = &stack_dCert; +#endif pkcs7->singleCert = cert; pkcs7->singleCertSz = certSz; - InitDecodedCert(&dCert, cert, certSz, 0); + InitDecodedCert(dCert, cert, certSz, 0); - ret = ParseCert(&dCert, CA_TYPE, NO_VERIFY, 0); + ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0); if (ret < 0) { - FreeDecodedCert(&dCert); + FreeDecodedCert(dCert); +#ifdef CYASSL_SMALL_STACK + XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ret; } - XMEMCPY(pkcs7->publicKey, dCert.publicKey, dCert.pubKeySize); - pkcs7->publicKeySz = dCert.pubKeySize; - XMEMCPY(pkcs7->issuerHash, dCert.issuerHash, SHA_SIZE); - pkcs7->issuer = dCert.issuerRaw; - pkcs7->issuerSz = dCert.issuerRawLen; - XMEMCPY(pkcs7->issuerSn, dCert.serial, dCert.serialSz); - pkcs7->issuerSnSz = dCert.serialSz; - FreeDecodedCert(&dCert); + + XMEMCPY(pkcs7->publicKey, dCert->publicKey, dCert->pubKeySize); + pkcs7->publicKeySz = dCert->pubKeySize; + XMEMCPY(pkcs7->issuerHash, dCert->issuerHash, SHA_SIZE); + pkcs7->issuer = dCert->issuerRaw; + pkcs7->issuerSz = dCert->issuerRawLen; + XMEMCPY(pkcs7->issuerSn, dCert->serial, dCert->serialSz); + pkcs7->issuerSnSz = dCert->serialSz; + FreeDecodedCert(dCert); + +#ifdef CYASSL_SMALL_STACK + XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif } return ret; @@ -325,7 +343,13 @@ int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 }; - ESD esd; +#ifdef CYASSL_SMALL_STACK + ESD* esd = NULL; +#else + ESD stack_esd; + ESD* esd = &stack_esd; +#endif + word32 signerInfoSz = 0; word32 totalSz = 0; int idx = 0, ret = 0; @@ -341,41 +365,51 @@ int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) output == NULL || outputSz == 0) return BAD_FUNC_ARG; - XMEMSET(&esd, 0, sizeof(esd)); - ret = InitSha(&esd.sha); - if (ret != 0) +#ifdef CYASSL_SMALL_STACK + esd = (ESD*)XMALLOC(sizeof(ESD), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (esd == NULL) + return MEMORY_E; +#endif + + XMEMSET(esd, 0, sizeof(ESD)); + ret = InitSha(&esd->sha); + if (ret != 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ret; + } if (pkcs7->contentSz != 0) { - ShaUpdate(&esd.sha, pkcs7->content, pkcs7->contentSz); - esd.contentDigest[0] = ASN_OCTET_STRING; - esd.contentDigest[1] = SHA_DIGEST_SIZE; - ShaFinal(&esd.sha, &esd.contentDigest[2]); + ShaUpdate(&esd->sha, pkcs7->content, pkcs7->contentSz); + esd->contentDigest[0] = ASN_OCTET_STRING; + esd->contentDigest[1] = SHA_DIGEST_SIZE; + ShaFinal(&esd->sha, &esd->contentDigest[2]); } - esd.innerOctetsSz = SetOctetString(pkcs7->contentSz, esd.innerOctets); - esd.innerContSeqSz = SetExplicit(0, esd.innerOctetsSz + pkcs7->contentSz, - esd.innerContSeq); - esd.contentInfoSeqSz = SetSequence(pkcs7->contentSz + esd.innerOctetsSz + - innerOidSz + esd.innerContSeqSz, - esd.contentInfoSeq); + esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets); + esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz + pkcs7->contentSz, + esd->innerContSeq); + esd->contentInfoSeqSz = SetSequence(pkcs7->contentSz + esd->innerOctetsSz + + innerOidSz + esd->innerContSeqSz, + esd->contentInfoSeq); - esd.issuerSnSz = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz, - esd.issuerSn); - signerInfoSz += esd.issuerSnSz; - esd.issuerNameSz = SetSequence(pkcs7->issuerSz, esd.issuerName); - signerInfoSz += esd.issuerNameSz + pkcs7->issuerSz; - esd.issuerSnSeqSz = SetSequence(signerInfoSz, esd.issuerSnSeq); - signerInfoSz += esd.issuerSnSeqSz; - esd.signerVersionSz = SetMyVersion(1, esd.signerVersion, 0); - signerInfoSz += esd.signerVersionSz; - esd.signerDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd.signerDigAlgoId, + esd->issuerSnSz = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz, + esd->issuerSn); + signerInfoSz += esd->issuerSnSz; + esd->issuerNameSz = SetSequence(pkcs7->issuerSz, esd->issuerName); + signerInfoSz += esd->issuerNameSz + pkcs7->issuerSz; + esd->issuerSnSeqSz = SetSequence(signerInfoSz, esd->issuerSnSeq); + signerInfoSz += esd->issuerSnSeqSz; + esd->signerVersionSz = SetMyVersion(1, esd->signerVersion, 0); + signerInfoSz += esd->signerVersionSz; + esd->signerDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->signerDigAlgoId, hashType, 0); - signerInfoSz += esd.signerDigAlgoIdSz; - esd.digEncAlgoIdSz = SetAlgoID(pkcs7->encryptOID, esd.digEncAlgoId, + signerInfoSz += esd->signerDigAlgoIdSz; + esd->digEncAlgoIdSz = SetAlgoID(pkcs7->encryptOID, esd->digEncAlgoId, keyType, 0); - signerInfoSz += esd.digEncAlgoIdSz; + signerInfoSz += esd->digEncAlgoIdSz; if (pkcs7->signedAttribsSz != 0) { byte contentTypeOid[] = @@ -393,35 +427,45 @@ int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) { contentTypeOid, sizeof(contentTypeOid), contentType, sizeof(contentType) }, { messageDigestOid, sizeof(messageDigestOid), - esd.contentDigest, sizeof(esd.contentDigest) } + esd->contentDigest, sizeof(esd->contentDigest) } }; word32 cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib); - esd.signedAttribsCount += cannedAttribsCount; - esd.signedAttribsSz += EncodeAttributes(&esd.signedAttribs[0], 2, + esd->signedAttribsCount += cannedAttribsCount; + esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[0], 2, cannedAttribs, cannedAttribsCount); - esd.signedAttribsCount += pkcs7->signedAttribsSz; - esd.signedAttribsSz += EncodeAttributes(&esd.signedAttribs[2], 4, + esd->signedAttribsCount += pkcs7->signedAttribsSz; + esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[2], 4, pkcs7->signedAttribs, pkcs7->signedAttribsSz); - flatSignedAttribs = (byte*)XMALLOC(esd.signedAttribsSz, 0, NULL); - flatSignedAttribsSz = esd.signedAttribsSz; - if (flatSignedAttribs == NULL) + flatSignedAttribs = (byte*)XMALLOC(esd->signedAttribsSz, 0, NULL); + flatSignedAttribsSz = esd->signedAttribsSz; + if (flatSignedAttribs == NULL) { +#ifdef CYASSL_SMALL_STACK + XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return MEMORY_E; + } FlattenAttributes(flatSignedAttribs, - esd.signedAttribs, esd.signedAttribsCount); - esd.signedAttribSetSz = SetImplicit(ASN_SET, 0, esd.signedAttribsSz, - esd.signedAttribSet); + esd->signedAttribs, esd->signedAttribsCount); + esd->signedAttribSetSz = SetImplicit(ASN_SET, 0, esd->signedAttribsSz, + esd->signedAttribSet); } /* Calculate the final hash and encrypt it. */ { - RsaKey privKey; int result; word32 scratch = 0; +#ifdef CYASSL_SMALL_STACK + byte* digestInfo; + RsaKey* privKey; +#else + RsaKey stack_privKey; + RsaKey* privKey = &stack_privKey; byte digestInfo[MAX_SEQ_SZ + MAX_ALGO_SZ + MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE]; +#endif byte digestInfoSeq[MAX_SEQ_SZ]; byte digestStr[MAX_OCTET_STR_SZ]; word32 digestInfoSeqSz, digestStrSz; @@ -433,145 +477,203 @@ int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) attribSetSz = SetSet(flatSignedAttribsSz, attribSet); - ret = InitSha(&esd.sha); + ret = InitSha(&esd->sha); if (ret < 0) { XFREE(flatSignedAttribs, 0, NULL); +#ifdef CYASSL_SMALL_STACK + XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ret; } - ShaUpdate(&esd.sha, attribSet, attribSetSz); - ShaUpdate(&esd.sha, flatSignedAttribs, flatSignedAttribsSz); + ShaUpdate(&esd->sha, attribSet, attribSetSz); + ShaUpdate(&esd->sha, flatSignedAttribs, flatSignedAttribsSz); } - ShaFinal(&esd.sha, esd.contentAttribsDigest); + ShaFinal(&esd->sha, esd->contentAttribsDigest); digestStrSz = SetOctetString(SHA_DIGEST_SIZE, digestStr); - digestInfoSeqSz = SetSequence(esd.signerDigAlgoIdSz + + digestInfoSeqSz = SetSequence(esd->signerDigAlgoIdSz + digestStrSz + SHA_DIGEST_SIZE, digestInfoSeq); +#ifdef CYASSL_SMALL_STACK + digestInfo = (byte*)XMALLOC(MAX_SEQ_SZ + MAX_ALGO_SZ + + MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE, + NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (digestInfo == NULL) { + if (pkcs7->signedAttribsSz != 0) + XFREE(flatSignedAttribs, 0, NULL); + XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } +#endif + XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz); digIdx += digestInfoSeqSz; XMEMCPY(digestInfo + digIdx, - esd.signerDigAlgoId, esd.signerDigAlgoIdSz); - digIdx += esd.signerDigAlgoIdSz; + esd->signerDigAlgoId, esd->signerDigAlgoIdSz); + digIdx += esd->signerDigAlgoIdSz; XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz); digIdx += digestStrSz; - XMEMCPY(digestInfo + digIdx, esd.contentAttribsDigest, SHA_DIGEST_SIZE); + XMEMCPY(digestInfo + digIdx, esd->contentAttribsDigest, + SHA_DIGEST_SIZE); digIdx += SHA_DIGEST_SIZE; - result = InitRsaKey(&privKey, NULL); +#ifdef CYASSL_SMALL_STACK + privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (privKey == NULL) { + if (pkcs7->signedAttribsSz != 0) + XFREE(flatSignedAttribs, 0, NULL); + XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } +#endif + + result = InitRsaKey(privKey, NULL); if (result == 0) - result = RsaPrivateKeyDecode(pkcs7->privateKey, &scratch, &privKey, + result = RsaPrivateKeyDecode(pkcs7->privateKey, &scratch, privKey, pkcs7->privateKeySz); if (result < 0) { - XFREE(flatSignedAttribs, 0, NULL); + if (pkcs7->signedAttribsSz != 0) + XFREE(flatSignedAttribs, 0, NULL); +#ifdef CYASSL_SMALL_STACK + XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return PUBLIC_KEY_E; } + result = RsaSSL_Sign(digestInfo, digIdx, - esd.encContentDigest, sizeof(esd.encContentDigest), - &privKey, pkcs7->rng); - FreeRsaKey(&privKey); + esd->encContentDigest, + sizeof(esd->encContentDigest), + privKey, pkcs7->rng); + + FreeRsaKey(privKey); + +#ifdef CYASSL_SMALL_STACK + XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + if (result < 0) { - XFREE(flatSignedAttribs, 0, NULL); + if (pkcs7->signedAttribsSz != 0) + XFREE(flatSignedAttribs, 0, NULL); +#ifdef CYASSL_SMALL_STACK + XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return result; } - esd.encContentDigestSz = (word32)result; + esd->encContentDigestSz = (word32)result; } - signerInfoSz += flatSignedAttribsSz + esd.signedAttribSetSz; + signerInfoSz += flatSignedAttribsSz + esd->signedAttribSetSz; - esd.signerDigestSz = SetOctetString(esd.encContentDigestSz, - esd.signerDigest); - signerInfoSz += esd.signerDigestSz + esd.encContentDigestSz; + esd->signerDigestSz = SetOctetString(esd->encContentDigestSz, + esd->signerDigest); + signerInfoSz += esd->signerDigestSz + esd->encContentDigestSz; - esd.signerInfoSeqSz = SetSequence(signerInfoSz, esd.signerInfoSeq); - signerInfoSz += esd.signerInfoSeqSz; - esd.signerInfoSetSz = SetSet(signerInfoSz, esd.signerInfoSet); - signerInfoSz += esd.signerInfoSetSz; + esd->signerInfoSeqSz = SetSequence(signerInfoSz, esd->signerInfoSeq); + signerInfoSz += esd->signerInfoSeqSz; + esd->signerInfoSetSz = SetSet(signerInfoSz, esd->signerInfoSet); + signerInfoSz += esd->signerInfoSetSz; - esd.certsSetSz = SetImplicit(ASN_SET, 0, pkcs7->singleCertSz, esd.certsSet); + esd->certsSetSz = SetImplicit(ASN_SET, 0, pkcs7->singleCertSz, + esd->certsSet); - esd.singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd.singleDigAlgoId, + esd->singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->singleDigAlgoId, hashType, 0); - esd.digAlgoIdSetSz = SetSet(esd.singleDigAlgoIdSz, esd.digAlgoIdSet); + esd->digAlgoIdSetSz = SetSet(esd->singleDigAlgoIdSz, esd->digAlgoIdSet); - esd.versionSz = SetMyVersion(1, esd.version, 0); + esd->versionSz = SetMyVersion(1, esd->version, 0); - totalSz = esd.versionSz + esd.singleDigAlgoIdSz + esd.digAlgoIdSetSz + - esd.contentInfoSeqSz + esd.certsSetSz + pkcs7->singleCertSz + - esd.innerOctetsSz + esd.innerContSeqSz + + totalSz = esd->versionSz + esd->singleDigAlgoIdSz + esd->digAlgoIdSetSz + + esd->contentInfoSeqSz + esd->certsSetSz + pkcs7->singleCertSz + + esd->innerOctetsSz + esd->innerContSeqSz + innerOidSz + pkcs7->contentSz + signerInfoSz; - esd.innerSeqSz = SetSequence(totalSz, esd.innerSeq); - totalSz += esd.innerSeqSz; - esd.outerContentSz = SetExplicit(0, totalSz, esd.outerContent); - totalSz += esd.outerContentSz + outerOidSz; - esd.outerSeqSz = SetSequence(totalSz, esd.outerSeq); - totalSz += esd.outerSeqSz; + esd->innerSeqSz = SetSequence(totalSz, esd->innerSeq); + totalSz += esd->innerSeqSz; + esd->outerContentSz = SetExplicit(0, totalSz, esd->outerContent); + totalSz += esd->outerContentSz + outerOidSz; + esd->outerSeqSz = SetSequence(totalSz, esd->outerSeq); + totalSz += esd->outerSeqSz; - if (outputSz < totalSz) + if (outputSz < totalSz) { + if (pkcs7->signedAttribsSz != 0) + XFREE(flatSignedAttribs, 0, NULL); +#ifdef CYASSL_SMALL_STACK + XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return BUFFER_E; + } idx = 0; - XMEMCPY(output + idx, esd.outerSeq, esd.outerSeqSz); - idx += esd.outerSeqSz; + XMEMCPY(output + idx, esd->outerSeq, esd->outerSeqSz); + idx += esd->outerSeqSz; XMEMCPY(output + idx, outerOid, outerOidSz); idx += outerOidSz; - XMEMCPY(output + idx, esd.outerContent, esd.outerContentSz); - idx += esd.outerContentSz; - XMEMCPY(output + idx, esd.innerSeq, esd.innerSeqSz); - idx += esd.innerSeqSz; - XMEMCPY(output + idx, esd.version, esd.versionSz); - idx += esd.versionSz; - XMEMCPY(output + idx, esd.digAlgoIdSet, esd.digAlgoIdSetSz); - idx += esd.digAlgoIdSetSz; - XMEMCPY(output + idx, esd.singleDigAlgoId, esd.singleDigAlgoIdSz); - idx += esd.singleDigAlgoIdSz; - XMEMCPY(output + idx, esd.contentInfoSeq, esd.contentInfoSeqSz); - idx += esd.contentInfoSeqSz; + XMEMCPY(output + idx, esd->outerContent, esd->outerContentSz); + idx += esd->outerContentSz; + XMEMCPY(output + idx, esd->innerSeq, esd->innerSeqSz); + idx += esd->innerSeqSz; + XMEMCPY(output + idx, esd->version, esd->versionSz); + idx += esd->versionSz; + XMEMCPY(output + idx, esd->digAlgoIdSet, esd->digAlgoIdSetSz); + idx += esd->digAlgoIdSetSz; + XMEMCPY(output + idx, esd->singleDigAlgoId, esd->singleDigAlgoIdSz); + idx += esd->singleDigAlgoIdSz; + XMEMCPY(output + idx, esd->contentInfoSeq, esd->contentInfoSeqSz); + idx += esd->contentInfoSeqSz; XMEMCPY(output + idx, innerOid, innerOidSz); idx += innerOidSz; - XMEMCPY(output + idx, esd.innerContSeq, esd.innerContSeqSz); - idx += esd.innerContSeqSz; - XMEMCPY(output + idx, esd.innerOctets, esd.innerOctetsSz); - idx += esd.innerOctetsSz; + XMEMCPY(output + idx, esd->innerContSeq, esd->innerContSeqSz); + idx += esd->innerContSeqSz; + XMEMCPY(output + idx, esd->innerOctets, esd->innerOctetsSz); + idx += esd->innerOctetsSz; XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz); idx += pkcs7->contentSz; - XMEMCPY(output + idx, esd.certsSet, esd.certsSetSz); - idx += esd.certsSetSz; + XMEMCPY(output + idx, esd->certsSet, esd->certsSetSz); + idx += esd->certsSetSz; XMEMCPY(output + idx, pkcs7->singleCert, pkcs7->singleCertSz); idx += pkcs7->singleCertSz; - XMEMCPY(output + idx, esd.signerInfoSet, esd.signerInfoSetSz); - idx += esd.signerInfoSetSz; - XMEMCPY(output + idx, esd.signerInfoSeq, esd.signerInfoSeqSz); - idx += esd.signerInfoSeqSz; - XMEMCPY(output + idx, esd.signerVersion, esd.signerVersionSz); - idx += esd.signerVersionSz; - XMEMCPY(output + idx, esd.issuerSnSeq, esd.issuerSnSeqSz); - idx += esd.issuerSnSeqSz; - XMEMCPY(output + idx, esd.issuerName, esd.issuerNameSz); - idx += esd.issuerNameSz; + XMEMCPY(output + idx, esd->signerInfoSet, esd->signerInfoSetSz); + idx += esd->signerInfoSetSz; + XMEMCPY(output + idx, esd->signerInfoSeq, esd->signerInfoSeqSz); + idx += esd->signerInfoSeqSz; + XMEMCPY(output + idx, esd->signerVersion, esd->signerVersionSz); + idx += esd->signerVersionSz; + XMEMCPY(output + idx, esd->issuerSnSeq, esd->issuerSnSeqSz); + idx += esd->issuerSnSeqSz; + XMEMCPY(output + idx, esd->issuerName, esd->issuerNameSz); + idx += esd->issuerNameSz; XMEMCPY(output + idx, pkcs7->issuer, pkcs7->issuerSz); idx += pkcs7->issuerSz; - XMEMCPY(output + idx, esd.issuerSn, esd.issuerSnSz); - idx += esd.issuerSnSz; - XMEMCPY(output + idx, esd.signerDigAlgoId, esd.signerDigAlgoIdSz); - idx += esd.signerDigAlgoIdSz; + XMEMCPY(output + idx, esd->issuerSn, esd->issuerSnSz); + idx += esd->issuerSnSz; + XMEMCPY(output + idx, esd->signerDigAlgoId, esd->signerDigAlgoIdSz); + idx += esd->signerDigAlgoIdSz; /* SignerInfo:Attributes */ if (pkcs7->signedAttribsSz != 0) { - XMEMCPY(output + idx, esd.signedAttribSet, esd.signedAttribSetSz); - idx += esd.signedAttribSetSz; + XMEMCPY(output + idx, esd->signedAttribSet, esd->signedAttribSetSz); + idx += esd->signedAttribSetSz; XMEMCPY(output + idx, flatSignedAttribs, flatSignedAttribsSz); idx += flatSignedAttribsSz; XFREE(flatSignedAttribs, 0, NULL); } - XMEMCPY(output + idx, esd.digEncAlgoId, esd.digEncAlgoIdSz); - idx += esd.digEncAlgoIdSz; - XMEMCPY(output + idx, esd.signerDigest, esd.signerDigestSz); - idx += esd.signerDigestSz; - XMEMCPY(output + idx, esd.encContentDigest, esd.encContentDigestSz); - idx += esd.encContentDigestSz; + XMEMCPY(output + idx, esd->digEncAlgoId, esd->digEncAlgoIdSz); + idx += esd->digEncAlgoIdSz; + XMEMCPY(output + idx, esd->signerDigest, esd->signerDigestSz); + idx += esd->signerDigestSz; + XMEMCPY(output + idx, esd->encContentDigest, esd->encContentDigestSz); + idx += esd->encContentDigestSz; + +#ifdef CYASSL_SMALL_STACK + XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return idx; } @@ -707,11 +809,6 @@ int PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz) return ASN_PARSE_E; if (length > 0) { - RsaKey key; - word32 scratch = 0; - int plainSz = 0; - byte digest[MAX_SEQ_SZ+MAX_ALGO_SZ+MAX_OCTET_STR_SZ+SHA_DIGEST_SIZE]; - /* Get the sequence of the first signerInfo */ if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) return ASN_PARSE_E; @@ -770,21 +867,67 @@ int PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz) idx += length; } - XMEMSET(digest, 0, sizeof(digest)); pkcs7->content = content; pkcs7->contentSz = contentSz; - ret = InitRsaKey(&key, NULL); - if (ret != 0) return ret; - if (RsaPublicKeyDecode(pkcs7->publicKey, &scratch, &key, - pkcs7->publicKeySz) < 0) { - CYASSL_MSG("ASN RSA key decode error"); - return PUBLIC_KEY_E; + { + word32 scratch = 0; + int plainSz = 0; + int digestSz = MAX_SEQ_SZ + MAX_ALGO_SZ + + MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE; + +#ifdef CYASSL_SMALL_STACK + byte* digest; + RsaKey* key; + + digest = (byte*)XMALLOC(digestSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + if (digest == NULL) + return MEMORY_E; + + key = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (key == NULL) { + XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } +#else + byte digest[digestSz]; + RsaKey stack_key; + RsaKey* key = &stack_key; +#endif + + XMEMSET(digest, 0, digestSz); + + ret = InitRsaKey(key, NULL); + if (ret != 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return ret; + } + if (RsaPublicKeyDecode(pkcs7->publicKey, &scratch, key, + pkcs7->publicKeySz) < 0) { + CYASSL_MSG("ASN RSA key decode error"); +#ifdef CYASSL_SMALL_STACK + XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return PUBLIC_KEY_E; + } + + plainSz = RsaSSL_Verify(sig, sigSz, digest, digestSz, key); + FreeRsaKey(key); + +#ifdef CYASSL_SMALL_STACK + XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + if (plainSz < 0) + return plainSz; } - plainSz = RsaSSL_Verify(sig, sigSz, digest, sizeof(digest), &key); - FreeRsaKey(&key); - if (plainSz < 0) - return plainSz; } return 0; @@ -805,20 +948,49 @@ CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz, int encKeyOctetStrSz; byte ver[MAX_VERSION_SZ]; - byte serial[MAX_SN_SZ]; byte issuerSerialSeq[MAX_SEQ_SZ]; byte recipSeq[MAX_SEQ_SZ]; byte issuerSeq[MAX_SEQ_SZ]; - byte keyAlgArray[MAX_ALGO_SZ]; byte encKeyOctetStr[MAX_OCTET_STR_SZ]; - RsaKey pubKey; - DecodedCert decoded; +#ifdef CYASSL_SMALL_STACK + byte *serial; + byte *keyAlgArray; + + RsaKey* pubKey; + DecodedCert* decoded; - InitDecodedCert(&decoded, (byte*)cert, certSz, 0); - ret = ParseCert(&decoded, CA_TYPE, NO_VERIFY, 0); + serial = (byte*)XMALLOC(MAX_SN_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); + keyAlgArray = (byte*)XMALLOC(MAX_SN_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); + decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + + if (decoded == NULL || serial == NULL || keyAlgArray == NULL) { + if (serial) XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (keyAlgArray) XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (decoded) XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } + +#else + byte serial[MAX_SN_SZ]; + byte keyAlgArray[MAX_ALGO_SZ]; + + RsaKey stack_pubKey; + RsaKey* pubKey = &stack_pubKey; + DecodedCert stack_decoded; + DecodedCert* decoded = &stack_decoded; +#endif + + InitDecodedCert(decoded, (byte*)cert, certSz, 0); + ret = ParseCert(decoded, CA_TYPE, NO_VERIFY, 0); if (ret < 0) { - FreeDecodedCert(&decoded); + FreeDecodedCert(decoded); +#ifdef CYASSL_SMALL_STACK + XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ret; } @@ -826,46 +998,110 @@ CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz, verSz = SetMyVersion(0, ver, 0); /* IssuerAndSerialNumber */ - if (decoded.issuerRaw == NULL || decoded.issuerRawLen == 0) { + if (decoded->issuerRaw == NULL || decoded->issuerRawLen == 0) { CYASSL_MSG("DecodedCert lacks raw issuer pointer and length"); - FreeDecodedCert(&decoded); + FreeDecodedCert(decoded); +#ifdef CYASSL_SMALL_STACK + XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return -1; } - issuerSz = decoded.issuerRawLen; + issuerSz = decoded->issuerRawLen; issuerSeqSz = SetSequence(issuerSz, issuerSeq); - if (decoded.serial == NULL || decoded.serialSz == 0) { + if (decoded->serial == NULL || decoded->serialSz == 0) { CYASSL_MSG("DecodedCert missing serial number"); - FreeDecodedCert(&decoded); + FreeDecodedCert(decoded); +#ifdef CYASSL_SMALL_STACK + XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return -1; } - snSz = SetSerialNumber(decoded.serial, decoded.serialSz, serial); + snSz = SetSerialNumber(decoded->serial, decoded->serialSz, serial); issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz, issuerSerialSeq); /* KeyEncryptionAlgorithmIdentifier, only support RSA now */ - if (keyEncAlgo != RSAk) + if (keyEncAlgo != RSAk) { + FreeDecodedCert(decoded); +#ifdef CYASSL_SMALL_STACK + XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ALGO_ID_E; + } keyEncAlgSz = SetAlgoID(keyEncAlgo, keyAlgArray, keyType, 0); - if (keyEncAlgSz == 0) + if (keyEncAlgSz == 0) { + FreeDecodedCert(decoded); +#ifdef CYASSL_SMALL_STACK + XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return BAD_FUNC_ARG; + } + +#ifdef CYASSL_SMALL_STACK + pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (pubKey == NULL) { + FreeDecodedCert(decoded); + XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } +#endif /* EncryptedKey */ - ret = InitRsaKey(&pubKey, 0); - if (ret != 0) return ret; - if (RsaPublicKeyDecode(decoded.publicKey, &idx, &pubKey, - decoded.pubKeySize) < 0) { + ret = InitRsaKey(pubKey, 0); + if (ret != 0) { + FreeDecodedCert(decoded); +#ifdef CYASSL_SMALL_STACK + XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return ret; + } + + if (RsaPublicKeyDecode(decoded->publicKey, &idx, pubKey, + decoded->pubKeySize) < 0) { CYASSL_MSG("ASN RSA key decode error"); + FreeRsaKey(pubKey); + FreeDecodedCert(decoded); +#ifdef CYASSL_SMALL_STACK + XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return PUBLIC_KEY_E; } *keyEncSz = RsaPublicEncrypt(contentKeyPlain, blockKeySz, contentKeyEnc, - MAX_ENCRYPTED_KEY_SZ, &pubKey, rng); - FreeRsaKey(&pubKey); + MAX_ENCRYPTED_KEY_SZ, pubKey, rng); + FreeRsaKey(pubKey); + +#ifdef CYASSL_SMALL_STACK + XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + if (*keyEncSz < 0) { CYASSL_MSG("RSA Public Encrypt failed"); + FreeDecodedCert(decoded); +#ifdef CYASSL_SMALL_STACK + XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return *keyEncSz; } @@ -879,6 +1115,12 @@ CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz, if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz + keyEncAlgSz + encKeyOctetStrSz + *keyEncSz > (int)outSz) { CYASSL_MSG("RecipientInfo output buffer too small"); + FreeDecodedCert(decoded); +#ifdef CYASSL_SMALL_STACK + XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return BUFFER_E; } @@ -890,7 +1132,7 @@ CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz, totalSz += issuerSerialSeqSz; XMEMCPY(out + totalSz, issuerSeq, issuerSeqSz); totalSz += issuerSeqSz; - XMEMCPY(out + totalSz, decoded.issuerRaw, issuerSz); + XMEMCPY(out + totalSz, decoded->issuerRaw, issuerSz); totalSz += issuerSz; XMEMCPY(out + totalSz, serial, snSz); totalSz += snSz; @@ -901,7 +1143,13 @@ CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz, XMEMCPY(out + totalSz, contentKeyEnc, *keyEncSz); totalSz += *keyEncSz; - FreeDecodedCert(&decoded); + FreeDecodedCert(decoded); + +#ifdef CYASSL_SMALL_STACK + XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return totalSz; } @@ -926,12 +1174,20 @@ int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) int contentKeyEncSz, blockKeySz; int dynamicFlag = 0; byte contentKeyPlain[MAX_CONTENT_KEY_LEN]; +#ifdef CYASSL_SMALL_STACK + byte* contentKeyEnc; +#else byte contentKeyEnc[MAX_ENCRYPTED_KEY_SZ]; +#endif byte* plain; byte* encryptedContent; int recipSz, recipSetSz; +#ifdef CYASSL_SMALL_STACK + byte* recip; +#else byte recip[MAX_RECIP_SZ]; +#endif byte recipSet[MAX_SET_SZ]; int encContentOctetSz, encContentSeqSz, contentTypeSz; @@ -979,36 +1235,68 @@ int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) ret = RNG_GenerateBlock(&rng, contentKeyPlain, blockKeySz); if (ret != 0) return ret; + +#ifdef CYASSL_SMALL_STACK + recip = (byte*)XMALLOC(MAX_RECIP_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); + contentKeyEnc = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (contentKeyEnc == NULL || recip == NULL) { + if (recip) XFREE(recip, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (contentKeyEnc) XFREE(contentKeyEnc, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } + +#endif /* build RecipientInfo, only handle 1 for now */ recipSz = CreateRecipientInfo(pkcs7->singleCert, pkcs7->singleCertSz, RSAk, blockKeySz, &rng, contentKeyPlain, contentKeyEnc, &contentKeyEncSz, recip, MAX_RECIP_SZ); + + XMEMSET(contentKeyEnc, 0, MAX_ENCRYPTED_KEY_SZ); + +#ifdef CYASSL_SMALL_STACK + XFREE(contentKeyEnc, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif if (recipSz < 0) { CYASSL_MSG("Failed to create RecipientInfo"); +#ifdef CYASSL_SMALL_STACK + XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); +#endif return recipSz; } recipSetSz = SetSet(recipSz, recipSet); /* generate IV for block cipher */ ret = RNG_GenerateBlock(&rng, tmpIv, DES_BLOCK_SIZE); - if (ret != 0) + if (ret != 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); +#endif return ret; + } /* EncryptedContentInfo */ contentTypeSz = SetContentType(pkcs7->contentOID, contentType); - if (contentTypeSz == 0) + if (contentTypeSz == 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); +#endif return BAD_FUNC_ARG; + } /* allocate encrypted content buffer, pad if necessary, PKCS#7 padding */ padSz = DES_BLOCK_SIZE - (pkcs7->contentSz % DES_BLOCK_SIZE); desOutSz = pkcs7->contentSz + padSz; if (padSz != 0) { - plain = XMALLOC(desOutSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + plain = (byte*)XMALLOC(desOutSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { +#ifdef CYASSL_SMALL_STACK + XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); +#endif return MEMORY_E; } XMEMCPY(plain, pkcs7->content, pkcs7->contentSz); @@ -1023,10 +1311,13 @@ int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) desOutSz = pkcs7->contentSz; } - encryptedContent = XMALLOC(desOutSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + encryptedContent = (byte*)XMALLOC(desOutSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (encryptedContent == NULL) { if (dynamicFlag) XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#ifdef CYASSL_SMALL_STACK + XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); +#endif return MEMORY_E; } @@ -1037,8 +1328,16 @@ int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) * adding (ivOctetStringSz + DES_BLOCK_SIZE) for IV OCTET STRING */ contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo, blkType, ivOctetStringSz + DES_BLOCK_SIZE); - if (contentEncAlgoSz == 0) + + if (contentEncAlgoSz == 0) { + XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (dynamicFlag) + XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#ifdef CYASSL_SMALL_STACK + XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); +#endif return BAD_FUNC_ARG; + } /* encrypt content */ if (pkcs7->encryptOID == DESb) { @@ -1053,6 +1352,9 @@ int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (dynamicFlag) XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#ifdef CYASSL_SMALL_STACK + XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); +#endif return ret; } } @@ -1068,6 +1370,9 @@ int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (dynamicFlag) XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#ifdef CYASSL_SMALL_STACK + XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); +#endif return ret; } } @@ -1102,6 +1407,9 @@ int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (dynamicFlag) XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#ifdef CYASSL_SMALL_STACK + XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); +#endif return BUFFER_E; } @@ -1139,11 +1447,14 @@ int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) #endif XMEMSET(contentKeyPlain, 0, MAX_CONTENT_KEY_LEN); - XMEMSET(contentKeyEnc, 0, MAX_ENCRYPTED_KEY_SZ); if (dynamicFlag) XFREE(plain, NULL, DYNAMMIC_TYPE_TMP_BUFFER); XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); + +#ifdef CYASSL_SMALL_STACK + XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); +#endif return idx; } @@ -1158,14 +1469,23 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, word32 savedIdx = 0, idx = 0; word32 contentType, encOID; byte issuerHash[SHA_DIGEST_SIZE]; - mp_int serialNum; int encryptedKeySz, keySz; byte tmpIv[DES_BLOCK_SIZE]; - byte encryptedKey[MAX_ENCRYPTED_KEY_SZ]; byte* decryptedKey = NULL; - RsaKey privKey; +#ifdef CYASSL_SMALL_STACK + mp_int* serialNum; + byte* encryptedKey; + RsaKey* privKey; +#else + mp_int stack_serialNum; + mp_int* serialNum = &stack_serialNum; + byte encryptedKey[MAX_ENCRYPTED_KEY_SZ]; + + RsaKey stack_privKey; + RsaKey* privKey = &stack_privKey; +#endif int encryptedContentSz; byte padLen; byte* encryptedContent = NULL; @@ -1179,18 +1499,6 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, output == NULL || outputSz == 0) return BAD_FUNC_ARG; - /* load private key */ - ret = InitRsaKey(&privKey, 0); - if (ret != 0) return ret; - ret = RsaPrivateKeyDecode(pkcs7->privateKey, &idx, &privKey, - pkcs7->privateKeySz); - if (ret != 0) { - CYASSL_MSG("Failed to decode RSA private key"); - return ret; - } - - idx = 0; - /* read past ContentInfo, verify type is envelopedData */ if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) return ASN_PARSE_E; @@ -1224,7 +1532,14 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, /* walk through RecipientInfo set, find correct recipient */ if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0) return ASN_PARSE_E; - + +#ifdef CYASSL_SMALL_STACK + encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (encryptedKey == NULL) + return MEMORY_E; +#endif + savedIdx = idx; recipFound = 0; @@ -1244,39 +1559,86 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, break; } - if (version != 0) + if (version != 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_VERSION_E; - + } + /* remove IssuerAndSerialNumber */ - if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) + if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; - - if (GetNameHash(pkiMsg, &idx, issuerHash, pkiMsgSz) < 0) + } + + if (GetNameHash(pkiMsg, &idx, issuerHash, pkiMsgSz) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; - + } + /* if we found correct recipient, issuer hashes will match */ if (XMEMCMP(issuerHash, pkcs7->issuerHash, SHA_DIGEST_SIZE) == 0) { recipFound = 1; } - - if (GetInt(&serialNum, pkiMsg, &idx, pkiMsgSz) < 0) + +#ifdef CYASSL_SMALL_STACK + serialNum = (mp_int*)XMALLOC(sizeof(mp_int), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (serialNum == NULL) { + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } +#endif + + if (GetInt(serialNum, pkiMsg, &idx, pkiMsgSz) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(serialNum, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; - mp_clear(&serialNum); - - if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0) + } + + mp_clear(serialNum); + +#ifdef CYASSL_SMALL_STACK + XFREE(serialNum, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; - + } + /* key encryption algorithm must be RSA for now */ - if (encOID != RSAk) + if (encOID != RSAk) { +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ALGO_ID_E; - + } + /* read encryptedKey */ - if (pkiMsg[idx++] != ASN_OCTET_STRING) + if (pkiMsg[idx++] != ASN_OCTET_STRING) { +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; - - if (GetLength(pkiMsg, &idx, &encryptedKeySz, pkiMsgSz) < 0) + } + + if (GetLength(pkiMsg, &idx, &encryptedKeySz, pkiMsgSz) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; - + } + if (recipFound == 1) XMEMCPY(encryptedKey, &pkiMsg[idx], encryptedKeySz); idx += encryptedKeySz; @@ -1287,28 +1649,54 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, if (recipFound == 0) { CYASSL_MSG("No recipient found in envelopedData that matches input"); +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return PKCS7_RECIP_E; } /* remove EncryptedContentInfo */ - if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) + if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; - - if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) + } + + if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; + } - if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0) + if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; - + } + /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */ - if (pkiMsg[idx++] != ASN_OCTET_STRING) + if (pkiMsg[idx++] != ASN_OCTET_STRING) { +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; - - if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) + } + + if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; - + } + if (length != DES_BLOCK_SIZE) { CYASSL_MSG("Incorrect IV length, must be of DES_BLOCK_SIZE"); +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; } @@ -1316,23 +1704,80 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, idx += length; /* read encryptedContent, cont[0] */ - if (pkiMsg[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) + if (pkiMsg[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) { +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; + } - if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) < 0) + if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) < 0) { +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ASN_PARSE_E; - - encryptedContent = XMALLOC(encryptedContentSz, NULL, - DYNAMIC_TYPE_TMP_BUFFER); + } + + encryptedContent = (byte*)XMALLOC(encryptedContentSz, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (encryptedContent == NULL) { +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return MEMORY_E; + } XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz); + /* load private key */ +#ifdef CYASSL_SMALL_STACK + privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (privKey == NULL) { + XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; + } +#endif + + ret = InitRsaKey(privKey, 0); + if (ret != 0) { + XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#ifdef CYASSL_SMALL_STACK + XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return ret; + } + + idx = 0; + + ret = RsaPrivateKeyDecode(pkcs7->privateKey, &idx, privKey, + pkcs7->privateKeySz); + if (ret != 0) { + CYASSL_MSG("Failed to decode RSA private key"); + XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#ifdef CYASSL_SMALL_STACK + XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return ret; + } + /* decrypt encryptedKey */ keySz = RsaPrivateDecryptInline(encryptedKey, encryptedKeySz, - &decryptedKey, &privKey); - FreeRsaKey(&privKey); - if (keySz <= 0) + &decryptedKey, privKey); + FreeRsaKey(privKey); + +#ifdef CYASSL_SMALL_STACK + XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + if (keySz <= 0) { + XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return keySz; + } /* decrypt encryptedContent */ if (encOID == DESb) { @@ -1345,6 +1790,9 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, if (ret != 0) { XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ret; } } @@ -1357,10 +1805,17 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, if (ret != 0) { XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ret; } } else { CYASSL_MSG("Unsupported content encryption OID type"); + XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ALGO_ID_E; } @@ -1373,7 +1828,10 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, XMEMSET(encryptedKey, 0, MAX_ENCRYPTED_KEY_SZ); XMEMSET(encryptedContent, 0, encryptedContentSz); XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); - +#ifdef CYASSL_SMALL_STACK + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return encryptedContentSz - padLen; } diff --git a/ctaocrypt/src/random.c b/ctaocrypt/src/random.c index 22643e3ad..7442fe123 100644 --- a/ctaocrypt/src/random.c +++ b/ctaocrypt/src/random.c @@ -30,10 +30,16 @@ */ +#ifdef HAVE_FIPS + /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ + #define FIPS_NO_WRAPPERS +#endif + #include #include #if defined(HAVE_HASHDRBG) || defined(NO_RC4) + #include #ifdef NO_INLINE @@ -74,9 +80,16 @@ #define NONCE_SZ (ENTROPY_SZ/2) #define ENTROPY_NONCE_SZ (ENTROPY_SZ+NONCE_SZ) -#define DRBG_SUCCESS 0 -#define DRBG_ERROR 1 -#define DRBG_NEED_RESEED 2 +/* Internal return codes */ +#define DRBG_SUCCESS 0 +#define DRBG_ERROR 1 +#define DRBG_FAILURE 2 +#define DRBG_NEED_RESEED 3 + +/* RNG health states */ +#define DRBG_NOT_INIT 0 +#define DRBG_OK 1 +#define DRBG_FAILED 2 enum { @@ -88,10 +101,11 @@ enum { }; +/* Hash Derivation Function */ +/* Returns: DRBG_SUCCESS or DRBG_FAILURE */ static int Hash_df(RNG* rng, byte* out, word32 outSz, byte type, - byte* inA, word32 inASz, - byte* inB, word32 inBSz, - byte* inC, word32 inCSz) + const byte* inA, word32 inASz, + const byte* inB, word32 inBSz) { byte ctr; int i; @@ -107,33 +121,29 @@ static int Hash_df(RNG* rng, byte* out, word32 outSz, byte type, for (i = 0, ctr = 1; i < len; i++, ctr++) { if (InitSha256(&rng->sha) != 0) - return DRBG_ERROR; + return DRBG_FAILURE; if (Sha256Update(&rng->sha, &ctr, sizeof(ctr)) != 0) - return DRBG_ERROR; + return DRBG_FAILURE; if (Sha256Update(&rng->sha, (byte*)&bits, sizeof(bits)) != 0) - return DRBG_ERROR; + return DRBG_FAILURE; /* churning V is the only string that doesn't have * the type added */ if (type != drbgInitV) if (Sha256Update(&rng->sha, &type, sizeof(type)) != 0) - return DRBG_ERROR; + return DRBG_FAILURE; if (Sha256Update(&rng->sha, inA, inASz) != 0) - return DRBG_ERROR; + return DRBG_FAILURE; if (inB != NULL && inBSz > 0) if (Sha256Update(&rng->sha, inB, inBSz) != 0) - return DRBG_ERROR; - - if (inC != NULL && inCSz > 0) - if (Sha256Update(&rng->sha, inC, inCSz) != 0) - return DRBG_ERROR; + return DRBG_FAILURE; if (Sha256Final(&rng->sha, rng->digest) != 0) - return DRBG_ERROR; + return DRBG_FAILURE; if (outSz > OUTPUT_BLOCK_LEN) { XMEMCPY(out, rng->digest, OUTPUT_BLOCK_LEN); @@ -149,26 +159,26 @@ static int Hash_df(RNG* rng, byte* out, word32 outSz, byte type, } -static int Hash_DRBG_Reseed(RNG* rng, byte* entropy, word32 entropySz) +/* Returns: DRBG_SUCCESS or DRBG_FAILURE */ +static int Hash_DRBG_Reseed(RNG* rng, const byte* entropy, word32 entropySz) { - int ret; byte seed[DRBG_SEED_LEN]; - ret = Hash_df(rng, seed, sizeof(seed), drbgReseed, rng->V, sizeof(rng->V), - entropy, entropySz, NULL, 0); - if (ret != 0) - return ret; + if (Hash_df(rng, seed, sizeof(seed), drbgReseed, rng->V, sizeof(rng->V), + entropy, entropySz) != DRBG_SUCCESS) { + return DRBG_FAILURE; + } XMEMCPY(rng->V, seed, sizeof(rng->V)); XMEMSET(seed, 0, sizeof(seed)); - ret = Hash_df(rng, rng->C, sizeof(rng->C), drbgInitC, rng->V, - sizeof(rng->V), NULL, 0, NULL, 0); - if (ret != 0) - return ret; + if (Hash_df(rng, rng->C, sizeof(rng->C), drbgInitC, rng->V, + sizeof(rng->V), NULL, 0) != DRBG_SUCCESS) { + return DRBG_FAILURE; + } rng->reseedCtr = 1; - return 0; + return DRBG_SUCCESS; } static INLINE void array_add_one(byte* data, word32 dataSz) @@ -182,26 +192,23 @@ static INLINE void array_add_one(byte* data, word32 dataSz) } } -static int Hash_gen(RNG* rng, byte* out, word32 outSz, byte* V) + +/* Returns: DRBG_SUCCESS or DRBG_FAILURE */ +static int Hash_gen(RNG* rng, byte* out, word32 outSz, const byte* V) { byte data[DRBG_SEED_LEN]; - int i, ret; + int i; int len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0); XMEMCPY(data, V, sizeof(data)); for (i = 0; i < len; i++) { - ret = InitSha256(&rng->sha); - if (ret != 0) - return ret; + if (InitSha256(&rng->sha) != 0 || + Sha256Update(&rng->sha, data, sizeof(data)) != 0 || + Sha256Final(&rng->sha, rng->digest) != 0) { - ret = Sha256Update(&rng->sha, data, sizeof(data)); - if (ret != 0) - return ret; - - ret = Sha256Final(&rng->sha, rng->digest); - if (ret != 0) - return ret; + return DRBG_FAILURE; + } if (outSz > OUTPUT_BLOCK_LEN) { XMEMCPY(out, rng->digest, OUTPUT_BLOCK_LEN); @@ -215,11 +222,11 @@ static int Hash_gen(RNG* rng, byte* out, word32 outSz, byte* V) } XMEMSET(data, 0, sizeof(data)); - return 0; + return DRBG_SUCCESS; } -static INLINE void array_add(byte* d, word32 dLen, byte* s, word32 sLen) +static INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen) { word16 carry = 0; @@ -238,74 +245,67 @@ static INLINE void array_add(byte* d, word32 dLen, byte* s, word32 sLen) } +/* Returns: DRBG_SUCCESS, DRBG_NEED_RESEED, or DRBG_FAILURE */ static int Hash_DRBG_Generate(RNG* rng, byte* out, word32 outSz) { - int ret; + int ret = DRBG_NEED_RESEED; if (rng->reseedCtr != RESEED_INTERVAL) { byte type = drbgGenerateH; word32 reseedCtr = rng->reseedCtr; rng->reseedCtr++; - if (Hash_gen(rng, out, outSz, rng->V) != 0) - return DRBG_ERROR; - if (InitSha256(&rng->sha) != 0) - return DRBG_ERROR; - if (Sha256Update(&rng->sha, &type, sizeof(type)) != 0) - return DRBG_ERROR; - if (Sha256Update(&rng->sha, rng->V, sizeof(rng->V)) != 0) - return DRBG_ERROR; - if (Sha256Final(&rng->sha, rng->digest) != 0) - return DRBG_ERROR; + if (Hash_gen(rng, out, outSz, rng->V) != 0 || + InitSha256(&rng->sha) != 0 || + Sha256Update(&rng->sha, &type, sizeof(type)) != 0 || + Sha256Update(&rng->sha, rng->V, sizeof(rng->V)) != 0 || + Sha256Final(&rng->sha, rng->digest) != 0) { - array_add(rng->V, sizeof(rng->V), rng->digest, sizeof(rng->digest)); - array_add(rng->V, sizeof(rng->V), rng->C, sizeof(rng->C)); - #ifdef LITTLE_ENDIAN_ORDER - reseedCtr = ByteReverseWord32(reseedCtr); - #endif - array_add(rng->V, sizeof(rng->V), (byte*)&reseedCtr, sizeof(reseedCtr)); - ret = DRBG_SUCCESS; - } - else { - ret = DRBG_NEED_RESEED; + ret = DRBG_FAILURE; + } + else { + array_add(rng->V, sizeof(rng->V), rng->digest, sizeof(rng->digest)); + array_add(rng->V, sizeof(rng->V), rng->C, sizeof(rng->C)); + #ifdef LITTLE_ENDIAN_ORDER + reseedCtr = ByteReverseWord32(reseedCtr); + #endif + array_add(rng->V, sizeof(rng->V), + (byte*)&reseedCtr, sizeof(reseedCtr)); + ret = DRBG_SUCCESS; + } } + return ret; } -static int Hash_DRBG_Instantiate(RNG* rng, byte* seed, word32 seedSz, - byte* nonce, word32 nonceSz, byte* personal, word32 personalSz) +/* Returns: DRBG_SUCCESS or DRBG_FAILURE */ +static int Hash_DRBG_Instantiate(RNG* rng, const byte* seed, word32 seedSz, + const byte* nonce, word32 nonceSz) { - int ret; + int ret = DRBG_FAILURE; XMEMSET(rng, 0, sizeof(*rng)); - ret = Hash_df(rng, rng->V, sizeof(rng->V), drbgInitV, seed, seedSz, - nonce, nonceSz, personal, personalSz); - if (ret != 0) - return ret; + if (Hash_df(rng, rng->V, sizeof(rng->V), drbgInitV, seed, seedSz, + nonce, nonceSz) == DRBG_SUCCESS && + Hash_df(rng, rng->C, sizeof(rng->C), drbgInitC, rng->V, + sizeof(rng->V), NULL, 0) == DRBG_SUCCESS) { - ret = Hash_df(rng, rng->C, sizeof(rng->C), drbgInitC, rng->V, - sizeof(rng->V), NULL, 0, NULL, 0); - if (ret != 0) - return ret; + rng->reseedCtr = 1; + ret = DRBG_SUCCESS; + } - rng->reseedCtr = 1; - - return 0; + return ret; } +/* Returns: DRBG_SUCCESS */ static int Hash_DRBG_Uninstantiate(RNG* rng) { - int result = DRBG_ERROR; + XMEMSET(rng, 0, sizeof(*rng)); - if (rng != NULL) { - XMEMSET(rng, 0, sizeof(*rng)); - result = DRBG_SUCCESS; - } - - return result; + return DRBG_SUCCESS; } /* End NIST DRBG Code */ @@ -314,17 +314,27 @@ static int Hash_DRBG_Uninstantiate(RNG* rng) /* Get seed and key cipher */ int InitRng(RNG* rng) { - byte entropy[ENTROPY_NONCE_SZ]; - int ret = DRBG_ERROR; + int ret = BAD_FUNC_ARG; - /* This doesn't use a separate nonce. The entropy input will be - * the default size plus the size of the nonce making the seed - * size. */ - if (GenerateSeed(&rng->seed, entropy, ENTROPY_NONCE_SZ) == 0) - ret = Hash_DRBG_Instantiate(rng, entropy, ENTROPY_NONCE_SZ, - NULL, 0, NULL, 0); + if (rng != NULL) { + byte entropy[ENTROPY_NONCE_SZ]; - XMEMSET(entropy, 0, ENTROPY_NONCE_SZ); + /* This doesn't use a separate nonce. The entropy input will be + * the default size plus the size of the nonce making the seed + * size. */ + if (GenerateSeed(&rng->seed, entropy, ENTROPY_NONCE_SZ) == 0 && + Hash_DRBG_Instantiate(rng, entropy, ENTROPY_NONCE_SZ, + NULL, 0) == DRBG_SUCCESS) { + rng->status = DRBG_OK; + ret = 0; + } + else { + rng->status = DRBG_FAILED; + ret = RNG_FAILURE_E; + } + + XMEMSET(entropy, 0, ENTROPY_NONCE_SZ); + } return ret; } @@ -335,24 +345,36 @@ int RNG_GenerateBlock(RNG* rng, byte* output, word32 sz) { int ret; - XMEMSET(output, 0, sz); - ret = Hash_DRBG_Generate(rng, output, sz); + if (rng == NULL || output == NULL || sz > MAX_REQUEST_LEN) + return BAD_FUNC_ARG; - if (ret == DRBG_NEED_RESEED) { + if (rng->status != DRBG_OK) + return RNG_FAILURE_E; + + ret = Hash_DRBG_Generate(rng, output, sz); + if (ret == DRBG_SUCCESS) { + ret = 0; + } + else if (ret == DRBG_NEED_RESEED) { byte entropy[ENTROPY_SZ]; - ret = GenerateSeed(&rng->seed, entropy, ENTROPY_SZ); - if (ret == 0) { - ret = Hash_DRBG_Reseed(rng, entropy, ENTROPY_SZ); + if (GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0 && + Hash_DRBG_Reseed(rng, entropy, ENTROPY_SZ) == DRBG_SUCCESS && + Hash_DRBG_Generate(rng, output, sz) == DRBG_SUCCESS) { - if (ret == 0) - ret = Hash_DRBG_Generate(rng, output, sz); + ret = 0; + } + else { + ret = RNG_FAILURE_E; + rng->status = DRBG_FAILED; } - else - ret = DRBG_ERROR; XMEMSET(entropy, 0, ENTROPY_SZ); } + else { + ret = RNG_FAILURE_E; + rng->status = DRBG_FAILED; + } return ret; } @@ -364,11 +386,59 @@ int RNG_GenerateByte(RNG* rng, byte* b) } -void FreeRng(RNG* rng) +int FreeRng(RNG* rng) { - Hash_DRBG_Uninstantiate(rng); + int ret = BAD_FUNC_ARG; + + if (rng != NULL) { + if (Hash_DRBG_Uninstantiate(rng) == DRBG_SUCCESS) + ret = 0; + else + ret = RNG_FAILURE_E; + } + + return ret; } + +int RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz, + const byte* entropyB, word32 entropyBSz, + const byte* output, word32 outputSz) +{ + RNG rng; + byte check[SHA256_DIGEST_SIZE * 4]; + + if (Hash_DRBG_Instantiate(&rng, entropyA, entropyASz, NULL, 0) != 0) + return -1; + + if (reseed) { + if (Hash_DRBG_Reseed(&rng, entropyB, entropyBSz) != 0) { + Hash_DRBG_Uninstantiate(&rng); + return -1; + } + } + + if (Hash_DRBG_Generate(&rng, check, sizeof(check)) != 0) { + Hash_DRBG_Uninstantiate(&rng); + return -1; + } + + if (Hash_DRBG_Generate(&rng, check, sizeof(check)) != 0) { + Hash_DRBG_Uninstantiate(&rng); + return -1; + } + + if (outputSz != sizeof(check) || XMEMCMP(output, check, sizeof(check))) { + Hash_DRBG_Uninstantiate(&rng); + return -1; + } + + Hash_DRBG_Uninstantiate(&rng); + + return 0; +} + + #else /* HAVE_HASHDRBG || NO_RC4 */ /* Get seed and key cipher */ diff --git a/ctaocrypt/src/sha.c b/ctaocrypt/src/sha.c index 9797b5317..7501312d5 100644 --- a/ctaocrypt/src/sha.c +++ b/ctaocrypt/src/sha.c @@ -40,6 +40,9 @@ #endif #include +#include +#include + #ifdef NO_INLINE #include #else @@ -392,4 +395,35 @@ int ShaFinal(Sha* sha, byte* hash) #endif /* STM32F2_HASH */ + +int ShaHash(const byte* data, word32 len, byte* hash) +{ + int ret = 0; +#ifdef CYASSL_SMALL_STACK + Sha* sha; +#else + Sha sha[1]; +#endif + +#ifdef CYASSL_SMALL_STACK + sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (sha == NULL) + return MEMORY_E; +#endif + + if ((ret = InitSha(sha)) != 0) { + CYASSL_MSG("InitSha failed"); + } + else { + ShaUpdate(sha, data, len); + ShaFinal(sha, hash); + } + +#ifdef CYASSL_SMALL_STACK + XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; +} + #endif /* NO_SHA */ diff --git a/ctaocrypt/src/sha256.c b/ctaocrypt/src/sha256.c index 2a0d1f979..a90fb19b5 100644 --- a/ctaocrypt/src/sha256.c +++ b/ctaocrypt/src/sha256.c @@ -42,7 +42,9 @@ #endif #include +#include #include + #ifdef NO_INLINE #include #else @@ -283,5 +285,38 @@ int Sha256Final(Sha256* sha256, byte* hash) } +int Sha256Hash(const byte* data, word32 len, byte* hash) +{ + int ret = 0; +#ifdef CYASSL_SMALL_STACK + Sha256* sha256; +#else + Sha256 sha256[1]; +#endif + +#ifdef CYASSL_SMALL_STACK + sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (sha256 == NULL) + return MEMORY_E; +#endif + + if ((ret = InitSha256(sha256)) != 0) { + CYASSL_MSG("InitSha256 failed"); + } + else if ((ret = Sha256Update(sha256, data, len)) != 0) { + CYASSL_MSG("Sha256Update failed"); + } + else if ((ret = Sha256Final(sha256, hash)) != 0) { + CYASSL_MSG("Sha256Final failed"); + } + +#ifdef CYASSL_SMALL_STACK + XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; +} + + #endif /* NO_SHA256 */ diff --git a/ctaocrypt/src/sha512.c b/ctaocrypt/src/sha512.c index ceb5a7e72..40086949b 100644 --- a/ctaocrypt/src/sha512.c +++ b/ctaocrypt/src/sha512.c @@ -33,7 +33,9 @@ #endif #include +#include #include + #ifdef NO_INLINE #include #else @@ -296,6 +298,38 @@ int Sha512Final(Sha512* sha512, byte* hash) } +int Sha512Hash(const byte* data, word32 len, byte* hash) +{ + int ret = 0; +#ifdef CYASSL_SMALL_STACK + Sha512* sha512; +#else + Sha512 sha512[1]; +#endif + +#ifdef CYASSL_SMALL_STACK + sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (sha512 == NULL) + return MEMORY_E; +#endif + + if ((ret = InitSha512(sha512)) != 0) { + CYASSL_MSG("InitSha512 failed"); + } + else if ((ret = Sha512Update(sha512, data, len)) != 0) { + CYASSL_MSG("Sha512Update failed"); + } + else if ((ret = Sha512Final(sha512, hash)) != 0) { + CYASSL_MSG("Sha512Final failed"); + } + +#ifdef CYASSL_SMALL_STACK + XFREE(sha512, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; +} + #ifdef CYASSL_SHA384 @@ -470,6 +504,39 @@ int Sha384Final(Sha384* sha384, byte* hash) return InitSha384(sha384); /* reset state */ } + +int Sha384Hash(const byte* data, word32 len, byte* hash) +{ + int ret = 0; +#ifdef CYASSL_SMALL_STACK + Sha384* sha384; +#else + Sha384 sha384[1]; +#endif + +#ifdef CYASSL_SMALL_STACK + sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (sha384 == NULL) + return MEMORY_E; +#endif + + if ((ret = InitSha384(sha384)) != 0) { + CYASSL_MSG("InitSha384 failed"); + } + else if ((ret = Sha384Update(sha384, data, len)) != 0) { + CYASSL_MSG("Sha384Update failed"); + } + else if ((ret = Sha384Final(sha384, hash)) != 0) { + CYASSL_MSG("Sha384Final failed"); + } + +#ifdef CYASSL_SMALL_STACK + XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; +} + #endif /* CYASSL_SHA384 */ #endif /* CYASSL_SHA512 */ diff --git a/ctaocrypt/test/test.c b/ctaocrypt/test/test.c index 0a3b2e11a..73011d6da 100644 --- a/ctaocrypt/test/test.c +++ b/ctaocrypt/test/test.c @@ -103,7 +103,7 @@ #endif #ifdef HAVE_NTRU - #include "crypto_ntru.h" + #include "ntru_crypto.h" #endif #ifdef HAVE_CAVIUM #include "cavium_sysdep.h" @@ -1167,9 +1167,11 @@ int hmac_md5_test(void) test_hmac[2] = c; for (i = 0; i < times; ++i) { -#ifdef HAVE_CAVIUM +#if defined(HAVE_FIPS) || defined(HAVE_CAVIUM) if (i == 1) - continue; /* driver can't handle keys <= bytes */ + continue; /* cavium can't handle short keys, fips not allowed */ +#endif +#ifdef HAVE_CAVIUM if (HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) return -20009; #endif @@ -1242,9 +1244,11 @@ int hmac_sha_test(void) test_hmac[2] = c; for (i = 0; i < times; ++i) { -#ifdef HAVE_CAVIUM +#if defined(HAVE_FIPS) || defined(HAVE_CAVIUM) if (i == 1) - continue; /* driver can't handle keys <= bytes */ + continue; /* cavium can't handle short keys, fips not allowed */ +#endif +#ifdef HAVE_CAVIUM if (HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) return -20010; #endif @@ -1321,9 +1325,11 @@ int hmac_sha256_test(void) test_hmac[2] = c; for (i = 0; i < times; ++i) { -#ifdef HAVE_CAVIUM +#if defined(HAVE_FIPS) || defined(HAVE_CAVIUM) if (i == 1) - continue; /* driver can't handle keys <= bytes */ + continue; /* cavium can't handle short keys, fips not allowed */ +#endif +#ifdef HAVE_CAVIUM if (HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) return -20011; #endif @@ -1400,9 +1406,11 @@ int hmac_blake2b_test(void) test_hmac[2] = c; for (i = 0; i < times; ++i) { -#ifdef HAVE_CAVIUM +#if defined(HAVE_FIPS) || defined(HAVE_CAVIUM) if (i == 1) - continue; /* driver can't handle keys <= bytes */ + continue; /* cavium can't handle short keys, fips not allowed */ +#endif +#ifdef HAVE_CAVIUM if (HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) return -20011; #endif @@ -1483,6 +1491,10 @@ int hmac_sha384_test(void) 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; @@ -1559,6 +1571,10 @@ int hmac_sha512_test(void) 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; @@ -2790,6 +2806,74 @@ int camellia_test(void) #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; + + 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 */ + int random_test(void) { RNG rng; @@ -2809,6 +2893,8 @@ int random_test(void) return 0; } +#endif /* HAVE_HASHDRBG || NO_RC4 */ + #ifdef HAVE_NTRU @@ -2997,8 +3083,8 @@ int rsa_test(void) int pemSz = 0; RsaKey derIn; RsaKey genKey; - FILE* keyFile; - FILE* pemFile; + FILE* keyFile; + FILE* pemFile; ret = InitRsaKey(&genKey, 0); if (ret != 0) @@ -3192,7 +3278,7 @@ int rsa_test(void) int pemSz; size_t bytes3; word32 idx3 = 0; - FILE* file3 ; + FILE* file3 ; #ifdef CYASSL_TEST_CERT DecodedCert decode; #endif @@ -3493,38 +3579,46 @@ int rsa_test(void) 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); + 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); + 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); - - if (rc != NTRU_OK) { - free(derCert); - free(pem); - return -452; - } - caFile = fopen(caKeyFile, "rb"); if (!caFile) { free(derCert); free(pem); - return -453; + return -452; } bytes = fread(tmp, 1, FOURK_BUF, caFile); @@ -3534,7 +3628,7 @@ int rsa_test(void) if (ret != 0) { free(derCert); free(pem); - return -459; + return -453; } ret = RsaPrivateKeyDecode(tmp, &idx3, &caKey, (word32)bytes); if (ret != 0) { @@ -3911,7 +4005,7 @@ int openssl_test(void) 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) @@ -3928,7 +4022,7 @@ int openssl_test(void) 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) @@ -3945,7 +4039,7 @@ int openssl_test(void) 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) @@ -3989,7 +4083,7 @@ int openssl_test(void) 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) @@ -4264,6 +4358,8 @@ int hkdf_test(void) (void)res2; (void)res3; (void)res4; + (void)salt1; + (void)info1; #ifndef NO_SHA ret = HKDF(SHA, ikm1, 22, NULL, 0, NULL, 0, okm1, L); @@ -4273,12 +4369,15 @@ int hkdf_test(void) 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 @@ -4289,12 +4388,15 @@ int hkdf_test(void) 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; @@ -4473,6 +4575,9 @@ int ecc_encrypt_test(void) 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; diff --git a/cyassl/certs_test.h b/cyassl/certs_test.h index 5d10679a6..cd3341f4b 100644 --- a/cyassl/certs_test.h +++ b/cyassl/certs_test.h @@ -70,7 +70,7 @@ const unsigned char client_key_der_1024[] = 0xA2, 0xFE, 0xBF, 0x08, 0x6B, 0x1A, 0x5D, 0x3F, 0x90, 0x12, 0xB1, 0x05, 0x86, 0x31, 0x29, 0xDB, 0xD9, 0xE2 }; -const int sizeof_client_key_der_1024 = sizeof(client_key_der_1024) ; +const int sizeof_client_key_der_1024 = sizeof(client_key_der_1024); /* ./certs/1024/client-cert.der, 1024-bit */ const unsigned char client_cert_der_1024[] = @@ -152,7 +152,7 @@ const unsigned char client_cert_der_1024[] = 0x1B, 0x4E, 0x5D, 0xBC, 0x4E, 0x9A, 0x7C, 0x1F, 0xAB, 0x56, 0x47, 0x4A }; -const int sizeof_client_cert_der_1024 = sizeof(client_cert_der_1024) ; +const int sizeof_client_cert_der_1024 = sizeof(client_cert_der_1024); /* ./certs/1024/dh1024.der, 1024-bit */ const unsigned char dh_key_der_1024[] = @@ -172,7 +172,7 @@ const unsigned char dh_key_der_1024[] = 0x8C, 0x63, 0x0A, 0xAD, 0xC7, 0x10, 0xEA, 0xC7, 0xA1, 0xB9, 0x9D, 0xF2, 0xA8, 0x37, 0x73, 0x02, 0x01, 0x02 }; -const int sizeof_dh_key_der_1024 = sizeof(dh_key_der_1024) ; +const int sizeof_dh_key_der_1024 = sizeof(dh_key_der_1024); /* ./certs/1024/dsa1024.der, 1024-bit */ const unsigned char dsa_key_der_1024[] = @@ -223,7 +223,7 @@ const unsigned char dsa_key_der_1024[] = 0x3B, 0xA1, 0x19, 0x75, 0xDF, 0x9B, 0xF5, 0x72, 0x53, 0x4F, 0x39, 0xE1, 0x1C, 0xEC, 0x13, 0x84, 0x82, 0x18 }; -const int sizeof_dsa_key_der_1024 = sizeof(dsa_key_der_1024) ; +const int sizeof_dsa_key_der_1024 = sizeof(dsa_key_der_1024); /* ./certs/1024/rsa1024.der, 1024-bit */ const unsigned char rsa_key_der_1024[] = @@ -290,7 +290,7 @@ const unsigned char rsa_key_der_1024[] = 0xB9, 0x9E, 0xD5, 0x5B, 0x2E, 0x87, 0x1C, 0x58, 0xD0, 0x37, 0x89, 0x96, 0xEC, 0x48, 0x54, 0xF5, 0x9F, 0x0F, 0xB3 }; -const int sizeof_rsa_key_der_1024 = sizeof(rsa_key_der_1024) ; +const int sizeof_rsa_key_der_1024 = sizeof(rsa_key_der_1024); #elif defined(USE_CERT_BUFFERS_2048) @@ -418,7 +418,7 @@ const unsigned char client_key_der_2048[] = 0x45, 0x5D, 0x13, 0x39, 0x65, 0x42, 0x46, 0xA1, 0x9F, 0xCD, 0xF5, 0xBF }; -const int sizeof_client_key_der_2048 = sizeof(client_key_der_2048) ; +const int sizeof_client_key_der_2048 = sizeof(client_key_der_2048); /* ./certs/client-cert.der, 2048-bit */ const unsigned char client_cert_der_2048[] = @@ -543,11 +543,11 @@ const unsigned char client_cert_der_2048[] = 0xC9, 0xB1, 0x71, 0x7E, 0x1B, 0x2B, 0xE1, 0xE3, 0xAF, 0xC0 }; -const int sizeof_client_cert_der_2048 = sizeof(client_cert_der_2048) ; +const int sizeof_client_cert_der_2048 = sizeof(client_cert_der_2048); /* ./certs/dh2048.der, 2048-bit */ const unsigned char dh_key_der_2048[] = -{ +{ 0x30, 0x82, 0x01, 0x08, 0x02, 0x82, 0x01, 0x01, 0x00, 0xB0, 0xA1, 0x08, 0x06, 0x9C, 0x08, 0x13, 0xBA, 0x59, 0x06, 0x3C, 0xBC, 0x30, 0xD5, 0xF5, 0x00, 0xC1, 0x4F, 0x44, 0xA7, 0xD6, @@ -576,7 +576,7 @@ const unsigned char dh_key_der_2048[] = 0xC3, 0xA9, 0x41, 0x83, 0xFB, 0xC7, 0xFA, 0xC8, 0xE2, 0x1E, 0x7E, 0xAF, 0x00, 0x3F, 0x93, 0x02, 0x01, 0x02 }; -const int sizeof_dh_key_der_2048 = sizeof(dh_key_der_2048) ; +const int sizeof_dh_key_der_2048 = sizeof(dh_key_der_2048); /* ./certs/dsa2048.der, 2048-bit */ const unsigned char dsa_key_der_2048[] = @@ -666,7 +666,7 @@ const unsigned char dsa_key_der_2048[] = 0x3E, 0x75, 0x13, 0x13, 0x06, 0x8F, 0x94, 0xD3, 0xE6, 0xE9, 0x00, 0xCB, 0x62, 0x6D, 0x9A }; -const int sizeof_dsa_key_der_2048 = sizeof(dsa_key_der_2048) ; +const int sizeof_dsa_key_der_2048 = sizeof(dsa_key_der_2048); /* ./certs/rsa2048.der, 2048-bit */ const unsigned char rsa_key_der_2048[] = @@ -792,7 +792,356 @@ const unsigned char rsa_key_der_2048[] = 0x83, 0x0B, 0xD4, 0x74, 0x80, 0xB6, 0x7D, 0x62, 0x45, 0xBF, 0x56 }; -const int sizeof_rsa_key_der_2048 = sizeof(rsa_key_der_2048) ; +const int sizeof_rsa_key_der_2048 = sizeof(rsa_key_der_2048); + +/* ./certs/ca-cert.der, 2048-bit */ +const unsigned char ca_cert_der_2048[] = +{ + 0x30, 0x82, 0x04, 0x9E, 0x30, 0x82, 0x03, 0x86, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xE9, 0xD0, 0xA7, 0x5F, + 0x79, 0x25, 0xF4, 0x3C, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, + 0x81, 0x90, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x4D, 0x6F, 0x6E, 0x74, + 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x13, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, + 0x6E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x08, 0x53, 0x61, 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x0A, 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, + 0x67, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0D, 0x77, 0x77, 0x77, 0x2E, 0x79, 0x61, 0x73, 0x73, + 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, + 0x16, 0x0E, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x79, 0x61, 0x73, + 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x1E, 0x17, 0x0D, + 0x31, 0x31, 0x31, 0x30, 0x32, 0x34, 0x31, 0x38, 0x31, 0x38, + 0x31, 0x35, 0x5A, 0x17, 0x0D, 0x31, 0x34, 0x30, 0x37, 0x32, + 0x30, 0x31, 0x38, 0x31, 0x38, 0x31, 0x35, 0x5A, 0x30, 0x81, + 0x90, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x13, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, + 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, + 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, + 0x08, 0x53, 0x61, 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0A, + 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, + 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x0D, 0x77, 0x77, 0x77, 0x2E, 0x79, 0x61, 0x73, 0x73, 0x6C, + 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, + 0x0E, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x79, 0x61, 0x73, 0x73, + 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x82, 0x01, 0x22, 0x30, + 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, + 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, + 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xBF, 0x0C, + 0xCA, 0x2D, 0x14, 0xB2, 0x1E, 0x84, 0x42, 0x5B, 0xCD, 0x38, + 0x1F, 0x4A, 0xF2, 0x4D, 0x75, 0x10, 0xF1, 0xB6, 0x35, 0x9F, + 0xDF, 0xCA, 0x7D, 0x03, 0x98, 0xD3, 0xAC, 0xDE, 0x03, 0x66, + 0xEE, 0x2A, 0xF1, 0xD8, 0xB0, 0x7D, 0x6E, 0x07, 0x54, 0x0B, + 0x10, 0x98, 0x21, 0x4D, 0x80, 0xCB, 0x12, 0x20, 0xE7, 0xCC, + 0x4F, 0xDE, 0x45, 0x7D, 0xC9, 0x72, 0x77, 0x32, 0xEA, 0xCA, + 0x90, 0xBB, 0x69, 0x52, 0x10, 0x03, 0x2F, 0xA8, 0xF3, 0x95, + 0xC5, 0xF1, 0x8B, 0x62, 0x56, 0x1B, 0xEF, 0x67, 0x6F, 0xA4, + 0x10, 0x41, 0x95, 0xAD, 0x0A, 0x9B, 0xE3, 0xA5, 0xC0, 0xB0, + 0xD2, 0x70, 0x76, 0x50, 0x30, 0x5B, 0xA8, 0xE8, 0x08, 0x2C, + 0x7C, 0xED, 0xA7, 0xA2, 0x7A, 0x8D, 0x38, 0x29, 0x1C, 0xAC, + 0xC7, 0xED, 0xF2, 0x7C, 0x95, 0xB0, 0x95, 0x82, 0x7D, 0x49, + 0x5C, 0x38, 0xCD, 0x77, 0x25, 0xEF, 0xBD, 0x80, 0x75, 0x53, + 0x94, 0x3C, 0x3D, 0xCA, 0x63, 0x5B, 0x9F, 0x15, 0xB5, 0xD3, + 0x1D, 0x13, 0x2F, 0x19, 0xD1, 0x3C, 0xDB, 0x76, 0x3A, 0xCC, + 0xB8, 0x7D, 0xC9, 0xE5, 0xC2, 0xD7, 0xDA, 0x40, 0x6F, 0xD8, + 0x21, 0xDC, 0x73, 0x1B, 0x42, 0x2D, 0x53, 0x9C, 0xFE, 0x1A, + 0xFC, 0x7D, 0xAB, 0x7A, 0x36, 0x3F, 0x98, 0xDE, 0x84, 0x7C, + 0x05, 0x67, 0xCE, 0x6A, 0x14, 0x38, 0x87, 0xA9, 0xF1, 0x8C, + 0xB5, 0x68, 0xCB, 0x68, 0x7F, 0x71, 0x20, 0x2B, 0xF5, 0xA0, + 0x63, 0xF5, 0x56, 0x2F, 0xA3, 0x26, 0xD2, 0xB7, 0x6F, 0xB1, + 0x5A, 0x17, 0xD7, 0x38, 0x99, 0x08, 0xFE, 0x93, 0x58, 0x6F, + 0xFE, 0xC3, 0x13, 0x49, 0x08, 0x16, 0x0B, 0xA7, 0x4D, 0x67, + 0x00, 0x52, 0x31, 0x67, 0x23, 0x4E, 0x98, 0xED, 0x51, 0x45, + 0x1D, 0xB9, 0x04, 0xD9, 0x0B, 0xEC, 0xD8, 0x28, 0xB3, 0x4B, + 0xBD, 0xED, 0x36, 0x79, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, + 0x81, 0xF8, 0x30, 0x81, 0xF5, 0x30, 0x1D, 0x06, 0x03, 0x55, + 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x27, 0x8E, 0x67, 0x11, + 0x74, 0xC3, 0x26, 0x1D, 0x3F, 0xED, 0x33, 0x63, 0xB3, 0xA4, + 0xD8, 0x1D, 0x30, 0xE5, 0xE8, 0xD5, 0x30, 0x81, 0xC5, 0x06, + 0x03, 0x55, 0x1D, 0x23, 0x04, 0x81, 0xBD, 0x30, 0x81, 0xBA, + 0x80, 0x14, 0x27, 0x8E, 0x67, 0x11, 0x74, 0xC3, 0x26, 0x1D, + 0x3F, 0xED, 0x33, 0x63, 0xB3, 0xA4, 0xD8, 0x1D, 0x30, 0xE5, + 0xE8, 0xD5, 0xA1, 0x81, 0x96, 0xA4, 0x81, 0x93, 0x30, 0x81, + 0x90, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x13, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, + 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, + 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, + 0x08, 0x53, 0x61, 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0A, + 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, + 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x0D, 0x77, 0x77, 0x77, 0x2E, 0x79, 0x61, 0x73, 0x73, 0x6C, + 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, + 0x0E, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x79, 0x61, 0x73, 0x73, + 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x82, 0x09, 0x00, 0xE9, 0xD0, + 0xA7, 0x5F, 0x79, 0x25, 0xF4, 0x3C, 0x30, 0x0C, 0x06, 0x03, + 0x55, 0x1D, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, + 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, + 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x5F, 0x86, 0x14, 0xF4, 0x51, 0x8B, 0xBC, 0xA5, 0x4E, 0x30, + 0xDA, 0x5E, 0xAC, 0x9A, 0xF8, 0x6C, 0xD9, 0x26, 0x4B, 0x93, + 0xF9, 0xE3, 0x1C, 0x89, 0x6F, 0x9E, 0xEE, 0xB3, 0x9D, 0x77, + 0x3E, 0x89, 0x20, 0x76, 0xA3, 0xE6, 0xE8, 0x86, 0x15, 0x21, + 0xDB, 0xE2, 0x33, 0xB2, 0x34, 0xD5, 0xD0, 0x9F, 0xF3, 0xC1, + 0xA4, 0x87, 0x92, 0x5C, 0xF9, 0xD1, 0xFF, 0x30, 0x2F, 0x8E, + 0x03, 0xBC, 0xB3, 0x3C, 0x0C, 0x32, 0xA3, 0x90, 0x5F, 0x1A, + 0x90, 0x1E, 0xAF, 0x9D, 0xF3, 0x9E, 0xD7, 0x07, 0x02, 0xA9, + 0x7D, 0x27, 0x66, 0x63, 0x2F, 0xAF, 0x18, 0xD7, 0xAC, 0x18, + 0x98, 0x8C, 0x83, 0x8F, 0x38, 0xF3, 0x0B, 0xAC, 0x36, 0x10, + 0x75, 0xFB, 0xCA, 0x76, 0x13, 0x50, 0x5B, 0x02, 0x8F, 0x73, + 0xBF, 0xE3, 0xA0, 0xEE, 0x83, 0x52, 0x25, 0x54, 0xCE, 0x26, + 0xCE, 0x9C, 0xBD, 0x2F, 0x79, 0xAB, 0x1B, 0x60, 0xB8, 0x92, + 0xF1, 0x03, 0xC0, 0xFC, 0x3B, 0x08, 0xD9, 0xC0, 0xAD, 0xD5, + 0x72, 0x08, 0x25, 0x80, 0x61, 0x2D, 0xDC, 0x9F, 0xA7, 0x83, + 0x62, 0x07, 0x47, 0xE0, 0x07, 0x4C, 0x4B, 0x07, 0x30, 0x04, + 0xA9, 0x87, 0x1C, 0x55, 0x7F, 0x07, 0x12, 0xD0, 0xCB, 0x42, + 0x5D, 0xCB, 0xCF, 0x66, 0x01, 0x1A, 0x17, 0xEE, 0xF9, 0x0F, + 0x60, 0xB7, 0xDB, 0x6F, 0x68, 0xE5, 0x4E, 0x41, 0x62, 0x6E, + 0xD3, 0x6F, 0x60, 0x4F, 0x4B, 0x27, 0xDE, 0xCF, 0x18, 0x07, + 0xF1, 0x13, 0x5D, 0xCB, 0x3F, 0xA9, 0x25, 0x44, 0xDA, 0x52, + 0x5C, 0xC8, 0x04, 0xE1, 0x56, 0x12, 0xF5, 0x2A, 0x90, 0x4E, + 0xD1, 0xE2, 0xAF, 0x01, 0xB5, 0x23, 0xA1, 0xEC, 0x31, 0xDA, + 0x7B, 0x63, 0x69, 0xC4, 0xB8, 0xF3, 0xE7, 0xCE, 0xA1, 0x3D, + 0xC0, 0xDB, 0x6D, 0xF3, 0xB2, 0xD9, 0x46, 0xC8, 0x9F, 0xC3, + 0xB8, 0x70, 0x5A, 0x1F, 0x7F, 0xCA +}; +const int sizeof_ca_cert_der_2048 = sizeof(ca_cert_der_2048); + +/* ./certs/server-key.der, 2048-bit */ +const unsigned char server_key_der_2048[] = +{ + 0x30, 0x82, 0x04, 0xA5, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xC0, 0x95, 0x08, 0xE1, 0x57, 0x41, 0xF2, 0x71, + 0x6D, 0xB7, 0xD2, 0x45, 0x41, 0x27, 0x01, 0x65, 0xC6, 0x45, + 0xAE, 0xF2, 0xBC, 0x24, 0x30, 0xB8, 0x95, 0xCE, 0x2F, 0x4E, + 0xD6, 0xF6, 0x1C, 0x88, 0xBC, 0x7C, 0x9F, 0xFB, 0xA8, 0x67, + 0x7F, 0xFE, 0x5C, 0x9C, 0x51, 0x75, 0xF7, 0x8A, 0xCA, 0x07, + 0xE7, 0x35, 0x2F, 0x8F, 0xE1, 0xBD, 0x7B, 0xC0, 0x2F, 0x7C, + 0xAB, 0x64, 0xA8, 0x17, 0xFC, 0xCA, 0x5D, 0x7B, 0xBA, 0xE0, + 0x21, 0xE5, 0x72, 0x2E, 0x6F, 0x2E, 0x86, 0xD8, 0x95, 0x73, + 0xDA, 0xAC, 0x1B, 0x53, 0xB9, 0x5F, 0x3F, 0xD7, 0x19, 0x0D, + 0x25, 0x4F, 0xE1, 0x63, 0x63, 0x51, 0x8B, 0x0B, 0x64, 0x3F, + 0xAD, 0x43, 0xB8, 0xA5, 0x1C, 0x5C, 0x34, 0xB3, 0xAE, 0x00, + 0xA0, 0x63, 0xC5, 0xF6, 0x7F, 0x0B, 0x59, 0x68, 0x78, 0x73, + 0xA6, 0x8C, 0x18, 0xA9, 0x02, 0x6D, 0xAF, 0xC3, 0x19, 0x01, + 0x2E, 0xB8, 0x10, 0xE3, 0xC6, 0xCC, 0x40, 0xB4, 0x69, 0xA3, + 0x46, 0x33, 0x69, 0x87, 0x6E, 0xC4, 0xBB, 0x17, 0xA6, 0xF3, + 0xE8, 0xDD, 0xAD, 0x73, 0xBC, 0x7B, 0x2F, 0x21, 0xB5, 0xFD, + 0x66, 0x51, 0x0C, 0xBD, 0x54, 0xB3, 0xE1, 0x6D, 0x5F, 0x1C, + 0xBC, 0x23, 0x73, 0xD1, 0x09, 0x03, 0x89, 0x14, 0xD2, 0x10, + 0xB9, 0x64, 0xC3, 0x2A, 0xD0, 0xA1, 0x96, 0x4A, 0xBC, 0xE1, + 0xD4, 0x1A, 0x5B, 0xC7, 0xA0, 0xC0, 0xC1, 0x63, 0x78, 0x0F, + 0x44, 0x37, 0x30, 0x32, 0x96, 0x80, 0x32, 0x23, 0x95, 0xA1, + 0x77, 0xBA, 0x13, 0xD2, 0x97, 0x73, 0xE2, 0x5D, 0x25, 0xC9, + 0x6A, 0x0D, 0xC3, 0x39, 0x60, 0xA4, 0xB4, 0xB0, 0x69, 0x42, + 0x42, 0x09, 0xE9, 0xD8, 0x08, 0xBC, 0x33, 0x20, 0xB3, 0x58, + 0x22, 0xA7, 0xAA, 0xEB, 0xC4, 0xE1, 0xE6, 0x61, 0x83, 0xC5, + 0xD2, 0x96, 0xDF, 0xD9, 0xD0, 0x4F, 0xAD, 0xD7, 0x02, 0x03, + 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x01, 0x00, 0x9A, 0xD0, + 0x34, 0x0F, 0x52, 0x62, 0x05, 0x50, 0x01, 0xEF, 0x9F, 0xED, + 0x64, 0x6E, 0xC2, 0xC4, 0xDA, 0x1A, 0xF2, 0x84, 0xD7, 0x92, + 0x10, 0x48, 0x92, 0xC4, 0xE9, 0x6A, 0xEB, 0x8B, 0x75, 0x6C, + 0xC6, 0x79, 0x38, 0xF2, 0xC9, 0x72, 0x4A, 0x86, 0x64, 0x54, + 0x95, 0x77, 0xCB, 0xC3, 0x9A, 0x9D, 0xB7, 0xD4, 0x1D, 0xA4, + 0x00, 0xC8, 0x9E, 0x4E, 0xE4, 0xDD, 0xC7, 0xBA, 0x67, 0x16, + 0xC1, 0x74, 0xBC, 0xA9, 0xD6, 0x94, 0x8F, 0x2B, 0x30, 0x1A, + 0xFB, 0xED, 0xDF, 0x21, 0x05, 0x23, 0xD9, 0x4A, 0x39, 0xBD, + 0x98, 0x6B, 0x65, 0x9A, 0xB8, 0xDC, 0xC4, 0x7D, 0xEE, 0xA6, + 0x43, 0x15, 0x2E, 0x3D, 0xBE, 0x1D, 0x22, 0x60, 0x2A, 0x73, + 0x30, 0xD5, 0x3E, 0xD8, 0xA2, 0xAC, 0x86, 0x43, 0x2E, 0xC4, + 0xF5, 0x64, 0x5E, 0x3F, 0x89, 0x75, 0x0F, 0x11, 0xD8, 0x51, + 0x25, 0x4E, 0x9F, 0xD8, 0xAA, 0xA3, 0xCE, 0x60, 0xB3, 0xE2, + 0x8A, 0xD9, 0x7E, 0x1B, 0xF0, 0x64, 0xCA, 0x9A, 0x5B, 0x05, + 0x0B, 0x5B, 0xAA, 0xCB, 0xE5, 0xE3, 0x3F, 0x6E, 0x32, 0x22, + 0x05, 0xF3, 0xD0, 0xFA, 0xEF, 0x74, 0x52, 0x81, 0xE2, 0x5F, + 0x74, 0xD3, 0xBD, 0xFF, 0x31, 0x83, 0x45, 0x75, 0xFA, 0x63, + 0x7A, 0x97, 0x2E, 0xD6, 0xB6, 0x19, 0xC6, 0x92, 0x26, 0xE4, + 0x28, 0x06, 0x50, 0x50, 0x0E, 0x78, 0x2E, 0xA9, 0x78, 0x0D, + 0x14, 0x97, 0xB4, 0x12, 0xD8, 0x31, 0x40, 0xAB, 0xA1, 0x01, + 0x41, 0xC2, 0x30, 0xF8, 0x07, 0x5F, 0x16, 0xE4, 0x61, 0x77, + 0xD2, 0x60, 0xF2, 0x9F, 0x8D, 0xE8, 0xF4, 0xBA, 0xEB, 0x63, + 0xDE, 0x2A, 0x97, 0x81, 0xEF, 0x4C, 0x6C, 0xE6, 0x55, 0x34, + 0x51, 0x2B, 0x28, 0x34, 0xF4, 0x53, 0x1C, 0xC4, 0x58, 0x0A, + 0x3F, 0xBB, 0xAF, 0xB5, 0xF7, 0x4A, 0x85, 0x43, 0x2D, 0x3C, + 0xF1, 0x58, 0x58, 0x81, 0x02, 0x81, 0x81, 0x00, 0xF2, 0x2C, + 0x54, 0x76, 0x39, 0x23, 0x63, 0xC9, 0x10, 0x32, 0xB7, 0x93, + 0xAD, 0xAF, 0xBE, 0x19, 0x75, 0x96, 0x81, 0x64, 0xE6, 0xB5, + 0xB8, 0x89, 0x42, 0x41, 0xD1, 0x6D, 0xD0, 0x1C, 0x1B, 0xF8, + 0x1B, 0xAC, 0x69, 0xCB, 0x36, 0x3C, 0x64, 0x7D, 0xDC, 0xF4, + 0x19, 0xB8, 0xC3, 0x60, 0xB1, 0x57, 0x48, 0x5F, 0x52, 0x4F, + 0x59, 0x3A, 0x55, 0x7F, 0x32, 0xC0, 0x19, 0x43, 0x50, 0x3F, + 0xAE, 0xCE, 0x6F, 0x17, 0xF3, 0x0E, 0x9F, 0x40, 0xCA, 0x4E, + 0xAD, 0x15, 0x3B, 0xC9, 0x79, 0xE9, 0xC0, 0x59, 0x38, 0x73, + 0x70, 0x9C, 0x0A, 0x7C, 0xC9, 0x3A, 0x48, 0x32, 0xA7, 0xD8, + 0x49, 0x75, 0x0A, 0x85, 0xC2, 0xC2, 0xFD, 0x15, 0x73, 0xDA, + 0x99, 0x09, 0x2A, 0x69, 0x9A, 0x9F, 0x0A, 0x71, 0xBF, 0xB0, + 0x04, 0xA6, 0x8C, 0x7A, 0x5A, 0x6F, 0x48, 0x5A, 0x54, 0x3B, + 0xC6, 0xB1, 0x53, 0x17, 0xDF, 0xE7, 0x02, 0x81, 0x81, 0x00, + 0xCB, 0x93, 0xDE, 0x77, 0x15, 0x5D, 0xB7, 0x5C, 0x5C, 0x7C, + 0xD8, 0x90, 0xA9, 0x98, 0x2D, 0xD6, 0x69, 0x0E, 0x63, 0xB3, + 0xA3, 0xDC, 0xA6, 0xCC, 0x8B, 0x6A, 0xA4, 0xA2, 0x12, 0x8C, + 0x8E, 0x7B, 0x48, 0x2C, 0xB2, 0x4B, 0x37, 0xDC, 0x06, 0x18, + 0x7D, 0xEA, 0xFE, 0x76, 0xA1, 0xD4, 0xA1, 0xE9, 0x3F, 0x0D, + 0xCD, 0x1B, 0x5F, 0xAF, 0x5F, 0x9E, 0x96, 0x5B, 0x5B, 0x0F, + 0xA1, 0x7C, 0xAF, 0xB3, 0x9B, 0x90, 0xDB, 0x57, 0x73, 0x3A, + 0xED, 0xB0, 0x23, 0x44, 0xAE, 0x41, 0x4F, 0x1F, 0x07, 0x42, + 0x13, 0x23, 0x4C, 0xCB, 0xFA, 0xF4, 0x14, 0xA4, 0xD5, 0xF7, + 0x9E, 0x36, 0x7C, 0x5B, 0x9F, 0xA8, 0x3C, 0xC1, 0x85, 0x5F, + 0x74, 0xD2, 0x39, 0x2D, 0xFF, 0xD0, 0x84, 0xDF, 0xFB, 0xB3, + 0x20, 0x7A, 0x2E, 0x9B, 0x17, 0xAE, 0xE6, 0xBA, 0x0B, 0xAE, + 0x5F, 0x53, 0xA4, 0x52, 0xED, 0x1B, 0xC4, 0x91, 0x02, 0x81, + 0x81, 0x00, 0xEC, 0x98, 0xDA, 0xBB, 0xD5, 0xFE, 0xF9, 0x52, + 0x4A, 0x7D, 0x02, 0x55, 0x49, 0x6F, 0x55, 0x6E, 0x52, 0x2F, + 0x84, 0xA3, 0x2B, 0xB3, 0x86, 0x62, 0xB3, 0x54, 0xD2, 0x63, + 0x52, 0xDA, 0xE3, 0x88, 0x76, 0xA0, 0xEF, 0x8B, 0x15, 0xA5, + 0xD3, 0x18, 0x14, 0x72, 0x77, 0x5E, 0xC7, 0xA3, 0x04, 0x1F, + 0x9E, 0x19, 0x62, 0xB5, 0x1B, 0x1B, 0x9E, 0xC3, 0xF2, 0xB5, + 0x32, 0xF9, 0x4C, 0xC1, 0xAA, 0xEB, 0x0C, 0x26, 0x7D, 0xD4, + 0x5F, 0x4A, 0x51, 0x5C, 0xA4, 0x45, 0x06, 0x70, 0x44, 0xA7, + 0x56, 0xC0, 0xD4, 0x22, 0x14, 0x76, 0x9E, 0xD8, 0x63, 0x50, + 0x89, 0x90, 0xD3, 0xE2, 0xBF, 0x81, 0x95, 0x92, 0x31, 0x41, + 0x87, 0x39, 0x1A, 0x43, 0x0B, 0x18, 0xA5, 0x53, 0x1F, 0x39, + 0x1A, 0x5F, 0x1F, 0x43, 0xBC, 0x87, 0x6A, 0xDF, 0x6E, 0xD3, + 0x22, 0x00, 0xFE, 0x22, 0x98, 0x70, 0x4E, 0x1A, 0x19, 0x29, + 0x02, 0x81, 0x81, 0x00, 0x8A, 0x41, 0x56, 0x28, 0x51, 0x9E, + 0x5F, 0xD4, 0x9E, 0x0B, 0x3B, 0x98, 0xA3, 0x54, 0xF2, 0x6C, + 0x56, 0xD4, 0xAA, 0xE9, 0x69, 0x33, 0x85, 0x24, 0x0C, 0xDA, + 0xD4, 0x0C, 0x2D, 0xC4, 0xBF, 0x4F, 0x02, 0x69, 0x38, 0x7C, + 0xD4, 0xE6, 0xDC, 0x4C, 0xED, 0xD7, 0x16, 0x11, 0xC3, 0x3E, + 0x00, 0xE7, 0xC3, 0x26, 0xC0, 0x51, 0x02, 0xDE, 0xBB, 0x75, + 0x9C, 0x6F, 0x56, 0x9C, 0x7A, 0xF3, 0x8E, 0xEF, 0xCF, 0x8A, + 0xC5, 0x2B, 0xD2, 0xDA, 0x06, 0x6A, 0x44, 0xC9, 0x73, 0xFE, + 0x6E, 0x99, 0x87, 0xF8, 0x5B, 0xBE, 0xF1, 0x7C, 0xE6, 0x65, + 0xB5, 0x4F, 0x6C, 0xF0, 0xC9, 0xC5, 0xFF, 0x16, 0xCA, 0x8B, + 0x1B, 0x17, 0xE2, 0x58, 0x3D, 0xA2, 0x37, 0xAB, 0x01, 0xBC, + 0xBF, 0x40, 0xCE, 0x53, 0x8C, 0x8E, 0xED, 0xEF, 0xEE, 0x59, + 0x9D, 0xE0, 0x63, 0xE6, 0x7C, 0x5E, 0xF5, 0x8E, 0x4B, 0xF1, + 0x3B, 0xC1, 0x02, 0x81, 0x80, 0x4D, 0x45, 0xF9, 0x40, 0x8C, + 0xC5, 0x5B, 0xF4, 0x2A, 0x1A, 0x8A, 0xB4, 0xF2, 0x1C, 0xAC, + 0x6B, 0xE9, 0x0C, 0x56, 0x36, 0xB7, 0x4E, 0x72, 0x96, 0xD5, + 0xE5, 0x8A, 0xD2, 0xE2, 0xFF, 0xF1, 0xF1, 0x18, 0x13, 0x3D, + 0x86, 0x09, 0xB8, 0xD8, 0x76, 0xA7, 0xC9, 0x1C, 0x71, 0x52, + 0x94, 0x30, 0x43, 0xE0, 0xF1, 0x78, 0x74, 0xFD, 0x61, 0x1B, + 0x4C, 0x09, 0xCC, 0xE6, 0x68, 0x2A, 0x71, 0xAD, 0x1C, 0xDF, + 0x43, 0xBC, 0x56, 0xDB, 0xA5, 0xA4, 0xBE, 0x35, 0x70, 0xA4, + 0x5E, 0xCF, 0x4F, 0xFC, 0x00, 0x55, 0x99, 0x3A, 0x3D, 0x23, + 0xCF, 0x67, 0x5A, 0xF5, 0x22, 0xF8, 0xB5, 0x29, 0xD0, 0x44, + 0x11, 0xEB, 0x35, 0x2E, 0x46, 0xBE, 0xFD, 0x8E, 0x18, 0xB2, + 0x5F, 0xA8, 0xBF, 0x19, 0x32, 0xA1, 0xF5, 0xDC, 0x03, 0xE6, + 0x7C, 0x9A, 0x1F, 0x0C, 0x7C, 0xA9, 0xB0, 0x0E, 0x21, 0x37, + 0x3B, 0xF1, 0xB0 +}; +const int sizeof_server_key_der_2048 = sizeof(server_key_der_2048); + +/* ./certs/server-cert.der, 2048-bit */ +const unsigned char server_cert_der_2048[] = +{ + 0x30, 0x82, 0x03, 0x90, 0x30, 0x82, 0x02, 0x78, 0x02, 0x01, + 0x02, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, + 0x0D, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0x90, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, + 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x11, + 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x08, 0x53, + 0x61, 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0A, 0x43, 0x6F, + 0x6E, 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x31, 0x16, + 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0D, 0x77, + 0x77, 0x77, 0x2E, 0x79, 0x61, 0x73, 0x73, 0x6C, 0x2E, 0x63, + 0x6F, 0x6D, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x0E, 0x69, + 0x6E, 0x66, 0x6F, 0x40, 0x79, 0x61, 0x73, 0x73, 0x6C, 0x2E, + 0x63, 0x6F, 0x6D, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x31, 0x31, + 0x30, 0x32, 0x34, 0x31, 0x38, 0x32, 0x37, 0x31, 0x33, 0x5A, + 0x17, 0x0D, 0x31, 0x34, 0x30, 0x37, 0x32, 0x30, 0x31, 0x38, + 0x32, 0x37, 0x31, 0x33, 0x5A, 0x30, 0x81, 0x8A, 0x31, 0x0B, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x13, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, + 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x0E, 0x30, + 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x05, 0x79, 0x61, + 0x53, 0x53, 0x4C, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x04, 0x0B, 0x13, 0x07, 0x53, 0x75, 0x70, 0x70, 0x6F, 0x72, + 0x74, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0D, 0x77, 0x77, 0x77, 0x2E, 0x79, 0x61, 0x73, 0x73, + 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, + 0x16, 0x0E, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x79, 0x61, 0x73, + 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x82, 0x01, 0x22, + 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, + 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, + 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xC0, + 0x95, 0x08, 0xE1, 0x57, 0x41, 0xF2, 0x71, 0x6D, 0xB7, 0xD2, + 0x45, 0x41, 0x27, 0x01, 0x65, 0xC6, 0x45, 0xAE, 0xF2, 0xBC, + 0x24, 0x30, 0xB8, 0x95, 0xCE, 0x2F, 0x4E, 0xD6, 0xF6, 0x1C, + 0x88, 0xBC, 0x7C, 0x9F, 0xFB, 0xA8, 0x67, 0x7F, 0xFE, 0x5C, + 0x9C, 0x51, 0x75, 0xF7, 0x8A, 0xCA, 0x07, 0xE7, 0x35, 0x2F, + 0x8F, 0xE1, 0xBD, 0x7B, 0xC0, 0x2F, 0x7C, 0xAB, 0x64, 0xA8, + 0x17, 0xFC, 0xCA, 0x5D, 0x7B, 0xBA, 0xE0, 0x21, 0xE5, 0x72, + 0x2E, 0x6F, 0x2E, 0x86, 0xD8, 0x95, 0x73, 0xDA, 0xAC, 0x1B, + 0x53, 0xB9, 0x5F, 0x3F, 0xD7, 0x19, 0x0D, 0x25, 0x4F, 0xE1, + 0x63, 0x63, 0x51, 0x8B, 0x0B, 0x64, 0x3F, 0xAD, 0x43, 0xB8, + 0xA5, 0x1C, 0x5C, 0x34, 0xB3, 0xAE, 0x00, 0xA0, 0x63, 0xC5, + 0xF6, 0x7F, 0x0B, 0x59, 0x68, 0x78, 0x73, 0xA6, 0x8C, 0x18, + 0xA9, 0x02, 0x6D, 0xAF, 0xC3, 0x19, 0x01, 0x2E, 0xB8, 0x10, + 0xE3, 0xC6, 0xCC, 0x40, 0xB4, 0x69, 0xA3, 0x46, 0x33, 0x69, + 0x87, 0x6E, 0xC4, 0xBB, 0x17, 0xA6, 0xF3, 0xE8, 0xDD, 0xAD, + 0x73, 0xBC, 0x7B, 0x2F, 0x21, 0xB5, 0xFD, 0x66, 0x51, 0x0C, + 0xBD, 0x54, 0xB3, 0xE1, 0x6D, 0x5F, 0x1C, 0xBC, 0x23, 0x73, + 0xD1, 0x09, 0x03, 0x89, 0x14, 0xD2, 0x10, 0xB9, 0x64, 0xC3, + 0x2A, 0xD0, 0xA1, 0x96, 0x4A, 0xBC, 0xE1, 0xD4, 0x1A, 0x5B, + 0xC7, 0xA0, 0xC0, 0xC1, 0x63, 0x78, 0x0F, 0x44, 0x37, 0x30, + 0x32, 0x96, 0x80, 0x32, 0x23, 0x95, 0xA1, 0x77, 0xBA, 0x13, + 0xD2, 0x97, 0x73, 0xE2, 0x5D, 0x25, 0xC9, 0x6A, 0x0D, 0xC3, + 0x39, 0x60, 0xA4, 0xB4, 0xB0, 0x69, 0x42, 0x42, 0x09, 0xE9, + 0xD8, 0x08, 0xBC, 0x33, 0x20, 0xB3, 0x58, 0x22, 0xA7, 0xAA, + 0xEB, 0xC4, 0xE1, 0xE6, 0x61, 0x83, 0xC5, 0xD2, 0x96, 0xDF, + 0xD9, 0xD0, 0x4F, 0xAD, 0xD7, 0x02, 0x03, 0x01, 0x00, 0x01, + 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, + 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x71, 0x4E, 0xD3, 0x62, 0xDF, 0xCC, 0x4C, 0xF7, 0xCD, 0xB7, + 0x6E, 0x52, 0x0B, 0x6C, 0x6E, 0xE0, 0xBD, 0xC2, 0x2D, 0x07, + 0xD7, 0xC0, 0xB0, 0x6E, 0x43, 0x1E, 0x35, 0xBC, 0x30, 0x01, + 0x50, 0xF0, 0xFF, 0x99, 0x23, 0x6C, 0x18, 0x1A, 0x41, 0xB6, + 0x11, 0xD6, 0xD4, 0x19, 0x61, 0xFD, 0xE4, 0x77, 0x97, 0x1C, + 0x39, 0xE1, 0x57, 0xAB, 0xC5, 0x15, 0x63, 0x77, 0x11, 0x36, + 0x5E, 0x74, 0xE2, 0x24, 0x0B, 0x1F, 0x41, 0x78, 0xAD, 0xB7, + 0x81, 0xE7, 0xB4, 0x40, 0x66, 0x80, 0xF0, 0x4B, 0x91, 0xA0, + 0x6D, 0xA8, 0x6E, 0x3D, 0x53, 0xD9, 0x8B, 0xCE, 0x2A, 0xE1, + 0x0B, 0x45, 0x65, 0x87, 0xA1, 0x96, 0xAE, 0xEE, 0x3E, 0x88, + 0xD5, 0x12, 0x1F, 0x78, 0x17, 0xAE, 0x2C, 0xC5, 0x73, 0x44, + 0xD8, 0xDC, 0xF4, 0xAF, 0xD8, 0xCC, 0xAE, 0x4C, 0xE1, 0x0C, + 0xBE, 0x55, 0xA4, 0x99, 0xF7, 0x6E, 0x96, 0xC0, 0xC8, 0x45, + 0x87, 0xBF, 0xDC, 0x51, 0x57, 0xFF, 0x9E, 0x73, 0x37, 0x6A, + 0x18, 0x9C, 0xC3, 0xF9, 0x22, 0x7A, 0xF4, 0xB0, 0x52, 0xBD, + 0xFC, 0x21, 0x30, 0xF8, 0xC5, 0xFF, 0x1E, 0x87, 0x7D, 0xAD, + 0xA2, 0x5A, 0x35, 0xF5, 0x22, 0xA8, 0xB4, 0x0A, 0x76, 0x38, + 0xE6, 0x76, 0xB0, 0x98, 0xAF, 0x1B, 0xEC, 0x8A, 0x0A, 0x43, + 0x74, 0xD2, 0x85, 0x34, 0x37, 0x84, 0x07, 0xE1, 0xF6, 0x23, + 0xB2, 0x29, 0xDE, 0xA6, 0xB6, 0xB7, 0x4C, 0x57, 0x7E, 0x96, + 0x06, 0xCB, 0xA9, 0x16, 0x25, 0x29, 0x3A, 0x03, 0x2D, 0x55, + 0x7D, 0xA6, 0x8C, 0xA4, 0xF7, 0x9E, 0x81, 0xC9, 0x95, 0xB6, + 0x7C, 0xC1, 0x4A, 0xCE, 0x94, 0x66, 0x0C, 0xCA, 0x88, 0xEB, + 0xD2, 0x09, 0xF5, 0x5B, 0x19, 0x58, 0x82, 0xDF, 0x27, 0xFD, + 0x67, 0x95, 0x78, 0xB7, 0x02, 0x06, 0xD5, 0xA7, 0x61, 0xBD, + 0xEF, 0x3A, 0xFC, 0xB2, 0x61, 0xCD +}; +const int sizeof_server_cert_der_2048 = sizeof(server_cert_der_2048); #endif /* USE_CERT_BUFFERS_1024 */ diff --git a/cyassl/ctaocrypt/aes.h b/cyassl/ctaocrypt/aes.h index c36dfd5f5..69d86abf3 100644 --- a/cyassl/ctaocrypt/aes.h +++ b/cyassl/ctaocrypt/aes.h @@ -41,6 +41,8 @@ #if defined (__GNUC__) #define ALIGN16 __attribute__ ( (aligned (16))) #elif defined(_MSC_VER) + /* disable align warning, we want alignment ! */ + #pragma warning(disable: 4324) #define ALIGN16 __declspec (align (16)) #else #define ALIGN16 diff --git a/cyassl/ctaocrypt/asn.h b/cyassl/ctaocrypt/asn.h index 239c07491..bc51e529c 100644 --- a/cyassl/ctaocrypt/asn.h +++ b/cyassl/ctaocrypt/asn.h @@ -189,7 +189,7 @@ enum Block_Sum { enum Key_Sum { DSAk = 515, RSAk = 645, - NTRUk = 364, + NTRUk = 274, ECDSAk = 518 }; @@ -340,7 +340,8 @@ struct DecodedCert { #endif /* HAVE_OCSP */ byte* signature; /* not owned, points into raw cert */ char* subjectCN; /* CommonName */ - int subjectCNLen; + int subjectCNLen; /* CommonName Length */ + char subjectCNEnc; /* CommonName Encoding */ int subjectCNStored; /* have we saved a copy we own */ char issuer[ASN_NAME_MAX]; /* full name including common name */ char subject[ASN_NAME_MAX]; /* full name including common name */ @@ -411,16 +412,22 @@ struct DecodedCert { /* easy access to subject info for other sign */ char* subjectSN; int subjectSNLen; + char subjectSNEnc; char* subjectC; int subjectCLen; + char subjectCEnc; char* subjectL; int subjectLLen; + char subjectLEnc; char* subjectST; int subjectSTLen; + char subjectSTEnc; char* subjectO; int subjectOLen; + char subjectOEnc; char* subjectOU; int subjectOULen; + char subjectOUEnc; char* subjectEmail; int subjectEmailLen; #endif /* CYASSL_CERT_GEN */ diff --git a/cyassl/ctaocrypt/asn_public.h b/cyassl/ctaocrypt/asn_public.h index 3ad601709..34c899dc0 100644 --- a/cyassl/ctaocrypt/asn_public.h +++ b/cyassl/ctaocrypt/asn_public.h @@ -62,6 +62,11 @@ enum Ctc_SigType { CTC_SHA512wECDSA = 526 }; +enum Ctc_Encoding { + CTC_UTF8 = 0x0c, /* utf8 */ + CTC_PRINTABLE = 0x13 /* printable */ +}; + #ifdef CYASSL_CERT_GEN @@ -70,20 +75,27 @@ enum Ctc_SigType { #endif enum Ctc_Misc { - CTC_NAME_SIZE = 64, - CTC_DATE_SIZE = 32, - CTC_MAX_ALT_SIZE = 8192, /* may be huge */ - CTC_SERIAL_SIZE = 8 + CTC_NAME_SIZE = 64, + CTC_DATE_SIZE = 32, + CTC_MAX_ALT_SIZE = 16384, /* may be huge */ + CTC_SERIAL_SIZE = 8 }; typedef struct CertName { char country[CTC_NAME_SIZE]; + char countryEnc; char state[CTC_NAME_SIZE]; + char stateEnc; char locality[CTC_NAME_SIZE]; + char localityEnc; char sur[CTC_NAME_SIZE]; + char surEnc; char org[CTC_NAME_SIZE]; + char orgEnc; char unit[CTC_NAME_SIZE]; + char unitEnc; char commonName[CTC_NAME_SIZE]; + char commonNameEnc; char email[CTC_NAME_SIZE]; /* !!!! email has to be last !!!! */ } CertName; diff --git a/cyassl/ctaocrypt/des3.h b/cyassl/ctaocrypt/des3.h index 13da7e28a..0c8f64006 100644 --- a/cyassl/ctaocrypt/des3.h +++ b/cyassl/ctaocrypt/des3.h @@ -82,9 +82,9 @@ typedef struct Des3 { CYASSL_API int Des_SetKey(Des* des, const byte* key, const byte* iv, int dir); CYASSL_API void Des_SetIV(Des* des, const byte* iv); -CYASSL_API void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz); -CYASSL_API void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz); -CYASSL_API void Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz); +CYASSL_API int Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz); +CYASSL_API int Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz); +CYASSL_API int Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz); CYASSL_API int Des3_SetKey(Des3* des, const byte* key, const byte* iv,int dir); CYASSL_API int Des3_SetIV(Des3* des, const byte* iv); diff --git a/cyassl/ctaocrypt/ecc.h b/cyassl/ctaocrypt/ecc.h index 0c44a4f0a..a885abf63 100644 --- a/cyassl/ctaocrypt/ecc.h +++ b/cyassl/ctaocrypt/ecc.h @@ -164,6 +164,8 @@ CYASSL_API const byte* ecc_ctx_get_own_salt(ecEncCtx*); CYASSL_API int ecc_ctx_set_peer_salt(ecEncCtx*, const byte* salt); +CYASSL_API +int ecc_ctx_set_info(ecEncCtx*, const byte* info, int sz); CYASSL_API int ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, diff --git a/cyassl/ctaocrypt/error-crypt.h b/cyassl/ctaocrypt/error-crypt.h index 113d2d73a..c75d37ceb 100644 --- a/cyassl/ctaocrypt/error-crypt.h +++ b/cyassl/ctaocrypt/error-crypt.h @@ -33,7 +33,7 @@ /* error codes */ enum { - MAX_CODE_E = -100, /* errors -101 - -199 */ + MAX_CODE_E = -100, /* errors -101 - -299 */ OPEN_RAN_E = -101, /* opening random device error */ READ_RAN_E = -102, /* reading random device error */ WINCRYPT_E = -103, /* windows crypt init error */ @@ -125,11 +125,16 @@ enum { FIPS_NOT_ALLOWED_E = -197, /* FIPS not allowed error */ ASN_NAME_INVALID_E = -198, /* ASN name constraint error */ - MIN_CODE_E = -200 /* errors -101 - -199 */ + RNG_FAILURE_E = -199, /* RNG Failed, Reinitialize */ + + HMAC_MIN_KEYLEN_E = -200, /* FIPS Mode HMAC Minimum Key Length error */ + + MIN_CODE_E = -300 /* errors -101 - -299 */ }; CYASSL_API void CTaoCryptErrorString(int err, char* buff); +CYASSL_API const char* CTaoCryptGetErrorString(int error); #ifdef __cplusplus diff --git a/cyassl/ctaocrypt/hmac.h b/cyassl/ctaocrypt/hmac.h index 68627efcd..78cc9556c 100644 --- a/cyassl/ctaocrypt/hmac.h +++ b/cyassl/ctaocrypt/hmac.h @@ -60,6 +60,8 @@ #define CYASSL_HMAC_CAVIUM_MAGIC 0xBEEF0005 enum { + HMAC_FIPS_MIN_KEY = 14, /* 112 bit key length minimum */ + IPAD = 0x36, OPAD = 0x5C, diff --git a/cyassl/ctaocrypt/include.am b/cyassl/ctaocrypt/include.am index 2f71f6ebd..f03b67334 100644 --- a/cyassl/ctaocrypt/include.am +++ b/cyassl/ctaocrypt/include.am @@ -24,7 +24,7 @@ nobase_include_HEADERS+= \ cyassl/ctaocrypt/md5.h \ cyassl/ctaocrypt/misc.h \ cyassl/ctaocrypt/pkcs7.h \ - cyassl/ctaocrypt/port.h \ + cyassl/ctaocrypt/wc_port.h \ cyassl/ctaocrypt/pwdbased.h \ cyassl/ctaocrypt/rabbit.h \ cyassl/ctaocrypt/chacha.h \ diff --git a/cyassl/ctaocrypt/integer.h b/cyassl/ctaocrypt/integer.h index 8f20f901b..77b5552c7 100644 --- a/cyassl/ctaocrypt/integer.h +++ b/cyassl/ctaocrypt/integer.h @@ -70,6 +70,10 @@ extern "C" { #define MP_64BIT #endif #endif +/* if intel compiler doesn't provide 128 bit type don't turn on 64bit */ +#if defined(MP_64BIT) && defined(__INTEL_COMPILER) && !defined(HAVE___UINT128_T) + #undef MP_64BIT +#endif /* some default configurations. * diff --git a/cyassl/ctaocrypt/md2.h b/cyassl/ctaocrypt/md2.h index 0b99c43ba..2d55cd9ea 100644 --- a/cyassl/ctaocrypt/md2.h +++ b/cyassl/ctaocrypt/md2.h @@ -54,6 +54,7 @@ typedef struct Md2 { CYASSL_API void InitMd2(Md2*); CYASSL_API void Md2Update(Md2*, const byte*, word32); CYASSL_API void Md2Final(Md2*, byte*); +CYASSL_API int Md2Hash(const byte*, word32, byte*); #ifdef __cplusplus diff --git a/cyassl/ctaocrypt/md5.h b/cyassl/ctaocrypt/md5.h index 418d7b14d..f62ede96c 100644 --- a/cyassl/ctaocrypt/md5.h +++ b/cyassl/ctaocrypt/md5.h @@ -63,6 +63,8 @@ typedef struct Md5 { CYASSL_API void InitMd5(Md5*); CYASSL_API void Md5Update(Md5*, const byte*, word32); CYASSL_API void Md5Final(Md5*, byte*); +CYASSL_API int Md5Hash(const byte*, word32, byte*); + #ifdef __cplusplus } /* extern "C" */ diff --git a/cyassl/ctaocrypt/random.h b/cyassl/ctaocrypt/random.h index 8111ac494..728c22209 100644 --- a/cyassl/ctaocrypt/random.h +++ b/cyassl/ctaocrypt/random.h @@ -84,6 +84,7 @@ typedef struct RNG { byte V[DRBG_SEED_LEN]; byte C[DRBG_SEED_LEN]; word32 reseedCtr; + byte status; } RNG; @@ -119,10 +120,33 @@ CYASSL_API int RNG_GenerateByte(RNG*, byte*); #if defined(HAVE_HASHDRBG) || defined(NO_RC4) - CYASSL_API void FreeRng(RNG*); + CYASSL_API int FreeRng(RNG*); + CYASSL_API int RNG_HealthTest(int reseed, + const byte* entropyA, word32 entropyASz, + const byte* entropyB, word32 entropyBSz, + const byte* output, word32 outputSz); #endif /* HAVE_HASHDRBG || NO_RC4 */ +#ifdef HAVE_FIPS + /* fips wrapper calls, user can call direct */ + CYASSL_API int InitRng_fips(RNG* rng); + CYASSL_API int FreeRng_fips(RNG* rng); + CYASSL_API int RNG_GenerateBlock_fips(RNG* rng, byte* buf, word32 bufSz); + CYASSL_API int RNG_HealthTest_fips(int reseed, + const byte* entropyA, word32 entropyASz, + const byte* entropyB, word32 entropyBSz, + const byte* output, word32 outputSz); + #ifndef FIPS_NO_WRAPPERS + /* if not impl or fips.c impl wrapper force fips calls if fips build */ + #define InitRng InitRng_fips + #define FreeRng FreeRng_fips + #define RNG_GenerateBlock RNG_GenerateBlock_fips + #define RNG_HealthTest RNG_HealthTest_fips + #endif /* FIPS_NO_WRAPPERS */ +#endif /* HAVE_FIPS */ + + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/cyassl/ctaocrypt/settings.h b/cyassl/ctaocrypt/settings.h index c8bd28f14..57bb8290e 100644 --- a/cyassl/ctaocrypt/settings.h +++ b/cyassl/ctaocrypt/settings.h @@ -647,6 +647,11 @@ #endif +/* FreeScale MMCAU hardware crypto has 4 byte alignment */ +#ifdef FREESCALE_MMCAU + #define CYASSL_MMCAU_ALIGNMENT 4 +#endif + /* if using hardware crypto and have alignment requirements, specify the requirement here. The record header of SSL/TLS will prvent easy alignment. This hint tries to help as much as possible. */ @@ -655,6 +660,8 @@ #define CYASSL_GENERAL_ALIGNMENT 16 #elif defined(XSTREAM_ALIGNMENT) #define CYASSL_GENERAL_ALIGNMENT 4 + #elif defined(FREESCALE_MMCAU) + #define CYASSL_GENERAL_ALIGNMENT CYASSL_MMCAU_ALIGNMENT #else #define CYASSL_GENERAL_ALIGNMENT 0 #endif @@ -666,6 +673,12 @@ #define NO_SKID #endif + +#ifdef __INTEL_COMPILER + #pragma warning(disable:2259) /* explicit casts to smaller sizes, disable */ +#endif + + /* Place any other flags or defines here */ diff --git a/cyassl/ctaocrypt/sha.h b/cyassl/ctaocrypt/sha.h index 749b728a5..f1820a6d9 100644 --- a/cyassl/ctaocrypt/sha.h +++ b/cyassl/ctaocrypt/sha.h @@ -65,6 +65,7 @@ typedef struct Sha { CYASSL_API int InitSha(Sha*); CYASSL_API int ShaUpdate(Sha*, const byte*, word32); CYASSL_API int ShaFinal(Sha*, byte*); +CYASSL_API int ShaHash(const byte*, word32, byte*); #ifdef HAVE_FIPS diff --git a/cyassl/ctaocrypt/sha256.h b/cyassl/ctaocrypt/sha256.h index 5b709c23e..c619461a3 100644 --- a/cyassl/ctaocrypt/sha256.h +++ b/cyassl/ctaocrypt/sha256.h @@ -61,9 +61,10 @@ typedef struct Sha256 { } Sha256; -CYASSL_API int InitSha256(Sha256*); -CYASSL_API int Sha256Update(Sha256*, const byte*, word32); -CYASSL_API int Sha256Final(Sha256*, byte*); +CYASSL_API int InitSha256(Sha256*); +CYASSL_API int Sha256Update(Sha256*, const byte*, word32); +CYASSL_API int Sha256Final(Sha256*, byte*); +CYASSL_API int Sha256Hash(const byte*, word32, byte*); #ifdef HAVE_FIPS diff --git a/cyassl/ctaocrypt/sha512.h b/cyassl/ctaocrypt/sha512.h index 5a49942cb..143402439 100644 --- a/cyassl/ctaocrypt/sha512.h +++ b/cyassl/ctaocrypt/sha512.h @@ -54,6 +54,7 @@ typedef struct Sha512 { CYASSL_API int InitSha512(Sha512*); CYASSL_API int Sha512Update(Sha512*, const byte*, word32); CYASSL_API int Sha512Final(Sha512*, byte*); +CYASSL_API int Sha512Hash(const byte*, word32, byte*); #if defined(CYASSL_SHA384) || defined(HAVE_AESGCM) @@ -80,6 +81,7 @@ typedef struct Sha384 { CYASSL_API int InitSha384(Sha384*); CYASSL_API int Sha384Update(Sha384*, const byte*, word32); CYASSL_API int Sha384Final(Sha384*, byte*); +CYASSL_API int Sha384Hash(const byte*, word32, byte*); #ifdef HAVE_FIPS diff --git a/cyassl/ctaocrypt/tfm.h b/cyassl/ctaocrypt/tfm.h index abb588f78..f4e98c152 100644 --- a/cyassl/ctaocrypt/tfm.h +++ b/cyassl/ctaocrypt/tfm.h @@ -73,6 +73,11 @@ #if defined(__x86_64__) && !defined(FP_64BIT) #define FP_64BIT #endif +/* if intel compiler doesn't provide 128 bit type don't turn on 64bit */ +#if defined(FP_64BIT) && defined(__INTEL_COMPILER) && !defined(HAVE___UINT128_T) + #undef FP_64BIT + #undef TFM_X86_64 +#endif #endif /* NO_64BIT */ /* try to detect x86-32 */ diff --git a/cyassl/ctaocrypt/types.h b/cyassl/ctaocrypt/types.h index 194b50b76..33cdb780e 100644 --- a/cyassl/ctaocrypt/types.h +++ b/cyassl/ctaocrypt/types.h @@ -24,7 +24,7 @@ #define CTAO_CRYPT_TYPES_H #include -#include +#include #ifdef __cplusplus extern "C" { diff --git a/cyassl/error-ssl.h b/cyassl/error-ssl.h index 74445b40c..71778ec15 100644 --- a/cyassl/error-ssl.h +++ b/cyassl/error-ssl.h @@ -30,98 +30,99 @@ #endif enum CyaSSL_ErrorCodes { - INPUT_CASE_ERROR = -201, /* process input state error */ - PREFIX_ERROR = -202, /* bad index to key rounds */ - MEMORY_ERROR = -203, /* out of memory */ - VERIFY_FINISHED_ERROR = -204, /* verify problem on finished */ - VERIFY_MAC_ERROR = -205, /* verify mac problem */ - PARSE_ERROR = -206, /* parse error on header */ - UNKNOWN_HANDSHAKE_TYPE = -207, /* weird handshake type */ - SOCKET_ERROR_E = -208, /* error state on socket */ - SOCKET_NODATA = -209, /* expected data, not there */ - INCOMPLETE_DATA = -210, /* don't have enough data to + INPUT_CASE_ERROR = -301, /* process input state error */ + PREFIX_ERROR = -302, /* bad index to key rounds */ + MEMORY_ERROR = -303, /* out of memory */ + VERIFY_FINISHED_ERROR = -304, /* verify problem on finished */ + VERIFY_MAC_ERROR = -305, /* verify mac problem */ + PARSE_ERROR = -306, /* parse error on header */ + UNKNOWN_HANDSHAKE_TYPE = -307, /* weird handshake type */ + SOCKET_ERROR_E = -308, /* error state on socket */ + SOCKET_NODATA = -309, /* expected data, not there */ + INCOMPLETE_DATA = -310, /* don't have enough data to complete task */ - UNKNOWN_RECORD_TYPE = -211, /* unknown type in record hdr */ - DECRYPT_ERROR = -212, /* error during decryption */ - FATAL_ERROR = -213, /* recvd alert fatal error */ - ENCRYPT_ERROR = -214, /* error during encryption */ - FREAD_ERROR = -215, /* fread problem */ - NO_PEER_KEY = -216, /* need peer's key */ - NO_PRIVATE_KEY = -217, /* need the private key */ - RSA_PRIVATE_ERROR = -218, /* error during rsa priv op */ - NO_DH_PARAMS = -219, /* server missing DH params */ - BUILD_MSG_ERROR = -220, /* build message failure */ + UNKNOWN_RECORD_TYPE = -311, /* unknown type in record hdr */ + DECRYPT_ERROR = -312, /* error during decryption */ + FATAL_ERROR = -313, /* recvd alert fatal error */ + ENCRYPT_ERROR = -314, /* error during encryption */ + FREAD_ERROR = -315, /* fread problem */ + NO_PEER_KEY = -316, /* need peer's key */ + NO_PRIVATE_KEY = -317, /* need the private key */ + RSA_PRIVATE_ERROR = -318, /* error during rsa priv op */ + NO_DH_PARAMS = -319, /* server missing DH params */ + BUILD_MSG_ERROR = -320, /* build message failure */ - BAD_HELLO = -221, /* client hello malformed */ - DOMAIN_NAME_MISMATCH = -222, /* peer subject name mismatch */ - WANT_READ = -223, /* want read, call again */ - NOT_READY_ERROR = -224, /* handshake layer not ready */ - PMS_VERSION_ERROR = -225, /* pre m secret version error */ - VERSION_ERROR = -226, /* record layer version error */ - WANT_WRITE = -227, /* want write, call again */ - BUFFER_ERROR = -228, /* malformed buffer input */ - VERIFY_CERT_ERROR = -229, /* verify cert error */ - VERIFY_SIGN_ERROR = -230, /* verify sign error */ - CLIENT_ID_ERROR = -231, /* psk client identity error */ - SERVER_HINT_ERROR = -232, /* psk server hint error */ - PSK_KEY_ERROR = -233, /* psk key error */ - ZLIB_INIT_ERROR = -234, /* zlib init error */ - ZLIB_COMPRESS_ERROR = -235, /* zlib compression error */ - ZLIB_DECOMPRESS_ERROR = -236, /* zlib decompression error */ + BAD_HELLO = -321, /* client hello malformed */ + DOMAIN_NAME_MISMATCH = -322, /* peer subject name mismatch */ + WANT_READ = -323, /* want read, call again */ + NOT_READY_ERROR = -324, /* handshake layer not ready */ + PMS_VERSION_ERROR = -325, /* pre m secret version error */ + VERSION_ERROR = -326, /* record layer version error */ + WANT_WRITE = -327, /* want write, call again */ + BUFFER_ERROR = -328, /* malformed buffer input */ + VERIFY_CERT_ERROR = -329, /* verify cert error */ + VERIFY_SIGN_ERROR = -330, /* verify sign error */ + CLIENT_ID_ERROR = -331, /* psk client identity error */ + SERVER_HINT_ERROR = -332, /* psk server hint error */ + PSK_KEY_ERROR = -333, /* psk key error */ + ZLIB_INIT_ERROR = -334, /* zlib init error */ + ZLIB_COMPRESS_ERROR = -335, /* zlib compression error */ + ZLIB_DECOMPRESS_ERROR = -336, /* zlib decompression error */ - GETTIME_ERROR = -237, /* gettimeofday failed ??? */ - GETITIMER_ERROR = -238, /* getitimer failed ??? */ - SIGACT_ERROR = -239, /* sigaction failed ??? */ - SETITIMER_ERROR = -240, /* setitimer failed ??? */ - LENGTH_ERROR = -241, /* record layer length error */ - PEER_KEY_ERROR = -242, /* can't decode peer key */ - ZERO_RETURN = -243, /* peer sent close notify */ - SIDE_ERROR = -244, /* wrong client/server type */ - NO_PEER_CERT = -245, /* peer didn't send key */ - NTRU_KEY_ERROR = -246, /* NTRU key error */ - NTRU_DRBG_ERROR = -247, /* NTRU drbg error */ - NTRU_ENCRYPT_ERROR = -248, /* NTRU encrypt error */ - NTRU_DECRYPT_ERROR = -249, /* NTRU decrypt error */ - ECC_CURVETYPE_ERROR = -250, /* Bad ECC Curve Type */ - ECC_CURVE_ERROR = -251, /* Bad ECC Curve */ - ECC_PEERKEY_ERROR = -252, /* Bad Peer ECC Key */ - ECC_MAKEKEY_ERROR = -253, /* Bad Make ECC Key */ - ECC_EXPORT_ERROR = -254, /* Bad ECC Export Key */ - ECC_SHARED_ERROR = -255, /* Bad ECC Shared Secret */ - NOT_CA_ERROR = -257, /* Not a CA cert error */ - BAD_PATH_ERROR = -258, /* Bad path for opendir */ - BAD_CERT_MANAGER_ERROR = -259, /* Bad Cert Manager */ - OCSP_CERT_REVOKED = -260, /* OCSP Certificate revoked */ - CRL_CERT_REVOKED = -261, /* CRL Certificate revoked */ - CRL_MISSING = -262, /* CRL Not loaded */ - MONITOR_RUNNING_E = -263, /* CRL Monitor already running */ - THREAD_CREATE_E = -264, /* Thread Create Error */ - OCSP_NEED_URL = -265, /* OCSP need an URL for lookup */ - OCSP_CERT_UNKNOWN = -266, /* OCSP responder doesn't know */ - OCSP_LOOKUP_FAIL = -267, /* OCSP lookup not successful */ - MAX_CHAIN_ERROR = -268, /* max chain depth exceeded */ - COOKIE_ERROR = -269, /* dtls cookie error */ - SEQUENCE_ERROR = -270, /* dtls sequence error */ - SUITES_ERROR = -271, /* suites pointer error */ - SSL_NO_PEM_HEADER = -272, /* no PEM header found */ - OUT_OF_ORDER_E = -273, /* out of order message */ - BAD_KEA_TYPE_E = -274, /* bad KEA type found */ - SANITY_CIPHER_E = -275, /* sanity check on cipher error */ - RECV_OVERFLOW_E = -276, /* RXCB returned more than rqed */ - GEN_COOKIE_E = -277, /* Generate Cookie Error */ - NO_PEER_VERIFY = -278, /* Need peer cert verify Error */ - FWRITE_ERROR = -279, /* fwrite problem */ - CACHE_MATCH_ERROR = -280, /* chache hdr match error */ - UNKNOWN_SNI_HOST_NAME_E = -281, /* Unrecognized host name Error */ - UNKNOWN_MAX_FRAG_LEN_E = -282, /* Unrecognized max frag len Error */ + GETTIME_ERROR = -337, /* gettimeofday failed ??? */ + GETITIMER_ERROR = -338, /* getitimer failed ??? */ + SIGACT_ERROR = -339, /* sigaction failed ??? */ + SETITIMER_ERROR = -340, /* setitimer failed ??? */ + LENGTH_ERROR = -341, /* record layer length error */ + PEER_KEY_ERROR = -342, /* can't decode peer key */ + ZERO_RETURN = -343, /* peer sent close notify */ + SIDE_ERROR = -344, /* wrong client/server type */ + NO_PEER_CERT = -345, /* peer didn't send key */ + NTRU_KEY_ERROR = -346, /* NTRU key error */ + NTRU_DRBG_ERROR = -347, /* NTRU drbg error */ + NTRU_ENCRYPT_ERROR = -348, /* NTRU encrypt error */ + NTRU_DECRYPT_ERROR = -349, /* NTRU decrypt error */ + ECC_CURVETYPE_ERROR = -350, /* Bad ECC Curve Type */ + ECC_CURVE_ERROR = -351, /* Bad ECC Curve */ + ECC_PEERKEY_ERROR = -352, /* Bad Peer ECC Key */ + ECC_MAKEKEY_ERROR = -353, /* Bad Make ECC Key */ + ECC_EXPORT_ERROR = -354, /* Bad ECC Export Key */ + ECC_SHARED_ERROR = -355, /* Bad ECC Shared Secret */ + NOT_CA_ERROR = -357, /* Not a CA cert error */ + BAD_PATH_ERROR = -358, /* Bad path for opendir */ + BAD_CERT_MANAGER_ERROR = -359, /* Bad Cert Manager */ + OCSP_CERT_REVOKED = -360, /* OCSP Certificate revoked */ + CRL_CERT_REVOKED = -361, /* CRL Certificate revoked */ + CRL_MISSING = -362, /* CRL Not loaded */ + MONITOR_RUNNING_E = -363, /* CRL Monitor already running */ + THREAD_CREATE_E = -364, /* Thread Create Error */ + OCSP_NEED_URL = -365, /* OCSP need an URL for lookup */ + OCSP_CERT_UNKNOWN = -366, /* OCSP responder doesn't know */ + OCSP_LOOKUP_FAIL = -367, /* OCSP lookup not successful */ + MAX_CHAIN_ERROR = -368, /* max chain depth exceeded */ + COOKIE_ERROR = -369, /* dtls cookie error */ + SEQUENCE_ERROR = -370, /* dtls sequence error */ + SUITES_ERROR = -371, /* suites pointer error */ + SSL_NO_PEM_HEADER = -372, /* no PEM header found */ + OUT_OF_ORDER_E = -373, /* out of order message */ + BAD_KEA_TYPE_E = -374, /* bad KEA type found */ + SANITY_CIPHER_E = -375, /* sanity check on cipher error */ + RECV_OVERFLOW_E = -376, /* RXCB returned more than rqed */ + GEN_COOKIE_E = -377, /* Generate Cookie Error */ + NO_PEER_VERIFY = -378, /* Need peer cert verify Error */ + FWRITE_ERROR = -379, /* fwrite problem */ + CACHE_MATCH_ERROR = -380, /* chache hdr match error */ + UNKNOWN_SNI_HOST_NAME_E = -381, /* Unrecognized host name Error */ + UNKNOWN_MAX_FRAG_LEN_E = -382, /* Unrecognized max frag len Error */ + KEYUSE_SIGNATURE_E = -383, /* KeyUse digSignature error */ + KEYUSE_ENCIPHER_E = -385, /* KeyUse keyEncipher error */ + EXTKEYUSE_AUTH_E = -386, /* ExtKeyUse server|client_auth */ + SEND_OOB_READ_E = -387, /* Send Cb out of bounds read */ /* add strings to SetErrorString !!!!! */ - KEYUSE_SIGNATURE_E = -283, /* KeyUse digSignature error */ - KEYUSE_ENCIPHER_E = -285, /* KeyUse keyEncipher error */ - EXTKEYUSE_AUTH_E = -286, /* ExtKeyUse server|client_auth */ /* begin negotiation parameter errors */ - UNSUPPORTED_SUITE = -290, /* unsupported cipher suite */ - MATCH_SUITE_ERROR = -291 /* can't match cipher suite */ + UNSUPPORTED_SUITE = -390, /* unsupported cipher suite */ + MATCH_SUITE_ERROR = -391 /* can't match cipher suite */ /* end negotiation parameter errors only 10 for now */ /* add strings to SetErrorString !!!!! */ }; diff --git a/cyassl/internal.h b/cyassl/internal.h index 397d14f82..8a74fc749 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -216,7 +216,7 @@ void c32to24(word32 in, word24 out); #define BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 #define BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 #endif - #if !defined(NO_DH) && defined(OPENSSL_EXTRA) + #if !defined(NO_DH) #if !defined(NO_SHA) #define BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA #define BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA @@ -242,6 +242,14 @@ void c32to24(word32 in, word24 out); #ifdef HAVE_AESCCM #define BUILD_TLS_PSK_WITH_AES_128_CCM_8 #define BUILD_TLS_PSK_WITH_AES_256_CCM_8 + #define BUILD_TLS_PSK_WITH_AES_128_CCM + #define BUILD_TLS_PSK_WITH_AES_256_CCM + #endif + #endif + #ifdef CYASSL_SHA384 + #define BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384 + #ifdef HAVE_AESGCM + #define BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384 #endif #endif #endif @@ -262,6 +270,9 @@ void c32to24(word32 in, word24 out); #ifndef NO_SHA256 #define BUILD_TLS_PSK_WITH_NULL_SHA256 #endif + #ifdef CYASSL_SHA384 + #define BUILD_TLS_PSK_WITH_NULL_SHA384 + #endif #endif #endif @@ -282,7 +293,7 @@ void c32to24(word32 in, word24 out); #endif #if !defined(NO_DH) && !defined(NO_AES) && !defined(NO_TLS) && \ - !defined(NO_RSA) && defined(OPENSSL_EXTRA) + !defined(NO_RSA) #if !defined(NO_SHA) #define BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA #define BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA @@ -299,6 +310,32 @@ void c32to24(word32 in, word24 out); #endif #endif + +#if !defined(NO_DH) && !defined(NO_PSK) && !defined(NO_TLS) + #ifndef NO_SHA256 + #define BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + #ifdef HAVE_NULL_CIPHER + #define BUILD_TLS_DHE_PSK_WITH_NULL_SHA256 + #endif + #ifdef HAVE_AESGCM + #define BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + #endif + #ifdef HAVE_AESCCM + #define BUILD_TLS_DHE_PSK_WITH_AES_128_CCM + #define BUILD_TLS_DHE_PSK_WITH_AES_256_CCM + #endif + #endif + #ifdef CYASSL_SHA384 + #define BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + #ifdef HAVE_NULL_CIPHER + #define BUILD_TLS_DHE_PSK_WITH_NULL_SHA384 + #endif + #ifdef HAVE_AESGCM + #define BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + #endif + #endif +#endif + #if defined(HAVE_ECC) && !defined(NO_TLS) #if !defined(NO_AES) #if !defined(NO_SHA) @@ -439,7 +476,6 @@ void c32to24(word32 in, word24 out); #endif - /* actual cipher values, 2nd byte */ enum { TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x39, @@ -449,8 +485,10 @@ enum { TLS_RSA_WITH_NULL_SHA = 0x02, TLS_PSK_WITH_AES_256_CBC_SHA = 0x8d, TLS_PSK_WITH_AES_128_CBC_SHA256 = 0xae, + TLS_PSK_WITH_AES_256_CBC_SHA384 = 0xaf, TLS_PSK_WITH_AES_128_CBC_SHA = 0x8c, TLS_PSK_WITH_NULL_SHA256 = 0xb0, + TLS_PSK_WITH_NULL_SHA384 = 0xb1, TLS_PSK_WITH_NULL_SHA = 0x2c, SSL_RSA_WITH_RC4_128_SHA = 0x05, SSL_RSA_WITH_RC4_128_MD5 = 0x04, @@ -484,7 +522,6 @@ enum { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 = 0x2A, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0x26, - /* CyaSSL extension - eSTREAM */ TLS_RSA_WITH_HC_128_MD5 = 0xFB, TLS_RSA_WITH_HC_128_SHA = 0xFC, @@ -498,7 +535,7 @@ enum { /* CyaSSL extension - NTRU */ TLS_NTRU_RSA_WITH_RC4_128_SHA = 0xe5, TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA = 0xe6, - TLS_NTRU_RSA_WITH_AES_128_CBC_SHA = 0xe7, /* clases w/ official SHA-256 */ + TLS_NTRU_RSA_WITH_AES_128_CBC_SHA = 0xe7, /* clashes w/official SHA-256 */ TLS_NTRU_RSA_WITH_AES_256_CBC_SHA = 0xe8, /* SHA256 */ @@ -507,12 +544,22 @@ enum { TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x3d, TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x3c, TLS_RSA_WITH_NULL_SHA256 = 0x3b, + TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 = 0xb2, + TLS_DHE_PSK_WITH_NULL_SHA256 = 0xb4, + + /* SHA384 */ + TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 = 0xb3, + TLS_DHE_PSK_WITH_NULL_SHA384 = 0xb5, /* AES-GCM */ TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x9c, TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x9d, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x9e, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x9f, + TLS_PSK_WITH_AES_128_GCM_SHA256 = 0xa8, + TLS_PSK_WITH_AES_256_GCM_SHA384 = 0xa9, + TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 = 0xaa, + TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 = 0xab, /* ECC AES-GCM, first byte is 0xC0 (ECC_BYTE) */ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0x2b, @@ -536,7 +583,10 @@ enum { TLS_PSK_WITH_AES_256_CCM = 0xa5, TLS_PSK_WITH_AES_128_CCM_8 = 0xa8, TLS_PSK_WITH_AES_256_CCM_8 = 0xa9, + TLS_DHE_PSK_WITH_AES_128_CCM = 0xa6, + TLS_DHE_PSK_WITH_AES_256_CCM = 0xa7, + /* Camellia */ TLS_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x41, TLS_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x84, TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xba, @@ -644,7 +694,7 @@ enum Misc { TLS_FINISHED_SZ = 12, /* TLS has a shorter size */ MASTER_LABEL_SZ = 13, /* TLS master secret label sz */ KEY_LABEL_SZ = 13, /* TLS key block expansion sz */ - MAX_PRF_HALF = 128, /* Maximum half secret len */ + MAX_PRF_HALF = 256, /* Maximum half secret len */ MAX_PRF_LABSEED = 128, /* Maximum label + seed len */ MAX_PRF_DIG = 224, /* Maximum digest len */ MAX_REQUEST_SZ = 256, /* Maximum cert req len (no auth yet */ @@ -953,32 +1003,6 @@ int SetCipherList(Suites*, const char* list); #endif /* PSK_TYPES_DEFINED */ -#ifndef CYASSL_USER_IO - /* default IO callbacks */ - CYASSL_LOCAL - int EmbedReceive(CYASSL *ssl, char *buf, int sz, void *ctx); - CYASSL_LOCAL - int EmbedSend(CYASSL *ssl, char *buf, int sz, void *ctx); - - #ifdef HAVE_OCSP - CYASSL_LOCAL - int EmbedOcspLookup(void*, const char*, int, byte*, int, byte**); - CYASSL_LOCAL - void EmbedOcspRespFree(void*, byte*); - #endif - - #ifdef CYASSL_DTLS - CYASSL_LOCAL - int EmbedReceiveFrom(CYASSL *ssl, char *buf, int sz, void *ctx); - CYASSL_LOCAL - int EmbedSendTo(CYASSL *ssl, char *buf, int sz, void *ctx); - CYASSL_LOCAL - int EmbedGenerateCookie(CYASSL* ssl, byte *buf, int sz, void *ctx); - CYASSL_LOCAL - int IsUDP(void*); - #endif /* CYASSL_DTLS */ -#endif /* CYASSL_USER_IO */ - #ifdef HAVE_NETX CYASSL_LOCAL int NetX_Receive(CYASSL *ssl, char *buf, int sz, void *ctx); CYASSL_LOCAL int NetX_Send(CYASSL *ssl, char *buf, int sz, void *ctx); @@ -1146,6 +1170,7 @@ typedef struct TLSX { CYASSL_LOCAL TLSX* TLSX_Find(TLSX* list, TLSX_Type type); CYASSL_LOCAL void TLSX_FreeAll(TLSX* list); +CYASSL_LOCAL int TLSX_SupportExtensions(CYASSL* ssl); #ifndef NO_CYASSL_CLIENT CYASSL_LOCAL word16 TLSX_GetRequestSize(CYASSL* ssl); @@ -1360,6 +1385,7 @@ enum KeyExchangeAlgorithm { diffie_hellman_kea, fortezza_kea, psk_kea, + dhe_psk_kea, ntru_kea, ecc_diffie_hellman_kea, ecc_static_diffie_hellman_kea /* for verify suite only */ @@ -1401,7 +1427,10 @@ enum ClientCertificateType { dss_fixed_dh = 4, rsa_ephemeral_dh = 5, dss_ephemeral_dh = 6, - fortezza_kea_cert = 20 + fortezza_kea_cert = 20, + ecdsa_sign = 64, + rsa_fixed_ecdh = 65, + ecdsa_fixed_ecdh = 66 }; @@ -1597,7 +1626,7 @@ typedef struct Buffers { #ifndef NO_CERTS buffer certificate; /* CYASSL_CTX owns, unless we own */ buffer key; /* CYASSL_CTX owns, unless we own */ - buffer certChain; /* CYASSL_CTX owns */ + buffer certChain; /* CYASSL_CTX owns, unless we own */ /* chain after self, in DER, with leading size for each cert */ buffer serverDH_P; /* CYASSL_CTX owns, unless we own */ buffer serverDH_G; /* CYASSL_CTX owns, unless we own */ @@ -1613,6 +1642,7 @@ typedef struct Buffers { int plainSz; /* plain text bytes in buffer to send when got WANT_WRITE */ byte weOwnCert; /* SSL own cert flag */ + byte weOwnCertChain; /* SSL own cert chain flag */ byte weOwnKey; /* SSL own key flag */ byte weOwnDH; /* SSL own dh (p,g) flag */ #ifdef CYASSL_DTLS diff --git a/cyassl/openssl/ssl.h b/cyassl/openssl/ssl.h index 0fb6d453a..acb6b0104 100644 --- a/cyassl/openssl/ssl.h +++ b/cyassl/openssl/ssl.h @@ -142,6 +142,7 @@ typedef CYASSL_X509_STORE_CTX X509_STORE_CTX; #define ERR_error_string CyaSSL_ERR_error_string #define ERR_error_string_n CyaSSL_ERR_error_string_n +#define ERR_reason_error_string CyaSSL_ERR_reason_error_string #define SSL_set_ex_data CyaSSL_set_ex_data #define SSL_get_shutdown CyaSSL_get_shutdown diff --git a/cyassl/ssl.h b/cyassl/ssl.h index 645fd916b..19a19a15a 100644 --- a/cyassl/ssl.h +++ b/cyassl/ssl.h @@ -312,6 +312,7 @@ CYASSL_API int CyaSSL_ERR_GET_REASON(int err); CYASSL_API char* CyaSSL_ERR_error_string(unsigned long,char*); CYASSL_API void CyaSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long sz); +CYASSL_API const char* CyaSSL_ERR_reason_error_string(unsigned long); /* extras */ @@ -937,6 +938,27 @@ CYASSL_API void* CyaSSL_GetIOWriteCtx(CYASSL* ssl); CYASSL_API void CyaSSL_SetIOReadFlags( CYASSL* ssl, int flags); CYASSL_API void CyaSSL_SetIOWriteFlags(CYASSL* ssl, int flags); + +#ifndef CYASSL_USER_IO + /* default IO callbacks */ + CYASSL_API int EmbedReceive(CYASSL* ssl, char* buf, int sz, void* ctx); + CYASSL_API int EmbedSend(CYASSL* ssl, char* buf, int sz, void* ctx); + + #ifdef HAVE_OCSP + CYASSL_API int EmbedOcspLookup(void*, const char*, int, unsigned char*, + int, unsigned char**); + CYASSL_API void EmbedOcspRespFree(void*, unsigned char*); + #endif + + #ifdef CYASSL_DTLS + CYASSL_API int EmbedReceiveFrom(CYASSL* ssl, char* buf, int sz, void*); + CYASSL_API int EmbedSendTo(CYASSL* ssl, char* buf, int sz, void* ctx); + CYASSL_API int EmbedGenerateCookie(CYASSL* ssl, unsigned char* buf, + int sz, void*); + #endif /* CYASSL_DTLS */ +#endif /* CYASSL_USER_IO */ + + #ifdef HAVE_NETX CYASSL_API void CyaSSL_SetIO_NetX(CYASSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption); diff --git a/cyassl/test.h b/cyassl/test.h index 667476ed2..179e049ec 100644 --- a/cyassl/test.h +++ b/cyassl/test.h @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef ATOMIC_USER #include @@ -894,6 +895,25 @@ static INLINE int myVerify(int preverify, CYASSL_X509_STORE_CTX* store) #endif /* VERIFY_CALLBACK */ +static INLINE int myDateCb(int preverify, CYASSL_X509_STORE_CTX* store) +{ + (void)preverify; + char buffer[CYASSL_MAX_ERROR_SZ]; + + printf("In verification callback, error = %d, %s\n", store->error, + CyaSSL_ERR_error_string(store->error, buffer)); + printf("Subject's domain name is %s\n", store->domain); + + if (store->error == ASN_BEFORE_DATE_E || store->error == ASN_AFTER_DATE_E) { + printf("Overriding cert date error as example for bad clock testing\n"); + return 1; + } + printf("Cert error is not date error, not overriding\n"); + + return 0; +} + + #ifdef HAVE_CRL static INLINE void CRL_CallBack(const char* url) @@ -912,6 +932,7 @@ static INLINE void CaCb(unsigned char* der, int sz, int type) } +#ifndef NO_DH static INLINE void SetDH(CYASSL* ssl) { /* dh1024 p */ @@ -965,7 +986,7 @@ static INLINE void SetDHCtx(CYASSL_CTX* ctx) CyaSSL_CTX_SetTmpDH(ctx, p, sizeof(p), g, sizeof(g)); } - +#endif /* NO_DH */ #endif /* !NO_CERTS */ #ifdef HAVE_CAVIUM diff --git a/cyassl/version.h b/cyassl/version.h index 9df3246e7..f520844e6 100644 --- a/cyassl/version.h +++ b/cyassl/version.h @@ -26,8 +26,8 @@ extern "C" { #endif -#define LIBCYASSL_VERSION_STRING "3.0.0" -#define LIBCYASSL_VERSION_HEX 0x03000000 +#define LIBCYASSL_VERSION_STRING "3.0.3" +#define LIBCYASSL_VERSION_HEX 0x03000003 #ifdef __cplusplus } diff --git a/examples/client/client.c b/examples/client/client.c index 1c4041850..6c268e65d 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -128,6 +128,7 @@ static void Usage(void) printf("-s Use pre Shared keys\n"); printf("-t Track CyaSSL memory use\n"); printf("-d Disable peer checks\n"); + printf("-D Override Date Errors example\n"); printf("-g Send server HTTP GET\n"); printf("-u Use UDP DTLS," " add -v 2 for DTLSv1 (default), -v 3 for DTLSv1.2\n"); @@ -197,6 +198,7 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) int fewerPackets = 0; int atomicUser = 0; int pkCallbacks = 0; + int overrideDateErrors = 0; char* cipherList = NULL; const char* verifyCert = caCert; const char* ourCert = cliCert; @@ -238,7 +240,7 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) StackTrap(); while ((ch = mygetopt(argc, argv, - "?gdusmNrtfxUPh:p:v:l:A:c:k:b:zS:L:ToO:")) != -1) { + "?gdDusmNrtfxUPh:p:v:l:A:c:k:b:zS:L:ToO:")) != -1) { switch (ch) { case '?' : Usage(); @@ -252,6 +254,10 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) doPeerCheck = 0; break; + case 'D' : + overrideDateErrors = 1; + break; + case 'u' : doDTLS = 1; break; @@ -545,6 +551,8 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) #if !defined(NO_CERTS) if (!usePsk && doPeerCheck == 0) CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); + if (!usePsk && overrideDateErrors == 1) + CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myDateCb); #endif #ifdef HAVE_CAVIUM diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index 33f6df3df..214284eb8 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -227,9 +227,9 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args) ssl = CyaSSL_new(ctx); if (ssl == NULL) err_sys("SSL_new failed"); CyaSSL_set_fd(ssl, clientfd); - #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) + #if !defined(NO_FILESYSTEM) && !defined(NO_DH) CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM); - #elif !defined(NO_CERTS) + #elif !defined(NO_DH) SetDH(ssl); /* will repick suites with DHE, higher than PSK */ #endif if (CyaSSL_accept(ssl) != SSL_SUCCESS) { diff --git a/examples/server/server.c b/examples/server/server.c index 6e1358e8c..43a5ad7fb 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -481,9 +481,9 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) SSL_set_fd(ssl, clientfd); if (usePsk == 0 || cipherList != NULL) { - #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) + #if !defined(NO_FILESYSTEM) && !defined(NO_DH) CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM); - #elif !defined(NO_CERTS) + #elif !defined(NO_DH) SetDH(ssl); /* repick suites with DHE, higher priority than PSK */ #endif } diff --git a/gencertbuf.pl b/gencertbuf.pl index 6fb1929a1..9e12c8209 100755 --- a/gencertbuf.pl +++ b/gencertbuf.pl @@ -1,10 +1,10 @@ #!/usr/bin/perl # gencertbuf.pl -# version 1.0 -# Updated 01/28/2013 +# version 1.1 +# Updated 07/01/2014 # -# Copyright (C) 2006-2013 wolfSSL +# Copyright (C) 2006-2014 wolfSSL Inc. # use strict; @@ -34,7 +34,10 @@ my @fileList_2048 = ( [ "./certs/client-cert.der", "client_cert_der_2048" ], [ "./certs/dh2048.der", "dh_key_der_2048" ], [ "./certs/dsa2048.der", "dsa_key_der_2048" ], - [ "./certs/rsa2048.der", "rsa_key_der_2048" ] + [ "./certs/rsa2048.der", "rsa_key_der_2048" ], + [ "./certs/ca-cert.der", "ca_cert_der_2048" ], + [ "./certs/server-key.der", "server_key_der_2048" ], + [ "./certs/server-cert.der", "server_cert_der_2048" ] ); # ---------------------------------------------------------------------------- @@ -51,22 +54,32 @@ print OUT_FILE "#define CYASSL_CERTS_TEST_H\n\n"; # convert and print 1024-bit cert/keys print OUT_FILE "#ifdef USE_CERT_BUFFERS_1024\n\n"; -for(my $i = 0; $i < $num_1024; $i++) { - print OUT_FILE "/* $fileList_1024[$i][0], 1024-bit */\n"; - print OUT_FILE "const unsigned char $fileList_1024[$i][1]\[] =\n"; +for (my $i = 0; $i < $num_1024; $i++) { + + my $fname = $fileList_1024[$i][0]; + my $sname = $fileList_1024[$i][1]; + + print OUT_FILE "/* $fname, 1024-bit */\n"; + print OUT_FILE "const unsigned char $sname\[] =\n"; print OUT_FILE "{\n"; - file_to_hex($fileList_1024[$i][0]); - print OUT_FILE "};\n\n"; + file_to_hex($fname); + print OUT_FILE "};\n"; + print OUT_FILE "const int sizeof_$sname = sizeof($sname);\n\n"; } # convert and print 2048-bit certs/keys print OUT_FILE "#elif defined(USE_CERT_BUFFERS_2048)\n\n"; -for(my $i = 0; $i < $num_2048; $i++) { - print OUT_FILE "/* $fileList_2048[$i][0], 2048-bit */\n"; - print OUT_FILE "const unsigned char $fileList_2048[$i][1]\[] =\n"; +for (my $i = 0; $i < $num_2048; $i++) { + + my $fname = $fileList_2048[$i][0]; + my $sname = $fileList_2048[$i][1]; + + print OUT_FILE "/* $fname, 2048-bit */\n"; + print OUT_FILE "const unsigned char $sname\[] =\n"; print OUT_FILE "{\n"; - file_to_hex($fileList_2048[$i][0]); - print OUT_FILE "};\n\n"; + file_to_hex($fname); + print OUT_FILE "};\n"; + print OUT_FILE "const int sizeof_$sname = sizeof($sname);\n\n"; } print OUT_FILE "#endif /* USE_CERT_BUFFERS_1024 */\n\n"; @@ -108,3 +121,4 @@ sub file_to_hex { close($fp); } + diff --git a/src/crl.c b/src/crl.c index 42591b997..9b94aab7b 100644 --- a/src/crl.c +++ b/src/crl.c @@ -501,7 +501,7 @@ static int StopMonitor(int mfd) static void* DoMonitor(void* arg) { int notifyFd; - int wd; + int wd = -1; CYASSL_CRL* crl = (CYASSL_CRL*)arg; CYASSL_ENTER("DoMonitor"); @@ -575,7 +575,8 @@ static void* DoMonitor(void* arg) } } - inotify_rm_watch(notifyFd, wd); + if (wd > 0) + inotify_rm_watch(notifyFd, wd); close(crl->mfd); close(notifyFd); diff --git a/src/include.am b/src/include.am index bd6fc8b3f..48b895d13 100644 --- a/src/include.am +++ b/src/include.am @@ -19,7 +19,7 @@ src_libcyassl_la_SOURCES += \ ctaocrypt/src/random.c \ ctaocrypt/src/sha256.c \ ctaocrypt/src/logging.c \ - ctaocrypt/src/port.c \ + ctaocrypt/src/wc_port.c \ ctaocrypt/src/error.c src_libcyassl_la_LDFLAGS = ${AM_LDFLAGS} -no-undefined -version-info ${CYASSL_LIBRARY_VERSION} src_libcyassl_la_LIBADD = $(LIBM) diff --git a/src/internal.c b/src/internal.c index 2ee09acb2..58cc15ee5 100644 --- a/src/internal.c +++ b/src/internal.c @@ -35,7 +35,7 @@ #endif #ifdef HAVE_NTRU - #include "crypto_ntru.h" + #include "ntru_crypto.h" #endif #if defined(DEBUG_CYASSL) || defined(SHOW_SECRETS) || defined(CHACHA_AEAD_TEST) @@ -58,10 +58,6 @@ #endif -#if defined(OPENSSL_EXTRA) && defined(NO_DH) - #error OPENSSL_EXTRA needs DH, please remove NO_DH -#endif - #if defined(CYASSL_CALLBACKS) && !defined(LARGE_STATIC_BUFFERS) #error \ CYASSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS @@ -979,7 +975,6 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK, } #endif - #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA if (tls && haveDH && haveRSA) { suites->suites[idx++] = 0; @@ -1050,6 +1045,20 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK, } #endif +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + if (tls1_2 && haveDH && havePSK) { + suites->suites[idx++] = 0; + suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_GCM_SHA384; + } +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384 + if (tls1_2 && havePSK) { + suites->suites[idx++] = 0; + suites->suites[idx++] = TLS_PSK_WITH_AES_256_GCM_SHA384; + } +#endif + #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA if (tls && havePSK) { suites->suites[idx++] = 0; @@ -1057,6 +1066,41 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK, } #endif +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + if (tls && haveDH && havePSK) { + suites->suites[idx++] = 0; + suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA384; + } +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384 + if (tls && havePSK) { + suites->suites[idx++] = 0; + suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA384; + } +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + if (tls1_2 && haveDH && havePSK) { + suites->suites[idx++] = 0; + suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_GCM_SHA256; + } +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256 + if (tls1_2 && havePSK) { + suites->suites[idx++] = 0; + suites->suites[idx++] = TLS_PSK_WITH_AES_128_GCM_SHA256; + } +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + if (tls && haveDH && havePSK) { + suites->suites[idx++] = 0; + suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA256; + } +#endif + #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256 if (tls && havePSK) { suites->suites[idx++] = 0; @@ -1071,6 +1115,34 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK, } #endif +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM + if (tls && haveDH && havePSK) { + suites->suites[idx++] = ECC_BYTE; + suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CCM; + } +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM + if (tls && haveDH && havePSK) { + suites->suites[idx++] = ECC_BYTE; + suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CCM; + } +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM + if (tls && havePSK) { + suites->suites[idx++] = ECC_BYTE; + suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM; + } +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM + if (tls && havePSK) { + suites->suites[idx++] = ECC_BYTE; + suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM; + } +#endif + #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8 if (tls && havePSK) { suites->suites[idx++] = ECC_BYTE; @@ -1085,6 +1157,27 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK, } #endif +#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384 + if (tls && haveDH && havePSK) { + suites->suites[idx++] = 0; + suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA384; + } +#endif + +#ifdef BUILD_TLS_PSK_WITH_NULL_SHA384 + if (tls && havePSK) { + suites->suites[idx++] = 0; + suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA384; + } +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256 + if (tls && haveDH && havePSK) { + suites->suites[idx++] = 0; + suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA256; + } +#endif + #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256 if (tls && havePSK) { suites->suites[idx++] = 0; @@ -1573,9 +1666,10 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->buffers.serverDH_G = ctx->serverDH_G; } #endif - ssl->buffers.weOwnCert = 0; - ssl->buffers.weOwnKey = 0; - ssl->buffers.weOwnDH = 0; + ssl->buffers.weOwnCert = 0; + ssl->buffers.weOwnCertChain = 0; + ssl->buffers.weOwnKey = 0; + ssl->buffers.weOwnDH = 0; #ifdef CYASSL_DTLS ssl->buffers.dtlsCtx.fd = -1; @@ -1800,9 +1894,10 @@ void SSL_ResourceFree(CYASSL* ssl) XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH); } - /* CYASSL_CTX always owns certChain */ if (ssl->buffers.weOwnCert) XFREE(ssl->buffers.certificate.buffer, ssl->heap, DYNAMIC_TYPE_CERT); + if (ssl->buffers.weOwnCertChain) + XFREE(ssl->buffers.certChain.buffer, ssl->heap, DYNAMIC_TYPE_CERT); if (ssl->buffers.weOwnKey) XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY); #endif @@ -2008,7 +2103,7 @@ int DtlsPoolSave(CYASSL* ssl, const byte *src, int sz) DtlsPool *pool = ssl->dtls_pool; if (pool != NULL && pool->used < DTLS_POOL_SZ) { buffer *pBuf = &pool->buf[pool->used]; - pBuf->buffer = (byte*)XMALLOC(sz, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER); + pBuf->buffer = (byte*)XMALLOC(sz, ssl->heap, DYNAMIC_TYPE_DTLS_POOL); if (pBuf->buffer == NULL) { CYASSL_MSG("DTLS Buffer Memory error"); return MEMORY_ERROR; @@ -2030,7 +2125,7 @@ void DtlsPoolReset(CYASSL* ssl) used = pool->used; for (i = 0, pBuf = &pool->buf[0]; i < used; i++, pBuf++) { - XFREE(pBuf->buffer, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER); + XFREE(pBuf->buffer, ssl->heap, DYNAMIC_TYPE_DTLS_POOL); pBuf->buffer = NULL; pBuf->length = 0; } @@ -2706,6 +2801,11 @@ int SendBuffered(CYASSL* ssl) return SOCKET_ERROR_E; } + if (sent > (int)ssl->buffers.outputBuffer.length) { + CYASSL_MSG("SendBuffered() out of bounds read"); + return SEND_OOB_READ_E; + } + ssl->buffers.outputBuffer.idx += sent; ssl->buffers.outputBuffer.length -= sent; } @@ -3048,12 +3148,446 @@ static int BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender) } + /* cipher requirements */ + enum { + REQUIRES_RSA, + REQUIRES_DHE, + REQUIRES_ECC_DSA, + REQUIRES_ECC_STATIC, + REQUIRES_PSK, + REQUIRES_NTRU, + REQUIRES_RSA_SIG + }; + + + + /* Does this cipher suite (first, second) have the requirement + an ephemeral key exchange will still require the key for signing + the key exchange so ECHDE_RSA requires an rsa key thus rsa_kea */ + static int CipherRequires(byte first, byte second, int requirement) + { + + if (first == CHACHA_BYTE) { + + switch (second) { + + case TLS_ECDHE_RSA_WITH_CHACHA20_256_POLY1305_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + break; + } + } + /* ECC extensions */ + if (first == ECC_BYTE) { + + switch (second) { + +#ifndef NO_RSA + case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + break; + +#ifndef NO_DES3 + case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + break; +#endif + +#ifndef NO_RC4 + case TLS_ECDHE_RSA_WITH_RC4_128_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_ECDH_RSA_WITH_RC4_128_SHA : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + break; +#endif +#endif /* NO_RSA */ + +#ifndef NO_DES3 + case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA : + if (requirement == REQUIRES_ECC_DSA) + return 1; + break; + + case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + break; +#endif +#ifndef NO_RC4 + case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : + if (requirement == REQUIRES_ECC_DSA) + return 1; + break; + + case TLS_ECDH_ECDSA_WITH_RC4_128_SHA : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + break; +#endif +#ifndef NO_RSA + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + break; +#endif + + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA : + if (requirement == REQUIRES_ECC_DSA) + return 1; + break; + + case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + break; + + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA : + if (requirement == REQUIRES_ECC_DSA) + return 1; + break; + + case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + break; + + case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 : + if (requirement == REQUIRES_ECC_DSA) + return 1; + break; + + case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 : + if (requirement == REQUIRES_ECC_DSA) + return 1; + break; + + case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + break; + + case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + break; + +#ifndef NO_RSA + case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + break; + + case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + break; + + case TLS_RSA_WITH_AES_128_CCM_8 : + case TLS_RSA_WITH_AES_256_CCM_8 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + break; + + case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + break; + + case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 : + case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 : + if (requirement == REQUIRES_RSA_SIG) + return 1; + if (requirement == REQUIRES_ECC_STATIC) + return 1; + break; +#endif + + case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 : + case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 : + if (requirement == REQUIRES_ECC_DSA) + return 1; + break; + + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 : + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : + if (requirement == REQUIRES_ECC_DSA) + return 1; + break; + + case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 : + case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 : + if (requirement == REQUIRES_ECC_DSA) + return 1; + if (requirement == REQUIRES_ECC_STATIC) + return 1; + break; + + case TLS_PSK_WITH_AES_128_CCM: + case TLS_PSK_WITH_AES_256_CCM: + case TLS_PSK_WITH_AES_128_CCM_8: + case TLS_PSK_WITH_AES_256_CCM_8: + if (requirement == REQUIRES_PSK) + return 1; + break; + + case TLS_DHE_PSK_WITH_AES_128_CCM: + case TLS_DHE_PSK_WITH_AES_256_CCM: + if (requirement == REQUIRES_PSK) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; + + default: + CYASSL_MSG("Unsupported cipher suite, CipherRequires ECC"); + return 0; + } /* switch */ + } /* if */ + if (first != ECC_BYTE) { /* normal suites */ + switch (second) { + +#ifndef NO_RSA + case SSL_RSA_WITH_RC4_128_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_NTRU_RSA_WITH_RC4_128_SHA : + if (requirement == REQUIRES_NTRU) + return 1; + break; + + case SSL_RSA_WITH_RC4_128_MD5 : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case SSL_RSA_WITH_3DES_EDE_CBC_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA : + if (requirement == REQUIRES_NTRU) + return 1; + break; + + case TLS_RSA_WITH_AES_128_CBC_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_RSA_WITH_AES_128_CBC_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA : + if (requirement == REQUIRES_NTRU) + return 1; + break; + + case TLS_RSA_WITH_AES_256_CBC_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_RSA_WITH_AES_256_CBC_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_RSA_WITH_NULL_SHA : + case TLS_RSA_WITH_NULL_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA : + if (requirement == REQUIRES_NTRU) + return 1; + break; +#endif + + case TLS_PSK_WITH_AES_128_GCM_SHA256 : + case TLS_PSK_WITH_AES_256_GCM_SHA384 : + case TLS_PSK_WITH_AES_128_CBC_SHA256 : + case TLS_PSK_WITH_AES_256_CBC_SHA384 : + case TLS_PSK_WITH_AES_128_CBC_SHA : + case TLS_PSK_WITH_AES_256_CBC_SHA : + case TLS_PSK_WITH_NULL_SHA384 : + case TLS_PSK_WITH_NULL_SHA256 : + case TLS_PSK_WITH_NULL_SHA : + if (requirement == REQUIRES_PSK) + return 1; + break; + + case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 : + case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 : + case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 : + case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 : + case TLS_DHE_PSK_WITH_NULL_SHA384 : + case TLS_DHE_PSK_WITH_NULL_SHA256 : + if (requirement == REQUIRES_DHE) + return 1; + if (requirement == REQUIRES_PSK) + return 1; + break; + +#ifndef NO_RSA + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; + + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; + + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; + + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; + + case TLS_RSA_WITH_HC_128_MD5 : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_RSA_WITH_HC_128_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_RSA_WITH_HC_128_B2B256: + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_RSA_WITH_AES_128_CBC_B2B256: + case TLS_RSA_WITH_AES_256_CBC_B2B256: + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_RSA_WITH_RABBIT_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_RSA_WITH_AES_128_GCM_SHA256 : + case TLS_RSA_WITH_AES_256_GCM_SHA384 : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 : + case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; + + case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA : + case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA : + case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 : + case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA : + case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA : + case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 : + case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; +#endif + + default: + CYASSL_MSG("Unsupported cipher suite, CipherRequires"); + return 0; + } /* switch */ + } /* if ECC / Normal suites else */ + + return 0; + } + + #ifndef NO_CERTS /* Match names with wildcards, each wildcard can represent a single name component or fragment but not mulitple names, i.e., - *.z.com matches y.z.com but not x.y.z.com + *.z.com matches y.z.com but not x.y.z.com return 1 on success */ static int MatchDomainName(const char* pattern, int len, const char* str) @@ -3118,7 +3652,7 @@ static int CheckAltNames(DecodedCert* dCert, char* domain) match = 1; break; } - + altName = altName->next; } @@ -3500,7 +4034,7 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, if (doCrlLookup) { CYASSL_MSG("Doing Leaf CRL check"); ret = CheckCertCRL(ssl->ctx->cm->crl, &dCert); - + if (ret != 0) { CYASSL_MSG("\tCRL check not ok"); fatal = 0; @@ -3517,7 +4051,7 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, if (copyRet == MEMORY_E) fatal = 1; } -#endif +#endif #ifndef IGNORE_KEY_EXTENSIONS if (dCert.extKeyUsageSet) { @@ -3567,7 +4101,7 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, domain[0] = '\0'; if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer) { - if (MatchDomainName(dCert.subjectCN, dCert.subjectCNLen, + if (MatchDomainName(dCert.subjectCN, dCert.subjectCNLen, (char*)ssl->buffers.domainName.buffer) == 0) { CYASSL_MSG("DomainName match on common name failed"); if (CheckAltNames(&dCert, @@ -3600,7 +4134,7 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, else { XMEMCPY(ssl->buffers.peerRsaKey.buffer, dCert.publicKey, dCert.pubKeySize); - ssl->buffers.peerRsaKey.length = + ssl->buffers.peerRsaKey.length = dCert.pubKeySize; } #endif /* NO_RSA */ @@ -3642,7 +4176,7 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, else { XMEMCPY(ssl->buffers.peerEccDsaKey.buffer, dCert.publicKey, dCert.pubKeySize); - ssl->buffers.peerEccDsaKey.length = + ssl->buffers.peerEccDsaKey.length = dCert.pubKeySize; } #endif /* HAVE_ECC */ @@ -3657,12 +4191,10 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, FreeDecodedCert(&dCert); } - + if (anyError != 0 && ret == 0) ret = anyError; - if (ret == 0 && ssl->options.side == CYASSL_CLIENT_END) - ssl->options.serverState = SERVER_CERT_COMPLETE; if (ret != 0) { if (!ssl->options.verifyNone) { @@ -3688,7 +4220,7 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, #endif ok = ssl->verifyCallback(0, &store); if (ok) { - CYASSL_MSG("Verify callback overriding error!"); + CYASSL_MSG("Verify callback overriding error!"); ret = 0; } #ifdef SESSION_CERTS @@ -3738,6 +4270,15 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, } #endif + if (ssl->options.verifyNone && + (ret == CRL_MISSING || ret == CRL_CERT_REVOKED)) { + CYASSL_MSG("Ignoring CRL problem based on verify setting"); + ret = ssl->error = 0; + } + + if (ret == 0 && ssl->options.side == CYASSL_CLIENT_END) + ssl->options.serverState = SERVER_CERT_COMPLETE; + return ret; } @@ -3767,10 +4308,8 @@ static int DoHelloRequest(CYASSL* ssl, const byte* input, word32* inOutIdx, /* access beyond input + size should be checked against totalSz */ if ((word32) (*inOutIdx + ssl->specs.hash_size + padSz) > totalSz) - { - printf("line 3799\n"); - return INCOMPLETE_DATA; - } + return INCOMPLETE_DATA; + /* verify */ if (XMEMCMP(input + *inOutIdx, verify, ssl->specs.hash_size) != 0) { CYASSL_MSG(" hello_request verify mac error"); @@ -3811,9 +4350,8 @@ int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, word32 size, /* increment beyond input + size should be checked against totalSz */ if (*inOutIdx + size + ssl->keys.padSz > totalSz) - { printf("line 3842\n"); return INCOMPLETE_DATA; - } + /* force input exhaustion at ProcessReply consuming padSz */ *inOutIdx += size + ssl->keys.padSz; @@ -3860,9 +4398,8 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx, /* make sure can read the message */ if (*inOutIdx + size > totalSz) - {printf("line 3891\n"); return INCOMPLETE_DATA; - } + ret = HashInput(ssl, input + *inOutIdx, size); if (ret != 0) return ret; @@ -3918,7 +4455,7 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx, CYASSL_MSG("processing hello verify request"); ret = DoHelloVerifyRequest(ssl, input,inOutIdx, size); break; - + case server_hello: CYASSL_MSG("processing server hello"); ret = DoServerHello(ssl, input, inOutIdx, size); @@ -3947,7 +4484,7 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx, case server_hello_done: CYASSL_MSG("processing server hello done"); #ifdef CYASSL_CALLBACKS - if (ssl->hsInfoOn) + if (ssl->hsInfoOn) AddPacketName("ServerHelloDone", &ssl->handShakeInfo); if (ssl->toInfoOn) AddLateName("ServerHelloDone", &ssl->timeoutInfo); @@ -4035,7 +4572,7 @@ static INLINE int DtlsCheckWindow(DtlsState* state) if ((next > DTLS_SEQ_BITS) && (cur < next - DTLS_SEQ_BITS)) { return 0; } - else if ((cur < next) && (window & (1 << (next - cur - 1)))) { + else if ((cur < next) && (window & ((DtlsSeq)1 << (next - cur - 1)))) { return 0; } @@ -4061,7 +4598,7 @@ static INLINE int DtlsUpdateWindow(DtlsState* state) cur = state->curSeq; if (cur < *next) { - *window |= (1 << (*next - cur - 1)); + *window |= ((DtlsSeq)1 << (*next - cur - 1)); } else { *window <<= (1 + cur - *next); @@ -4112,9 +4649,8 @@ static int DoDtlsHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx, return PARSE_ERROR; if (*inOutIdx + fragSz > totalSz) - {printf("line 4143\n"); return INCOMPLETE_DATA; - } + /* Check the handshake sequence number first. If out of order, * add the current message to the list. If the message is in order, * but it is a fragment, add the current message to the list, then @@ -4170,9 +4706,9 @@ static int DoDtlsHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx, static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify) { if (verify) - return ssl->keys.peer_sequence_number++; + return ssl->keys.peer_sequence_number++; else - return ssl->keys.sequence_number++; + return ssl->keys.sequence_number++; } @@ -4197,6 +4733,7 @@ static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word16 sz) CYASSL_MSG("Encrypt ciphers not setup"); return ENCRYPT_ERROR; } + switch (ssl->specs.bulk_cipher_algorithm) { #ifdef BUILD_ARC4 case cyassl_rc4: @@ -4217,11 +4754,11 @@ static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word16 sz) #ifdef BUILD_AESGCM case cyassl_aes_gcm: { - byte additional[AES_BLOCK_SIZE]; + byte additional[AEAD_AUTH_DATA_SZ]; byte nonce[AEAD_NONCE_SZ]; const byte* additionalSrc = input - 5; - XMEMSET(additional, 0, AES_BLOCK_SIZE); + XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ); /* sequence number field is 64-bits, we only use 32-bits */ c32toa(GetSEQIncrement(ssl, 0), @@ -4230,8 +4767,10 @@ static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word16 sz) /* Store the type, version. Unfortunately, they are in * the input buffer ahead of the plaintext. */ #ifdef CYASSL_DTLS - if (ssl->options.dtls) + if (ssl->options.dtls) { + c16toa(ssl->keys.dtls_epoch, additional); additionalSrc -= DTLS_HANDSHAKE_EXTRA; + } #endif XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3); @@ -4248,8 +4787,8 @@ static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word16 sz) sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size, nonce, AEAD_NONCE_SZ, out + sz - ssl->specs.aead_mac_size, - ssl->specs.aead_mac_size, additional, - AEAD_AUTH_DATA_SZ); + ssl->specs.aead_mac_size, + additional, AEAD_AUTH_DATA_SZ); AeadIncrementExpIV(ssl); XMEMSET(nonce, 0, AEAD_NONCE_SZ); } @@ -4259,11 +4798,11 @@ static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word16 sz) #ifdef HAVE_AESCCM case cyassl_aes_ccm: { - byte additional[AES_BLOCK_SIZE]; + byte additional[AEAD_AUTH_DATA_SZ]; byte nonce[AEAD_NONCE_SZ]; const byte* additionalSrc = input - 5; - XMEMSET(additional, 0, AES_BLOCK_SIZE); + XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ); /* sequence number field is 64-bits, we only use 32-bits */ c32toa(GetSEQIncrement(ssl, 0), @@ -4296,9 +4835,8 @@ static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word16 sz) additional, AEAD_AUTH_DATA_SZ); AeadIncrementExpIV(ssl); XMEMSET(nonce, 0, AEAD_NONCE_SZ); - - break; } + break; #endif #ifdef HAVE_CAMELLIA @@ -4470,14 +5008,19 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, #ifdef BUILD_AESGCM case cyassl_aes_gcm: { - byte additional[AES_BLOCK_SIZE]; + byte additional[AEAD_AUTH_DATA_SZ]; byte nonce[AEAD_NONCE_SZ]; - XMEMSET(additional, 0, AES_BLOCK_SIZE); + XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ); /* sequence number field is 64-bits, we only use 32-bits */ c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET); - + + #ifdef CYASSL_DTLS + if (ssl->options.dtls) + c16toa(ssl->keys.dtls_state.curEpoch, additional); + #endif + additional[AEAD_TYPE_OFFSET] = ssl->curRL.type; additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor; additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor; @@ -4499,17 +5042,17 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, return VERIFY_MAC_ERROR; } XMEMSET(nonce, 0, AEAD_NONCE_SZ); - break; } + break; #endif #ifdef HAVE_AESCCM case cyassl_aes_ccm: { - byte additional[AES_BLOCK_SIZE]; + byte additional[AEAD_AUTH_DATA_SZ]; byte nonce[AEAD_NONCE_SZ]; - XMEMSET(additional, 0, AES_BLOCK_SIZE); + XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ); /* sequence number field is 64-bits, we only use 32-bits */ c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET); @@ -4540,8 +5083,8 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, return VERIFY_MAC_ERROR; } XMEMSET(nonce, 0, AEAD_NONCE_SZ); - break; } + break; #endif #ifdef HAVE_CAMELLIA @@ -4575,6 +5118,7 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, XMEMSET(tag, 0, 16); XMEMSET(cipher, 0, sizeof(cipher)); + XMEMSET(nonce, 0, AEAD_NONCE_SZ); XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE); XMEMSET(p, 0, CHACHA20_BLOCK_SIZE + padding2 + 16); @@ -5726,6 +6270,7 @@ static void BuildMD5_CertVerify(CYASSL* ssl, byte* digest) Md5Final(&ssl->hashMd5, digest); } + static void BuildSHA_CertVerify(CYASSL* ssl, byte* digest) { byte sha_result[SHA_DIGEST_SIZE]; @@ -5789,8 +6334,8 @@ static int BuildCertHashes(CYASSL* ssl, Hashes* hashes) } /* restore */ - ssl->hashMd5 = md5; - ssl->hashSha = sha; + ssl->hashMd5 = md5; + ssl->hashSha = sha; #endif if (IsAtLeastTLSv1_2(ssl)) { #ifndef NO_SHA256 @@ -5807,8 +6352,8 @@ static int BuildCertHashes(CYASSL* ssl, Hashes* hashes) #endif /* CYASSL_LEANPSK */ /* Build SSL Message, encrypted */ -static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz, - int type) +static int BuildMessage(CYASSL* ssl, byte* output, int outSz, + const byte* input, int inSz, int type) { #ifdef HAVE_TRUNCATED_HMAC word32 digestSz = min(ssl->specs.hash_size, @@ -5863,6 +6408,10 @@ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz, XMEMCPY(iv, ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ); } #endif + if (sz > (word32)outSz) { + CYASSL_MSG("Oops, want to write past output buffer size"); + return BUFFER_E; + } size = (word16)(sz - headerSz); /* include mac and digest */ AddRecordHeader(output, size, (byte)type, ssl); @@ -5931,6 +6480,7 @@ int SendFinished(CYASSL* ssl) Hashes* hashes; int ret; int headerSz = HANDSHAKE_HEADER_SZ; + int outputSz; #ifdef CYASSL_DTLS word32 sequence_number = ssl->keys.dtls_sequence_number; @@ -5939,7 +6489,8 @@ int SendFinished(CYASSL* ssl) /* check for available size */ - if ((ret = CheckAvailableSize(ssl, sizeof(input) + MAX_MSG_EXTRA)) != 0) + outputSz = sizeof(input) + MAX_MSG_EXTRA; + if ((ret = CheckAvailableSize(ssl, outputSz)) != 0) return ret; #ifdef CYASSL_DTLS @@ -5964,7 +6515,10 @@ int SendFinished(CYASSL* ssl) ssl->options.side == CYASSL_CLIENT_END ? client : server); if (ret != 0) return ret; - sendSz = BuildMessage(ssl, output, input, headerSz + finishedSz, handshake); + sendSz = BuildMessage(ssl, output, outputSz, input, headerSz + finishedSz, + handshake); + if (sendSz < 0) + return BUILD_MSG_ERROR; #ifdef CYASSL_DTLS if (ssl->options.dtls) { @@ -5973,9 +6527,6 @@ int SendFinished(CYASSL* ssl) } #endif - if (sendSz < 0) - return BUILD_MSG_ERROR; - if (!ssl->options.resuming) { #ifndef NO_SESSION_CACHE AddSession(ssl); /* just try */ @@ -6133,7 +6684,7 @@ int SendCertificateRequest(CYASSL* ssl) int sendSz; word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; - int typeTotal = 1; /* only rsa for now */ + int typeTotal = 1; /* only 1 for now */ int reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ; /* add auth later */ if (IsAtLeastTLSv1_2(ssl)) @@ -6161,7 +6712,15 @@ int SendCertificateRequest(CYASSL* ssl) /* write to output */ output[i++] = (byte)typeTotal; /* # of types */ - output[i++] = rsa_sign; +#ifdef HAVE_ECC + if (ssl->options.cipherSuite0 == ECC_BYTE && + ssl->specs.sig_algo == ecc_dsa_sa_algo) { + output[i++] = ecdsa_sign; + } else +#endif /* HAVE_ECC */ + { + output[i++] = rsa_sign; + } /* supported hash/sig */ if (IsAtLeastTLSv1_2(ssl)) { @@ -6208,7 +6767,8 @@ int SendData(CYASSL* ssl, const void* data, int sz) { int sent = 0, /* plainText size */ sendSz, - ret; + ret, + dtlsExtra = 0; if (ssl->error == WANT_WRITE) ssl->error = 0; @@ -6236,6 +6796,12 @@ int SendData(CYASSL* ssl, const void* data, int sz) } } +#ifdef CYASSL_DTLS + if (ssl->options.dtls) { + dtlsExtra = DTLS_RECORD_EXTRA; + } +#endif + for (;;) { #ifdef HAVE_MAX_FRAGMENT int len = min(sz - sent, min(ssl->max_fragment, OUTPUT_RECORD_SIZE)); @@ -6244,7 +6810,8 @@ int SendData(CYASSL* ssl, const void* data, int sz) #endif byte* out; byte* sendBuffer = (byte*)data + sent; /* may switch on comp */ - int buffSz = len; /* may switch on comp */ + int buffSz = len; /* may switch on comp */ + int outputSz; #ifdef HAVE_LIBZ byte comp[MAX_RECORD_SIZE + MAX_COMP_EXTRA]; #endif @@ -6259,8 +6826,8 @@ int SendData(CYASSL* ssl, const void* data, int sz) #endif /* check for available size */ - if ((ret = CheckAvailableSize(ssl, len + COMP_EXTRA + - MAX_MSG_EXTRA)) != 0) + outputSz = len + COMP_EXTRA + dtlsExtra + MAX_MSG_EXTRA; + if ((ret = CheckAvailableSize(ssl, outputSz)) != 0) return ssl->error = ret; /* get ouput buffer */ @@ -6276,8 +6843,10 @@ int SendData(CYASSL* ssl, const void* data, int sz) sendBuffer = comp; } #endif - sendSz = BuildMessage(ssl, out, sendBuffer, buffSz, + sendSz = BuildMessage(ssl, out, outputSz, sendBuffer, buffSz, application_data); + if (sendSz < 0) + return BUILD_MSG_ERROR; ssl->buffers.outputBuffer.length += sendSz; @@ -6370,6 +6939,7 @@ int SendAlert(CYASSL* ssl, int severity, int type) byte *output; int sendSz; int ret; + int outputSz; int dtlsExtra = 0; /* if sendalert is called again for nonbloking */ @@ -6386,8 +6956,8 @@ int SendAlert(CYASSL* ssl, int severity, int type) #endif /* check for available size */ - if ((ret = CheckAvailableSize(ssl, - ALERT_SIZE + MAX_MSG_EXTRA + dtlsExtra)) != 0) + outputSz = ALERT_SIZE + MAX_MSG_EXTRA + dtlsExtra; + if ((ret = CheckAvailableSize(ssl, outputSz)) != 0) return ret; /* get ouput buffer */ @@ -6405,7 +6975,7 @@ int SendAlert(CYASSL* ssl, int severity, int type) /* only send encrypted alert if handshake actually complete, otherwise other side may not be able to handle it */ if (ssl->keys.encryptionOn && ssl->options.handShakeState == HANDSHAKE_DONE) - sendSz = BuildMessage(ssl, output, input, ALERT_SIZE, alert); + sendSz = BuildMessage(ssl, output, outputSz, input, ALERT_SIZE, alert); else { AddRecordHeader(output, ALERT_SIZE, alert, ssl); @@ -6422,6 +6992,8 @@ int SendAlert(CYASSL* ssl, int severity, int type) sendSz += DTLS_RECORD_EXTRA; #endif } + if (sendSz < 0) + return BUILD_MSG_ERROR; #ifdef CYASSL_CALLBACKS if (ssl->hsInfoOn) @@ -6436,377 +7008,296 @@ int SendAlert(CYASSL* ssl, int severity, int type) return SendBuffered(ssl); } - - -void SetErrorString(int error, char* str) +const char* CyaSSL_ERR_reason_error_string(unsigned long e) { - const int max = CYASSL_MAX_ERROR_SZ; /* shorthand */ - #ifdef NO_ERROR_STRINGS - (void)error; - XSTRNCPY(str, "no support for error strings built in", max); + (void)e; + return "no support for error strings built in"; #else + int error = (int)e; + /* pass to CTaoCrypt */ if (error < MAX_CODE_E && error > MIN_CODE_E) { - CTaoCryptErrorString(error, str); - return; + return CTaoCryptGetErrorString(error); } switch (error) { case UNSUPPORTED_SUITE : - XSTRNCPY(str, "unsupported cipher suite", max); - break; + return "unsupported cipher suite"; case INPUT_CASE_ERROR : - XSTRNCPY(str, "input state error", max); - break; + return "input state error"; case PREFIX_ERROR : - XSTRNCPY(str, "bad index to key rounds", max); - break; + return "bad index to key rounds"; case MEMORY_ERROR : - XSTRNCPY(str, "out of memory", max); - break; + return "out of memory"; case VERIFY_FINISHED_ERROR : - XSTRNCPY(str, "verify problem on finished", max); - break; + return "verify problem on finished"; case VERIFY_MAC_ERROR : - XSTRNCPY(str, "verify mac problem", max); - break; + return "verify mac problem"; case PARSE_ERROR : - XSTRNCPY(str, "parse error on header", max); - break; + return "parse error on header"; case SIDE_ERROR : - XSTRNCPY(str, "wrong client/server type", max); - break; + return "wrong client/server type"; case NO_PEER_CERT : - XSTRNCPY(str, "peer didn't send cert", max); - break; + return "peer didn't send cert"; case UNKNOWN_HANDSHAKE_TYPE : - XSTRNCPY(str, "weird handshake type", max); - break; + return "weird handshake type"; case SOCKET_ERROR_E : - XSTRNCPY(str, "error state on socket", max); - break; + return "error state on socket"; case SOCKET_NODATA : - XSTRNCPY(str, "expected data, not there", max); - break; + return "expected data, not there"; case INCOMPLETE_DATA : - XSTRNCPY(str, "don't have enough data to complete task", max); - break; + return "don't have enough data to complete task"; case UNKNOWN_RECORD_TYPE : - XSTRNCPY(str, "unknown type in record hdr", max); - break; + return "unknown type in record hdr"; case DECRYPT_ERROR : - XSTRNCPY(str, "error during decryption", max); - break; + return "error during decryption"; case FATAL_ERROR : - XSTRNCPY(str, "revcd alert fatal error", max); - break; + return "revcd alert fatal error"; case ENCRYPT_ERROR : - XSTRNCPY(str, "error during encryption", max); - break; + return "error during encryption"; case FREAD_ERROR : - XSTRNCPY(str, "fread problem", max); - break; + return "fread problem"; case NO_PEER_KEY : - XSTRNCPY(str, "need peer's key", max); - break; + return "need peer's key"; case NO_PRIVATE_KEY : - XSTRNCPY(str, "need the private key", max); - break; + return "need the private key"; case NO_DH_PARAMS : - XSTRNCPY(str, "server missing DH params", max); - break; + return "server missing DH params"; case RSA_PRIVATE_ERROR : - XSTRNCPY(str, "error during rsa priv op", max); - break; + return "error during rsa priv op"; case MATCH_SUITE_ERROR : - XSTRNCPY(str, "can't match cipher suite", max); - break; + return "can't match cipher suite"; case BUILD_MSG_ERROR : - XSTRNCPY(str, "build message failure", max); - break; + return "build message failure"; case BAD_HELLO : - XSTRNCPY(str, "client hello malformed", max); - break; + return "client hello malformed"; case DOMAIN_NAME_MISMATCH : - XSTRNCPY(str, "peer subject name mismatch", max); - break; + return "peer subject name mismatch"; case WANT_READ : case SSL_ERROR_WANT_READ : - XSTRNCPY(str, "non-blocking socket wants data to be read", max); - break; + return "non-blocking socket wants data to be read"; case NOT_READY_ERROR : - XSTRNCPY(str, "handshake layer not ready yet, complete first", max); - break; + return "handshake layer not ready yet, complete first"; case PMS_VERSION_ERROR : - XSTRNCPY(str, "premaster secret version mismatch error", max); - break; + return "premaster secret version mismatch error"; case VERSION_ERROR : - XSTRNCPY(str, "record layer version error", max); - break; + return "record layer version error"; case WANT_WRITE : case SSL_ERROR_WANT_WRITE : - XSTRNCPY(str, "non-blocking socket write buffer full", max); - break; + return "non-blocking socket write buffer full"; case BUFFER_ERROR : - XSTRNCPY(str, "malformed buffer input error", max); - break; + return "malformed buffer input error"; case VERIFY_CERT_ERROR : - XSTRNCPY(str, "verify problem on certificate", max); - break; + return "verify problem on certificate"; case VERIFY_SIGN_ERROR : - XSTRNCPY(str, "verify problem based on signature", max); - break; + return "verify problem based on signature"; case CLIENT_ID_ERROR : - XSTRNCPY(str, "psk client identity error", max); - break; + return "psk client identity error"; case SERVER_HINT_ERROR: - XSTRNCPY(str, "psk server hint error", max); - break; + return "psk server hint error"; case PSK_KEY_ERROR: - XSTRNCPY(str, "psk key callback error", max); - break; + return "psk key callback error"; case NTRU_KEY_ERROR: - XSTRNCPY(str, "NTRU key error", max); - break; + return "NTRU key error"; case NTRU_DRBG_ERROR: - XSTRNCPY(str, "NTRU drbg error", max); - break; + return "NTRU drbg error"; case NTRU_ENCRYPT_ERROR: - XSTRNCPY(str, "NTRU encrypt error", max); - break; + return "NTRU encrypt error"; case NTRU_DECRYPT_ERROR: - XSTRNCPY(str, "NTRU decrypt error", max); - break; + return "NTRU decrypt error"; case ZLIB_INIT_ERROR: - XSTRNCPY(str, "zlib init error", max); - break; + return "zlib init error"; case ZLIB_COMPRESS_ERROR: - XSTRNCPY(str, "zlib compress error", max); - break; + return "zlib compress error"; case ZLIB_DECOMPRESS_ERROR: - XSTRNCPY(str, "zlib decompress error", max); - break; + return "zlib decompress error"; case GETTIME_ERROR: - XSTRNCPY(str, "gettimeofday() error", max); - break; + return "gettimeofday() error"; case GETITIMER_ERROR: - XSTRNCPY(str, "getitimer() error", max); - break; + return "getitimer() error"; case SIGACT_ERROR: - XSTRNCPY(str, "sigaction() error", max); - break; + return "sigaction() error"; case SETITIMER_ERROR: - XSTRNCPY(str, "setitimer() error", max); - break; + return "setitimer() error"; case LENGTH_ERROR: - XSTRNCPY(str, "record layer length error", max); - break; + return "record layer length error"; case PEER_KEY_ERROR: - XSTRNCPY(str, "cant decode peer key", max); - break; + return "cant decode peer key"; case ZERO_RETURN: case SSL_ERROR_ZERO_RETURN: - XSTRNCPY(str, "peer sent close notify alert", max); - break; + return "peer sent close notify alert"; case ECC_CURVETYPE_ERROR: - XSTRNCPY(str, "Bad ECC Curve Type or unsupported", max); - break; + return "Bad ECC Curve Type or unsupported"; case ECC_CURVE_ERROR: - XSTRNCPY(str, "Bad ECC Curve or unsupported", max); - break; + return "Bad ECC Curve or unsupported"; case ECC_PEERKEY_ERROR: - XSTRNCPY(str, "Bad ECC Peer Key", max); - break; + return "Bad ECC Peer Key"; case ECC_MAKEKEY_ERROR: - XSTRNCPY(str, "ECC Make Key failure", max); - break; + return "ECC Make Key failure"; case ECC_EXPORT_ERROR: - XSTRNCPY(str, "ECC Export Key failure", max); - break; + return "ECC Export Key failure"; case ECC_SHARED_ERROR: - XSTRNCPY(str, "ECC DHE shared failure", max); - break; + return "ECC DHE shared failure"; case NOT_CA_ERROR: - XSTRNCPY(str, "Not a CA by basic constraint error", max); - break; + return "Not a CA by basic constraint error"; case BAD_PATH_ERROR: - XSTRNCPY(str, "Bad path for opendir error", max); - break; + return "Bad path for opendir error"; case BAD_CERT_MANAGER_ERROR: - XSTRNCPY(str, "Bad Cert Manager error", max); - break; + return "Bad Cert Manager error"; case OCSP_CERT_REVOKED: - XSTRNCPY(str, "OCSP Cert revoked", max); - break; + return "OCSP Cert revoked"; case CRL_CERT_REVOKED: - XSTRNCPY(str, "CRL Cert revoked", max); - break; + return "CRL Cert revoked"; case CRL_MISSING: - XSTRNCPY(str, "CRL missing, not loaded", max); - break; + return "CRL missing, not loaded"; case MONITOR_RUNNING_E: - XSTRNCPY(str, "CRL monitor already running", max); - break; + return "CRL monitor already running"; case THREAD_CREATE_E: - XSTRNCPY(str, "Thread creation problem", max); - break; + return "Thread creation problem"; case OCSP_NEED_URL: - XSTRNCPY(str, "OCSP need URL", max); - break; + return "OCSP need URL"; case OCSP_CERT_UNKNOWN: - XSTRNCPY(str, "OCSP Cert unknown", max); - break; + return "OCSP Cert unknown"; case OCSP_LOOKUP_FAIL: - XSTRNCPY(str, "OCSP Responder lookup fail", max); - break; + return "OCSP Responder lookup fail"; case MAX_CHAIN_ERROR: - XSTRNCPY(str, "Maximum Chain Depth Exceeded", max); - break; + return "Maximum Chain Depth Exceeded"; case COOKIE_ERROR: - XSTRNCPY(str, "DTLS Cookie Error", max); - break; + return "DTLS Cookie Error"; case SEQUENCE_ERROR: - XSTRNCPY(str, "DTLS Sequence Error", max); - break; + return "DTLS Sequence Error"; case SUITES_ERROR: - XSTRNCPY(str, "Suites Pointer Error", max); - break; + return "Suites Pointer Error"; case SSL_NO_PEM_HEADER: - XSTRNCPY(str, "No PEM Header Error", max); - break; + return "No PEM Header Error"; case OUT_OF_ORDER_E: - XSTRNCPY(str, "Out of order message, fatal", max); - break; + return "Out of order message, fatal"; case BAD_KEA_TYPE_E: - XSTRNCPY(str, "Bad KEA type found", max); - break; + return "Bad KEA type found"; case SANITY_CIPHER_E: - XSTRNCPY(str, "Sanity check on ciphertext failed", max); - break; + return "Sanity check on ciphertext failed"; case RECV_OVERFLOW_E: - XSTRNCPY(str, "Receive callback returned more than requested", max); - break; + return "Receive callback returned more than requested"; case GEN_COOKIE_E: - XSTRNCPY(str, "Generate Cookie Error", max); - break; + return "Generate Cookie Error"; case NO_PEER_VERIFY: - XSTRNCPY(str, "Need peer certificate verify Error", max); - break; + return "Need peer certificate verify Error"; case FWRITE_ERROR: - XSTRNCPY(str, "fwrite Error", max); - break; + return "fwrite Error"; case CACHE_MATCH_ERROR: - XSTRNCPY(str, "Cache restore header match Error", max); - break; + return "Cache restore header match Error"; case UNKNOWN_SNI_HOST_NAME_E: - XSTRNCPY(str, "Unrecognized host name Error", max); - break; + return "Unrecognized host name Error"; case KEYUSE_SIGNATURE_E: - XSTRNCPY(str, "Key Use digitalSignature not set Error", max); - break; + return "Key Use digitalSignature not set Error"; case KEYUSE_ENCIPHER_E: - XSTRNCPY(str, "Key Use keyEncipherment not set Error", max); - break; + return "Key Use keyEncipherment not set Error"; case EXTKEYUSE_AUTH_E: - XSTRNCPY(str, "Ext Key Use server/client auth not set Error", max); - break; + return "Ext Key Use server/client auth not set Error"; + + case SEND_OOB_READ_E: + return "Send Callback Out of Bounds Read Error"; default : - XSTRNCPY(str, "unknown error number", max); + return "unknown error number"; } #endif /* NO_ERROR_STRINGS */ } +void SetErrorString(int error, char* str) +{ + XSTRNCPY(str, CyaSSL_ERR_reason_error_string(error), CYASSL_MAX_ERROR_SZ); +} /* be sure to add to cipher_name_idx too !!!! */ @@ -6848,6 +7339,34 @@ static const char* const cipher_names[] = "DHE-RSA-AES256-SHA", #endif +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + "DHE-PSK-AES256-GCM-SHA384", +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + "DHE-PSK-AES128-GCM-SHA256", +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384 + "PSK-AES256-GCM-SHA384", +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256 + "PSK-AES128-GCM-SHA256", +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + "DHE-PSK-AES256-CBC-SHA384", +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + "DHE-PSK-AES128-CBC-SHA256", +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384 + "PSK-AES256-CBC-SHA384", +#endif + #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256 "PSK-AES128-CBC-SHA256", #endif @@ -6860,6 +7379,22 @@ static const char* const cipher_names[] = "PSK-AES256-CBC-SHA", #endif +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM + "DHE-PSK-AES128-CCM", +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM + "DHE-PSK-AES256-CCM", +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM + "PSK-AES128-CCM", +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM + "PSK-AES256-CCM", +#endif + #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8 "PSK-AES128-CCM-8", #endif @@ -6868,6 +7403,18 @@ static const char* const cipher_names[] = "PSK-AES256-CCM-8", #endif +#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384 + "DHE-PSK-NULL-SHA384", +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256 + "DHE-PSK-NULL-SHA256", +#endif + +#ifdef BUILD_TLS_PSK_WITH_NULL_SHA384 + "PSK-NULL-SHA384", +#endif + #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256 "PSK-NULL-SHA256", #endif @@ -7172,6 +7719,34 @@ static int cipher_name_idx[] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA, #endif +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384 + TLS_PSK_WITH_AES_256_GCM_SHA384, +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256 + TLS_PSK_WITH_AES_128_GCM_SHA256, +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384 + TLS_PSK_WITH_AES_256_CBC_SHA384, +#endif + #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256 TLS_PSK_WITH_AES_128_CBC_SHA256, #endif @@ -7184,6 +7759,22 @@ static int cipher_name_idx[] = TLS_PSK_WITH_AES_256_CBC_SHA, #endif +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM + TLS_DHE_PSK_WITH_AES_128_CCM, +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM + TLS_DHE_PSK_WITH_AES_256_CCM, +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM + TLS_PSK_WITH_AES_128_CCM, +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM + TLS_PSK_WITH_AES_256_CCM, +#endif + #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8 TLS_PSK_WITH_AES_128_CCM_8, #endif @@ -7192,6 +7783,18 @@ static int cipher_name_idx[] = TLS_PSK_WITH_AES_256_CCM_8, #endif +#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384 + TLS_DHE_PSK_WITH_NULL_SHA384, +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256 + TLS_DHE_PSK_WITH_NULL_SHA256, +#endif + +#ifdef BUILD_TLS_PSK_WITH_NULL_SHA384 + TLS_PSK_WITH_NULL_SHA384, +#endif + #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256 TLS_PSK_WITH_NULL_SHA256, #endif @@ -7448,10 +8051,6 @@ static int cipher_name_idx[] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, #endif -#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_128_POLY1305_SHA256 - TLS_ECDHE_RSA_WITH_CHACHA20_128_POLY1305_SHA256, -#endif - #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_256_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_CHACHA20_256_POLY1305_SHA256, #endif @@ -7500,10 +8099,10 @@ int SetCipherList(Suites* s, const char* list) for (i = 0; i < suiteSz; i++) if (XSTRNCMP(name, cipher_names[i], sizeof(name)) == 0) { - if (XSTRSTR(name, "EC") || XSTRSTR(name, "CCM")) { - if (XSTRSTR(name, "CHACHA")) - s->suites[idx++] = CHACHA_BYTE; - else + if (XSTRSTR(name, "CHACHA")) + s->suites[idx++] = CHACHA_BYTE; + else if (XSTRSTR(name, "EC") || XSTRSTR(name, "CCM")) { + s->suites[idx++] = ECC_BYTE; /* ECC suite */ } else @@ -8028,7 +8627,7 @@ static void PickHashSigAlgo(CYASSL* ssl, /* tls extensions */ if ( (i - begin) < helloSz) { #ifdef HAVE_TLS_EXTENSIONS - if (IsTLS(ssl)) { + if (TLSX_SupportExtensions(ssl)) { int ret = 0; word16 totalExtSz; Suites clSuites; /* just for compatibility right now */ @@ -8098,6 +8697,31 @@ static void PickHashSigAlgo(CYASSL* ssl, } + /* Make sure client setup is valid for this suite, true on success */ + int VerifyClientSuite(CYASSL* ssl) + { + int havePSK = 0; + byte first = ssl->options.cipherSuite0; + byte second = ssl->options.cipherSuite; + + CYASSL_ENTER("VerifyClientSuite"); + + #ifndef NO_PSK + havePSK = ssl->options.havePSK; + #endif + + if (CipherRequires(first, second, REQUIRES_PSK)) { + CYASSL_MSG("Requires PSK"); + if (havePSK == 0) { + CYASSL_MSG("Don't have PSK"); + return 0; + } + } + + return 1; /* success */ + } + + #ifndef NO_CERTS /* just read in and ignore for now TODO: */ static int DoCertificateRequest(CYASSL* ssl, const byte* input, word32* @@ -8219,7 +8843,7 @@ static void PickHashSigAlgo(CYASSL* ssl, return 0; } #endif - #ifdef OPENSSL_EXTRA + #ifndef NO_DH if (ssl->specs.kea == diffie_hellman_kea) { /* p */ @@ -8285,7 +8909,7 @@ static void PickHashSigAlgo(CYASSL* ssl, XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + *inOutIdx, length); *inOutIdx += length; } /* dh_kea */ - #endif /* OPENSSL_EXTRA */ + #endif /* NO_DH */ #ifdef HAVE_ECC if (ssl->specs.kea == ecc_diffie_hellman_kea) @@ -8320,11 +8944,95 @@ static void PickHashSigAlgo(CYASSL* ssl, } #endif /* HAVE_ECC */ - #if defined(OPENSSL_EXTRA) || defined(HAVE_ECC) + #if !defined(NO_DH) && !defined(NO_PSK) + if (ssl->specs.kea == dhe_psk_kea) { + if ((*inOutIdx - begin) + OPAQUE16_LEN > size) + return BUFFER_ERROR; + + ato16(input + *inOutIdx, &length); + *inOutIdx += OPAQUE16_LEN; + + if ((*inOutIdx - begin) + length > size) + return BUFFER_ERROR; + + XMEMCPY(ssl->arrays->server_hint, input + *inOutIdx, + min(length, MAX_PSK_ID_LEN)); + + ssl->arrays->server_hint[min(length, MAX_PSK_ID_LEN - 1)] = 0; + *inOutIdx += length; + + /* p */ + if ((*inOutIdx - begin) + OPAQUE16_LEN > size) + return BUFFER_ERROR; + + ato16(input + *inOutIdx, &length); + *inOutIdx += OPAQUE16_LEN; + + if ((*inOutIdx - begin) + length > size) + return BUFFER_ERROR; + + ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap, + DYNAMIC_TYPE_DH); + + if (ssl->buffers.serverDH_P.buffer) + ssl->buffers.serverDH_P.length = length; + else + return MEMORY_ERROR; + + XMEMCPY(ssl->buffers.serverDH_P.buffer, input + *inOutIdx, length); + *inOutIdx += length; + + /* g */ + if ((*inOutIdx - begin) + OPAQUE16_LEN > size) + return BUFFER_ERROR; + + ato16(input + *inOutIdx, &length); + *inOutIdx += OPAQUE16_LEN; + + if ((*inOutIdx - begin) + length > size) + return BUFFER_ERROR; + + ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap, + DYNAMIC_TYPE_DH); + + if (ssl->buffers.serverDH_G.buffer) + ssl->buffers.serverDH_G.length = length; + else + return MEMORY_ERROR; + + XMEMCPY(ssl->buffers.serverDH_G.buffer, input + *inOutIdx, length); + *inOutIdx += length; + + /* pub */ + if ((*inOutIdx - begin) + OPAQUE16_LEN > size) + return BUFFER_ERROR; + + ato16(input + *inOutIdx, &length); + *inOutIdx += OPAQUE16_LEN; + + if ((*inOutIdx - begin) + length > size) + return BUFFER_ERROR; + + ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap, + DYNAMIC_TYPE_DH); + + if (ssl->buffers.serverDH_Pub.buffer) + ssl->buffers.serverDH_Pub.length = length; + else + return MEMORY_ERROR; + + XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + *inOutIdx, length); + *inOutIdx += length; + } + #endif /* !NO_DH || !NO_PSK */ + + #if !defined(NO_DH) || defined(HAVE_ECC) + if (ssl->specs.kea == ecc_diffie_hellman_kea || + ssl->specs.kea == diffie_hellman_kea) { #ifndef NO_OLD_TLS - Md5 md5; - Sha sha; + Md5 md5; + Sha sha; #endif #ifndef NO_SHA256 Sha256 sha256; @@ -8383,7 +9091,6 @@ static void PickHashSigAlgo(CYASSL* ssl, ShaUpdate(&sha, ssl->arrays->serverRandom, RAN_LEN); ShaUpdate(&sha, messageVerify, verifySz); ShaFinal(&sha, hash + MD5_DIGEST_SIZE); - #endif #ifndef NO_SHA256 @@ -8564,12 +9271,11 @@ static void PickHashSigAlgo(CYASSL* ssl, *inOutIdx += length; ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE; - - return 0; } -#else /* HAVE_OPENSSL or HAVE_ECC */ + return 0; +#else /* !NO_DH or HAVE_ECC */ return NOT_COMPILED_IN; /* not supported by build */ -#endif /* HAVE_OPENSSL or HAVE_ECC */ +#endif /* !NO_DH or HAVE_ECC */ } @@ -8630,7 +9336,7 @@ static void PickHashSigAlgo(CYASSL* ssl, } break; #endif - #ifdef OPENSSL_EXTRA + #ifndef NO_DH case diffie_hellman_kea: { buffer serverP = ssl->buffers.serverDH_P; @@ -8658,7 +9364,7 @@ static void PickHashSigAlgo(CYASSL* ssl, FreeDhKey(&key); } break; - #endif /* OPENSSL_EXTRA */ + #endif /* NO_DH */ #ifndef NO_PSK case psk_kea: { @@ -8689,6 +9395,73 @@ static void PickHashSigAlgo(CYASSL* ssl, } break; #endif /* NO_PSK */ + #if !defined(NO_DH) && !defined(NO_PSK) + case dhe_psk_kea: + { + byte* pms = ssl->arrays->preMasterSecret; + byte* es = encSecret; + buffer serverP = ssl->buffers.serverDH_P; + buffer serverG = ssl->buffers.serverDH_G; + buffer serverPub = ssl->buffers.serverDH_Pub; + byte priv[ENCRYPT_LEN]; + word32 privSz = 0; + word32 pubSz = 0; + word32 esSz = 0; + DhKey key; + + if (serverP.buffer == 0 || serverG.buffer == 0 || + serverPub.buffer == 0) + return NO_PEER_KEY; + + ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl, + ssl->arrays->server_hint, ssl->arrays->client_identity, + MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN); + if (ssl->arrays->psk_keySz == 0 || + ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) + return PSK_KEY_ERROR; + esSz = (word32)XSTRLEN(ssl->arrays->client_identity); + + if (esSz > MAX_PSK_ID_LEN) + return CLIENT_ID_ERROR; + c16toa((word16)esSz, es); + es += OPAQUE16_LEN; + XMEMCPY(es, ssl->arrays->client_identity, esSz); + es += esSz; + encSz = esSz + OPAQUE16_LEN; + + InitDhKey(&key); + ret = DhSetKey(&key, serverP.buffer, serverP.length, + serverG.buffer, serverG.length); + if (ret == 0) + /* for DH, encSecret is Yc, agree is pre-master */ + ret = DhGenerateKeyPair(&key, ssl->rng, priv, &privSz, + es + OPAQUE16_LEN, &pubSz); + if (ret == 0) + ret = DhAgree(&key, pms + OPAQUE16_LEN, + &ssl->arrays->preMasterSz, priv, privSz, + serverPub.buffer, serverPub.length); + FreeDhKey(&key); + if (ret != 0) + return ret; + + c16toa((word16)pubSz, es); + encSz += pubSz + OPAQUE16_LEN; + c16toa((word16)ssl->arrays->preMasterSz, pms); + ssl->arrays->preMasterSz += OPAQUE16_LEN; + pms += ssl->arrays->preMasterSz; + + /* make psk pre master secret */ + /* length of key + length 0s + length of key + key */ + c16toa((word16)ssl->arrays->psk_keySz, pms); + pms += OPAQUE16_LEN; + XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz); + ssl->arrays->preMasterSz += + ssl->arrays->psk_keySz + OPAQUE16_LEN; + XMEMSET(ssl->arrays->psk_key, 0, ssl->arrays->psk_keySz); + ssl->arrays->psk_keySz = 0; /* No further need */ + } + break; + #endif /* !NO_DH && !NO_PSK */ #ifdef HAVE_NTRU case ntru_kea: { @@ -8709,18 +9482,18 @@ static void PickHashSigAlgo(CYASSL* ssl, if (ssl->peerNtruKeyPresent == 0) return NO_PEER_KEY; - rc = crypto_drbg_instantiate(MAX_NTRU_BITS, cyasslStr, - sizeof(cyasslStr), GetEntropy, - &drbg); + rc = ntru_crypto_drbg_instantiate(MAX_NTRU_BITS, cyasslStr, + sizeof(cyasslStr), GetEntropy, + &drbg); if (rc != DRBG_OK) return NTRU_DRBG_ERROR; - rc = crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen, - ssl->peerNtruKey, - ssl->arrays->preMasterSz, - ssl->arrays->preMasterSecret, - &cipherLen, encSecret); - crypto_drbg_uninstantiate(drbg); + rc = ntru_crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen, + ssl->peerNtruKey, + ssl->arrays->preMasterSz, + ssl->arrays->preMasterSecret, + &cipherLen, encSecret); + ntru_crypto_drbg_uninstantiate(drbg); if (rc != NTRU_OK) return NTRU_ENCRYPT_ERROR; @@ -8788,7 +9561,8 @@ static void PickHashSigAlgo(CYASSL* ssl, if (ssl->options.tls || ssl->specs.kea == diffie_hellman_kea) tlsSz = 2; - if (ssl->specs.kea == ecc_diffie_hellman_kea) /* always off */ + if (ssl->specs.kea == ecc_diffie_hellman_kea || + ssl->specs.kea == dhe_psk_kea) /* always off */ tlsSz = 0; sendSz = encSz + tlsSz + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ; @@ -9215,8 +9989,7 @@ static void PickHashSigAlgo(CYASSL* ssl, /* last, extensions */ #ifdef HAVE_TLS_EXTENSIONS - if (IsTLS(ssl)) - TLSX_WriteResponse(ssl, output + idx); + TLSX_WriteResponse(ssl, output + idx); #endif ssl->buffers.outputBuffer.length += sendSz; @@ -9334,6 +10107,126 @@ static void PickHashSigAlgo(CYASSL* ssl, } #endif /*NO_PSK */ + #if !defined(NO_DH) && !defined(NO_PSK) + if (ssl->specs.kea == dhe_psk_kea) { + byte *output; + word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; + word32 hintLen; + int sendSz; + DhKey dhKey; + + if (ssl->buffers.serverDH_P.buffer == NULL || + ssl->buffers.serverDH_G.buffer == NULL) + return NO_DH_PARAMS; + + if (ssl->buffers.serverDH_Pub.buffer == NULL) { + ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC( + ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap, + DYNAMIC_TYPE_DH); + if (ssl->buffers.serverDH_Pub.buffer == NULL) + return MEMORY_E; + } + + if (ssl->buffers.serverDH_Priv.buffer == NULL) { + ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC( + ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap, + DYNAMIC_TYPE_DH); + if (ssl->buffers.serverDH_Priv.buffer == NULL) + return MEMORY_E; + } + + InitDhKey(&dhKey); + ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer, + ssl->buffers.serverDH_P.length, + ssl->buffers.serverDH_G.buffer, + ssl->buffers.serverDH_G.length); + if (ret == 0) + ret = DhGenerateKeyPair(&dhKey, ssl->rng, + ssl->buffers.serverDH_Priv.buffer, + &ssl->buffers.serverDH_Priv.length, + ssl->buffers.serverDH_Pub.buffer, + &ssl->buffers.serverDH_Pub.length); + FreeDhKey(&dhKey); + if (ret != 0) + return ret; + + length = LENGTH_SZ * 3 + /* p, g, pub */ + ssl->buffers.serverDH_P.length + + ssl->buffers.serverDH_G.length + + ssl->buffers.serverDH_Pub.length; + + /* include size part */ + hintLen = (word32)XSTRLEN(ssl->arrays->server_hint); + if (hintLen > MAX_PSK_ID_LEN) + return SERVER_HINT_ERROR; + length += hintLen + HINT_LEN_SZ; + sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ; + + #ifdef CYASSL_DTLS + if (ssl->options.dtls) { + sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; + idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; + } + #endif + /* check for available size */ + if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) + return ret; + + /* get ouput buffer */ + output = ssl->buffers.outputBuffer.buffer + + ssl->buffers.outputBuffer.length; + + AddHeaders(output, length, server_key_exchange, ssl); + + /* key data */ + c16toa((word16)hintLen, output + idx); + idx += HINT_LEN_SZ; + XMEMCPY(output + idx, ssl->arrays->server_hint, hintLen); + idx += hintLen; + + /* add p, g, pub */ + c16toa((word16)ssl->buffers.serverDH_P.length, output + idx); + idx += LENGTH_SZ; + XMEMCPY(output + idx, ssl->buffers.serverDH_P.buffer, + ssl->buffers.serverDH_P.length); + idx += ssl->buffers.serverDH_P.length; + + /* g */ + c16toa((word16)ssl->buffers.serverDH_G.length, output + idx); + idx += LENGTH_SZ; + XMEMCPY(output + idx, ssl->buffers.serverDH_G.buffer, + ssl->buffers.serverDH_G.length); + idx += ssl->buffers.serverDH_G.length; + + /* pub */ + c16toa((word16)ssl->buffers.serverDH_Pub.length, output + idx); + idx += LENGTH_SZ; + XMEMCPY(output + idx, ssl->buffers.serverDH_Pub.buffer, + ssl->buffers.serverDH_Pub.length); + idx += ssl->buffers.serverDH_Pub.length; + + ret = HashOutput(ssl, output, sendSz, 0); + + if (ret != 0) + return ret; + + #ifdef CYASSL_CALLBACKS + if (ssl->hsInfoOn) + AddPacketName("ServerKeyExchange", &ssl->handShakeInfo); + if (ssl->toInfoOn) + AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo, + output, sendSz, ssl->heap); + #endif + + ssl->buffers.outputBuffer.length += sendSz; + if (ssl->options.groupMessages) + ret = 0; + else + ret = SendBuffered(ssl); + ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE; + } + #endif /* !NO_DH && !NO_PSK */ + #ifdef HAVE_ECC if (ssl->specs.kea == ecc_diffie_hellman_kea) { @@ -9676,7 +10569,7 @@ static void PickHashSigAlgo(CYASSL* ssl, } #endif /* HAVE_ECC */ - #ifdef OPENSSL_EXTRA + #if !defined(NO_DH) && !defined(NO_RSA) if (ssl->specs.kea == diffie_hellman_kea) { byte *output; word32 length = 0, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; @@ -9957,447 +10850,12 @@ static void PickHashSigAlgo(CYASSL* ssl, ret = SendBuffered(ssl); ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE; } - #endif /* OPENSSL_EXTRA */ + #endif /* NO_DH */ return ret; } - /* cipher requirements */ - enum { - REQUIRES_RSA, - REQUIRES_DHE, - REQUIRES_ECC_DSA, - REQUIRES_ECC_STATIC, - REQUIRES_PSK, - REQUIRES_NTRU, - REQUIRES_RSA_SIG - }; - - - - /* Does this cipher suite (first, second) have the requirement - an ephemeral key exchange will still require the key for signing - the key exchange so ECHDE_RSA requires an rsa key thus rsa_kea */ - static int CipherRequires(byte first, byte second, int requirement) - { - - if (first == CHACHA_BYTE) { - - switch (second) { - - case TLS_ECDHE_RSA_WITH_CHACHA20_256_POLY1305_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - break; - } - } - - /* ECC extensions */ - if (first == ECC_BYTE) { - - switch (second) { -#ifndef NO_RSA - case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - break; - -#ifndef NO_DES3 - case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - break; -#endif - -#ifndef NO_RC4 - case TLS_ECDHE_RSA_WITH_RC4_128_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_ECDH_RSA_WITH_RC4_128_SHA : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - break; -#endif -#endif /* NO_RSA */ - -#ifndef NO_DES3 - case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA : - if (requirement == REQUIRES_ECC_DSA) - return 1; - break; - - case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - break; -#endif -#ifndef NO_RC4 - case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : - if (requirement == REQUIRES_ECC_DSA) - return 1; - break; - - case TLS_ECDH_ECDSA_WITH_RC4_128_SHA : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - break; -#endif -#ifndef NO_RSA - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - break; -#endif - - case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA : - if (requirement == REQUIRES_ECC_DSA) - return 1; - break; - - case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - break; - - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA : - if (requirement == REQUIRES_ECC_DSA) - return 1; - break; - - case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - break; - - case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 : - if (requirement == REQUIRES_ECC_DSA) - return 1; - break; - - case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 : - if (requirement == REQUIRES_ECC_DSA) - return 1; - break; - - case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - break; - - case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - break; - -#ifndef NO_RSA - case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - break; - - case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - break; - - case TLS_RSA_WITH_AES_128_CCM_8 : - case TLS_RSA_WITH_AES_256_CCM_8 : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - break; - - case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - break; - - case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 : - case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 : - if (requirement == REQUIRES_RSA_SIG) - return 1; - if (requirement == REQUIRES_ECC_STATIC) - return 1; - break; -#endif - - case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 : - case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 : - if (requirement == REQUIRES_ECC_DSA) - return 1; - break; - - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 : - case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : - if (requirement == REQUIRES_ECC_DSA) - return 1; - break; - - case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 : - case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 : - if (requirement == REQUIRES_ECC_DSA) - return 1; - if (requirement == REQUIRES_ECC_STATIC) - return 1; - break; - - case TLS_PSK_WITH_AES_128_CCM: - case TLS_PSK_WITH_AES_256_CCM: - case TLS_PSK_WITH_AES_128_CCM_8: - case TLS_PSK_WITH_AES_256_CCM_8: - if (requirement == REQUIRES_PSK) - return 1; - break; - - default: - CYASSL_MSG("Unsupported cipher suite, CipherRequires ECC"); - return 0; - } /* switch */ - } /* if */ - if (first != ECC_BYTE && first != CHACHA_BYTE) { /* normal suites */ - switch (second) { - -#ifndef NO_RSA - case SSL_RSA_WITH_RC4_128_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_NTRU_RSA_WITH_RC4_128_SHA : - if (requirement == REQUIRES_NTRU) - return 1; - break; - - case SSL_RSA_WITH_RC4_128_MD5 : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case SSL_RSA_WITH_3DES_EDE_CBC_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA : - if (requirement == REQUIRES_NTRU) - return 1; - break; - - case TLS_RSA_WITH_AES_128_CBC_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_RSA_WITH_AES_128_CBC_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA : - if (requirement == REQUIRES_NTRU) - return 1; - break; - - case TLS_RSA_WITH_AES_256_CBC_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_RSA_WITH_AES_256_CBC_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_RSA_WITH_NULL_SHA : - case TLS_RSA_WITH_NULL_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA : - if (requirement == REQUIRES_NTRU) - return 1; - break; -#endif - - case TLS_PSK_WITH_AES_128_CBC_SHA256 : - case TLS_PSK_WITH_AES_128_CBC_SHA : - case TLS_PSK_WITH_AES_256_CBC_SHA : - case TLS_PSK_WITH_NULL_SHA256 : - case TLS_PSK_WITH_NULL_SHA : - if (requirement == REQUIRES_PSK) - return 1; - break; - -#ifndef NO_RSA - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - break; - - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - break; - - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - break; - - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - break; - - case TLS_RSA_WITH_HC_128_MD5 : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_RSA_WITH_HC_128_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_RSA_WITH_HC_128_B2B256: - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_RSA_WITH_AES_128_CBC_B2B256: - case TLS_RSA_WITH_AES_256_CBC_B2B256: - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_RSA_WITH_RABBIT_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_RSA_WITH_AES_128_GCM_SHA256 : - case TLS_RSA_WITH_AES_256_GCM_SHA384 : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 : - case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - break; - - case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA : - case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA : - case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 : - case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - break; - - case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA : - case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA : - case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 : - case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - break; -#endif - - default: - CYASSL_MSG("Unsupported cipher suite, CipherRequires"); - return 0; - } /* switch */ - } /* if ECC / Normal suites else */ - - return 0; - } - - - /* Make sure client setup is valid for this suite, true on success */ - int VerifyClientSuite(CYASSL* ssl) - { - int havePSK = 0; - byte first = ssl->options.cipherSuite0; - byte second = ssl->options.cipherSuite; - - CYASSL_ENTER("VerifyClientSuite"); - - #ifndef NO_PSK - havePSK = ssl->options.havePSK; - #endif - - if (CipherRequires(first, second, REQUIRES_PSK)) { - CYASSL_MSG("Requires PSK"); - if (havePSK == 0) { - CYASSL_MSG("Don't have PSK"); - return 0; - } - } - - return 1; /* success */ - } - - /* Make sure server cert/key are valid for this suite, true on success */ static int VerifyServerSuite(CYASSL* ssl, word16 idx) { @@ -10883,7 +11341,7 @@ static void PickHashSigAlgo(CYASSL* ssl, /* tls extensions */ if ((i - begin) < helloSz) { #ifdef HAVE_TLS_EXTENSIONS - if (IsTLS(ssl)) { + if (TLSX_SupportExtensions(ssl)) { int ret = 0; #else if (IsAtLeastTLSv1_2(ssl)) { @@ -11260,6 +11718,7 @@ static void PickHashSigAlgo(CYASSL* ssl, (void)out; (void)input; (void)size; + (void)begin; if (ssl->options.side != CYASSL_SERVER_END) { CYASSL_MSG("Client received client keyexchange, attack?"); @@ -11444,7 +11903,7 @@ static void PickHashSigAlgo(CYASSL* ssl, if ((*inOutIdx - begin) + cipherLen > size) return BUFFER_ERROR; - if (NTRU_OK != crypto_ntru_decrypt( + if (NTRU_OK != ntru_crypto_ntru_decrypt( (word16) ssl->buffers.key.length, ssl->buffers.key.buffer, cipherLen, input + *inOutIdx, &plainLen, @@ -11506,7 +11965,7 @@ static void PickHashSigAlgo(CYASSL* ssl, } break; #endif /* HAVE_ECC */ - #ifdef OPENSSL_EXTRA + #ifndef NO_DH case diffie_hellman_kea: { word16 clientPubSz; @@ -11540,7 +11999,85 @@ static void PickHashSigAlgo(CYASSL* ssl, ret = MakeMasterSecret(ssl); } break; - #endif /* OPENSSL_EXTRA */ + #endif /* NO_DH */ + #if !defined(NO_DH) && !defined(NO_PSK) + case dhe_psk_kea: + { + byte* pms = ssl->arrays->preMasterSecret; + word16 clientSz; + DhKey dhKey; + + /* Read in the PSK hint */ + if ((*inOutIdx - begin) + OPAQUE16_LEN > size) + return BUFFER_ERROR; + + ato16(input + *inOutIdx, &clientSz); + *inOutIdx += OPAQUE16_LEN; + if (clientSz > MAX_PSK_ID_LEN) + return CLIENT_ID_ERROR; + + if ((*inOutIdx - begin) + clientSz > size) + return BUFFER_ERROR; + + XMEMCPY(ssl->arrays->client_identity, + input + *inOutIdx, clientSz); + *inOutIdx += clientSz; + ssl->arrays->client_identity[min(clientSz, MAX_PSK_ID_LEN-1)] = + 0; + + /* Read in the DHE business */ + if ((*inOutIdx - begin) + OPAQUE16_LEN > size) + return BUFFER_ERROR; + + ato16(input + *inOutIdx, &clientSz); + *inOutIdx += OPAQUE16_LEN; + + if ((*inOutIdx - begin) + clientSz > size) + return BUFFER_ERROR; + + InitDhKey(&dhKey); + ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer, + ssl->buffers.serverDH_P.length, + ssl->buffers.serverDH_G.buffer, + ssl->buffers.serverDH_G.length); + if (ret == 0) + ret = DhAgree(&dhKey, pms + OPAQUE16_LEN, + &ssl->arrays->preMasterSz, + ssl->buffers.serverDH_Priv.buffer, + ssl->buffers.serverDH_Priv.length, + input + *inOutIdx, clientSz); + FreeDhKey(&dhKey); + + *inOutIdx += clientSz; + c16toa((word16)ssl->arrays->preMasterSz, pms); + ssl->arrays->preMasterSz += OPAQUE16_LEN; + pms += ssl->arrays->preMasterSz; + + /* Use the PSK hint to look up the PSK and add it to the + * preMasterSecret here. */ + ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl, + ssl->arrays->client_identity, ssl->arrays->psk_key, + MAX_PSK_KEY_LEN); + + if (ssl->arrays->psk_keySz == 0 || + ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) + return PSK_KEY_ERROR; + + c16toa((word16) ssl->arrays->psk_keySz, pms); + pms += OPAQUE16_LEN; + + XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz); + ssl->arrays->preMasterSz += + ssl->arrays->psk_keySz + OPAQUE16_LEN; + if (ret == 0) + ret = MakeMasterSecret(ssl); + + /* No further need for PSK */ + XMEMSET(ssl->arrays->psk_key, 0, ssl->arrays->psk_keySz); + ssl->arrays->psk_keySz = 0; + } + break; + #endif /* !NO_DH && !NO_PSK */ default: { CYASSL_MSG("Bad kea type"); diff --git a/src/keys.c b/src/keys.c index 704a0eb04..510f825c0 100644 --- a/src/keys.c +++ b/src/keys.c @@ -39,6 +39,7 @@ int SetCipherSpecs(CYASSL* ssl) { +#ifndef NO_CYASSL_CLIENT if (ssl->options.side == CYASSL_CLIENT_END) { /* server side verified before SetCipherSpecs call */ if (VerifyClientSuite(ssl) != 1) { @@ -46,6 +47,7 @@ int SetCipherSpecs(CYASSL* ssl) return UNSUPPORTED_SUITE; } } +#endif /* NO_CYASSL_CLIENT */ /* Chacha extensions, 0xcc */ if (ssl->options.cipherSuite0 == CHACHA_BYTE) { @@ -81,7 +83,7 @@ int SetCipherSpecs(CYASSL* ssl) switch (ssl->options.cipherSuite) { #ifdef HAVE_ECC - + #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : ssl->specs.bulk_cipher_algorithm = cyassl_aes; @@ -737,6 +739,82 @@ int SetCipherSpecs(CYASSL* ssl) break; #endif +#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM + case TLS_PSK_WITH_AES_128_CCM : + ssl->specs.bulk_cipher_algorithm = cyassl_aes_ccm; + ssl->specs.cipher_type = aead; + ssl->specs.mac_algorithm = sha256_mac; + ssl->specs.kea = psk_kea; + ssl->specs.sig_algo = anonymous_sa_algo; + ssl->specs.hash_size = SHA256_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = AES_128_KEY_SIZE; + ssl->specs.block_size = AES_BLOCK_SIZE; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; + ssl->specs.aead_mac_size = AES_CCM_16_AUTH_SZ; + + ssl->options.usingPSK_cipher = 1; + break; +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM + case TLS_PSK_WITH_AES_256_CCM : + ssl->specs.bulk_cipher_algorithm = cyassl_aes_ccm; + ssl->specs.cipher_type = aead; + ssl->specs.mac_algorithm = sha256_mac; + ssl->specs.kea = psk_kea; + ssl->specs.sig_algo = anonymous_sa_algo; + ssl->specs.hash_size = SHA256_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = AES_256_KEY_SIZE; + ssl->specs.block_size = AES_BLOCK_SIZE; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; + ssl->specs.aead_mac_size = AES_CCM_16_AUTH_SZ; + + ssl->options.usingPSK_cipher = 1; + break; +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM + case TLS_DHE_PSK_WITH_AES_128_CCM : + ssl->specs.bulk_cipher_algorithm = cyassl_aes_ccm; + ssl->specs.cipher_type = aead; + ssl->specs.mac_algorithm = sha256_mac; + ssl->specs.kea = dhe_psk_kea; + ssl->specs.sig_algo = anonymous_sa_algo; + ssl->specs.hash_size = SHA256_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = AES_128_KEY_SIZE; + ssl->specs.block_size = AES_BLOCK_SIZE; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; + ssl->specs.aead_mac_size = AES_CCM_16_AUTH_SZ; + + ssl->options.usingPSK_cipher = 1; + break; +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM + case TLS_DHE_PSK_WITH_AES_256_CCM : + ssl->specs.bulk_cipher_algorithm = cyassl_aes_ccm; + ssl->specs.cipher_type = aead; + ssl->specs.mac_algorithm = sha256_mac; + ssl->specs.kea = dhe_psk_kea; + ssl->specs.sig_algo = anonymous_sa_algo; + ssl->specs.hash_size = SHA256_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = AES_256_KEY_SIZE; + ssl->specs.block_size = AES_BLOCK_SIZE; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; + ssl->specs.aead_mac_size = AES_CCM_16_AUTH_SZ; + + ssl->options.usingPSK_cipher = 1; + break; +#endif + default: CYASSL_MSG("Unsupported cipher suite, SetCipherSpecs ECC"); return UNSUPPORTED_SUITE; @@ -967,6 +1045,82 @@ int SetCipherSpecs(CYASSL* ssl) break; #endif +#ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256 + case TLS_PSK_WITH_AES_128_GCM_SHA256 : + ssl->specs.bulk_cipher_algorithm = cyassl_aes_gcm; + ssl->specs.cipher_type = aead; + ssl->specs.mac_algorithm = sha256_mac; + ssl->specs.kea = psk_kea; + ssl->specs.sig_algo = anonymous_sa_algo; + ssl->specs.hash_size = SHA256_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = AES_128_KEY_SIZE; + ssl->specs.block_size = AES_BLOCK_SIZE; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; + ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; + + ssl->options.usingPSK_cipher = 1; + break; +#endif + +#ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384 + case TLS_PSK_WITH_AES_256_GCM_SHA384 : + ssl->specs.bulk_cipher_algorithm = cyassl_aes_gcm; + ssl->specs.cipher_type = aead; + ssl->specs.mac_algorithm = sha384_mac; + ssl->specs.kea = psk_kea; + ssl->specs.sig_algo = anonymous_sa_algo; + ssl->specs.hash_size = SHA384_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = AES_256_KEY_SIZE; + ssl->specs.block_size = AES_BLOCK_SIZE; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; + ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; + + ssl->options.usingPSK_cipher = 1; + break; +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 : + ssl->specs.bulk_cipher_algorithm = cyassl_aes_gcm; + ssl->specs.cipher_type = aead; + ssl->specs.mac_algorithm = sha256_mac; + ssl->specs.kea = dhe_psk_kea; + ssl->specs.sig_algo = anonymous_sa_algo; + ssl->specs.hash_size = SHA256_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = AES_128_KEY_SIZE; + ssl->specs.block_size = AES_BLOCK_SIZE; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; + ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; + + ssl->options.usingPSK_cipher = 1; + break; +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 : + ssl->specs.bulk_cipher_algorithm = cyassl_aes_gcm; + ssl->specs.cipher_type = aead; + ssl->specs.mac_algorithm = sha384_mac; + ssl->specs.kea = dhe_psk_kea; + ssl->specs.sig_algo = anonymous_sa_algo; + ssl->specs.hash_size = SHA384_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = AES_256_KEY_SIZE; + ssl->specs.block_size = AES_BLOCK_SIZE; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; + ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; + + ssl->options.usingPSK_cipher = 1; + break; +#endif + #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256 case TLS_PSK_WITH_AES_128_CBC_SHA256 : ssl->specs.bulk_cipher_algorithm = cyassl_aes; @@ -985,6 +1139,60 @@ int SetCipherSpecs(CYASSL* ssl) break; #endif +#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384 + case TLS_PSK_WITH_AES_256_CBC_SHA384 : + ssl->specs.bulk_cipher_algorithm = cyassl_aes; + ssl->specs.cipher_type = block; + ssl->specs.mac_algorithm = sha384_mac; + ssl->specs.kea = psk_kea; + ssl->specs.sig_algo = anonymous_sa_algo; + ssl->specs.hash_size = SHA384_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = AES_256_KEY_SIZE; + ssl->specs.block_size = AES_BLOCK_SIZE; + ssl->specs.iv_size = AES_IV_SIZE; + + ssl->options.usingPSK_cipher = 1; + break; +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 : + ssl->specs.bulk_cipher_algorithm = cyassl_aes; + ssl->specs.cipher_type = block; + ssl->specs.mac_algorithm = sha256_mac; + ssl->specs.kea = dhe_psk_kea; + ssl->specs.sig_algo = anonymous_sa_algo; + ssl->specs.hash_size = SHA256_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = AES_128_KEY_SIZE; + ssl->specs.block_size = AES_BLOCK_SIZE; + ssl->specs.iv_size = AES_IV_SIZE; + + ssl->options.usingPSK_cipher = 1; + break; +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 : + ssl->specs.bulk_cipher_algorithm = cyassl_aes; + ssl->specs.cipher_type = block; + ssl->specs.mac_algorithm = sha384_mac; + ssl->specs.kea = dhe_psk_kea; + ssl->specs.sig_algo = anonymous_sa_algo; + ssl->specs.hash_size = SHA384_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = AES_256_KEY_SIZE; + ssl->specs.block_size = AES_BLOCK_SIZE; + ssl->specs.iv_size = AES_IV_SIZE; + + ssl->options.usingPSK_cipher = 1; + break; +#endif + #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA case TLS_PSK_WITH_AES_128_CBC_SHA : ssl->specs.bulk_cipher_algorithm = cyassl_aes; @@ -1039,6 +1247,24 @@ int SetCipherSpecs(CYASSL* ssl) break; #endif +#ifdef BUILD_TLS_PSK_WITH_NULL_SHA384 + case TLS_PSK_WITH_NULL_SHA384 : + ssl->specs.bulk_cipher_algorithm = cyassl_cipher_null; + ssl->specs.cipher_type = stream; + ssl->specs.mac_algorithm = sha384_mac; + ssl->specs.kea = psk_kea; + ssl->specs.sig_algo = anonymous_sa_algo; + ssl->specs.hash_size = SHA384_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = 0; + ssl->specs.block_size = 0; + ssl->specs.iv_size = 0; + + ssl->options.usingPSK_cipher = 1; + break; +#endif + #ifdef BUILD_TLS_PSK_WITH_NULL_SHA case TLS_PSK_WITH_NULL_SHA : ssl->specs.bulk_cipher_algorithm = cyassl_cipher_null; @@ -1057,6 +1283,42 @@ int SetCipherSpecs(CYASSL* ssl) break; #endif +#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256 + case TLS_DHE_PSK_WITH_NULL_SHA256 : + ssl->specs.bulk_cipher_algorithm = cyassl_cipher_null; + ssl->specs.cipher_type = stream; + ssl->specs.mac_algorithm = sha256_mac; + ssl->specs.kea = dhe_psk_kea; + ssl->specs.sig_algo = anonymous_sa_algo; + ssl->specs.hash_size = SHA256_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = 0; + ssl->specs.block_size = 0; + ssl->specs.iv_size = 0; + + ssl->options.usingPSK_cipher = 1; + break; +#endif + +#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384 + case TLS_DHE_PSK_WITH_NULL_SHA384 : + ssl->specs.bulk_cipher_algorithm = cyassl_cipher_null; + ssl->specs.cipher_type = stream; + ssl->specs.mac_algorithm = sha384_mac; + ssl->specs.kea = dhe_psk_kea; + ssl->specs.sig_algo = anonymous_sa_algo; + ssl->specs.hash_size = SHA384_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = 0; + ssl->specs.block_size = 0; + ssl->specs.iv_size = 0; + + ssl->options.usingPSK_cipher = 1; + break; +#endif + #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 : ssl->specs.bulk_cipher_algorithm = cyassl_aes; @@ -1299,10 +1561,6 @@ int SetCipherSpecs(CYASSL* ssl) break; #endif - - - - #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA : ssl->specs.bulk_cipher_algorithm = cyassl_camellia; @@ -1932,9 +2190,7 @@ int StoreKeys(CYASSL* ssl, const byte* keyData) /* Initialize the AES-GCM/CCM explicit IV to a zero. */ XMEMSET(ssl->keys.aead_exp_IV, 0, AEAD_EXP_IV_SZ); } - #endif - return SetKeys(&ssl->encrypt, &ssl->decrypt, &ssl->keys, &ssl->specs, ssl->options.side, ssl->heap, devId); @@ -2040,8 +2296,8 @@ static int MakeSslMasterSecret(CYASSL* ssl) XMEMCPY(md5Input, ssl->arrays->preMasterSecret, pmsSz); for (i = 0; i < MASTER_ROUNDS; ++i) { - byte prefix[PREFIX]; - if (!SetPrefix(prefix, i)) { + byte prefix[KEY_PREFIX]; /* only need PREFIX bytes but static */ + if (!SetPrefix(prefix, i)) { /* analysis thinks will overrun */ return PREFIX_ERROR; } diff --git a/src/sniffer.c b/src/sniffer.c index 3596fc4e9..2c6860c83 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -1594,12 +1594,6 @@ static int Decrypt(SSL* ssl, byte* output, const byte* input, word32 sz) break; #endif - #ifdef BUILD_CHACHA - case cyassl_chacha: - Chacha_Process(ssl->decrypt.chacha, output, input, sz); - break; - #endif - #ifdef HAVE_CAMELLIA case cyassl_camellia: CamelliaCbcDecrypt(ssl->decrypt.cam, output, input, sz); diff --git a/src/ssl.c b/src/ssl.c index 3e9492b80..010116ad2 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -365,8 +365,8 @@ int CyaSSL_GetObjectSize(void) } #endif -/* XXX should be NO_DH */ -#ifndef NO_CERTS + +#ifndef NO_DH /* server Diffie-Hellman parameters, SSL_SUCCESS on ok */ int CyaSSL_SetTmpDH(CYASSL* ssl, const unsigned char* p, int pSz, const unsigned char* g, int gSz) @@ -418,7 +418,7 @@ int CyaSSL_SetTmpDH(CYASSL* ssl, const unsigned char* p, int pSz, CYASSL_LEAVE("CyaSSL_SetTmpDH", 0); return SSL_SUCCESS; } -#endif /* !NO_CERTS */ +#endif /* !NO_DH */ int CyaSSL_write(CYASSL* ssl, const void* data, int sz) @@ -1774,7 +1774,7 @@ int CyaSSL_Init(void) { /* remove encrypted header if there */ char encHeader[] = "Proc-Type"; - char* line = XSTRNSTR((char*)buff, encHeader, PEM_LINE_LEN); + char* line = XSTRNSTR(headerEnd, encHeader, PEM_LINE_LEN); if (line) { char* newline; char* finish; @@ -1908,6 +1908,9 @@ int CyaSSL_Init(void) && format != SSL_FILETYPE_RAW) return SSL_BAD_FILETYPE; + if (ctx == NULL && ssl == NULL) + return BAD_FUNC_ARG; + if (type == CA_TYPE) dynamicType = DYNAMIC_TYPE_CA; else if (type == CERT_TYPE) @@ -1927,6 +1930,8 @@ int CyaSSL_Init(void) if (userChain && type == CERT_TYPE && info.consumed < sz) { byte staticBuffer[FILE_BUFFER_SIZE]; /* tmp chain buffer */ byte* chainBuffer = staticBuffer; + byte* shrinked = NULL; /* shrinked to size chainBuffer + * or staticBuffer */ int dynamicBuffer = 0; word32 bufferSz = sizeof(staticBuffer); long consumed = info.consumed; @@ -1989,22 +1994,30 @@ int CyaSSL_Init(void) } CYASSL_MSG("Finished Processing Cert Chain"); - if (ctx == NULL) { - CYASSL_MSG("certChain needs context"); - if (dynamicBuffer) - XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE); - XFREE(der.buffer, heap, dynamicType); - return BAD_FUNC_ARG; - } - ctx->certChain.buffer = (byte*)XMALLOC(idx, heap, - dynamicType); - if (ctx->certChain.buffer) { - ctx->certChain.length = idx; - XMEMCPY(ctx->certChain.buffer, chainBuffer, idx); + /* only retain actual size used */ + shrinked = (byte*)XMALLOC(idx, heap, dynamicType); + if (shrinked) { + if (ssl) { + if (ssl->buffers.certChain.buffer && + ssl->buffers.weOwnCertChain) { + XFREE(ssl->buffers.certChain.buffer, heap, + dynamicType); + } + ssl->buffers.certChain.buffer = shrinked; + ssl->buffers.certChain.length = idx; + XMEMCPY(ssl->buffers.certChain.buffer, chainBuffer,idx); + ssl->buffers.weOwnCertChain = 1; + } else if (ctx) { + if (ctx->certChain.buffer) + XFREE(ctx->certChain.buffer, heap, dynamicType); + ctx->certChain.buffer = shrinked; + ctx->certChain.length = idx; + XMEMCPY(ctx->certChain.buffer, chainBuffer, idx); + } } if (dynamicBuffer) XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE); - if (ctx->certChain.buffer == NULL) { + if (shrinked == NULL) { XFREE(der.buffer, heap, dynamicType); return MEMORY_E; } @@ -3095,42 +3108,7 @@ int CyaSSL_CTX_use_certificate_chain_file(CYASSL_CTX* ctx, const char* file) } -#ifdef OPENSSL_EXTRA -/* put SSL type in extra for now, not very common */ - -int CyaSSL_use_certificate_file(CYASSL* ssl, const char* file, int format) -{ - CYASSL_ENTER("CyaSSL_use_certificate_file"); - if (ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 0, NULL) - == SSL_SUCCESS) - return SSL_SUCCESS; - - return SSL_FAILURE; -} - - -int CyaSSL_use_PrivateKey_file(CYASSL* ssl, const char* file, int format) -{ - CYASSL_ENTER("CyaSSL_use_PrivateKey_file"); - if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE, ssl, 0, NULL) - == SSL_SUCCESS) - return SSL_SUCCESS; - - return SSL_FAILURE; -} - - -int CyaSSL_use_certificate_chain_file(CYASSL* ssl, const char* file) -{ - /* procces up to MAX_CHAIN_DEPTH plus subject cert */ - CYASSL_ENTER("CyaSSL_use_certificate_chain_file"); - if (ProcessFile(ssl->ctx, file, SSL_FILETYPE_PEM, CERT_TYPE, ssl, 1, NULL) - == SSL_SUCCESS) - return SSL_SUCCESS; - - return SSL_FAILURE; -} - +#ifndef NO_DH /* server wrapper for ctx or ssl Diffie-Hellman parameters */ static int CyaSSL_SetTmpDH_buffer_wrapper(CYASSL_CTX* ctx, CYASSL* ssl, @@ -3175,6 +3153,7 @@ static int CyaSSL_SetTmpDH_buffer_wrapper(CYASSL_CTX* ctx, CYASSL* ssl, return ret; } + /* server Diffie-Hellman parameters, SSL_SUCCESS on ok */ int CyaSSL_SetTmpDH_buffer(CYASSL* ssl, const unsigned char* buf, long sz, int format) @@ -3191,34 +3170,6 @@ int CyaSSL_CTX_SetTmpDH_buffer(CYASSL_CTX* ctx, const unsigned char* buf, } -#ifdef HAVE_ECC - -/* Set Temp CTX EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */ -int CyaSSL_CTX_SetTmpEC_DHE_Sz(CYASSL_CTX* ctx, word16 sz) -{ - if (ctx == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE) - return BAD_FUNC_ARG; - - ctx->eccTempKeySz = sz; - - return SSL_SUCCESS; -} - - -/* Set Temp SSL EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */ -int CyaSSL_SetTmpEC_DHE_Sz(CYASSL* ssl, word16 sz) -{ - if (ssl == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE) - return BAD_FUNC_ARG; - - ssl->eccTempKeySz = sz; - - return SSL_SUCCESS; -} - -#endif /* HAVE_ECC */ - - /* server Diffie-Hellman parameters */ static int CyaSSL_SetTmpDH_file_wrapper(CYASSL_CTX* ctx, CYASSL* ssl, const char* fname, int format) @@ -3278,6 +3229,108 @@ int CyaSSL_CTX_SetTmpDH_file(CYASSL_CTX* ctx, const char* fname, int format) } + /* server ctx Diffie-Hellman parameters, SSL_SUCCESS on ok */ + int CyaSSL_CTX_SetTmpDH(CYASSL_CTX* ctx, const unsigned char* p, int pSz, + const unsigned char* g, int gSz) + { + CYASSL_ENTER("CyaSSL_CTX_SetTmpDH"); + if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG; + + XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH); + XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH); + + ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap,DYNAMIC_TYPE_DH); + if (ctx->serverDH_P.buffer == NULL) + return MEMORY_E; + + ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap,DYNAMIC_TYPE_DH); + if (ctx->serverDH_G.buffer == NULL) { + XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH); + return MEMORY_E; + } + + ctx->serverDH_P.length = pSz; + ctx->serverDH_G.length = gSz; + + XMEMCPY(ctx->serverDH_P.buffer, p, pSz); + XMEMCPY(ctx->serverDH_G.buffer, g, gSz); + + ctx->haveDH = 1; + + CYASSL_LEAVE("CyaSSL_CTX_SetTmpDH", 0); + return SSL_SUCCESS; + } +#endif /* NO_DH */ + + +#ifdef OPENSSL_EXTRA +/* put SSL type in extra for now, not very common */ + +int CyaSSL_use_certificate_file(CYASSL* ssl, const char* file, int format) +{ + CYASSL_ENTER("CyaSSL_use_certificate_file"); + if (ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 0, NULL) + == SSL_SUCCESS) + return SSL_SUCCESS; + + return SSL_FAILURE; +} + + +int CyaSSL_use_PrivateKey_file(CYASSL* ssl, const char* file, int format) +{ + CYASSL_ENTER("CyaSSL_use_PrivateKey_file"); + if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE, ssl, 0, NULL) + == SSL_SUCCESS) + return SSL_SUCCESS; + + return SSL_FAILURE; +} + + +int CyaSSL_use_certificate_chain_file(CYASSL* ssl, const char* file) +{ + /* procces up to MAX_CHAIN_DEPTH plus subject cert */ + CYASSL_ENTER("CyaSSL_use_certificate_chain_file"); + if (ProcessFile(ssl->ctx, file, SSL_FILETYPE_PEM, CERT_TYPE, ssl, 1, NULL) + == SSL_SUCCESS) + return SSL_SUCCESS; + + return SSL_FAILURE; +} + + + +#ifdef HAVE_ECC + +/* Set Temp CTX EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */ +int CyaSSL_CTX_SetTmpEC_DHE_Sz(CYASSL_CTX* ctx, word16 sz) +{ + if (ctx == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE) + return BAD_FUNC_ARG; + + ctx->eccTempKeySz = sz; + + return SSL_SUCCESS; +} + + +/* Set Temp SSL EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */ +int CyaSSL_SetTmpEC_DHE_Sz(CYASSL* ssl, word16 sz) +{ + if (ssl == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE) + return BAD_FUNC_ARG; + + ssl->eccTempKeySz = sz; + + return SSL_SUCCESS; +} + +#endif /* HAVE_ECC */ + + + + int CyaSSL_CTX_use_RSAPrivateKey_file(CYASSL_CTX* ctx,const char* file, int format) { @@ -5869,6 +5922,14 @@ int CyaSSL_set_compression(CYASSL* ssl) ssl->buffers.certificate.buffer = NULL; } + if (ssl->buffers.weOwnCertChain) { + CYASSL_MSG("Unloading cert chain"); + XFREE(ssl->buffers.certChain.buffer, ssl->heap,DYNAMIC_TYPE_CERT); + ssl->buffers.weOwnCertChain = 0; + ssl->buffers.certChain.length = 0; + ssl->buffers.certChain.buffer = NULL; + } + if (ssl->buffers.weOwnKey) { CYASSL_MSG("Unloading key"); XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY); @@ -8304,6 +8365,7 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format) CYASSL_ENTER("SSL_CIPHER_get_name"); #ifndef NO_ERROR_STRINGS if (cipher) { +#if defined(HAVE_CHACHA) if (cipher->ssl->options.cipherSuite0 == CHACHA_BYTE) { /* ChaCha suites */ switch (cipher->ssl->options.cipherSuite) { @@ -8315,10 +8377,16 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format) #endif } } -#ifdef HAVE_ECC +#endif + +#if defined(HAVE_ECC) || defined(HAVE_AESCCM) + /* Awkwardly, the ECC cipher suites use the ECC_BYTE as expected, + * but the AES-CCM cipher suites also use it, even the ones that + * aren't ECC. */ if (cipher->ssl->options.cipherSuite0 == ECC_BYTE) { /* ECC suites */ switch (cipher->ssl->options.cipherSuite) { +#ifdef HAVE_ECC #ifndef NO_RSA case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; @@ -8385,7 +8453,6 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format) #ifndef NO_RSA case TLS_ECDH_RSA_WITH_RC4_128_SHA : return "TLS_ECDH_RSA_WITH_RC4_128_SHA"; - #endif case TLS_ECDH_ECDSA_WITH_RC4_128_SHA : return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"; @@ -8422,6 +8489,7 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format) case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 : return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"; #endif +#endif /* HAVE_ECC */ #ifdef HAVE_AESCCM #ifndef NO_RSA @@ -8430,10 +8498,26 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format) case TLS_RSA_WITH_AES_256_CCM_8 : return "TLS_RSA_WITH_AES_256_CCM_8"; #endif + #ifndef NO_PSK + case TLS_PSK_WITH_AES_128_CCM_8 : + return "TLS_PSK_WITH_AES_128_CCM_8"; + case TLS_PSK_WITH_AES_256_CCM_8 : + return "TLS_PSK_WITH_AES_256_CCM_8"; + case TLS_PSK_WITH_AES_128_CCM : + return "TLS_PSK_WITH_AES_128_CCM"; + case TLS_PSK_WITH_AES_256_CCM : + return "TLS_PSK_WITH_AES_256_CCM"; + case TLS_DHE_PSK_WITH_AES_128_CCM : + return "TLS_DHE_PSK_WITH_AES_128_CCM"; + case TLS_DHE_PSK_WITH_AES_256_CCM : + return "TLS_DHE_PSK_WITH_AES_256_CCM"; + #endif + #ifdef HAVE_ECC case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: return "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8"; case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 : return "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8"; + #endif #endif default: @@ -8483,8 +8567,6 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format) return "TLS_RSA_WITH_NULL_SHA256"; #endif /* NO_RSA */ #ifndef NO_PSK - case TLS_PSK_WITH_AES_128_CBC_SHA256 : - return "TLS_PSK_WITH_AES_128_CBC_SHA256"; #ifndef NO_SHA case TLS_PSK_WITH_AES_128_CBC_SHA : return "TLS_PSK_WITH_AES_128_CBC_SHA"; @@ -8492,14 +8574,36 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format) return "TLS_PSK_WITH_AES_256_CBC_SHA"; #endif #ifndef NO_SHA256 - #ifdef HAVE_AESCCM - case TLS_PSK_WITH_AES_128_CCM_8 : - return "TLS_PSK_WITH_AES_128_CCM_8"; - case TLS_PSK_WITH_AES_256_CCM_8 : - return "TLS_PSK_WITH_AES_256_CCM_8"; - #endif + case TLS_PSK_WITH_AES_128_CBC_SHA256 : + return "TLS_PSK_WITH_AES_128_CBC_SHA256"; case TLS_PSK_WITH_NULL_SHA256 : return "TLS_PSK_WITH_NULL_SHA256"; + case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 : + return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"; + case TLS_DHE_PSK_WITH_NULL_SHA256 : + return "TLS_DHE_PSK_WITH_NULL_SHA256"; + #ifdef HAVE_AESGCM + case TLS_PSK_WITH_AES_128_GCM_SHA256 : + return "TLS_PSK_WITH_AES_128_GCM_SHA256"; + case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 : + return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"; + #endif + #endif + #ifdef CYASSL_SHA384 + case TLS_PSK_WITH_AES_256_CBC_SHA384 : + return "TLS_PSK_WITH_AES_256_CBC_SHA384"; + case TLS_PSK_WITH_NULL_SHA384 : + return "TLS_PSK_WITH_NULL_SHA384"; + case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 : + return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"; + case TLS_DHE_PSK_WITH_NULL_SHA384 : + return "TLS_DHE_PSK_WITH_NULL_SHA384"; + #ifdef HAVE_AESGCM + case TLS_PSK_WITH_AES_256_GCM_SHA384 : + return "TLS_PSK_WITH_AES_256_GCM_SHA384"; + case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 : + return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"; + #endif #endif #ifndef NO_SHA case TLS_PSK_WITH_NULL_SHA : @@ -8598,40 +8702,6 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format) #ifdef OPENSSL_EXTRA -/* XXX shuld be NO_DH */ -#ifndef NO_CERTS - /* server ctx Diffie-Hellman parameters, SSL_SUCCESS on ok */ - int CyaSSL_CTX_SetTmpDH(CYASSL_CTX* ctx, const unsigned char* p, int pSz, - const unsigned char* g, int gSz) - { - CYASSL_ENTER("CyaSSL_CTX_SetTmpDH"); - if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG; - - XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH); - XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH); - - ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap,DYNAMIC_TYPE_DH); - if (ctx->serverDH_P.buffer == NULL) - return MEMORY_E; - - ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap,DYNAMIC_TYPE_DH); - if (ctx->serverDH_G.buffer == NULL) { - XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH); - return MEMORY_E; - } - - ctx->serverDH_P.length = pSz; - ctx->serverDH_G.length = gSz; - - XMEMCPY(ctx->serverDH_P.buffer, p, pSz); - XMEMCPY(ctx->serverDH_G.buffer, g, gSz); - - ctx->haveDH = 1; - - CYASSL_LEAVE("CyaSSL_CTX_SetTmpDH", 0); - return SSL_SUCCESS; - } -#endif /* !NO_CERTS */ char* CyaSSL_CIPHER_description(CYASSL_CIPHER* cipher, char* in, int len) @@ -8915,7 +8985,7 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format) NULL, DYNAMIC_TYPE_CERT); if (derCert.buffer != NULL) { derCert.length = x509->derCert.length; - // AddCA() frees the buffer. + /* AddCA() frees the buffer. */ XMEMCPY(derCert.buffer, x509->derCert.buffer, x509->derCert.length); result = AddCA(store->cm, derCert, CYASSL_USER_CA, 1); @@ -10027,6 +10097,8 @@ static int initGlobalRNG = 0; } + #ifndef NO_DH + static void InitCyaSSL_DH(CYASSL_DH* dh) { if (dh) { @@ -10265,6 +10337,7 @@ static int initGlobalRNG = 0; CYASSL_MSG("CyaSSL_compute_key success"); return (int)keySz; } + #endif /* NO_DH */ #ifndef NO_DSA @@ -10362,6 +10435,7 @@ static int initGlobalRNG = 0; } #endif /* NO_DSA */ +#ifndef NO_RSA static void InitCyaSSL_Rsa(CYASSL_RSA* rsa) { if (rsa) { @@ -10437,8 +10511,10 @@ static int initGlobalRNG = 0; XFREE(rsa, NULL, DYNAMIC_TYPE_RSA); } } +#endif /* NO_RSA */ +#if !defined(NO_RSA) || !defined(NO_DSA) static int SetIndividualExternal(CYASSL_BIGNUM** bn, mp_int* mpi) { CYASSL_MSG("Entering SetIndividualExternal"); @@ -10463,6 +10539,7 @@ static int initGlobalRNG = 0; return 0; } +#endif /* !NO_RSA && !NO_DSA */ #ifndef NO_DSA @@ -10510,6 +10587,7 @@ static int initGlobalRNG = 0; #endif /* NO_DSA */ +#ifndef NO_RSA static int SetRsaExternal(CYASSL_RSA* rsa) { RsaKey* key; @@ -10659,6 +10737,7 @@ static int initGlobalRNG = 0; return CyaSSL_BN_num_bytes(rsa->n); } +#endif /* NO_RSA */ #ifndef NO_DSA @@ -10700,6 +10779,7 @@ static int initGlobalRNG = 0; #endif /* NO_DSA */ +#ifndef NO_RSA /* return SSL_SUCCES on ok, 0 otherwise */ int CyaSSL_RSA_sign(int type, const unsigned char* m, unsigned int mLen, unsigned char* sigRet, @@ -10831,6 +10911,7 @@ static int initGlobalRNG = 0; else return SSL_FATAL_ERROR; } +#endif /* NO_RSA */ void CyaSSL_HMAC_Init(CYASSL_HMAC_CTX* ctx, const void* key, int keylen, @@ -11191,7 +11272,7 @@ static int initGlobalRNG = 0; - +#ifndef NO_RSA /* Load RSA from Der, SSL_SUCCESS on success < 0 on error */ int CyaSSL_RSA_LoadDer(CYASSL_RSA* rsa, const unsigned char* der, int derSz) { @@ -11220,6 +11301,7 @@ int CyaSSL_RSA_LoadDer(CYASSL_RSA* rsa, const unsigned char* der, int derSz) return SSL_SUCCESS; } +#endif /* NO_RSA */ #ifndef NO_DSA diff --git a/src/tls.c b/src/tls.c index 1cbc27d63..edac823a9 100644 --- a/src/tls.c +++ b/src/tls.c @@ -23,17 +23,13 @@ #include #endif -#ifdef CHACHA_AEAD_TEST - #include -#endif - #include #include #include #include #include -#include + #ifndef NO_TLS @@ -485,7 +481,6 @@ int CyaSSL_GetHmacType(CYASSL* ssl) if (ssl == NULL) return BAD_FUNC_ARG; - printf("getting mac \n"); switch (ssl->specs.mac_algorithm) { #ifndef NO_MD5 case md5_mac: @@ -493,13 +488,6 @@ int CyaSSL_GetHmacType(CYASSL* ssl) return MD5; } #endif - #ifdef HAVE_POLY1305 - case poly1305_mac: - { - printf("poly1305 selected\n"); - return POLY1305; - } - #endif #ifndef NO_SHA256 case sha256_mac: { @@ -559,15 +547,13 @@ int CyaSSL_SetTlsHmacInner(CYASSL* ssl, byte* inner, word32 sz, int content, int TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, int content, int verify) { - int ret; Hmac hmac; + int ret; byte myInner[CYASSL_TLS_HMAC_INNER_SZ]; - + if (ssl == NULL) return BAD_FUNC_ARG; - - CyaSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify); ret = HmacSetKey(&hmac, CyaSSL_GetHmacType(ssl), @@ -577,7 +563,7 @@ int TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, ret = HmacUpdate(&hmac, myInner, sizeof(myInner)); if (ret != 0) return ret; - ret = HmacUpdate(&hmac, in, sz); /* content */ + ret = HmacUpdate(&hmac, in, sz); /* content */ if (ret != 0) return ret; ret = HmacFinal(&hmac, digest); @@ -1011,7 +997,7 @@ int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, if (helloSz < offset + len16) return BUFFER_ERROR; - while (len16 > OPAQUE16_LEN + OPAQUE16_LEN) { + while (len16 >= OPAQUE16_LEN + OPAQUE16_LEN) { word16 extType; word16 extLen; @@ -1061,7 +1047,7 @@ int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, len16 -= min(2 * OPAQUE16_LEN + extLen, len16); } - return len16 ? BUFFER_ERROR : SSL_SUCCESS; + return len16 ? BUFFER_ERROR : 0; } #endif @@ -1228,8 +1214,8 @@ static int TLSX_THM_Parse(CYASSL* ssl, byte* input, word16 length, #ifdef HAVE_SUPPORTED_CURVES #ifndef HAVE_ECC -#error "Elliptic Curves Extension requires Elliptic Curve Cryptography. \ -Use --enable-ecc in the configure script or define HAVE_ECC." +#error Elliptic Curves Extension requires Elliptic Curve Cryptography. \ + Use --enable-ecc in the configure script or define HAVE_ECC. #endif static void TLSX_EllipticCurve_FreeAll(EllipticCurve* list) @@ -1550,6 +1536,10 @@ void TLSX_FreeAll(TLSX* list) } } +int TLSX_SupportExtensions(CYASSL* ssl) { + return ssl && (IsTLS(ssl) || ssl->version.major == DTLS_MAJOR); +} + static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest) { TLSX* extension; @@ -1649,7 +1639,7 @@ word16 TLSX_GetRequestSize(CYASSL* ssl) { word16 length = 0; - if (ssl && IsTLS(ssl)) { + if (TLSX_SupportExtensions(ssl)) { byte semaphore[16] = {0}; EC_VALIDATE_REQUEST(ssl, semaphore); @@ -1674,7 +1664,7 @@ word16 TLSX_WriteRequest(CYASSL* ssl, byte* output) { word16 offset = 0; - if (ssl && IsTLS(ssl) && output) { + if (TLSX_SupportExtensions(ssl) && output) { byte semaphore[16] = {0}; offset += OPAQUE16_LEN; /* extensions length */ @@ -1725,7 +1715,7 @@ word16 TLSX_GetResponseSize(CYASSL* ssl) word16 length = 0; byte semaphore[16] = {0}; - if (ssl && IsTLS(ssl)) + if (TLSX_SupportExtensions(ssl)) length += TLSX_GetSize(ssl->extensions, semaphore, 0); /* All the response data is set at the ssl object only, so no ctx here. */ @@ -1740,7 +1730,7 @@ word16 TLSX_WriteResponse(CYASSL *ssl, byte* output) { word16 offset = 0; - if (ssl && IsTLS(ssl) && output) { + if (TLSX_SupportExtensions(ssl) && output) { byte semaphore[16] = {0}; offset += OPAQUE16_LEN; /* extensions length */ @@ -1843,7 +1833,7 @@ int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest, || defined(HAVE_TRUNCATED_HMAC) \ || defined(HAVE_SUPPORTED_CURVES) -#error "Using TLS extensions requires HAVE_TLS_EXTENSIONS to be defined." +#error Using TLS extensions requires HAVE_TLS_EXTENSIONS to be defined. #endif /* HAVE_TLS_EXTENSIONS */ diff --git a/tests/api.c b/tests/api.c index 200fca2e1..8342da249 100644 --- a/tests/api.c +++ b/tests/api.c @@ -24,6 +24,7 @@ #endif #include +#include #include #include @@ -252,7 +253,8 @@ static void use_SNI_at_ctx(CYASSL_CTX* ctx) byte type = CYASSL_SNI_HOST_NAME; char name[] = "www.yassl.com"; - AssertIntEQ(1, CyaSSL_CTX_UseSNI(ctx, type, (void *) name, XSTRLEN(name))); + AssertIntEQ(SSL_SUCCESS, + CyaSSL_CTX_UseSNI(ctx, type, (void *) name, XSTRLEN(name))); } static void use_SNI_at_ssl(CYASSL* ssl) @@ -260,7 +262,8 @@ static void use_SNI_at_ssl(CYASSL* ssl) byte type = CYASSL_SNI_HOST_NAME; char name[] = "www.yassl.com"; - AssertIntEQ(1, CyaSSL_UseSNI(ssl, type, (void *) name, XSTRLEN(name))); + AssertIntEQ(SSL_SUCCESS, + CyaSSL_UseSNI(ssl, type, (void *) name, XSTRLEN(name))); } static void different_SNI_at_ssl(CYASSL* ssl) @@ -268,7 +271,8 @@ static void different_SNI_at_ssl(CYASSL* ssl) byte type = CYASSL_SNI_HOST_NAME; char name[] = "ww2.yassl.com"; - AssertIntEQ(1, CyaSSL_UseSNI(ssl, type, (void *) name, XSTRLEN(name))); + AssertIntEQ(SSL_SUCCESS, + CyaSSL_UseSNI(ssl, type, (void *) name, XSTRLEN(name))); } static void use_SNI_WITH_CONTINUE_at_ssl(CYASSL* ssl) @@ -291,14 +295,12 @@ static void use_SNI_WITH_FAKE_ANSWER_at_ssl(CYASSL* ssl) static void verify_SNI_abort_on_client(CYASSL* ssl) { - /* FATAL_ERROR */ - AssertIntEQ(-213, CyaSSL_get_error(ssl, 0)); + AssertIntEQ(FATAL_ERROR, CyaSSL_get_error(ssl, 0)); } static void verify_SNI_abort_on_server(CYASSL* ssl) { - /* UNKNOWN_SNI_HOST_NAME_E */ - AssertIntEQ(-281, CyaSSL_get_error(ssl, 0)); + AssertIntEQ(UNKNOWN_SNI_HOST_NAME_E, CyaSSL_get_error(ssl, 0)); } static void verify_SNI_no_matching(CYASSL* ssl) @@ -385,40 +387,63 @@ static void test_CyaSSL_SNI_GetFromBuffer(void) 0x00, 0x0d, 0x00, 0x06, 0x00, 0x04, 0x04, 0x01, 0x02, 0x01 }; + byte buffer4[] = { /* last extension has zero size */ + 0x16, 0x03, 0x01, 0x00, 0xba, 0x01, 0x00, 0x00, + 0xb6, 0x03, 0x03, 0x83, 0xa3, 0xe6, 0xdc, 0x16, 0xa1, 0x43, 0xe9, 0x45, + 0x15, 0xbd, 0x64, 0xa9, 0xb6, 0x07, 0xb4, 0x50, 0xc6, 0xdd, 0xff, 0xc2, + 0xd3, 0x0d, 0x4f, 0x36, 0xb4, 0x41, 0x51, 0x61, 0xc1, 0xa5, 0x9e, 0x00, + 0x00, 0x28, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e, + 0xc0, 0x0a, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x07, 0xc0, 0x11, + 0x00, 0x33, 0x00, 0x32, 0x00, 0x39, 0x00, 0x9c, 0x00, 0x2f, 0x00, 0x35, + 0x00, 0x0a, 0x00, 0x05, 0x00, 0x04, 0x01, 0x00, 0x00, 0x65, 0xff, 0x01, + 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, + 0x18, 0x00, 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, + 0x00, 0x33, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00, 0x1b, 0x00, 0x19, 0x06, + 0x73, 0x70, 0x64, 0x79, 0x2f, 0x33, 0x08, 0x73, 0x70, 0x64, 0x79, 0x2f, + 0x33, 0x2e, 0x31, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, + 0x75, 0x50, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x00, 0x12, 0x00, 0x10, 0x04, 0x01, 0x05, 0x01, 0x02, + 0x01, 0x04, 0x03, 0x05, 0x03, 0x02, 0x03, 0x04, 0x02, 0x02, 0x02, 0x00, + 0x12, 0x00, 0x00 + }; + byte result[32] = {0}; word32 length = 32; - AssertIntEQ(SSL_SUCCESS, CyaSSL_SNI_GetFromBuffer(buffer3, sizeof(buffer3), + AssertIntEQ(0, CyaSSL_SNI_GetFromBuffer(buffer4, sizeof(buffer4), 0, result, &length)); - AssertIntEQ(SSL_SUCCESS, CyaSSL_SNI_GetFromBuffer(buffer2, sizeof(buffer2), + AssertIntEQ(0, CyaSSL_SNI_GetFromBuffer(buffer3, sizeof(buffer3), + 0, result, &length)); + + AssertIntEQ(0, CyaSSL_SNI_GetFromBuffer(buffer2, sizeof(buffer2), 1, result, &length)); - AssertIntEQ(-228, CyaSSL_SNI_GetFromBuffer(buffer, sizeof(buffer), 0, - result, &length)); + AssertIntEQ(BUFFER_ERROR, CyaSSL_SNI_GetFromBuffer(buffer, sizeof(buffer), + 0, result, &length)); buffer[0] = 0x16; - AssertIntEQ(-228, CyaSSL_SNI_GetFromBuffer(buffer, sizeof(buffer), 0, - result, &length)); + AssertIntEQ(BUFFER_ERROR, CyaSSL_SNI_GetFromBuffer(buffer, sizeof(buffer), + 0, result, &length)); buffer[1] = 0x03; - AssertIntEQ(-228, CyaSSL_SNI_GetFromBuffer(buffer, sizeof(buffer), 0, - result, &length)); + AssertIntEQ(BUFFER_ERROR, CyaSSL_SNI_GetFromBuffer(buffer, sizeof(buffer), + 0, result, &length)); buffer[2] = 0x03; - AssertIntEQ(-210, CyaSSL_SNI_GetFromBuffer(buffer, sizeof(buffer), 0, - result, &length)); + AssertIntEQ(INCOMPLETE_DATA, CyaSSL_SNI_GetFromBuffer(buffer, + sizeof(buffer), 0, result, &length)); buffer[4] = 0x64; - AssertIntEQ(1, CyaSSL_SNI_GetFromBuffer(buffer, sizeof(buffer), 0, - result, &length)); + AssertIntEQ(SSL_SUCCESS, CyaSSL_SNI_GetFromBuffer(buffer, sizeof(buffer), + 0, result, &length)); result[length] = 0; AssertStrEQ("www.paypal.com", (const char*) result); length = 32; - AssertIntEQ(1, CyaSSL_SNI_GetFromBuffer(buffer2, sizeof(buffer2), 0, - result, &length)); + AssertIntEQ(SSL_SUCCESS, CyaSSL_SNI_GetFromBuffer(buffer2, sizeof(buffer2), + 0, result, &length)); result[length] = 0; AssertStrEQ("api.textmate.org", (const char*) result); } @@ -435,16 +460,24 @@ void test_CyaSSL_UseSNI(void) AssertNotNull(ssl); /* error cases */ - AssertIntNE(1, CyaSSL_CTX_UseSNI(NULL, 0, (void *) "ctx", XSTRLEN("ctx"))); - AssertIntNE(1, CyaSSL_UseSNI( NULL, 0, (void *) "ssl", XSTRLEN("ssl"))); - AssertIntNE(1, CyaSSL_CTX_UseSNI(ctx, -1, (void *) "ctx", XSTRLEN("ctx"))); - AssertIntNE(1, CyaSSL_UseSNI( ssl, -1, (void *) "ssl", XSTRLEN("ssl"))); - AssertIntNE(1, CyaSSL_CTX_UseSNI(ctx, 0, (void *) NULL, XSTRLEN("ctx"))); - AssertIntNE(1, CyaSSL_UseSNI( ssl, 0, (void *) NULL, XSTRLEN("ssl"))); + AssertIntNE(SSL_SUCCESS, + CyaSSL_CTX_UseSNI(NULL, 0, (void *) "ctx", XSTRLEN("ctx"))); + AssertIntNE(SSL_SUCCESS, + CyaSSL_UseSNI( NULL, 0, (void *) "ssl", XSTRLEN("ssl"))); + AssertIntNE(SSL_SUCCESS, + CyaSSL_CTX_UseSNI(ctx, -1, (void *) "ctx", XSTRLEN("ctx"))); + AssertIntNE(SSL_SUCCESS, + CyaSSL_UseSNI( ssl, -1, (void *) "ssl", XSTRLEN("ssl"))); + AssertIntNE(SSL_SUCCESS, + CyaSSL_CTX_UseSNI(ctx, 0, (void *) NULL, XSTRLEN("ctx"))); + AssertIntNE(SSL_SUCCESS, + CyaSSL_UseSNI( ssl, 0, (void *) NULL, XSTRLEN("ssl"))); /* success case */ - AssertIntEQ(1, CyaSSL_CTX_UseSNI(ctx, 0, (void *) "ctx", XSTRLEN("ctx"))); - AssertIntEQ(1, CyaSSL_UseSNI( ssl, 0, (void *) "ssl", XSTRLEN("ssl"))); + AssertIntEQ(SSL_SUCCESS, + CyaSSL_CTX_UseSNI(ctx, 0, (void *) "ctx", XSTRLEN("ctx"))); + AssertIntEQ(SSL_SUCCESS, + CyaSSL_UseSNI( ssl, 0, (void *) "ssl", XSTRLEN("ssl"))); CyaSSL_free(ssl); CyaSSL_CTX_free(ctx); @@ -500,24 +533,24 @@ static void test_CyaSSL_UseMaxFragment(void) AssertNotNull(ssl); /* error cases */ - AssertIntNE(1, CyaSSL_CTX_UseMaxFragment(NULL, CYASSL_MFL_2_9)); - AssertIntNE(1, CyaSSL_UseMaxFragment( NULL, CYASSL_MFL_2_9)); - AssertIntNE(1, CyaSSL_CTX_UseMaxFragment(ctx, 0)); - AssertIntNE(1, CyaSSL_CTX_UseMaxFragment(ctx, 6)); - AssertIntNE(1, CyaSSL_UseMaxFragment(ssl, 0)); - AssertIntNE(1, CyaSSL_UseMaxFragment(ssl, 6)); + AssertIntNE(SSL_SUCCESS, CyaSSL_CTX_UseMaxFragment(NULL, CYASSL_MFL_2_9)); + AssertIntNE(SSL_SUCCESS, CyaSSL_UseMaxFragment( NULL, CYASSL_MFL_2_9)); + AssertIntNE(SSL_SUCCESS, CyaSSL_CTX_UseMaxFragment(ctx, 0)); + AssertIntNE(SSL_SUCCESS, CyaSSL_CTX_UseMaxFragment(ctx, 6)); + AssertIntNE(SSL_SUCCESS, CyaSSL_UseMaxFragment(ssl, 0)); + AssertIntNE(SSL_SUCCESS, CyaSSL_UseMaxFragment(ssl, 6)); /* success case */ - AssertIntEQ(1, CyaSSL_CTX_UseMaxFragment(ctx, CYASSL_MFL_2_9)); - AssertIntEQ(1, CyaSSL_CTX_UseMaxFragment(ctx, CYASSL_MFL_2_10)); - AssertIntEQ(1, CyaSSL_CTX_UseMaxFragment(ctx, CYASSL_MFL_2_11)); - AssertIntEQ(1, CyaSSL_CTX_UseMaxFragment(ctx, CYASSL_MFL_2_12)); - AssertIntEQ(1, CyaSSL_CTX_UseMaxFragment(ctx, CYASSL_MFL_2_13)); - AssertIntEQ(1, CyaSSL_UseMaxFragment( ssl, CYASSL_MFL_2_9)); - AssertIntEQ(1, CyaSSL_UseMaxFragment( ssl, CYASSL_MFL_2_10)); - AssertIntEQ(1, CyaSSL_UseMaxFragment( ssl, CYASSL_MFL_2_11)); - AssertIntEQ(1, CyaSSL_UseMaxFragment( ssl, CYASSL_MFL_2_12)); - AssertIntEQ(1, CyaSSL_UseMaxFragment( ssl, CYASSL_MFL_2_13)); + AssertIntEQ(SSL_SUCCESS, CyaSSL_CTX_UseMaxFragment(ctx, CYASSL_MFL_2_9)); + AssertIntEQ(SSL_SUCCESS, CyaSSL_CTX_UseMaxFragment(ctx, CYASSL_MFL_2_10)); + AssertIntEQ(SSL_SUCCESS, CyaSSL_CTX_UseMaxFragment(ctx, CYASSL_MFL_2_11)); + AssertIntEQ(SSL_SUCCESS, CyaSSL_CTX_UseMaxFragment(ctx, CYASSL_MFL_2_12)); + AssertIntEQ(SSL_SUCCESS, CyaSSL_CTX_UseMaxFragment(ctx, CYASSL_MFL_2_13)); + AssertIntEQ(SSL_SUCCESS, CyaSSL_UseMaxFragment( ssl, CYASSL_MFL_2_9)); + AssertIntEQ(SSL_SUCCESS, CyaSSL_UseMaxFragment( ssl, CYASSL_MFL_2_10)); + AssertIntEQ(SSL_SUCCESS, CyaSSL_UseMaxFragment( ssl, CYASSL_MFL_2_11)); + AssertIntEQ(SSL_SUCCESS, CyaSSL_UseMaxFragment( ssl, CYASSL_MFL_2_12)); + AssertIntEQ(SSL_SUCCESS, CyaSSL_UseMaxFragment( ssl, CYASSL_MFL_2_13)); CyaSSL_free(ssl); CyaSSL_CTX_free(ctx); @@ -534,12 +567,12 @@ static void test_CyaSSL_UseTruncatedHMAC(void) AssertNotNull(ssl); /* error cases */ - AssertIntNE(1, CyaSSL_CTX_UseTruncatedHMAC(NULL)); - AssertIntNE(1, CyaSSL_UseTruncatedHMAC(NULL)); + AssertIntNE(SSL_SUCCESS, CyaSSL_CTX_UseTruncatedHMAC(NULL)); + AssertIntNE(SSL_SUCCESS, CyaSSL_UseTruncatedHMAC(NULL)); /* success case */ - AssertIntEQ(1, CyaSSL_CTX_UseTruncatedHMAC(ctx)); - AssertIntEQ(1, CyaSSL_UseTruncatedHMAC(ssl)); + AssertIntEQ(SSL_SUCCESS, CyaSSL_CTX_UseTruncatedHMAC(ctx)); + AssertIntEQ(SSL_SUCCESS, CyaSSL_UseTruncatedHMAC(ssl)); CyaSSL_free(ssl); CyaSSL_CTX_free(ctx); @@ -557,15 +590,19 @@ static void test_CyaSSL_UseSupportedCurve(void) #ifndef NO_CYASSL_CLIENT /* error cases */ - AssertIntNE(1, CyaSSL_CTX_UseSupportedCurve(NULL, CYASSL_ECC_SECP160R1)); - AssertIntNE(1, CyaSSL_CTX_UseSupportedCurve(ctx, 0)); + AssertIntNE(SSL_SUCCESS, + CyaSSL_CTX_UseSupportedCurve(NULL, CYASSL_ECC_SECP160R1)); + AssertIntNE(SSL_SUCCESS, CyaSSL_CTX_UseSupportedCurve(ctx, 0)); - AssertIntNE(1, CyaSSL_UseSupportedCurve(NULL, CYASSL_ECC_SECP160R1)); - AssertIntNE(1, CyaSSL_UseSupportedCurve(ssl, 0)); + AssertIntNE(SSL_SUCCESS, + CyaSSL_UseSupportedCurve(NULL, CYASSL_ECC_SECP160R1)); + AssertIntNE(SSL_SUCCESS, CyaSSL_UseSupportedCurve(ssl, 0)); /* success case */ - AssertIntEQ(1, CyaSSL_CTX_UseSupportedCurve(ctx, CYASSL_ECC_SECP160R1)); - AssertIntEQ(1, CyaSSL_UseSupportedCurve(ssl, CYASSL_ECC_SECP160R1)); + AssertIntEQ(SSL_SUCCESS, + CyaSSL_CTX_UseSupportedCurve(ctx, CYASSL_ECC_SECP160R1)); + AssertIntEQ(SSL_SUCCESS, + CyaSSL_UseSupportedCurve(ssl, CYASSL_ECC_SECP160R1)); #endif CyaSSL_free(ssl); @@ -1009,9 +1046,9 @@ THREAD_RETURN CYASSL_THREAD test_server_nofail(void* args) CyaSSL_set_fd(ssl, clientfd); #ifdef NO_PSK - #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) + #if !defined(NO_FILESYSTEM) && !defined(NO_DH) CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM); - #else + #elif !defined(NO_DH) SetDH(ssl); /* will repick suites with DHE, higher priority than PSK */ #endif #endif @@ -1232,9 +1269,9 @@ THREAD_RETURN CYASSL_THREAD run_cyassl_server(void* args) CyaSSL_set_fd(ssl, cfd); #ifdef NO_PSK - #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) + #if !defined(NO_FILESYSTEM) && !defined(NO_DH) CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM); - #else + #elif !defined(NO_DH) SetDH(ssl); /* will repick suites with DHE, higher priority than PSK */ #endif #endif diff --git a/tests/hash.c b/tests/hash.c index 03bf4bcb0..e8a7e6df5 100644 --- a/tests/hash.c +++ b/tests/hash.c @@ -608,6 +608,10 @@ int hmac_md5_test(void) 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, MD5, (byte*)keys[i], (word32)strlen(keys[i])); if (ret != 0) return -4014; @@ -674,6 +678,10 @@ int hmac_sha_test(void) 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, SHA, (byte*)keys[i], (word32)strlen(keys[i])); if (ret != 0) return -4017; @@ -743,6 +751,10 @@ int hmac_sha256_test(void) 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,SHA256, (byte*)keys[i], (word32)strlen(keys[i])); if (ret != 0) return -4020; @@ -816,6 +828,10 @@ int hmac_sha384_test(void) 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 -4023;