From ee3003e2d684ec9b3face51aec8858417bcaa05c Mon Sep 17 00:00:00 2001 From: tom_win Date: Wed, 11 Mar 2020 22:01:54 +0100 Subject: [PATCH] nahratie suborov --- certifikaty/autorita_ecc.key | 8 + certifikaty/autorita_ecc.pem | 13 + certifikaty/autorita_rsa.key | 15 + certifikaty/autorita_rsa.pem | 15 + certifikaty/klient_ecc.key | 8 + certifikaty/klient_ecc.pem | 12 + certifikaty/klient_rsa.key | 15 + certifikaty/klient_rsa.pem | 15 + certifikaty/params.txt | 3 + certifikaty/server_ecc.key | 8 + certifikaty/server_ecc.pem | 12 + certifikaty/server_rsa.key | 15 + certifikaty/server_rsa.pem | 15 + kniznica/komunikacia.c | 199 + kniznica/komunikacia.h | 111 + kniznica/kryptografia.c | 373 ++ kniznica/kryptografia.h | 73 + kniznica/rs232.c | 873 ++++ kniznica/rs232.h | 88 + readme.txt | 54 + rs232_kanal/Makefile | 46 + rs232_kanal/klient.c | 105 + rs232_kanal/klient.exe | Bin 0 -> 84284 bytes rs232_kanal/klient.o | Bin 0 -> 2114 bytes rs232_kanal/komunikacia.o | Bin 0 -> 4114 bytes rs232_kanal/kryptografia.o | Bin 0 -> 8702 bytes rs232_kanal/rs232.o | Bin 0 -> 9793 bytes rs232_kanal/server.c | 118 + rs232_kanal/server.exe | Bin 0 -> 85660 bytes rs232_kanal/server.o | Bin 0 -> 2680 bytes rs232_kanal/wolfssl.dll | Bin 0 -> 811008 bytes tcpip_kanal/Makefile | 43 + tcpip_kanal/klient.c | 180 + tcpip_kanal/klient.exe | Bin 0 -> 82559 bytes tcpip_kanal/klient.o | Bin 0 -> 5227 bytes tcpip_kanal/komunikacia.o | Bin 0 -> 5802 bytes tcpip_kanal/kryptografia.o | Bin 0 -> 9912 bytes tcpip_kanal/nieco.txt | Bin 0 -> 9 bytes tcpip_kanal/server.c | 173 + tcpip_kanal/server.exe | Bin 0 -> 82392 bytes tcpip_kanal/server.o | Bin 0 -> 5119 bytes tcpip_kanal/spustit_klient.bat | 14 + tcpip_kanal/spustit_server.bat | 15 + tcpip_kanal/vcruntime140.dll | Bin 0 -> 84816 bytes tcpip_kanal/vcruntime140_64.dll | Bin 0 -> 88248 bytes tcpip_kanal/wolfssl.dll | Bin 0 -> 811008 bytes tcpip_kanal/wolfssl_32.dll | Bin 0 -> 650240 bytes teoria.txt | 16 + wolfssl_hlavickove_subory/wolfssl/callbacks.h | 91 + .../wolfssl/certs_test.h | 3207 ++++++++++++ wolfssl_hlavickove_subory/wolfssl/crl.h | 50 + wolfssl_hlavickove_subory/wolfssl/error-ssl.h | 203 + wolfssl_hlavickove_subory/wolfssl/include.am | 32 + wolfssl_hlavickove_subory/wolfssl/internal.h | 4430 +++++++++++++++++ wolfssl_hlavickove_subory/wolfssl/ocsp.h | 133 + .../wolfssl/openssl/aes.h | 111 + .../wolfssl/openssl/asn1.h | 84 + .../wolfssl/openssl/bio.h | 159 + .../wolfssl/openssl/bn.h | 213 + .../wolfssl/openssl/buffer.h | 47 + .../wolfssl/openssl/conf.h | 48 + .../wolfssl/openssl/crypto.h | 79 + .../wolfssl/openssl/des.h | 115 + .../wolfssl/openssl/dh.h | 93 + .../wolfssl/openssl/dsa.h | 87 + .../wolfssl/openssl/ec.h | 253 + .../wolfssl/openssl/ec25519.h | 44 + .../wolfssl/openssl/ecdh.h | 49 + .../wolfssl/openssl/ecdsa.h | 74 + .../wolfssl/openssl/ed25519.h | 47 + .../wolfssl/openssl/engine.h | 8 + .../wolfssl/openssl/err.h | 51 + .../wolfssl/openssl/evp.h | 745 +++ .../wolfssl/openssl/hmac.h | 100 + .../wolfssl/openssl/include.am | 47 + .../wolfssl/openssl/lhash.h | 2 + .../wolfssl/openssl/md4.h | 62 + .../wolfssl/openssl/md5.h | 81 + .../wolfssl/openssl/objects.h | 62 + .../wolfssl/openssl/ocsp.h | 82 + .../wolfssl/openssl/opensslconf.h | 8 + .../wolfssl/openssl/opensslv.h | 44 + .../wolfssl/openssl/ossl_typ.h | 32 + .../wolfssl/openssl/pem.h | 224 + .../wolfssl/openssl/pkcs12.h | 49 + .../wolfssl/openssl/pkcs7.h | 79 + .../wolfssl/openssl/rand.h | 27 + .../wolfssl/openssl/rc4.h | 59 + .../wolfssl/openssl/ripemd.h | 58 + .../wolfssl/openssl/rsa.h | 172 + .../wolfssl/openssl/sha.h | 203 + .../wolfssl/openssl/ssl.h | 1176 +++++ .../wolfssl/openssl/ssl23.h | 1 + .../wolfssl/openssl/stack.h | 59 + .../wolfssl/openssl/tls1.h | 46 + .../wolfssl/openssl/ui.h | 2 + .../wolfssl/openssl/x509.h | 23 + .../wolfssl/openssl/x509_vfy.h | 1 + .../wolfssl/openssl/x509v3.h | 116 + wolfssl_hlavickove_subory/wolfssl/options.h | 290 ++ wolfssl_hlavickove_subory/wolfssl/sniffer.h | 228 + .../wolfssl/sniffer_error.h | 137 + .../wolfssl/sniffer_error.rc | 116 + wolfssl_hlavickove_subory/wolfssl/ssl.h | 3692 ++++++++++++++ wolfssl_hlavickove_subory/wolfssl/test.h | 3473 +++++++++++++ wolfssl_hlavickove_subory/wolfssl/version.h | 40 + .../wolfssl/version.h.in | 40 + .../wolfssl/wolfcrypt/aes.h | 408 ++ .../wolfssl/wolfcrypt/arc4.h | 68 + .../wolfssl/wolfcrypt/asn.h | 1416 ++++++ .../wolfssl/wolfcrypt/asn_public.h | 578 +++ .../wolfssl/wolfcrypt/async.h | 0 .../wolfssl/wolfcrypt/blake2-impl.h | 155 + .../wolfssl/wolfcrypt/blake2-int.h | 184 + .../wolfssl/wolfcrypt/blake2.h | 96 + .../wolfssl/wolfcrypt/camellia.h | 101 + .../wolfssl/wolfcrypt/chacha.h | 82 + .../wolfssl/wolfcrypt/chacha20_poly1305.h | 84 + .../wolfssl/wolfcrypt/cmac.h | 97 + .../wolfssl/wolfcrypt/coding.h | 88 + .../wolfssl/wolfcrypt/compress.h | 58 + .../wolfssl/wolfcrypt/cpuid.h | 62 + .../wolfssl/wolfcrypt/cryptocb.h | 299 ++ .../wolfssl/wolfcrypt/curve25519.h | 159 + .../wolfssl/wolfcrypt/des3.h | 158 + .../wolfssl/wolfcrypt/dh.h | 131 + .../wolfssl/wolfcrypt/dsa.h | 97 + .../wolfssl/wolfcrypt/ecc.h | 730 +++ .../wolfssl/wolfcrypt/ed25519.h | 169 + .../wolfssl/wolfcrypt/error-crypt.h | 253 + .../wolfssl/wolfcrypt/fe_operations.h | 210 + .../wolfssl/wolfcrypt/fips.h | 0 .../wolfssl/wolfcrypt/fips_test.h | 59 + .../wolfssl/wolfcrypt/ge_operations.h | 113 + .../wolfssl/wolfcrypt/hash.h | 244 + .../wolfssl/wolfcrypt/hc128.h | 67 + .../wolfssl/wolfcrypt/hmac.h | 207 + .../wolfssl/wolfcrypt/idea.h | 70 + .../wolfssl/wolfcrypt/include.am | 137 + .../wolfssl/wolfcrypt/integer.h | 405 ++ .../wolfssl/wolfcrypt/logging.h | 189 + .../wolfssl/wolfcrypt/md2.h | 69 + .../wolfssl/wolfcrypt/md4.h | 67 + .../wolfssl/wolfcrypt/md5.h | 130 + .../wolfssl/wolfcrypt/mem_track.h | 401 ++ .../wolfssl/wolfcrypt/memory.h | 233 + .../wolfssl/wolfcrypt/misc.h | 116 + .../wolfssl/wolfcrypt/mpi_class.h | 1021 ++++ .../wolfssl/wolfcrypt/mpi_superclass.h | 96 + .../wolfssl/wolfcrypt/pkcs11.h | 537 ++ .../wolfssl/wolfcrypt/pkcs12.h | 72 + .../wolfssl/wolfcrypt/pkcs7.h | 500 ++ .../wolfssl/wolfcrypt/poly1305.h | 127 + .../wolfcrypt/port/Espressif/esp32-crypt.h | 152 + .../port/Renesas/renesas-tsip-crypt.h | 153 + .../wolfcrypt/port/af_alg/afalg_hash.h | 50 + .../wolfssl/wolfcrypt/port/af_alg/wc_afalg.h | 53 + .../wolfssl/wolfcrypt/port/arm/cryptoCell.h | 117 + .../wolfssl/wolfcrypt/port/atmel/atmel.h | 134 + .../wolfssl/wolfcrypt/port/caam/caam_driver.h | 187 + .../wolfssl/wolfcrypt/port/caam/wolfcaam.h | 63 + .../wolfcrypt/port/caam/wolfcaam_sha.h | 88 + .../wolfcrypt/port/cavium/cavium_nitrox.h | 0 .../port/cavium/cavium_octeon_sync.h | 31 + .../wolfcrypt/port/devcrypto/wc_devcrypto.h | 53 + .../wolfcrypt/port/intel/quickassist.h | 0 .../wolfcrypt/port/intel/quickassist_mem.h | 0 .../wolfcrypt/port/intel/quickassist_sync.h | 53 + .../wolfssl/wolfcrypt/port/nrf51.h | 44 + .../wolfssl/wolfcrypt/port/nxp/ksdk_port.h | 93 + .../wolfcrypt/port/pic32/pic32mz-crypt.h | 224 + .../wolfssl/wolfcrypt/port/st/stm32.h | 142 + .../wolfssl/wolfcrypt/port/st/stsafe.h | 94 + .../wolfssl/wolfcrypt/port/ti/ti-ccm.h | 47 + .../wolfssl/wolfcrypt/port/ti/ti-hash.h | 63 + .../wolfssl/wolfcrypt/port/xilinx/xil-sha3.h | 45 + .../wolfssl/wolfcrypt/pwdbased.h | 77 + .../wolfssl/wolfcrypt/rabbit.h | 73 + .../wolfssl/wolfcrypt/random.h | 250 + .../wolfssl/wolfcrypt/ripemd.h | 67 + .../wolfssl/wolfcrypt/rsa.h | 353 ++ .../wolfssl/wolfcrypt/selftest.h | 48 + .../wolfssl/wolfcrypt/settings.h | 2108 ++++++++ .../wolfssl/wolfcrypt/sha.h | 178 + .../wolfssl/wolfcrypt/sha256.h | 255 + .../wolfssl/wolfcrypt/sha3.h | 157 + .../wolfssl/wolfcrypt/sha512.h | 228 + .../wolfssl/wolfcrypt/signature.h | 87 + .../wolfssl/wolfcrypt/sp.h | 132 + .../wolfssl/wolfcrypt/sp_int.h | 271 + .../wolfssl/wolfcrypt/srp.h | 311 ++ .../wolfssl/wolfcrypt/tfm.h | 826 +++ .../wolfssl/wolfcrypt/types.h | 914 ++++ .../wolfssl/wolfcrypt/user_settings.h | 90 + .../wolfssl/wolfcrypt/visibility.h | 79 + .../wolfssl/wolfcrypt/wc_encrypt.h | 101 + .../wolfssl/wolfcrypt/wc_pkcs11.h | 94 + .../wolfssl/wolfcrypt/wc_port.h | 762 +++ .../wolfssl/wolfcrypt/wolfevent.h | 120 + .../wolfssl/wolfcrypt/wolfmath.h | 96 + wolfssl_hlavickove_subory/wolfssl/wolfio.h | 582 +++ 201 files changed, 44607 insertions(+) create mode 100644 certifikaty/autorita_ecc.key create mode 100644 certifikaty/autorita_ecc.pem create mode 100644 certifikaty/autorita_rsa.key create mode 100644 certifikaty/autorita_rsa.pem create mode 100644 certifikaty/klient_ecc.key create mode 100644 certifikaty/klient_ecc.pem create mode 100644 certifikaty/klient_rsa.key create mode 100644 certifikaty/klient_rsa.pem create mode 100644 certifikaty/params.txt create mode 100644 certifikaty/server_ecc.key create mode 100644 certifikaty/server_ecc.pem create mode 100644 certifikaty/server_rsa.key create mode 100644 certifikaty/server_rsa.pem create mode 100644 kniznica/komunikacia.c create mode 100644 kniznica/komunikacia.h create mode 100644 kniznica/kryptografia.c create mode 100644 kniznica/kryptografia.h create mode 100644 kniznica/rs232.c create mode 100644 kniznica/rs232.h create mode 100644 readme.txt create mode 100644 rs232_kanal/Makefile create mode 100644 rs232_kanal/klient.c create mode 100644 rs232_kanal/klient.exe create mode 100644 rs232_kanal/klient.o create mode 100644 rs232_kanal/komunikacia.o create mode 100644 rs232_kanal/kryptografia.o create mode 100644 rs232_kanal/rs232.o create mode 100644 rs232_kanal/server.c create mode 100644 rs232_kanal/server.exe create mode 100644 rs232_kanal/server.o create mode 100644 rs232_kanal/wolfssl.dll create mode 100644 tcpip_kanal/Makefile create mode 100644 tcpip_kanal/klient.c create mode 100644 tcpip_kanal/klient.exe create mode 100644 tcpip_kanal/klient.o create mode 100644 tcpip_kanal/komunikacia.o create mode 100644 tcpip_kanal/kryptografia.o create mode 100644 tcpip_kanal/nieco.txt create mode 100644 tcpip_kanal/server.c create mode 100644 tcpip_kanal/server.exe create mode 100644 tcpip_kanal/server.o create mode 100644 tcpip_kanal/spustit_klient.bat create mode 100644 tcpip_kanal/spustit_server.bat create mode 100644 tcpip_kanal/vcruntime140.dll create mode 100644 tcpip_kanal/vcruntime140_64.dll create mode 100644 tcpip_kanal/wolfssl.dll create mode 100644 tcpip_kanal/wolfssl_32.dll create mode 100644 teoria.txt create mode 100644 wolfssl_hlavickove_subory/wolfssl/callbacks.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/certs_test.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/crl.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/error-ssl.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/include.am create mode 100644 wolfssl_hlavickove_subory/wolfssl/internal.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/ocsp.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/aes.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/asn1.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/bio.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/bn.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/buffer.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/conf.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/crypto.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/des.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/dh.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/dsa.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/ec.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/ec25519.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/ecdh.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/ecdsa.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/ed25519.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/engine.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/err.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/evp.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/hmac.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/include.am create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/lhash.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/md4.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/md5.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/objects.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/ocsp.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/opensslconf.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/opensslv.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/ossl_typ.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/pem.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/pkcs12.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/pkcs7.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/rand.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/rc4.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/ripemd.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/rsa.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/sha.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/ssl.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/ssl23.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/stack.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/tls1.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/ui.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/x509.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/x509_vfy.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/openssl/x509v3.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/options.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/sniffer.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/sniffer_error.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/sniffer_error.rc create mode 100644 wolfssl_hlavickove_subory/wolfssl/ssl.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/test.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/version.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/version.h.in create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/aes.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/arc4.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/asn.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/asn_public.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/async.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/blake2-impl.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/blake2-int.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/blake2.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/camellia.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/chacha.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/chacha20_poly1305.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/cmac.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/coding.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/compress.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/cpuid.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/cryptocb.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/curve25519.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/des3.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/dh.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/dsa.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/ecc.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/ed25519.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/error-crypt.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/fe_operations.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/fips.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/fips_test.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/ge_operations.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/hash.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/hc128.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/hmac.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/idea.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/include.am create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/integer.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/logging.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/md2.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/md4.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/md5.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/mem_track.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/memory.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/misc.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/mpi_class.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/mpi_superclass.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/pkcs11.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/pkcs12.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/pkcs7.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/poly1305.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/af_alg/afalg_hash.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/af_alg/wc_afalg.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/arm/cryptoCell.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/atmel/atmel.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/caam/caam_driver.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/caam/wolfcaam.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/intel/quickassist.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/intel/quickassist_mem.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/intel/quickassist_sync.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/nrf51.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/nxp/ksdk_port.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/st/stm32.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/st/stsafe.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/ti/ti-ccm.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/ti/ti-hash.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/xilinx/xil-sha3.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/pwdbased.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/rabbit.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/random.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/ripemd.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/rsa.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/selftest.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/settings.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sha.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sha256.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sha3.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sha512.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/signature.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sp.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sp_int.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/srp.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/tfm.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/types.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/user_settings.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/visibility.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wc_encrypt.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wc_pkcs11.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wc_port.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wolfevent.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wolfmath.h create mode 100644 wolfssl_hlavickove_subory/wolfssl/wolfio.h diff --git a/certifikaty/autorita_ecc.key b/certifikaty/autorita_ecc.key new file mode 100644 index 0000000..e5b1075 --- /dev/null +++ b/certifikaty/autorita_ecc.key @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BggqhkjOPQMBBw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIEuYLm4s3SUBBm7VOdIJq+FlZgRMq+V3o4wQG7VaMgZaoAoGCCqGSM49 +AwEHoUQDQgAEVL+Z4OXsPkJkgObU3CfMSZK5BqDaavIA3fsPTzKyxsHbvZZNR111 +BiLEX7tlFvSTIvxo64eB352ys4MFnGDiAQ== +-----END EC PRIVATE KEY----- diff --git a/certifikaty/autorita_ecc.pem b/certifikaty/autorita_ecc.pem new file mode 100644 index 0000000..5faea49 --- /dev/null +++ b/certifikaty/autorita_ecc.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB4jCCAYcCFBk7etptGRbWY8jIvU8DB1eoNpxAMAoGCCqGSM49BAMCMHMxCzAJ +BgNVBAYTAlNLMQowCAYDVQQIDAEtMQ8wDQYDVQQHDAZLb3NpY2UxETAPBgNVBAoM +CEF1dG9yaXRhMSAwHgYJKoZIhvcNAQkBFhFhdXRvcml0YUB0dWtlLmNvbTESMBAG +A1UEAwwJbG9jYWwuZGV2MB4XDTIwMDMxMDE5MTQ1M1oXDTI1MDMwOTE5MTQ1M1ow +czELMAkGA1UEBhMCU0sxCjAIBgNVBAgMAS0xDzANBgNVBAcMBktvc2ljZTERMA8G +A1UECgwIQXV0b3JpdGExIDAeBgkqhkiG9w0BCQEWEWF1dG9yaXRhQHR1a2UuY29t +MRIwEAYDVQQDDAlsb2NhbC5kZXYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARU +v5ng5ew+QmSA5tTcJ8xJkrkGoNpq8gDd+w9PMrLGwdu9lk1HXXUGIsRfu2UW9JMi +/Gjrh4HfnbKzgwWcYOIBMAoGCCqGSM49BAMCA0kAMEYCIQDBPCxKKXPXYWa6kybL +v+2DFhby5iW5ko0R6dgyH1ce9AIhAJHGx9URfnuN3GKEYuJ2VDVHD+ZWl27gbBFP +DvGrgUNy +-----END CERTIFICATE----- diff --git a/certifikaty/autorita_rsa.key b/certifikaty/autorita_rsa.key new file mode 100644 index 0000000..53d059d --- /dev/null +++ b/certifikaty/autorita_rsa.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQCVKNbLNY4YLbZNe5bpupYKY1ytQiWdU5GPoN1VpBT2BYk36yTd +RKvfLwxQwLgBDiI2sifAxq/MIEFgada93dJvw9GfawnLGEDfsd8lVr6cefLJuAHa +b4rHy5VDFZuzLyEDgxY+1NvK31efyQCu08GdnTpoHdHIuVQS+EAZnJcOPwIDAQAB +AoGAd1OFimnctDEVr6TYlUFEuSjGQoExcEwjneCWUOYEMtE49jgydKV0Tgbodk3G +pml1K4aY0NriVo3TX1sshRZJOxGkfxvBNtE15j8uYtb3Gov1I/jV302CROvvRE4y +fIl2AIvd5TG92ZOPYu7H22ScnasHWpsw706qQ3yjfP5weukCQQDFMA6NAqaT93ku +ClyjSBo/kon39y/XgvyAPg43LIHdkUx4q26PfW9OvwqZ7XHa5eTqBQQF9oUo8gTs +UB+SwLqTAkEAwaWrLLApowA5g8Y+MGi1Gf/r7qdQxKRJGnaEyca5EL6avFvWdZEB +XivtrIeg5Cy7BWaIgGO8TsPnwtjURTbtJQJAVn2vxDYnbrub0ZAF9jDIIp5aGgO4 +XmU779xIS/cft1nmGv/G7PVt/zJYqg+2Yvd3oxY0H5Fz8vPFKQoz7yDONQJAFMNh +tjnxTPPyNsnj0yb2/CGvt3gjNeJzoC3DESuInl4Bk165gQOaRPGq20vzmWOebfbP +fgyznTJuQDslj4JTLQJAd2ryTnOjyc6Cr8RMIMmchZCltdqEIi7vK8BglWJOBtPV +8zHyLZeMVlPQhksQW7/+xqhgFWnTMRaG9DW7JN7e7Q== +-----END RSA PRIVATE KEY----- diff --git a/certifikaty/autorita_rsa.pem b/certifikaty/autorita_rsa.pem new file mode 100644 index 0000000..a9483d3 --- /dev/null +++ b/certifikaty/autorita_rsa.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICaDCCAdECFFukrYp09IcdOmB1UlP2XbyZetRDMA0GCSqGSIb3DQEBCwUAMHMx +CzAJBgNVBAYTAlNLMQowCAYDVQQIDAEtMQ8wDQYDVQQHDAZLb3NpY2UxETAPBgNV +BAoMCEF1dG9yaXRhMSAwHgYJKoZIhvcNAQkBFhFhdXRvcml0YUB0dWtlLmNvbTES +MBAGA1UEAwwJbG9jYWwuZGV2MB4XDTIwMDMwNTAxMTIwNVoXDTI1MDMwNDAxMTIw +NVowczELMAkGA1UEBhMCU0sxCjAIBgNVBAgMAS0xDzANBgNVBAcMBktvc2ljZTER +MA8GA1UECgwIQXV0b3JpdGExIDAeBgkqhkiG9w0BCQEWEWF1dG9yaXRhQHR1a2Uu +Y29tMRIwEAYDVQQDDAlsb2NhbC5kZXYwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ +AoGBAJUo1ss1jhgttk17lum6lgpjXK1CJZ1TkY+g3VWkFPYFiTfrJN1Eq98vDFDA +uAEOIjayJ8DGr8wgQWBp1r3d0m/D0Z9rCcsYQN+x3yVWvpx58sm4AdpvisfLlUMV +m7MvIQODFj7U28rfV5/JAK7TwZ2dOmgd0ci5VBL4QBmclw4/AgMBAAEwDQYJKoZI +hvcNAQELBQADgYEAj4WUeYeVX8ZcXUlYCo6KYb0NLF37eWjfaO9VHShto+Y2wqjN +jilDuNLBuoha5GHXpGe0lzYwKih5qXwhvcWn70SXeYZxtScfNuWufbmWA+0oGwWJ +SiKCA81A+UrDnCEW4MCyfgXIwGpT6ljayDCpIwqSzVe3+K/L9AoBCuw9bMg= +-----END CERTIFICATE----- diff --git a/certifikaty/klient_ecc.key b/certifikaty/klient_ecc.key new file mode 100644 index 0000000..93f6fd3 --- /dev/null +++ b/certifikaty/klient_ecc.key @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BggqhkjOPQMBBw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIEiOAuoubpho9KV8F1aMXamrOpJMT6TFCzcktOuliEiQoAoGCCqGSM49 +AwEHoUQDQgAENFi5L65dyn1XTUrS9rBa8x0nDfDJNhqKxYS8kjPl7pSajrl/Cj3w +B5Jr/RxntAhi17bAOZZMZx3f0BKKgJH9lA== +-----END EC PRIVATE KEY----- diff --git a/certifikaty/klient_ecc.pem b/certifikaty/klient_ecc.pem new file mode 100644 index 0000000..6f6666a --- /dev/null +++ b/certifikaty/klient_ecc.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB3DCCAYMCFH9I4ZXZiyO2Y4w+lFzlrxYivgHjMAoGCCqGSM49BAMCMHMxCzAJ +BgNVBAYTAlNLMQowCAYDVQQIDAEtMQ8wDQYDVQQHDAZLb3NpY2UxETAPBgNVBAoM +CEF1dG9yaXRhMSAwHgYJKoZIhvcNAQkBFhFhdXRvcml0YUB0dWtlLmNvbTESMBAG +A1UEAwwJbG9jYWwuZGV2MB4XDTIwMDMxMDE5MjA1OFoXDTI1MDMwOTE5MjA1OFow +bzELMAkGA1UEBhMCU0sxCjAIBgNVBAgMAS0xDzANBgNVBAcMBktvc2ljZTEPMA0G +A1UECgwGS2xpZW50MR4wHAYJKoZIhvcNAQkBFg9rbGllbnRAdHVrZS5jb20xEjAQ +BgNVBAMMCWxvY2FsLmRldjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDRYuS+u +Xcp9V01K0vawWvMdJw3wyTYaisWEvJIz5e6Umo65fwo98AeSa/0cZ7QIYte2wDmW +TGcd39ASioCR/ZQwCgYIKoZIzj0EAwIDRwAwRAIgG2q3mO5PEsyk6ZbibyyT8hZJ +U8SceTjxbLK9fbsmCiwCIFNF69S3kNHOAGNCOyXmkGnTC5/P1DAEZWqMlhjWvZP7 +-----END CERTIFICATE----- diff --git a/certifikaty/klient_rsa.key b/certifikaty/klient_rsa.key new file mode 100644 index 0000000..cc7a72a --- /dev/null +++ b/certifikaty/klient_rsa.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQC/DedvqCZsH2XVumJAHd79eWTQWtaShA14R1T4YGxN4F7EjEFW +mEW7vu+w356SLjaL7arbRI1U5UWBRkknjcftSJqf1HahyzcPkXOnbJmvf+z9gn4p +QdmzPxC+5T+deD2tr6l+/yuoJHNAe9DxE1CSquiENBzijMSTLHp4/eFPKwIDAQAB +AoGAdSUZWyVHKdS2pC38QEQQjmr4naiVGJFPkQhr2T+GKNoCQZGeHnKPj2aroU/7 +8rXTTEkWEgwefId37qQiBtawVoZHzx4afuRi+DZptMnHk618TenxL6rWTQy95KxR +cUQoJcbStu3+aENAVd8iVB3zNWY+GZbdDoISF9yu2810egECQQDninwFiXs+zdVX +HMj6+OxqPoNq1/a30FipSOOuxqUK90qww63OncNfmVWXXWvm+ONe+yB43hkyK5ZE +DNbU97jhAkEA0zyMJeoPkfRViV/rnynTG0myRIEvqNUqdEcOrIVRyObqd/0fatMq +u+2vXjTp7is4sMQOvX8SI2XoeoDyQAyNiwJBALS4+b6UpXbK0BcTZ6fEvTrcGlU9 +xduJKnrPYq9baxzZEhpQUYwwxXsLwqvHhl4cq9PJ7XmJ2V64eKwa3WATDuECQFw7 +69YCRZotXcwGHhP5ZzxbCYPwBKdrrIXpIPcjn3phma+azsUOP3Kfbhtsb1iXdsF4 +WhdUDM94B/K1qxFcadECQBWTRd++2ASbE6Z6bbS5XWnVgJAuSjk0MDvrP9gm1+uX +BYbdZI6VXOt5VJ/pN2nPrDNhWQfJZWSv8qt5ibq3VKs= +-----END RSA PRIVATE KEY----- diff --git a/certifikaty/klient_rsa.pem b/certifikaty/klient_rsa.pem new file mode 100644 index 0000000..54dff44 --- /dev/null +++ b/certifikaty/klient_rsa.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICZDCCAc0CFGSwoxKJ+ivTvM/jTdI8s78xF4MSMA0GCSqGSIb3DQEBCwUAMHMx +CzAJBgNVBAYTAlNLMQowCAYDVQQIDAEtMQ8wDQYDVQQHDAZLb3NpY2UxETAPBgNV +BAoMCEF1dG9yaXRhMSAwHgYJKoZIhvcNAQkBFhFhdXRvcml0YUB0dWtlLmNvbTES +MBAGA1UEAwwJbG9jYWwuZGV2MB4XDTIwMDMwNTAxMTU0MVoXDTI1MDMwNDAxMTU0 +MVowbzELMAkGA1UEBhMCU0sxCjAIBgNVBAgMAS0xDzANBgNVBAcMBktvc2ljZTEP +MA0GA1UECgwGS2xpZW50MR4wHAYJKoZIhvcNAQkBFg9rbGllbnRAdHVrZS5jb20x +EjAQBgNVBAMMCWxvY2FsLmRldjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA +vw3nb6gmbB9l1bpiQB3e/Xlk0FrWkoQNeEdU+GBsTeBexIxBVphFu77vsN+eki42 +i+2q20SNVOVFgUZJJ43H7Uian9R2ocs3D5Fzp2yZr3/s/YJ+KUHZsz8QvuU/nXg9 +ra+pfv8rqCRzQHvQ8RNQkqrohDQc4ozEkyx6eP3hTysCAwEAATANBgkqhkiG9w0B +AQsFAAOBgQCL4xhQ+gvnmTHR7CJH4iKmX86V5+vdVMowoF4XNssl/5BCKuk3zLFb +TkP8YHbwHbPNMAnh2qoiNICEZTP02HyIn7ehdq/r9eApotlE5Tgqb4cGc4UGSqhx +mXKLdQemTxe40rDNfB6wZ0ggW5JFgt20woXDnDl4i3jrbykrQKZTHQ== +-----END CERTIFICATE----- diff --git a/certifikaty/params.txt b/certifikaty/params.txt new file mode 100644 index 0000000..a76e47d --- /dev/null +++ b/certifikaty/params.txt @@ -0,0 +1,3 @@ +-----BEGIN EC PARAMETERS----- +BggqhkjOPQMBBw== +-----END EC PARAMETERS----- diff --git a/certifikaty/server_ecc.key b/certifikaty/server_ecc.key new file mode 100644 index 0000000..65ee2ac --- /dev/null +++ b/certifikaty/server_ecc.key @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BggqhkjOPQMBBw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIKBCwKxCE+XrPsnUhnP7AOaTq3Oao9r0wx5KxyOySKZ9oAoGCCqGSM49 +AwEHoUQDQgAEAk6bltpNprRbPvxe2bHnnkCn9vlR2Dkqy0Gmo+mHVnl61skd/AVR +NWJD+O5ryXHmV08pTxC1FTDjeCEBvfivuQ== +-----END EC PRIVATE KEY----- diff --git a/certifikaty/server_ecc.pem b/certifikaty/server_ecc.pem new file mode 100644 index 0000000..2dfd8bb --- /dev/null +++ b/certifikaty/server_ecc.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB3DCCAYMCFH9I4ZXZiyO2Y4w+lFzlrxYivgHiMAoGCCqGSM49BAMCMHMxCzAJ +BgNVBAYTAlNLMQowCAYDVQQIDAEtMQ8wDQYDVQQHDAZLb3NpY2UxETAPBgNVBAoM +CEF1dG9yaXRhMSAwHgYJKoZIhvcNAQkBFhFhdXRvcml0YUB0dWtlLmNvbTESMBAG +A1UEAwwJbG9jYWwuZGV2MB4XDTIwMDMxMDE5MTgzN1oXDTI1MDMwOTE5MTgzN1ow +bzELMAkGA1UEBhMCU0sxCjAIBgNVBAgMAS0xDzANBgNVBAcMBktvc2ljZTEPMA0G +A1UECgwGU2VydmVyMR4wHAYJKoZIhvcNAQkBFg9zZXJ2ZXJAdHVrZS5jb20xEjAQ +BgNVBAMMCWxvY2FsLmRldjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABAJOm5ba +Taa0Wz78Xtmx555Ap/b5Udg5KstBpqPph1Z5etbJHfwFUTViQ/jua8lx5ldPKU8Q +tRUw43ghAb34r7kwCgYIKoZIzj0EAwIDRwAwRAIgP3/bEfhPBcaGPzMT2+6HnACc +MjGaYiLP5BDP1VJpWEgCIHqlNP4euj0NE3Lo3Vpg7xJBn4MVQ9/IrtSASAa+k9sk +-----END CERTIFICATE----- diff --git a/certifikaty/server_rsa.key b/certifikaty/server_rsa.key new file mode 100644 index 0000000..b7cfbcd --- /dev/null +++ b/certifikaty/server_rsa.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQC1Zh/qu4/E8TYZxTl7CH+fv9+VsDf0kRgKXTx/7XM7hjyIV09p +OWMZOWsIW43VDre5qY4u69AXdnAT9BKRbGXw8ySnIMLrq9DkhdMvwFo70Q4Tm/aI +7lgvZ4KPZjAeRbv8Kn/8nZtLvMn75K8pw1GFqNf9OYu/C7E6gmtaiTg3NQIDAQAB +AoGAa/9TPUNRwyUA2rLrF+7lXMy1Zr81cSv5LiJ4ZImQM34mB95Dbxg1gc0HhkBL +3u8WPzlNZ24JxA5Fh/umGmJ5BcsLwU2zGM4S6cOrF23YZHIuy7Gj2suHQwXZt7Ui +DDxuHHjGsLTN7Dgx51p+UKOnOEXJDz5AgqXLoWCzFanzKEECQQDv0Ouyw4S4ox5v +Z1c96ceg7DsVY0TDyE6EkW/nLbxY08Pc/WHUiJzf6jDoT5bqjFltmBS6ZmGMydaM +dGMzLG0ZAkEAwaP8I3lvUG04bh/E+kWbrpGvyqtG5lOUHVf9joIXZs9BdMpOtN+1 +vO8fXywTKyAwQNtwMoOkVxbl6EMckerCfQJAFcAlIHmLOBPTVtdQmlTxvi6uzSnL +utYYCP4H4DfNtWC/ivOQQ+6AC+75sJhHX86K7d21Q5K1lkdYJjUIKkQFQQJAVDnZ +wCxfyKHZO71B1oJUdxgTWJorWp/b+u988HGRcDySAhTFK1NrH2T7RlBLfiSgGHXa +VX6BCwiAtAgM80MjmQJBAK6d2T7io3Hvc+cxudmwmHS66BGET1w/04H3Sjz1L7f8 +LR5SR5hEXiGl8k5oEcUvyigZwpBf/G5uM9Msi0gZjJ4= +-----END RSA PRIVATE KEY----- diff --git a/certifikaty/server_rsa.pem b/certifikaty/server_rsa.pem new file mode 100644 index 0000000..f30667b --- /dev/null +++ b/certifikaty/server_rsa.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICZDCCAc0CFGSwoxKJ+ivTvM/jTdI8s78xF4MRMA0GCSqGSIb3DQEBCwUAMHMx +CzAJBgNVBAYTAlNLMQowCAYDVQQIDAEtMQ8wDQYDVQQHDAZLb3NpY2UxETAPBgNV +BAoMCEF1dG9yaXRhMSAwHgYJKoZIhvcNAQkBFhFhdXRvcml0YUB0dWtlLmNvbTES +MBAGA1UEAwwJbG9jYWwuZGV2MB4XDTIwMDMwNTAxMTQzM1oXDTI1MDMwNDAxMTQz +M1owbzELMAkGA1UEBhMCU0sxCjAIBgNVBAgMAS0xDzANBgNVBAcMBktvc2ljZTEP +MA0GA1UECgwGU2VydmVyMR4wHAYJKoZIhvcNAQkBFg9zZXJ2ZXJAdHVrZS5jb20x +EjAQBgNVBAMMCWxvY2FsLmRldjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA +tWYf6ruPxPE2GcU5ewh/n7/flbA39JEYCl08f+1zO4Y8iFdPaTljGTlrCFuN1Q63 +uamOLuvQF3ZwE/QSkWxl8PMkpyDC66vQ5IXTL8BaO9EOE5v2iO5YL2eCj2YwHkW7 +/Cp//J2bS7zJ++SvKcNRhajX/TmLvwuxOoJrWok4NzUCAwEAATANBgkqhkiG9w0B +AQsFAAOBgQBt7oH2dMonlq9rGrnVq5BpHPg4RDtKT4cFHFrMyYAw1OjGwgzWJadK +M8je3WJ8vaTBmXrLqmx5lO7q/Fqb+dZpa1Zd4GZ7xqP0KZkiiOsdQ8s898CpZ/2F +V8WGMklX8Jn1noMJ/i/wQwvGw6WaJZ2mv9ZSL4RitjKGMk4X0zzZ+g== +-----END CERTIFICATE----- diff --git a/kniznica/komunikacia.c b/kniznica/komunikacia.c new file mode 100644 index 0000000..66f9f31 --- /dev/null +++ b/kniznica/komunikacia.c @@ -0,0 +1,199 @@ +////////////////////////////////////////////////// +// Bakalarska praca // +// Meno studenta: Tomas Lukac // +// Veduci BP: prof. Ing. Milos Drutarovsky CSc. // +// Skola: KEMT FEI TUKE // +// Datum poslednej upravy: 9.3.2020 // +////////////////////////////////////////////////// + +#include "komunikacia.h" +#include "kryptografia.h" + +int poslat_subor(WOLFSSL* ssl, WOLFSSL_CTX* ctx, char* cesta) +{ + wolfSSL_write(ssl, cesta, 64); + + FILE* subor = fopen(cesta, "r"); + if(subor == NULL) + { + fprintf(stderr, "Nebolo mozne najst pozadovany subor.\n"); + ukoncit_spojenie(ssl, ctx); + return -1; + } + else + { + printf("Posielam subor.\n"); + + //nastavi ukazovatel na koniec suboru + //a zisti velkost suboru + fseek(subor, 0, SEEK_END); + long velkost = ftell(subor); + char velkost_suboru[32]; + sprintf(velkost_suboru, "%ld", velkost); + printf("Velkost suboru: %s bajtov\n", velkost_suboru); + wolfSSL_write(ssl, velkost_suboru, 32); + + //nastavi ukazovatel na zaciatok suboru + //a nacita data zo suboru do pola + char* pole = malloc(velkost); + char* pole_uk = pole; + fseek(subor, 0, SEEK_SET); + fread(pole, 1, velkost, subor); + fclose(subor); + + //posielanie jednotlivych bajtov + for(int i = 0; i < velkost + 1; ++i) + { + wolfSSL_write(ssl, pole_uk, velkost); + pole_uk += 1; + } + printf("Subor bol uspesne odoslany.\n"); + return 0; + } +} + +int prijat_subor(WOLFSSL* ssl, WOLFSSL_CTX* ctx) +{ + char* cesta = calloc(100, sizeof(char)); + wolfSSL_read(ssl, cesta, 64); + printf("Prebieha prijimanie suboru %s\n", cesta); + + //ziskanie informacie od klienta o velkosti odoslaneho suboru + char velkost_suboru[32]; + wolfSSL_read(ssl, velkost_suboru, 32); + long velkost = atol(velkost_suboru); + if(velkost < 1) + { + printf("Nastala chyba pri prijati suboru\n"); + return -1; + } + else + { + printf("Velkost suboru: %s bajtov\n", velkost_suboru); + } + + //prijem jednotlivych bajtov + char* pole = malloc(velkost); + char* pole_uk = pole; + for(int i = 0; i < velkost + 1; ++i) + { + wolfSSL_read(ssl, pole_uk, velkost); + pole_uk += 1; + } + printf("Subor bol uspesne prijaty.\n"); + + //zapis nacitanych dat do suboru + FILE* subor = fopen(cesta, "w"); + fwrite(pole, 1, velkost, subor); + fclose(subor); + return 0; +} + +int pripojit_na_server(char *ip_adresa, int cislo_portu, int pocet_sekund) +{ + struct timeval casovy_interval; + int uspech; + int cislo_soketu; + struct hostent* hostitel; + struct sockaddr_in adresa; + fd_set sada_soketov; + socklen_t velkost_soketu; + int optval; + + if((hostitel = gethostbyname(ip_adresa)) == NULL) + { + printf("Nastala chyba pri spracovani nazvu hostitela.\n"); + return 0; + } + printf("Vytvaranie soketu...\n"); + cislo_soketu = socket(AF_INET, SOCK_STREAM, 0); + memset(&adresa, 0, sizeof(adresa)); + adresa.sin_family = AF_INET; //IPv4 + adresa.sin_port = htons(cislo_portu); + adresa.sin_addr.s_addr = *(long*)(hostitel->h_addr); + + //pokus o pripojenie s casovym intervalom + uspech = connect(cislo_soketu, (struct sockaddr*)&adresa, sizeof(adresa)); + if(uspech < 0) + { + if(errno == EINPROGRESS) + { + fprintf(stderr, "Nebolo mozne okamzite vytvorit spojenie\n"); + do + { + casovy_interval.tv_sec = pocet_sekund; + casovy_interval.tv_usec = 0; + FD_ZERO(&sada_soketov); + FD_SET(cislo_soketu, &sada_soketov); + uspech = select(cislo_soketu + 1, NULL, &sada_soketov, NULL, &casovy_interval); + if (uspech < 0 && errno != EINTR) + { + fprintf(stderr, "Nastala chyba pri pokuse o vytvorenie spojenia\nCislo chyby: %d\nPopis: %s\n", errno, strerror(errno)); + ukoncit_soket(cislo_soketu); + exit(0); + } + //bol zvoleny soket + else if(uspech > 0) + { + velkost_soketu = sizeof(int); + if (getsockopt(cislo_soketu, SOL_SOCKET, SO_ERROR, (void*)(&optval), &velkost_soketu) < 0) + { + fprintf(stderr, "Nastala chyba v nastaveni soketu\nCislo chyby: %d\nPopis: %s\n", errno, strerror(errno)); + ukoncit_soket(cislo_soketu); + exit(0); + } + if(optval) + { + fprintf(stderr, "Nastala chyba v spojeni\nCislo chyby: %d\nPopis: %s\n", optval, strerror(optval)); + ukoncit_soket(cislo_soketu); + exit(0); + } + break; + } + else + { + fprintf(stderr, "Casovy interval vyprsal\n"); + ukoncit_soket(cislo_soketu); + exit(0); + } + } while(1); + } + else + { + fprintf(stderr, "Spojenie zlyhalo.\nCislo chyby: %d\nPopis: %s\n", errno, strerror(errno)); + ukoncit_soket(cislo_soketu); + exit(0); + } + } + return cislo_soketu; +} + +int cakat_na_komunikaciu(int cislo_portu) +{ + int cislo_soketu; + struct sockaddr_in adresa; + + printf("Vytvaranie socketu...\n"); + cislo_soketu = socket(PF_INET, SOCK_STREAM, 0); + memset(&adresa, 0, sizeof(adresa)); + adresa.sin_family = AF_INET; //IPv4 + adresa.sin_port = htons(cislo_portu); + adresa.sin_addr.s_addr = INADDR_ANY; + + if(bind(cislo_soketu, (struct sockaddr*)&adresa, sizeof(adresa)) != 0) + { + fprintf(stderr, "Nebolo mozne priradit soket ku danemu portu.\n"); + return 0; + } + + if(listen(cislo_soketu, 10) != 0) + { + fprintf(stderr, "Na danom porte nie je mozne cakat na komunikaciu.\n"); + return 0; + } + else + { + printf("Server caka na komunikaciu na porte %d.\n", cislo_portu); + } + return cislo_soketu; +} diff --git a/kniznica/komunikacia.h b/kniznica/komunikacia.h new file mode 100644 index 0000000..45ab8f1 --- /dev/null +++ b/kniznica/komunikacia.h @@ -0,0 +1,111 @@ +////////////////////////////////////////////////// +// Bakalarska praca // +// Meno studenta: Tomas Lukac // +// Veduci BP: prof. Ing. Milos Drutarovsky CSc. // +// Skola: KEMT FEI TUKE // +// Datum poslednej upravy: 9.3.2020 // +////////////////////////////////////////////////// + +#ifndef __KOMUNIKACIA_H__ +#define __KOMUNIKACIA_H__ + +#include +#include +#include +#include + +#if defined(_WIN32) + //makro ktore urcuje win distribuciu ak nieje detekovana + #ifndef _WIN32_WINNT + #define _WIN32_WINNT 0x0600 + #endif + #include + #include + #include + #define ukoncit_soket closesocket + #define socklen_t int + #define EINPROGRESS WSAEINPROGRESS + #define EINTR WSAEINTR + + //hovori visual c prekladacu aby nalinkoval ws2_32 kniznicu + //ak pouzivame minqw pragma sa ignoruje a musime ju zadat pri kompilaci manualne : -lws2_32 + #pragma comment(lib, "ws2_32.lib") +#else + #include + #include + #include + #include + #include + #include + #include + #define ukoncit_soket close +#endif + +////////////////////////////// +// TCP/IP KOMUNIKACNY KANAL // +////////////////////////////// + +/** + * pripojit_na_server: realizuje pripojenie na server + * @parameter char* ip_adresa : ip adresa servera, na ktory sa chce klient pripojit + * @parameter int cislo_portu : cislo portu na ktorom server ocakava komunikaciu + * @parameter int pocet_sekund : casovy interval + * @vrati int : cislo soketu + */ +int pripojit_na_server(char *ip_adresa, int cislo_portu, int pocet_sekund); + +/** + * cakat_na_komunikaciu : realizuje vytvorenie soketu a jeho priradenie ku portu, + * na ktorom server ocakava komunikaciu + * @parameter int cislo_portu: cislo portu na ktorom server bude ocakavat komunikaciu + * @vrati int : cislo soketu + */ +int cakat_na_komunikaciu(int cislo_portu); + +///////////////////////////// +// RS232 KOMUNIKACNY KANAL // +///////////////////////////// + +/** + * rs232_zapis: umoznuje zapis dat do serialoveho portu + * @parameter WOLSSL* ssl : ukazuje na aktualnu relaciu + * @parameter char* buf : ukazuje na buffer, do kt. zapise wolfssl zasifrovany text na odoslanie + * @parameter int sz : velkost buffera + * @parameter void* ctx : ukazuje na WOLFSSL_CTX strukturu + * @vrati int + */ +int rs232_zapis(WOLFSSL *ssl, char *buf, int sz, void *ctx); + +/** + * rs232_citanie: umoznuje citanie dat zo serialoveho portu + * @parameter WOLFSSL* ssl : ukazuje na aktualnu relaciu + * @parameter char* buf : ukazuje na buffer, kde prichadzajuci zasifrovany text by mal byt nakopirovany + * aby ho wolfssl mohla odsifrovat + * @parameter int sz : velkost buffera + * @parameter void* ctx : ukazuje na WOLFSSL_CTX strukturu + * @vrati int + */ +int rs232_citanie(WOLFSSL *ssl, char *buf, int sz, void *ctx); + +////////////////////// +// PRACA SO SUBORMI // +////////////////////// + +/** + * poslat_subor: realizuje odoslanie suboru + * @parameter WOLFSSL* ssl : ukazuje na aktualnu relaciu + * @parameter WOLFSSL_CTX* ctx : ukazuje na WOLFSSL_CTX strukturu + * @parameter char* cesta: ukazuje na retazec, ktory reprezentuje cestu k suboru + * @vrati int : operacia bola uspesna(0), neuspesna(-1) + */ +int poslat_subor(WOLFSSL* ssl, WOLFSSL_CTX* ctx, char* cesta); + +/** + * prijat_subor: realizuje prijem suboru + * @parameter WOLFSSL* ssl : ukazuje na aktualnu relaciu + * @parameter WOLFSSL_CTX* ctx : ukazuje na WOLFSSL_CTX strukturu + * @vrati int : operacia bola uspesna(0), neuspesna(-1) + */ +int prijat_subor(WOLFSSL* ssl, WOLFSSL_CTX* ctx); + +#endif \ No newline at end of file diff --git a/kniznica/kryptografia.c b/kniznica/kryptografia.c new file mode 100644 index 0000000..3e0b1be --- /dev/null +++ b/kniznica/kryptografia.c @@ -0,0 +1,373 @@ +////////////////////////////////////////////////// +// Bakalarska praca // +// Meno studenta: Tomas Lukac // +// Veduci BP: prof. Ing. Milos Drutarovsky CSc. // +// Skola: KEMT FEI TUKE // +// Datum poslednej upravy: 9.3.2020 // +////////////////////////////////////////////////// + +#include "kryptografia.h" + +WOLFSSL_CTX* nastavit_ctx_klient() +{ + WOLFSSL_METHOD* method; + wolfSSL_Init(); + method = wolfTLSv1_2_client_method(); + WOLFSSL_CTX *ctx = wolfSSL_CTX_new(method); + wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0); + if (ctx == NULL) + { + printf("Nepodarilo sa inicializovat WOLFSSL_CTX\n"); + return NULL; + } + return ctx; +} + +WOLFSSL_CTX* nastavit_ctx_server() +{ + WOLFSSL_METHOD* method; + wolfSSL_Init(); + method = wolfTLSv1_2_server_method(); + WOLFSSL_CTX *ctx = wolfSSL_CTX_new(method); + + wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0); + if (ctx == NULL) + { + printf("Nepodarilo sa inicializovat WOLFSSL_CTX\n"); + return NULL; + } + return ctx; +} + +void nastav_sifry(WOLFSSL_CTX* ctx, const char* sifry) +{ + wolfSSL_CTX_set_cipher_list(ctx, sifry); +} + +void zobraz_sifru(WOLFSSL* ssl) +{ + printf ("Pouzita sifra: %s\n", wolfSSL_get_cipher(ssl)); +} + +int generovat_rsa_certifikat(WOLFSSL_CTX* ctx, int pocet_bitov, int exponent, int algoritmus, char* krajina, char* mesto, char* domena, char* email) +{ + int uspech; + + //premenne pre ukladanie dat autority + RsaKey kluc_autorita; + byte pem_autorita[4096]; + word32 pem_autorita_velkost; + byte der_autorita[4096]; + word32 der_autorita_velkost; + + //vytvorenie struktury RsaKey autority zo sukromneho kluca vo formate PEM ulozeneho v subore certifikaty/autorita.key + memset(pem_autorita, 0, sizeof(pem_autorita)); + FILE* subor = fopen("../certifikaty/autorita_rsa.key", "rb"); + pem_autorita_velkost = fread(pem_autorita, 1, 4096, subor); + if(pem_autorita_velkost < 0) + { + fprintf(stderr, "Nepodarilo sa nacitat obsah suboru\n"); + } + word32 index = 0; //nastavi odkial zacat citat buffer + memset(der_autorita, 0, sizeof(der_autorita)); + der_autorita_velkost = wolfSSL_KeyPemToDer(pem_autorita, sizeof(pem_autorita), der_autorita, sizeof(der_autorita), ""); + wc_InitRsaKey(&kluc_autorita, 0); + uspech = wc_RsaPrivateKeyDecode(der_autorita, &index, &kluc_autorita, der_autorita_velkost); + if(uspech != 0) + { + fprintf(stderr, "Nepodarilo sa vytvorit RsaKey strukturu z kluca autority\n"); + return -1; + } + RsaKey* k = &kluc_autorita; + if (k == NULL) + { + fprintf(stderr, "Nepodarilo sa vytvorit RsaKey strukturu z kluca autority\n"); + return -1; + } + + //generator nahodnych cisel + WC_RNG generator; + wc_InitRng(&generator); + + //premenne pre ukladanie dat vygenerovaneho kluca + RsaKey kluc; + byte der_kluc[4096]; + word32 der_kluc_velkost; + byte pem_kluc[4096]; + word32 pem_kluc_velkost; + + //vygenerovanie kluca + wc_InitRsaKey(&kluc, 0); + uspech = wc_MakeRsaKey(&kluc, pocet_bitov, exponent, &generator); + if(uspech != 0) + { + fprintf(stderr, "Chyba pri generovani kluca.\nCislo chyby: %d\nDovod chyby: %s\n", uspech, wc_GetErrorString(uspech)); + return -1; + } + der_kluc_velkost = wc_RsaKeyToDer(&kluc, der_kluc, sizeof(der_kluc)); + if(der_kluc_velkost < 0) + { + fprintf(stderr, "Nastala chyba pri vytvoreni suboru DER so sukromnym klucom.\n"); + return -1; + } + pem_kluc_velkost = wc_DerToPem(der_kluc, der_kluc_velkost, pem_kluc, sizeof(pem_kluc), PRIVATEKEY_TYPE); + if(pem_kluc_velkost < 0) + { + fprintf(stderr, "Nastala chyba pri vytvoreni suboru PEM so sukromnym klucom\n"); + return -1; + } + + //nacitanie vygenerovaneho kluca do WOLFSSL_CTX struktury + uspech = wolfSSL_CTX_use_PrivateKey_buffer(ctx, pem_kluc, pem_kluc_velkost, SSL_FILETYPE_PEM); + if(uspech != SSL_SUCCESS) + { + fprintf(stderr, "Chyba pri nacitani vygenerovaneho kluca.\nCislo chyby: %d\nDovod chyby: %s\n", uspech, wc_GetErrorString(uspech)); + return -1; + } + + printf("RSA kluc bol uspesne vygenerovany a nacitany.\n"); + + //premenne pre ukladanie dat certifikatu + Cert certifikat; + byte der_certifikat[4096]; + word32 der_certifikat_velkost; + byte pem_certifikat[4096]; + word32 pem_certifikat_velkost; + + //vygenerovanie a podpis certifikatu + wc_InitCert(&certifikat); + strncpy(certifikat.subject.country, krajina, CTC_NAME_SIZE); + strncpy(certifikat.subject.state, "-", CTC_NAME_SIZE); + strncpy(certifikat.subject.locality, mesto, CTC_NAME_SIZE); + strncpy(certifikat.subject.org, "-", CTC_NAME_SIZE); + strncpy(certifikat.subject.unit, "-", CTC_NAME_SIZE); + strncpy(certifikat.subject.commonName, domena, CTC_NAME_SIZE); + strncpy(certifikat.subject.email, email, CTC_NAME_SIZE); + //certifikat.isCA = 0; + certifikat.sigType = algoritmus; + uspech = wc_SetIssuer(&certifikat, "../certifikaty/autorita_rsa.pem"); + if(uspech < 0) + { + fprintf(stderr, "Nastala chyba pri nastaveni autority.\nCislo chyby: %d\nDovod chyby: %s\n", uspech, wc_GetErrorString(uspech)); + return -1; + } + der_certifikat_velkost = wc_MakeCert(&certifikat, der_certifikat, sizeof(der_certifikat), &kluc, NULL, &generator); + if(der_certifikat_velkost < 0) + { + fprintf(stderr, "Nastala chyba pri vytvoreni suboru DER s certifikatom.\n"); + return -1; + } + der_certifikat_velkost = wc_SignCert(certifikat.bodySz, certifikat.sigType, der_certifikat, sizeof(der_certifikat), &kluc_autorita, NULL, &generator); + if(der_certifikat_velkost < 0) + { + fprintf(stderr, "Nastala chyba pri podpisovani certifikatu.\n"); + return -1; + } + memset(pem_certifikat, 0, sizeof(pem_certifikat)); + pem_certifikat_velkost = wc_DerToPem(der_certifikat, der_certifikat_velkost, pem_certifikat, sizeof(pem_certifikat), CERT_TYPE); + if(pem_certifikat_velkost < 0) + { + fprintf(stderr, "Nastala chyba pri vytvoreni suboru PEM s certifikatom.\n"); + return -1; + } + + //nacitanie vygenerovaneho certifikatu do WOLFSSL_CTX struktury + uspech = wolfSSL_CTX_use_certificate_buffer(ctx, pem_certifikat, pem_certifikat_velkost, SSL_FILETYPE_PEM); + if(uspech != SSL_SUCCESS) + { + fprintf(stderr, "Chyba pri generovani certifikatu.\nCislo chyby: %d\nDovod chyby: %s\n", uspech, wc_GetErrorString(uspech)); + return -1; + } + printf("Certifikat bol uspesne vygenerovany a podpisany\n"); + + if(!wolfSSL_CTX_check_private_key(ctx)) + { + fprintf(stderr, "Sukromny kluc sa nezhoduje s certifikatom\n"); + return -1; + } + + return 0; +} + +int generovat_ecc_certifikat(WOLFSSL_CTX* ctx, int pocet_bitov, ecc_curve_id kluc_krivka, int algoritmus, char* krajina, char* mesto, char* domena, char* email) +{ + int uspech = 0; + + //premenne pre ukladanie dat autority + ecc_key kluc_autorita; + byte pem_autorita[4096]; + byte der_autorita[4096]; + word32 der_autorita_velkost; + + //vytvorenie struktury ecc_key autority zo sukromneho kluca vo formate PEM ulozeneho v subore certifikaty/autorita_ecc.key + memset(pem_autorita, 0, sizeof(pem_autorita)); + FILE* subor = fopen("../certifikaty/autorita_ecc.key", "rb"); + fread(pem_autorita, 1, 4096 , subor); + fclose(subor); + word32 index = 0; //nastavi odkial zacat citat buffer + der_autorita_velkost = wolfSSL_KeyPemToDer(pem_autorita, sizeof(pem_autorita), der_autorita, sizeof(der_autorita), ""); + wc_EccPrivateKeyDecode(der_autorita, &index, &kluc_autorita, der_autorita_velkost); + ecc_key* k = &kluc_autorita; + if (k == NULL) + { + fprintf(stderr, "Nepodarilo sa vytvorit ecc_key strukturu z kluca autority\n"); + return -1; + } + + //generator nahodnych cisel + WC_RNG generator; + wc_InitRng(&generator); + + //premenne pre ukladanie dat vygenerovaneho kluca + ecc_key kluc; + byte der_kluc[4096]; + word32 der_kluc_velkost; + byte pem_kluc[4096]; + word32 pem_kluc_velkost; + + //vygenerovanie kluca + wc_ecc_init(&kluc); + uspech = wc_ecc_make_key_ex(&generator, pocet_bitov, &kluc, kluc_krivka); + if(uspech != 0) + { + fprintf(stderr, "Chyba pri generovani kluca.\nCislo chyby: %d\nDovod chyby: %s\n", uspech, wc_GetErrorString(uspech)); + return -1; + } + der_kluc_velkost = wc_EccKeyToDer(&kluc, der_kluc, sizeof(der_kluc)); + pem_kluc_velkost = wc_DerToPem(der_kluc, der_kluc_velkost, pem_kluc, sizeof(pem_kluc), ECC_PRIVATEKEY_TYPE); + + //nacitanie vygenerovaneho kluca do WOLFSSL_CTX struktury + uspech = wolfSSL_CTX_use_PrivateKey_buffer(ctx, pem_kluc, pem_kluc_velkost, SSL_FILETYPE_PEM); + if(uspech != SSL_SUCCESS) + { + fprintf(stderr, "Chyba pri nacitani vygenerovaneho kluca.\nCislo chyby: %d\nDovod chyby: %s\n", uspech, wc_GetErrorString(uspech)); + return -1; + } + + printf("ECC kluc bol uspesne vygenerovany a nacitany.\n"); + + //premenne pre ukladanie dat certifikatu + Cert certifikat; + byte der_certifikat[4096]; + word32 der_certifikat_velkost; + byte pem_certifikat[4096]; + word32 pem_certifikat_velkost; + + //vygenerovanie a podpis certifikatu + wc_InitCert(&certifikat); + strncpy(certifikat.subject.country, krajina, CTC_NAME_SIZE); + strncpy(certifikat.subject.state, "-", CTC_NAME_SIZE); + strncpy(certifikat.subject.locality, mesto, CTC_NAME_SIZE); + strncpy(certifikat.subject.org, "-", CTC_NAME_SIZE); + strncpy(certifikat.subject.unit, "-", CTC_NAME_SIZE); + strncpy(certifikat.subject.commonName, domena, CTC_NAME_SIZE); + strncpy(certifikat.subject.email, email, CTC_NAME_SIZE); + certifikat.isCA = 0; + certifikat.sigType = algoritmus; + uspech = wc_SetIssuer(&certifikat, "../certifikaty/autorita_ecc.pem"); + if(uspech != 0) + { + fprintf(stderr, "Nastala chyba pri nastaveni autority.\nCislo chyby: %d\nDovod chyby: %s\n", uspech, wc_GetErrorString(uspech)); + return -1; + } + der_certifikat_velkost = wc_MakeCert(&certifikat, der_certifikat, sizeof(der_certifikat), NULL, &kluc, &generator); + if(der_certifikat_velkost < 0) + { + fprintf(stderr, "Nastala chyba pri vytvoreni suboru DER s certifikatom.\n"); + return -1; + } + der_certifikat_velkost = wc_SignCert(certifikat.bodySz, certifikat.sigType, der_certifikat, sizeof(der_certifikat), NULL, &kluc_autorita, &generator); + if(der_certifikat_velkost < 0) + { + fprintf(stderr, "Nastala chyba pri podpisovani certifikatu.\n"); + return -1; + } + memset(pem_certifikat, 0, sizeof(pem_certifikat)); + pem_certifikat_velkost = wc_DerToPem(der_certifikat, der_certifikat_velkost, pem_certifikat, sizeof(pem_certifikat), CERT_TYPE); + if(pem_certifikat_velkost < 0) + { + fprintf(stderr, "Nastala chyba pri vytvoreni suboru PEM s certifikatom.\n"); + return -1; + } + + //nacitanie vygenerovaneho certifikatu do WOLFSSL_CTX struktury + uspech = wolfSSL_CTX_use_certificate_buffer(ctx, pem_certifikat, pem_certifikat_velkost, SSL_FILETYPE_PEM); + if(uspech != SSL_SUCCESS) + { + fprintf(stderr, "Chyba pri generovani certifikatu.\nCislo chyby: %d\nDovod chyby: %s\n", uspech, wc_GetErrorString(uspech)); + return -1; + } + printf("Certifikat bol uspesne vygenerovany a podpisany\n"); + + if(!wolfSSL_CTX_check_private_key(ctx)) + { + fprintf(stderr, "Sukromny kluc sa nezhoduje s certifikatom\n"); + return -1; + } + return 0; +} + +int nacitat_certifikaty(WOLFSSL_CTX* ctx, const char* subor_certifikat, const char* subor_kluc) +{ + int uspech = 0; + + //nacitanie certifikatu do WOLFSSL_CTX struktury, cesta ku suboru sa predava z argumentu funkcie + uspech = wolfSSL_CTX_use_certificate_file(ctx, subor_certifikat, SSL_FILETYPE_PEM); + if(uspech != SSL_SUCCESS) + { + printf("Chyba pri nacitani certifikatu\n"); + return -1; + } + + //nacitanie sukromneho kluca do WOLFSSL_CTX struktury, cesta ku suboru sa predava z argumentu funkcie + uspech = wolfSSL_CTX_use_PrivateKey_file(ctx, subor_kluc, SSL_FILETYPE_PEM); + if(uspech != SSL_SUCCESS) + { + printf("Chyba pri nacitani kluca\n"); + return -1; + } + + printf("Certifikat a kluc boli uspesne nacitane\n"); + + //kontrola sukromneho kluca + if(!wolfSSL_CTX_check_private_key(ctx)) + { + fprintf(stderr, "Sukromny kluc sa nezhoduje s certifikatom\n"); + return -1; + } + return 0; +} + +void zobraz_certifikat(WOLFSSL* ssl) +{ + printf("Informacie o certifikate:\n"); + WOLFSSL_X509 *certifikat = wolfSSL_get_peer_certificate(ssl); + char* pole; + if (!certifikat) + { + printf("Nebolo mozne ziskat ziadny certifikat\n"); + } + if ((pole = wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name(certifikat), 0, 0))) + { + printf("Nazov domeny: %s\n", pole); + //wolfSSL_free(line); + } + if ((pole = wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_issuer_name(certifikat), 0, 0))) + { + printf("Certifikacna autorita: %s\n", pole); + //wolfSSL_free(line); + } + X509_free(certifikat); +} + + +void ukoncit_spojenie(WOLFSSL *ssl, WOLFSSL_CTX *ctx) +{ + printf("Ukoncujem program.\n"); + wolfSSL_shutdown(ssl); + wolfSSL_free(ssl); + printf("Spojenie ukoncene.\n"); + wolfSSL_CTX_free(ctx); + wolfSSL_Cleanup(); + printf("Program bol ukonceny.\n"); +} diff --git a/kniznica/kryptografia.h b/kniznica/kryptografia.h new file mode 100644 index 0000000..b20ebed --- /dev/null +++ b/kniznica/kryptografia.h @@ -0,0 +1,73 @@ +////////////////////////////////////////////////// +// Bakalarska praca // +// Meno studenta: Tomas Lukac // +// Veduci BP: prof. Ing. Milos Drutarovsky CSc. // +// Skola: KEMT FEI TUKE // +// Datum poslednej upravy: 9.3.2020 // +////////////////////////////////////////////////// + +#ifndef __KRYPTOGRAFIA_H__ +#define __KRYPTOGRAFIA_H__ + +#include +#include +#include +#include +#include +#include +#include + +int generovat_ecc_certifikat(WOLFSSL_CTX* ctx, int pocet_bitov, ecc_curve_id kluc_krivka, int algoritmus, char* krajina, char* mesto, char* domena, char* email); +int generovat_rsa_certifikat(WOLFSSL_CTX* ctx, int pocet_bitov, int exponent, int algoritmus, char* krajina, char* mesto, char* domena, char* email); + +/** + * nastav_ctx_klient : realizuje vytvorenie a inicializaciu CTX struktury + * na zaklade verzie tls (client method) + * @vrati smernik na ctx strukturu + */ +WOLFSSL_CTX* nastavit_ctx_klient(); + +/** + * nastav_ctx_server: realizuje vytvorenie a inicializaciu CTX struktury + * na zaklade verzie tls (server method) + * @vrati smernik na ctx strukturu + */ +WOLFSSL_CTX* nastavit_ctx_server(); + +/** + * Zobrazi sifru na ktorej sa strany dohodli + * @parameter WOLFSSL* ssl : ukazuje na aktualnu relaciu + */ +void zobraz_sifru(WOLFSSL* ssl); + +/** + * nastav_sifry: umoznuje manualne nastavit sifrovaci subor + * @parameter WOLFSSL_CTX* ctx : ukazuje na WOLFSSL_CTX strukturu + * @parameter const char* sifry : retazec, ktory sa sklada z nazvov sifier oddelenych pomocou znak ":" + * vyber sifry zakazeme vlozenim znaku "!" pred danu sifru + */ +void nastav_sifry(WOLFSSL_CTX* ctx, const char* sifry); + +/** + * nacitat_certifikaty: realizuje nacitanie certifikatov zo suborov do struktury WOLFSSL_CTX + * @parameter WOLFSSL_CTX* ctx : ukazuje na WOLFSSL_CTX strukturu + * @parameter const char* subor_certifikat : absolutna cesta ku suboru s certifikatom vo formate PEM + * @parameter const char* subor_kluc : absolutna cesta ku suboru so sukromnym klucom vo formate PEM + * @vrati int : operacia bola uspesna(0), neuspesna(-1) + */ +int nacitat_certifikaty(WOLFSSL_CTX* ctx, const char* subor_certifikat, const char* subor_kluc); + +/** + * zobraz_certifikat: realizuje vypis udajov extrahovanych z prijateho certifikatu + * @parameter WOLFSSL* ssl : ukazuje na aktualnu relaciu + */ +void zobraz_certifikat(WOLFSSL* ssl); + +/** + * ukoncit_spojenie: realizuje ukoncenie zabezpeceneho tls prenosoveho kanalu + * @parameter WOLFSSL* ssl : ukazuje na aktualnu relaciu + * @parameter WOLFSSL_CTX* ctx : ukazuje na WOLFSSL_CTX strukturu + */ +void ukoncit_spojenie(WOLFSSL *ssl, WOLFSSL_CTX *ctx); + +#endif diff --git a/kniznica/rs232.c b/kniznica/rs232.c new file mode 100644 index 0000000..6b0e872 --- /dev/null +++ b/kniznica/rs232.c @@ -0,0 +1,873 @@ +/* +*************************************************************************** +* +* Author: Teunis van Beelen +* +* Copyright (C) 2005 - 2019 Teunis van Beelen +* +* Email: teuniz@protonmail.com +* +*************************************************************************** +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*************************************************************************** +*/ + + +/* Last revision: May 31, 2019 */ +/* Added support for hardware flow control using RTS and CTS lines */ +/* For more info and how to use this library, visit: http://www.teuniz.net/RS-232/ */ + + +#include "rs232.h" + + +#if defined(__linux__) || defined(__FreeBSD__) /* Linux & FreeBSD */ + +#define RS232_PORTNR 38 + + +int Cport[RS232_PORTNR], + error; + +struct termios new_port_settings, + old_port_settings[RS232_PORTNR]; + +const char *comports[RS232_PORTNR]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2","/dev/ttyS3","/dev/ttyS4","/dev/ttyS5", + "/dev/ttyS6","/dev/ttyS7","/dev/ttyS8","/dev/ttyS9","/dev/ttyS10","/dev/ttyS11", + "/dev/ttyS12","/dev/ttyS13","/dev/ttyS14","/dev/ttyS15","/dev/ttyUSB0", + "/dev/ttyUSB1","/dev/ttyUSB2","/dev/ttyUSB3","/dev/ttyUSB4","/dev/ttyUSB5", + "/dev/ttyAMA0","/dev/ttyAMA1","/dev/ttyACM0","/dev/ttyACM1", + "/dev/rfcomm0","/dev/rfcomm1","/dev/ircomm0","/dev/ircomm1", + "/dev/cuau0","/dev/cuau1","/dev/cuau2","/dev/cuau3", + "/dev/cuaU0","/dev/cuaU1","/dev/cuaU2","/dev/cuaU3"}; + +int RS232_OpenComport(int comport_number, int baudrate, const char *mode, int flowctrl) +{ + int baudr, + status; + + if((comport_number>=RS232_PORTNR)||(comport_number<0)) + { + printf("illegal comport number\n"); + return(1); + } + + switch(baudrate) + { + case 50 : baudr = B50; + break; + case 75 : baudr = B75; + break; + case 110 : baudr = B110; + break; + case 134 : baudr = B134; + break; + case 150 : baudr = B150; + break; + case 200 : baudr = B200; + break; + case 300 : baudr = B300; + break; + case 600 : baudr = B600; + break; + case 1200 : baudr = B1200; + break; + case 1800 : baudr = B1800; + break; + case 2400 : baudr = B2400; + break; + case 4800 : baudr = B4800; + break; + case 9600 : baudr = B9600; + break; + case 19200 : baudr = B19200; + break; + case 38400 : baudr = B38400; + break; + case 57600 : baudr = B57600; + break; + case 115200 : baudr = B115200; + break; + case 230400 : baudr = B230400; + break; + case 460800 : baudr = B460800; + break; + case 500000 : baudr = B500000; + break; + case 576000 : baudr = B576000; + break; + case 921600 : baudr = B921600; + break; + case 1000000 : baudr = B1000000; + break; + case 1152000 : baudr = B1152000; + break; + case 1500000 : baudr = B1500000; + break; + case 2000000 : baudr = B2000000; + break; + case 2500000 : baudr = B2500000; + break; + case 3000000 : baudr = B3000000; + break; + case 3500000 : baudr = B3500000; + break; + case 4000000 : baudr = B4000000; + break; + default : printf("invalid baudrate\n"); + return(1); + break; + } + + int cbits=CS8, + cpar=0, + ipar=IGNPAR, + bstop=0; + + if(strlen(mode) != 3) + { + printf("invalid mode \"%s\"\n", mode); + return(1); + } + + switch(mode[0]) + { + case '8': cbits = CS8; + break; + case '7': cbits = CS7; + break; + case '6': cbits = CS6; + break; + case '5': cbits = CS5; + break; + default : printf("invalid number of data-bits '%c'\n", mode[0]); + return(1); + break; + } + + switch(mode[1]) + { + case 'N': + case 'n': cpar = 0; + ipar = IGNPAR; + break; + case 'E': + case 'e': cpar = PARENB; + ipar = INPCK; + break; + case 'O': + case 'o': cpar = (PARENB | PARODD); + ipar = INPCK; + break; + default : printf("invalid parity '%c'\n", mode[1]); + return(1); + break; + } + + switch(mode[2]) + { + case '1': bstop = 0; + break; + case '2': bstop = CSTOPB; + break; + default : printf("invalid number of stop bits '%c'\n", mode[2]); + return(1); + break; + } + +/* +http://pubs.opengroup.org/onlinepubs/7908799/xsh/termios.h.html + +http://man7.org/linux/man-pages/man3/termios.3.html +*/ + + Cport[comport_number] = open(comports[comport_number], O_RDWR | O_NOCTTY | O_NDELAY); + if(Cport[comport_number]==-1) + { + perror("unable to open comport "); + return(1); + } + + /* lock access so that another process can't also use the port */ + if(flock(Cport[comport_number], LOCK_EX | LOCK_NB) != 0) + { + close(Cport[comport_number]); + perror("Another process has locked the comport."); + return(1); + } + + error = tcgetattr(Cport[comport_number], old_port_settings + comport_number); + if(error==-1) + { + close(Cport[comport_number]); + flock(Cport[comport_number], LOCK_UN); /* free the port so that others can use it. */ + perror("unable to read portsettings "); + return(1); + } + memset(&new_port_settings, 0, sizeof(new_port_settings)); /* clear the new struct */ + + new_port_settings.c_cflag = cbits | cpar | bstop | CLOCAL | CREAD; + if(flowctrl) + { + new_port_settings.c_cflag |= CRTSCTS; + } + new_port_settings.c_iflag = ipar; + new_port_settings.c_oflag = 0; + new_port_settings.c_lflag = 0; + new_port_settings.c_cc[VMIN] = 0; /* block untill n bytes are received */ + new_port_settings.c_cc[VTIME] = 0; /* block untill a timer expires (n * 100 mSec.) */ + + cfsetispeed(&new_port_settings, baudr); + cfsetospeed(&new_port_settings, baudr); + + error = tcsetattr(Cport[comport_number], TCSANOW, &new_port_settings); + if(error==-1) + { + tcsetattr(Cport[comport_number], TCSANOW, old_port_settings + comport_number); + close(Cport[comport_number]); + flock(Cport[comport_number], LOCK_UN); /* free the port so that others can use it. */ + perror("unable to adjust portsettings "); + return(1); + } + +/* http://man7.org/linux/man-pages/man4/tty_ioctl.4.html */ + + if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1) + { + tcsetattr(Cport[comport_number], TCSANOW, old_port_settings + comport_number); + flock(Cport[comport_number], LOCK_UN); /* free the port so that others can use it. */ + perror("unable to get portstatus"); + return(1); + } + + status |= TIOCM_DTR; /* turn on DTR */ + status |= TIOCM_RTS; /* turn on RTS */ + + if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1) + { + tcsetattr(Cport[comport_number], TCSANOW, old_port_settings + comport_number); + flock(Cport[comport_number], LOCK_UN); /* free the port so that others can use it. */ + perror("unable to set portstatus"); + return(1); + } + + return(0); +} + + +int RS232_PollComport(int comport_number, unsigned char *buf, int size) +{ + int n; + + n = read(Cport[comport_number], buf, size); + + if(n < 0) + { + if(errno == EAGAIN) return 0; + } + + return(n); +} + + +int RS232_SendByte(int comport_number, unsigned char byte) +{ + int n = write(Cport[comport_number], &byte, 1); + if(n < 0) + { + if(errno == EAGAIN) + { + return 0; + } + else + { + return 1; + } + } + + return(0); +} + + +int RS232_SendBuf(int comport_number, unsigned char *buf, int size) +{ + int n = write(Cport[comport_number], buf, size); + if(n < 0) + { + if(errno == EAGAIN) + { + return 0; + } + else + { + return -1; + } + } + + return(n); +} + + +void RS232_CloseComport(int comport_number) +{ + int status; + + if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1) + { + perror("unable to get portstatus"); + } + + status &= ~TIOCM_DTR; /* turn off DTR */ + status &= ~TIOCM_RTS; /* turn off RTS */ + + if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1) + { + perror("unable to set portstatus"); + } + + tcsetattr(Cport[comport_number], TCSANOW, old_port_settings + comport_number); + close(Cport[comport_number]); + + flock(Cport[comport_number], LOCK_UN); /* free the port so that others can use it. */ +} + +/* +Constant Description +TIOCM_LE DSR (data set ready/line enable) +TIOCM_DTR DTR (data terminal ready) +TIOCM_RTS RTS (request to send) +TIOCM_ST Secondary TXD (transmit) +TIOCM_SR Secondary RXD (receive) +TIOCM_CTS CTS (clear to send) +TIOCM_CAR DCD (data carrier detect) +TIOCM_CD see TIOCM_CAR +TIOCM_RNG RNG (ring) +TIOCM_RI see TIOCM_RNG +TIOCM_DSR DSR (data set ready) + +http://man7.org/linux/man-pages/man4/tty_ioctl.4.html +*/ + +int RS232_IsDCDEnabled(int comport_number) +{ + int status; + + ioctl(Cport[comport_number], TIOCMGET, &status); + + if(status&TIOCM_CAR) return(1); + else return(0); +} + + +int RS232_IsRINGEnabled(int comport_number) +{ + int status; + + ioctl(Cport[comport_number], TIOCMGET, &status); + + if(status&TIOCM_RNG) return(1); + else return(0); +} + + +int RS232_IsCTSEnabled(int comport_number) +{ + int status; + + ioctl(Cport[comport_number], TIOCMGET, &status); + + if(status&TIOCM_CTS) return(1); + else return(0); +} + + +int RS232_IsDSREnabled(int comport_number) +{ + int status; + + ioctl(Cport[comport_number], TIOCMGET, &status); + + if(status&TIOCM_DSR) return(1); + else return(0); +} + + +void RS232_enableDTR(int comport_number) +{ + int status; + + if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1) + { + perror("unable to get portstatus"); + } + + status |= TIOCM_DTR; /* turn on DTR */ + + if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1) + { + perror("unable to set portstatus"); + } +} + + +void RS232_disableDTR(int comport_number) +{ + int status; + + if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1) + { + perror("unable to get portstatus"); + } + + status &= ~TIOCM_DTR; /* turn off DTR */ + + if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1) + { + perror("unable to set portstatus"); + } +} + + +void RS232_enableRTS(int comport_number) +{ + int status; + + if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1) + { + perror("unable to get portstatus"); + } + + status |= TIOCM_RTS; /* turn on RTS */ + + if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1) + { + perror("unable to set portstatus"); + } +} + + +void RS232_disableRTS(int comport_number) +{ + int status; + + if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1) + { + perror("unable to get portstatus"); + } + + status &= ~TIOCM_RTS; /* turn off RTS */ + + if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1) + { + perror("unable to set portstatus"); + } +} + + +void RS232_flushRX(int comport_number) +{ + tcflush(Cport[comport_number], TCIFLUSH); +} + + +void RS232_flushTX(int comport_number) +{ + tcflush(Cport[comport_number], TCOFLUSH); +} + + +void RS232_flushRXTX(int comport_number) +{ + tcflush(Cport[comport_number], TCIOFLUSH); +} + + +#else /* windows */ + +#define RS232_PORTNR 32 + +HANDLE Cport[RS232_PORTNR]; + + +const char *comports[RS232_PORTNR]={"\\\\.\\COM1", "\\\\.\\COM2", "\\\\.\\COM3", "\\\\.\\COM4", + "\\\\.\\COM5", "\\\\.\\COM6", "\\\\.\\COM7", "\\\\.\\COM8", + "\\\\.\\COM9", "\\\\.\\COM10", "\\\\.\\COM11", "\\\\.\\COM12", + "\\\\.\\COM13", "\\\\.\\COM14", "\\\\.\\COM15", "\\\\.\\COM16", + "\\\\.\\COM17", "\\\\.\\COM18", "\\\\.\\COM19", "\\\\.\\COM20", + "\\\\.\\COM21", "\\\\.\\COM22", "\\\\.\\COM23", "\\\\.\\COM24", + "\\\\.\\COM25", "\\\\.\\COM26", "\\\\.\\COM27", "\\\\.\\COM28", + "\\\\.\\COM29", "\\\\.\\COM30", "\\\\.\\COM31", "\\\\.\\COM32"}; + +char mode_str[128]; + + +int RS232_OpenComport(int comport_number, int baudrate, const char *mode, int flowctrl) +{ + if((comport_number>=RS232_PORTNR)||(comport_number<0)) + { + printf("illegal comport number\n"); + return(1); + } + + switch(baudrate) + { + case 110 : strcpy(mode_str, "baud=110"); + break; + case 300 : strcpy(mode_str, "baud=300"); + break; + case 600 : strcpy(mode_str, "baud=600"); + break; + case 1200 : strcpy(mode_str, "baud=1200"); + break; + case 2400 : strcpy(mode_str, "baud=2400"); + break; + case 4800 : strcpy(mode_str, "baud=4800"); + break; + case 9600 : strcpy(mode_str, "baud=9600"); + break; + case 19200 : strcpy(mode_str, "baud=19200"); + break; + case 38400 : strcpy(mode_str, "baud=38400"); + break; + case 57600 : strcpy(mode_str, "baud=57600"); + break; + case 115200 : strcpy(mode_str, "baud=115200"); + break; + case 128000 : strcpy(mode_str, "baud=128000"); + break; + case 256000 : strcpy(mode_str, "baud=256000"); + break; + case 500000 : strcpy(mode_str, "baud=500000"); + break; + case 921600 : strcpy(mode_str, "baud=921600"); + break; + case 1000000 : strcpy(mode_str, "baud=1000000"); + break; + case 1500000 : strcpy(mode_str, "baud=1500000"); + break; + case 2000000 : strcpy(mode_str, "baud=2000000"); + break; + case 3000000 : strcpy(mode_str, "baud=3000000"); + break; + default : printf("invalid baudrate\n"); + return(1); + break; + } + + if(strlen(mode) != 3) + { + printf("invalid mode \"%s\"\n", mode); + return(1); + } + + switch(mode[0]) + { + case '8': strcat(mode_str, " data=8"); + break; + case '7': strcat(mode_str, " data=7"); + break; + case '6': strcat(mode_str, " data=6"); + break; + case '5': strcat(mode_str, " data=5"); + break; + default : printf("invalid number of data-bits '%c'\n", mode[0]); + return(1); + break; + } + + switch(mode[1]) + { + case 'N': + case 'n': strcat(mode_str, " parity=n"); + break; + case 'E': + case 'e': strcat(mode_str, " parity=e"); + break; + case 'O': + case 'o': strcat(mode_str, " parity=o"); + break; + default : printf("invalid parity '%c'\n", mode[1]); + return(1); + break; + } + + switch(mode[2]) + { + case '1': strcat(mode_str, " stop=1"); + break; + case '2': strcat(mode_str, " stop=2"); + break; + default : printf("invalid number of stop bits '%c'\n", mode[2]); + return(1); + break; + } + + if(flowctrl) + { + strcat(mode_str, " xon=off to=off odsr=off dtr=on rts=off"); + } + else + { + strcat(mode_str, " xon=off to=off odsr=off dtr=on rts=on"); + } + +/* +http://msdn.microsoft.com/en-us/library/windows/desktop/aa363145%28v=vs.85%29.aspx + +http://technet.microsoft.com/en-us/library/cc732236.aspx + +https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-_dcb +*/ + + Cport[comport_number] = CreateFileA(comports[comport_number], + GENERIC_READ|GENERIC_WRITE, + 0, /* no share */ + NULL, /* no security */ + OPEN_EXISTING, + 0, /* no threads */ + NULL); /* no templates */ + + if(Cport[comport_number]==INVALID_HANDLE_VALUE) + { + printf("unable to open comport\n"); + return(1); + } + + DCB port_settings; + memset(&port_settings, 0, sizeof(port_settings)); /* clear the new struct */ + port_settings.DCBlength = sizeof(port_settings); + + if(!BuildCommDCBA(mode_str, &port_settings)) + { + printf("unable to set comport dcb settings\n"); + CloseHandle(Cport[comport_number]); + return(1); + } + + if(flowctrl) + { + port_settings.fOutxCtsFlow = TRUE; + port_settings.fRtsControl = RTS_CONTROL_HANDSHAKE; + } + + if(!SetCommState(Cport[comport_number], &port_settings)) + { + printf("unable to set comport cfg settings\n"); + CloseHandle(Cport[comport_number]); + return(1); + } + + COMMTIMEOUTS Cptimeouts; + + Cptimeouts.ReadIntervalTimeout = MAXDWORD; + Cptimeouts.ReadTotalTimeoutMultiplier = 0; + Cptimeouts.ReadTotalTimeoutConstant = 0; + Cptimeouts.WriteTotalTimeoutMultiplier = 0; + Cptimeouts.WriteTotalTimeoutConstant = 0; + + if(!SetCommTimeouts(Cport[comport_number], &Cptimeouts)) + { + printf("unable to set comport time-out settings\n"); + CloseHandle(Cport[comport_number]); + return(1); + } + + return(0); +} + + +int RS232_PollComport(int comport_number, unsigned char *buf, int size) +{ + int n; + +/* added the void pointer cast, otherwise gcc will complain about */ +/* "warning: dereferencing type-punned pointer will break strict aliasing rules" */ + + ReadFile(Cport[comport_number], buf, size, (LPDWORD)((void *)&n), NULL); + + return(n); +} + + +int RS232_SendByte(int comport_number, unsigned char byte) +{ + int n; + + WriteFile(Cport[comport_number], &byte, 1, (LPDWORD)((void *)&n), NULL); + + if(n<0) return(1); + + return(0); +} + + +int RS232_SendBuf(int comport_number, unsigned char *buf, int size) +{ + int n; + + if(WriteFile(Cport[comport_number], buf, size, (LPDWORD)((void *)&n), NULL)) + { + return(n); + } + + return(-1); +} + + +void RS232_CloseComport(int comport_number) +{ + CloseHandle(Cport[comport_number]); +} + +/* +http://msdn.microsoft.com/en-us/library/windows/desktop/aa363258%28v=vs.85%29.aspx +*/ + +int RS232_IsDCDEnabled(int comport_number) +{ + int status; + + GetCommModemStatus(Cport[comport_number], (LPDWORD)((void *)&status)); + + if(status&MS_RLSD_ON) return(1); + else return(0); +} + + +int RS232_IsRINGEnabled(int comport_number) +{ + int status; + + GetCommModemStatus(Cport[comport_number], (LPDWORD)((void *)&status)); + + if(status&MS_RING_ON) return(1); + else return(0); +} + + +int RS232_IsCTSEnabled(int comport_number) +{ + int status; + + GetCommModemStatus(Cport[comport_number], (LPDWORD)((void *)&status)); + + if(status&MS_CTS_ON) return(1); + else return(0); +} + + +int RS232_IsDSREnabled(int comport_number) +{ + int status; + + GetCommModemStatus(Cport[comport_number], (LPDWORD)((void *)&status)); + + if(status&MS_DSR_ON) return(1); + else return(0); +} + + +void RS232_enableDTR(int comport_number) +{ + EscapeCommFunction(Cport[comport_number], SETDTR); +} + + +void RS232_disableDTR(int comport_number) +{ + EscapeCommFunction(Cport[comport_number], CLRDTR); +} + + +void RS232_enableRTS(int comport_number) +{ + EscapeCommFunction(Cport[comport_number], SETRTS); +} + + +void RS232_disableRTS(int comport_number) +{ + EscapeCommFunction(Cport[comport_number], CLRRTS); +} + +/* +https://msdn.microsoft.com/en-us/library/windows/desktop/aa363428%28v=vs.85%29.aspx +*/ + +void RS232_flushRX(int comport_number) +{ + PurgeComm(Cport[comport_number], PURGE_RXCLEAR | PURGE_RXABORT); +} + + +void RS232_flushTX(int comport_number) +{ + PurgeComm(Cport[comport_number], PURGE_TXCLEAR | PURGE_TXABORT); +} + + +void RS232_flushRXTX(int comport_number) +{ + PurgeComm(Cport[comport_number], PURGE_RXCLEAR | PURGE_RXABORT); + PurgeComm(Cport[comport_number], PURGE_TXCLEAR | PURGE_TXABORT); +} + + +#endif + + +void RS232_cputs(int comport_number, const char *text) /* sends a string to serial port */ +{ + while(*text != 0) RS232_SendByte(comport_number, *(text++)); +} + + +/* return index in comports matching to device name or -1 if not found */ +int RS232_GetPortnr(const char *devname) +{ + int i; + + char str[32]; + +#if defined(__linux__) || defined(__FreeBSD__) /* Linux & FreeBSD */ + strcpy(str, "/dev/"); +#else /* windows */ + strcpy(str, "\\\\.\\"); +#endif + strncat(str, devname, 16); + str[31] = 0; + + for(i=0; i. +* +*************************************************************************** +*/ + +/* Last revision: May 31, 2019 */ + +/* For more info and how to use this library, visit: http://www.teuniz.net/RS-232/ */ + + +#ifndef rs232_INCLUDED +#define rs232_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + + + +#if defined(__linux__) || defined(__FreeBSD__) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#else + +#include + +#endif + +int RS232_OpenComport(int, int, const char *, int); +int RS232_PollComport(int, unsigned char *, int); +int RS232_SendByte(int, unsigned char); +int RS232_SendBuf(int, unsigned char *, int); +void RS232_CloseComport(int); +void RS232_cputs(int, const char *); +int RS232_IsDCDEnabled(int); +int RS232_IsRINGEnabled(int); +int RS232_IsCTSEnabled(int); +int RS232_IsDSREnabled(int); +void RS232_enableDTR(int); +void RS232_disableDTR(int); +void RS232_enableRTS(int); +void RS232_disableRTS(int); +void RS232_flushRX(int); +void RS232_flushTX(int); +void RS232_flushRXTX(int); +int RS232_GetPortnr(const char *); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + + diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..aa424fc --- /dev/null +++ b/readme.txt @@ -0,0 +1,54 @@ +Repozitar: Bakalarska praca +Meno studenta: Tomas Lukac +Datum poslednej upravy: 24.2.2020 +---------------------------- +Zoznam zdrojovych suborov + certifikaty + |__server.pem + |__server.key + kniznica + |__komunikacia.h + |__komunikacia.c + |__kryptografia.h + |__kryptografia.c + |__vstup.h + |__vstup.c + klient.c + server.c + Makefile + +Opis aplikacie + Realizuje zabezpecenu vymenu sprav medzi klientom a serverom + a autentizaciu servera klientom vyuzitim kniznice WolfSSL + +Navod na prelozenie a spustenie (Linux) + 1. prelozenie kniznice wolfssl s podporou OpenSSL (v adresari s kniznicou) + ./configure --enable-opensslextra --enable-certgen --enable-keygen + make + sudo make install + 2. prelozenie programov (v adresari) + make all + 3. spustenie + ./server -port port + ./server -port -g rsa|ecc + ./klient -ip 127.0.0.1 -port + +Navod na prelozenie a spustenie (Windows) + 1. prelozenie programov (v adresari) + mingw32-make all + 2. spustenie + server -port port + server -port -g rsa|ecc + klient -ip 127.0.0.1 -port port + +Postup prace: + 1. Spracovanie chyb pomocou stderr + 2. Doplnenie hlavicky do zdrojovych suborov + 3. Vytvorenie rutiny pre odosielanie suborov namiesto sprav + 4. Upravenie Makefile pre kompilovanie na platforme Windows + 5. Implementacia generovania certifikatov + 6. Implementacia obojsmernej autentizacie + +TODO: + 4. vytvorenie rozhrania pre komunikacny kanal rs232 pomocou wolfssl abstraction layer + (wolfssl.com/docs/wolfssl-manual/ch5) diff --git a/rs232_kanal/Makefile b/rs232_kanal/Makefile new file mode 100644 index 0000000..6062def --- /dev/null +++ b/rs232_kanal/Makefile @@ -0,0 +1,46 @@ +################################################## +## Bakalarska praca ## +## Meno studenta: Tomas Lukac ## +## Veduci BP: prof. Ing. Milos Drutarovsky CSc. ## +## Skola: KEMT FEI TUKE ## +## Datum poslednej upravy: 9.3.2020 ## +################################################## + +#prekladac +CC = gcc + +#prepinace pre prekladac +CFLAGS = -Wall -Wcpp -fPIC -DREPLICATION_ENABLED -DJOURNALING_ENABLED -I./../wolfssl_hlavickove_subory/ +LIB32 = -L. -lwolfssl -lws2_32 -Os +LIB64 = -L. -lwolfssl -lws2_32 -m64 + +all: klient server + +klient: klient.o kryptografia.o komunikacia.o rs232.o + $(CC) $(CFLAGS) -o klient klient.o kryptografia.o komunikacia.o rs232.o $(LIB64) + +server: server.o kryptografia.o komunikacia.o rs232.o + $(CC) $(CFLAGS) -o server server.o kryptografia.o komunikacia.o rs232.o $(LIB64) + +klient.o: klient.c + $(CC) -c klient.c $(LIB64) + +server.o: server.c + $(CC) -c server.c $(LIB64) + +kryptografia.o: ../kniznica/kryptografia.c ../kniznica/kryptografia.h + $(CC) -c ../kniznica/kryptografia.c $(LIB64) + +komunikacia.o: ../kniznica/komunikacia.c ../kniznica/komunikacia.h + $(CC) -c ../kniznica/komunikacia.c $(LIB64) + +rs232.o: ../kniznica/rs232.c ../kniznica/rs232.h + $(CC) -c ../kniznica/rs232.c $(LIB64) + +.PHONY: clean + +clean-linux: + rm *.o -f klient server + +clean-win: + del *.o klient.exe server.exe \ No newline at end of file diff --git a/rs232_kanal/klient.c b/rs232_kanal/klient.c new file mode 100644 index 0000000..53befc9 --- /dev/null +++ b/rs232_kanal/klient.c @@ -0,0 +1,105 @@ +////////////////////////////////////////////////// +// Bakalarska praca // +// Meno studenta: Tomas Lukac // +// Veduci BP: prof. Ing. Milos Drutarovsky CSc. // +// Skola: KEMT FEI TUKE // +// Datum poslednej upravy: 9.3.2020 // +////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include "../kniznica/kryptografia.h" +#include "../kniznica/rs232.h" + +int cislo_portu = 2; +int baud_frekvencia = 9600; +char rezim[]={'8','N','1', 0}; + +/** + * rs232_zapis: umoznuje zapis dat do serialoveho portu + * @parameter WOLSSL* ssl : ukazuje na aktualnu relaciu + * @parameter char* buf : ukazuje na buffer, do kt. zapise wolfssl zasifrovany text na odoslanie + * @parameter int sz : velkost buffera + * @vrati int + */ +int rs232_zapis(WOLFSSL *ssl, char *buf, int sz, void *ctx) +{ + printf("Klient posiela ...\n"); + int n = RS232_SendBuf(cislo_portu, buf, sz); + printf("Klient poslal %d bajtov...\n", n); + return n; +} + +/** + * rs232_citanie: umoznuje citanie dat zo serialoveho portu + * @parameter WOLFSSL* ssl : ukazuje na aktualnu relaciu + * @parameter char* buf : ukazuje na buffer, kde prichadzajuci zasifrovany text by mal byt nakopirovany + * aby ho wolfssl mohla odsifrovat + * @parameter int sz : velkost buffera + * @vrati int + */ +int rs232_citanie(WOLFSSL *ssl, char *buf, int sz, void *ctx) +{ + printf("Klienta prijima...\n"); + int n; + while(n <= 0) + n = RS232_PollComport(cislo_portu, buf, sz); + printf("Klienta prijal %d bajtov.\n", n); + return n; +} + +int main(int argc, char const *argv[]) +{ + WOLFSSL *ssl; + WOLFSSL_CTX *ctx = NULL; + + if(RS232_OpenComport(cislo_portu, baud_frekvencia, rezim, 1)) + { + printf("Nebolo mozne otvorit serialovy port\n"); + } + + if((ctx = nastavit_ctx_klient()) == NULL) + { + return -1; + } + const char* subor_certifikat = "../certifikaty/klient.pem"; + const char* subor_kluc = "../certifikaty/klient.key"; + if(!nacitat_certifikaty(ctx, subor_certifikat, subor_kluc)) return -1; + + wolfSSL_SetIOSend(ctx, rs232_zapis); + wolfSSL_SetIORecv(ctx, rs232_citanie); + + + if ((ssl = wolfSSL_new(ctx)) == NULL) + { + printf("Nepodarilo sa vytvorit ssl relaciu\n"); + wolfSSL_CTX_free(ctx); + return -1; + } + + wolfSSL_set_fd(ssl, *(int*)ctx); + wolfSSL_set_using_nonblock(ssl, *(int*)ctx); + + int uspech = 0; + if(wolfSSL_connect(ssl) != SSL_SUCCESS) + { + printf("nepodarilo sa pripojit\n"); + return -1; + } + + RS232_CloseComport(cislo_portu); + return 0; +} \ No newline at end of file diff --git a/rs232_kanal/klient.exe b/rs232_kanal/klient.exe new file mode 100644 index 0000000000000000000000000000000000000000..029c18ed707caddb325cd903a64a02b5cfbdbdca GIT binary patch literal 84284 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 AlmGw# literal 0 HcmV?d00001 diff --git a/rs232_kanal/komunikacia.o b/rs232_kanal/komunikacia.o new file mode 100644 index 0000000000000000000000000000000000000000..3adf9f9b3faa0a9b0ab63d34df0c8eb232bb31b2 GIT binary patch literal 4114 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 literal 0 HcmV?d00001 diff --git a/rs232_kanal/server.c b/rs232_kanal/server.c new file mode 100644 index 0000000..707ec0d --- /dev/null +++ b/rs232_kanal/server.c @@ -0,0 +1,118 @@ +////////////////////////////////////////////////// +// Bakalarska praca // +// Meno studenta: Tomas Lukac // +// Veduci BP: prof. Ing. Milos Drutarovsky CSc. // +// Skola: KEMT FEI TUKE // +// Datum poslednej upravy: 9.3.2020 // +////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include "../kniznica/kryptografia.h" +#include "../kniznica/rs232.h" + +int cislo_portu = 3; +int baud_frekvencia = 9600; +char rezim[]={'8','N','1', 0}; + +/** + * rs232_zapis: umoznuje zapis dat do serialoveho portu + * @parameter WOLSSL* ssl : ukazuje na aktualnu relaciu + * @parameter char* buf : ukazuje na buffer, do kt. zapise wolfssl zasifrovany text na odoslanie + * @parameter int sz : velkost buffera + * @vrati int + */ +int rs232_zapis(WOLFSSL *ssl, char *buf, int sz, void *ctx) +{ + printf("Server posiela ...\n"); + int n = RS232_SendBuf(cislo_portu, buf, sz); + printf("Server poslal %d bajtov\n", n); + return n; +} + +/** + * rs232_citanie: umoznuje citanie dat zo serialoveho portu + * @parameter WOLFSSL* ssl : ukazuje na aktualnu relaciu + * @parameter char* buf : ukazuje na buffer, kde prichadzajuci zasifrovany text by mal byt nakopirovany + * aby ho wolfssl mohla odsifrovat + * @parameter int sz : velkost buffera + * @vrati int + */ +int rs232_citanie(WOLFSSL *ssl, char *buf, int sz, void *ctx) +{ + printf("Server prijima...\n"); + int n; + int prijal = 0; + while(1) + { + n = RS232_PollComport(cislo_portu, buf, sz); + if(n > 0) + { + buf[n] = '\0'; /* always put a "null" at the end of a string! */ + for(int i=0; i < n; i++) + { + if(buf[i] < 32) /* replace unreadable control-codes by dots */ + { + buf[i] = '.'; + } + } + printf("received %i bytes: %s\n", n, (char *)buf); + } + prijal += n; + + } + return n; +} + + +int main(int argc, char const *argv[]) +{ + WOLFSSL *ssl; + WOLFSSL_CTX *ctx = NULL; + + //otvorenie portu pre citanie + if(RS232_OpenComport(cislo_portu, baud_frekvencia, rezim, 1)) + { + printf("Nebolo mozne otvorit serialovy port\n"); + } + + if((ctx = nastavit_ctx_server()) == NULL) + { + return -1; + } + const char* subor_certifikat = "../certifikaty/klient.pem"; + const char* subor_kluc = "../certifikaty/klient.key"; + if(!nacitat_certifikaty(ctx, subor_certifikat, subor_kluc)) return -1; + + wolfSSL_SetIOSend(ctx, rs232_zapis); + wolfSSL_SetIORecv(ctx, rs232_citanie); + + if ((ssl = wolfSSL_new(ctx)) == NULL) + { + printf("Nepodarilo sa vytvorit ssl relaciu\n"); + wolfSSL_CTX_free(ctx); + return -1; + } + + int ret; + if(wolfSSL_accept(ssl) == -1) + { + return -1; + } + + RS232_CloseComport(cislo_portu); + + return 0; +} \ No newline at end of file diff --git a/rs232_kanal/server.exe b/rs232_kanal/server.exe new file mode 100644 index 0000000000000000000000000000000000000000..7a6e303e1420d7bf58a0815ab9717a267af7babb GIT binary patch literal 85660 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 G=l=t%^lN

ey< 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

D!L)T>XZaCVGKQ_&U$( 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%0A=Ox?)A_;64Uy= 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 #$JY;Or3SkY_fuGeBYU4}zEk^!sf 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 + +#define RSA_VELKOST 1024 +#define ECC_VELKOST 32 +#define RSA_EXPONENT 65537 + +int main(int argc, char** argv) +{ + int autentizacia_klienta = 0; + int generovanie_certifikatu = 0; + int nacitanie_zo_suboru = 0; + int ip = 0; + int port = 0; + + #if defined (_WIN32) + WSADATA d; + if(WSAStartup(MAKEWORD(2,2), &d)) + { + printf("Nastala chyba pri inicializacii winsocketu\n"); + return -1; + } + #endif + + int cislo_soketu = 0; + int cislo_portu = 0; + char *ip_adresa = NULL; + const char *subor_certifikat = NULL; + const char *subor_kluc = NULL; + WOLFSSL *ssl; WOLFSSL_CTX *ctx; + + if((ctx = nastavit_ctx_klient()) == NULL) + { + return -1; + } + else + { + //skontroluje ci nebol zadany prepinac "-g" pre moznost generovanie certifikatu, + //ak ano pozrie aky typ certifikatu (v CLI argument hned za nim) bol zvoleny + for(int i = 0; i < argc; i++) + { + if( (!strcmp(argv[i], "-ip")) ) + { + port = 1; + if((argv[i+1] == NULL) ) + { + printf("Nezadali ste ip adresu\n"); + return -1; + } + else + { + ip_adresa = argv[i+1]; + } + } + else if( (!strcmp(argv[i], "-port")) ) + { + ip = 1; + if((argv[i+1] == NULL) ) + { + printf("Nezadali ste cislo portu\n"); + return -1; + } + else + { + cislo_portu = atoi(argv[i+1]); + } + } + else if( (!strcmp(argv[i], "-n")) ) + { + nacitanie_zo_suboru = 1; + if(generovanie_certifikatu) + { + fprintf(stderr, "Nie je mozne zvolit obidve metody nacitania certifikatov naraz\n"); + return -1; + } + if((argv[i+1] == NULL) || (i == argc-1)) + { + printf("Nezadali ste typ certifikatu ktory chcete nacitat zo suboru\n"); + return -1; + } + else if(!strcmp(argv[i+1], "rsa")) + { + wolfSSL_CTX_load_verify_locations(ctx, "../certifikaty/autorita_rsa.pem", NULL); + subor_certifikat = "../certifikaty/server_rsa.pem"; + subor_kluc = "../certifikaty/server_rsa.key"; + if(nacitat_certifikaty(ctx, subor_certifikat, subor_kluc) == -1) return -1; + } + else if(!strcmp(argv[i+1], "ecc")) + { + wolfSSL_CTX_load_verify_locations(ctx, "../certifikaty/autorita_ecc.pem", NULL); + subor_certifikat = "../certifikaty/server_ecc.pem"; + subor_kluc = "../certifikaty/server_ecc.key"; + if(nacitat_certifikaty(ctx, subor_certifikat, subor_kluc) == -1) return -1; + } + else + { + printf("Zadali ste nespravny typ certifikatu\n"); + return -1; + } + } + else if( (!strcmp(argv[i], "-g")) ) + { + generovanie_certifikatu = 1; + if((argv[i+1] == NULL) || (i == argc-1)) + { + printf("Nezadali ste typ certifikatu ktory chcete vygenerovat\n"); + return -1; + } + else if(!strcmp(argv[i+1], "rsa")) + { + wolfSSL_CTX_load_verify_locations(ctx, "../certifikaty/autorita_rsa.pem", NULL); + if(generovat_rsa_certifikat(ctx, RSA_VELKOST, RSA_EXPONENT, CTC_SHA256wRSA, "SR", "Kosice", "Klient.sk", "klient@klient.sk") == -1) + return -1; + } + else if(!strcmp(argv[i+1], "ecc")) + { + wolfSSL_CTX_load_verify_locations(ctx, "../certifikaty/autorita_ecc.pem", NULL); + if(generovat_ecc_certifikat(ctx, ECC_VELKOST, ECC_PRIME239V1, CTC_SHAwECDSA, "SR", "Kosice", "Klient.sk", "klient@klient.sk") == -1) + return -1; + } + else + { + printf("Zadali ste nespravny typ certifikatu\n"); + return -1; + } + } + } + + if(!ip) + { + printf("Nebola zadana ip adresa servera\n"); + return -1; + } + else if(!port) + { + printf("Nebol urceny port\n"); + return -1; + } + if(!generovanie_certifikatu && !nacitanie_zo_suboru) + { + fprintf(stderr, "Nebola zvolena metoda nacitania certifikatov\n"); + printf("Zadajde prepinac -g (generovanie), alebo -n (nacitanie_zo_suboru) s parametrom rsa alebo ecc\n"); + return -1; + } + //umoznuje vybrat sifry ktore sa budu nachadzat v sifrovacom subore + //nastav_sifry(ctx, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"); + + cislo_soketu = pripojit_na_server(ip_adresa, cislo_portu, 10); + + if(!cislo_soketu) return -1; + ssl = wolfSSL_new(ctx); + wolfSSL_set_fd(ssl, cislo_soketu); + int uspech = wolfSSL_connect(ssl); + if(uspech != SSL_SUCCESS) + { + fprintf(stderr, "Nastala chyba v spojeni.\n"); + printf("Skontrolujte certifikaty.\n"); + return -1; + } + zobraz_sifru(ssl); + zobraz_certifikat(ssl); + if(poslat_subor(ssl, ctx, "nieco.txt") == -1) return -1; + ukoncit_spojenie(ssl, ctx); + } + + #if defined (_WIN32) + WSACleanup(); + #endif + return 0; +} diff --git a/tcpip_kanal/klient.exe b/tcpip_kanal/klient.exe new file mode 100644 index 0000000000000000000000000000000000000000..443a5f0d91b6287dce286774fd0063621e5b8fea GIT binary patch literal 82559 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

  • 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 literal 0 HcmV?d00001 diff --git a/tcpip_kanal/klient.o b/tcpip_kanal/klient.o new file mode 100644 index 0000000000000000000000000000000000000000..1c7cdef04ead6c6a7dd3e08460d572eb608d380c GIT binary patch literal 5227 zcmbVQZEPGz8JYCu_2iz25SBs}srdm?g!%(jMRHOZxq;%Ss5C#}2Va7Igr-8OKtdJNJnziy z+^)|yE-QQYndg1y-Dl=~XLfIkPj6&&6gM&US&4dBHV{*R#OgHM%h;|AWB<5CwI9ZX zv$03AMKdrHe#^le8=KD-e1ADxl6#!|ymY|add5!Nob+N0@p9Rzv>(Yj-_{m;=h$#A zTj}<@2)~0ED;)@rc*D8fdt_6eazHP2#T&~#oPXlR@H)owtrrF!hflLLk6Fn#XRhM% z4hXgoJp-uF3mRS2=tmk|Xrp}VEA#p0l}qa=?(_!gx_B*`5AMjfK1K~0c6JfR^>fJ7 zLiCglaXt>Q5S{J7sSd2Pp^TAlMyJruH|FTV!afyrR0e&v?Rot>P%s@)Gk-4My8Ts> zke`mO5|O!}5B-IR215~a&&GUa`QGrSk?n?aVq`zRX)S%5a+uc_ zdJ@hnNIaO9SYL=}=0B3eBWa0uuT7$wm1ab_xxQr$N<~U(fAkhQE<{u@q_#09t0?&V zC6q^}J`Oiu8JWEw%w=-Ie4fH3F`rH{i>u@!xOF<3M~KEdnJ>zu%j8^42iv-)V6Dx6 zB`KYfZ9E7(*v5S1()R#IW-}P!Wrn<_QvL=;tx`^2diGY4yd>q1E|r{0`Tr}q zS4xIhcA4XpkQ{O)_fMGc?h<$nY(p-(j2g>+xfJ`Kee8q9#l{@%S4=KPdg3JV^?m9$ zcR`!S(q>m2pcuxsan!(Mkiow%+Wa$>|aLuT?y&`jO9Xl zKT5eXQ}5CeU*$ge=^44mmD7>dhMlxj+j_Cdgd61yygQI~j6L+jTJ3L7{F3tY?O&Wt z97jz*Fv}*lPSpw~uXr}M9ow?avRyYV+vaC%$9Js>5rk~WuCSw`ZWdwWejvDA;bzej zK1>zY3(`i*_RB6O9%hFfwFN&d_@rBR1g}@!vK?@@U>B?4MBo-{+`;_<)3KpNc!6EA zC(OXDg7(aMUpjVBt0bI4J`uQH4MVU5RH--tue;n23$7P3&o@~%ySo#%w%ZKR1-CO` z%T~nXQoAp_s_@oeoe(u9ENf|h9Urz;;{R_e#i!$&ooRQ3U-8VUQ{zkKfeoGf2=i2} zofMAn+^QL{iLx!6Ag3-_e}X+I35i_awgemhx|D(V1sCN)Rp6Mq0!*$Z%v5$BdX|7b zSrzGi$h<&DnR9c6oYUf^@t!UURHUfbNGTsW$p>S>jxBcX;$|6I_>jW~IoB+#d%bxw1y0;wp!*W8;xD#{JbeW1}+ zJONdd{Xj}f4oK;9G*<;uk$!MN68tt>r~-zCVrK0`YKeU0cG$!`)^9`NbdVwC(IfdXFM zC-E&pjwf>;xu%ZfcLh*dO8iqYt zF^-Rqj0YxO#VSk@hGAM>VAyWKD20yIX5ltk7N!F?hu#aTc3@b+l%bXaJL8s17@QP%YYQUBm*skNF7rn!wlYWD%vG}1K(A!kPk}%+zoHXDq6c1$F+c6FG zUZHR8h%*}dA}~rt-LzcC!4s6#-2&bi4c{)|)vw*?=wWykm!VL;C9n{Wdnh*AF93r5 E7r7gsOaK4? literal 0 HcmV?d00001 diff --git a/tcpip_kanal/komunikacia.o b/tcpip_kanal/komunikacia.o new file mode 100644 index 0000000000000000000000000000000000000000..323bc54d33e8572666461a65bd828ca3f92b1ab9 GIT binary patch literal 5802 zcmbVQeQXrR6`#XLOf3iwrIa+JS%O_mf)6L5e57e|1~yqrK&~7^rGy@PcWbPwLL75?1a{hB2{i$HALwLs+`CHD)ob?ZiPyJ zZ)SII*JmioNS^)eoA-Y2&6_uK}SGSh=KJb6C+W*%~1K?()oHl z$wVQl*8`Pl=;bk2YGjgRJ;_Z(5Nb)n-due#`5jQ)50&zjg5vINSKNWsPr9g3(Xbw*5-(85LK)fJt7!a}G}g0PSc1q@S5aN@huMxBK>PcUnwwfe5GM zt3+`59*VOn&rzJ=e3s?8SXsUr1L;@ftH<6)xCf!n!{x4(^7+ESx8|=9_je}iYa&_- z2GJ%Via6leqAVN_lo!kbCDBg;(po+?!@ji&W#B&Snp~|^S(Uk!-$7ax%r7dn7aH8iL167xW}#L- zM?G8a-b*3-Q>?PDZe9;*<#jlXM$Gqc7sW|-m}D28e3Dh3Ew^$Jf~m?34WmuT6Z}!R z<_S>v94pnQe(|dy%I$ADE6ZGt!k^gAk@fq_u~WfYu@kU7_t??9J)_LDN8}O_#wKE} zJRt^aN=&H@OdzoojpFX=kb2Kh9JDj(8B8^jhEY3^BLypw0!Ix=f|C1XL%4c=dj8() zUOfai8jtaIo~&TTvt9*RRv0 z8f#gZ82z+yzIw}XR^@tSV)=@e*7A{ z3uWll7~d~+I0sA6UeJkPM7n!_QJ}z_SkLpfcfXS|Eqrp&U}gJcs-M zy!Pi7K` zrJ`NXY%rTy(>B0JHwWJOEG?~TL#kA;^dovs&Fh-S1R~^MpK3d*p-P#d(KJ`$imIb~ zS_}9fCe?w9qwvsdZx<{zL(|eR&#_Wb8bb8CgJ~t${!yo-S|SK@SaXVrgcoTfKjyHS z8-s~dg1%|#n0&!Jq9Jx#HQt*27R=$IjSP53r0tujZ98=v*{4a4B7@nsKC__PluMs5 z%2z_@$V&+%lFbACe+={Oy?}3Kwo|pu(x{~89nC7K2I4MQwrYro`n?HDW5(!^YM6SKS>_EEb({ls<)u98Fp1YPX)&=~;&YcfST_fAJq_%ACE?|p| zblcicx22VOHcC5+y5UIaQE9K9f8s#*fi0V{15j)kXM?mY@jwFqP<#m-68_@s0rbl_ z+KzrLM+ltJe*tlJ7`+%ZfT*zJ>{;~pa#TYvM!y5Jj>}#{-@(yO(bGQ&arQQPq4ygg z@*QV?4rFv5uIIA z9?(XPJ`D6O0SUhhSr(&9fx5Zg8X&>97D(`I4`h!53EMqDBGM9&U^yA+ody!N-w$N3 z0IlUd-T@LheGf>?XjKbitN3USkci;RK!WA*K(;54rGY-rElvP!;^-wHs+lw78KjnEipQM=_^vBg})_%3ObE3ABDdoVGAy-6Z(ckIc|yFL8_4! z{(gil0G)XsfFKKhJ3^sBhiZ~mDB8a6z4G;lJr*7G-ku3bX>N>JO_JxEB&VAsFEvSi z)Fc^il1w#8-fxmzYLa}?Bx%$GYJ&}$1uY-wkc3)$uxcbJ6rIp_KW=4fT4UY01eZS} z!h<^^u04aEjPryAj3hbLFwCHAIgh2O*$B^I#xQNa=($y<$%+itMq*YSvk?xr8a#?i zW`rlFv0^Os58m`3w`%!+D|p+F literal 0 HcmV?d00001 diff --git a/tcpip_kanal/kryptografia.o b/tcpip_kanal/kryptografia.o new file mode 100644 index 0000000000000000000000000000000000000000..772062cfdcd5e9c282432c7fba84c5bf10919847 GIT binary patch literal 9912 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 literal 0 HcmV?d00001 diff --git a/tcpip_kanal/nieco.txt b/tcpip_kanal/nieco.txt new file mode 100644 index 0000000000000000000000000000000000000000..42390da3e6eddfd4fc93720bebc9af08502cf133 GIT binary patch literal 9 NcmZQ5c) + +#define RSA_VELKOST 1024 +#define ECC_VELKOST 32 +#define RSA_EXPONENT 65537 + +int main(int argc, char **argv) +{ + + int autentizacia_klienta = 0; + int generovanie_certifikatu = 0; + int nacitanie_zo_suboru = 0; + int port = 0; + + #if defined (_WIN32) + WSADATA d; + if(WSAStartup(MAKEWORD(2,2), &d)) + { + printf("Nastala chyba pri inicializacii winsocketu\n"); + return -1; + } + #endif + + int cislo_soketu; + int cislo_portu = 0; + const char *subor_certifikat = NULL; + const char *subor_kluc = NULL; + WOLFSSL_CTX* ctx; + + if((ctx = nastavit_ctx_server()) == NULL) + { + return -1; + } + else + { + //skontroluje ci nebol zadany prepinac "-g" pre moznost generovanie certifikatu, + //ak ano pozrie aky typ certifikatu (v CLI argument hned za nim) bol zvoleny + for(int i = 0; i < argc; i++) + { + if( (!strcmp(argv[i], "-port")) ) + { + port = 1; + if((argv[i+1] == NULL) ) + { + printf("Nezadali ste cislo portu\n"); + return -1; + } + else + { + cislo_portu = atoi(argv[i+1]); + } + } + else if( (!strcmp(argv[i], "-n")) ) + { + nacitanie_zo_suboru = 1; + if(generovanie_certifikatu) + { + fprintf(stderr, "Nie je mozne zvolit obidve metody nacitania certifikatov naraz\n"); + return -1; + } + if((argv[i+1] == NULL) || (i == argc-1)) + { + printf("Nezadali ste typ certifikatu ktory chcete nacitat zo suboru\n"); + return -1; + } + else if(!strcmp(argv[i+1], "rsa")) + { + wolfSSL_CTX_load_verify_locations(ctx, "../certifikaty/autorita_rsa.pem", NULL); + subor_certifikat = "../certifikaty/server_rsa.pem"; + subor_kluc = "../certifikaty/server_rsa.key"; + if(nacitat_certifikaty(ctx, subor_certifikat, subor_kluc) == -1) return -1; + } + else if(!strcmp(argv[i+1], "ecc")) + { + wolfSSL_CTX_load_verify_locations(ctx, "../certifikaty/autorita_ecc.pem", NULL); + subor_certifikat = "../certifikaty/server_ecc.pem"; + subor_kluc = "../certifikaty/server_ecc.key"; + if(nacitat_certifikaty(ctx, subor_certifikat, subor_kluc) == -1) return -1; + } + else + { + printf("Zadali ste nespravny typ certifikatu\n"); + return -1; + } + } + else if( (!strcmp(argv[i], "-g")) ) + { + generovanie_certifikatu = 1; + if(nacitanie_zo_suboru) + { + fprintf(stderr, "Nie je mozne zvolit obidve metody nacitania certifikatov naraz\n"); + return -1; + } + if((argv[i+1] == NULL) || (i == argc-1)) + { + printf("Nezadali ste typ certifikatu ktory chcete vygenerovat\n"); + return -1; + } + else if(!strcmp(argv[i+1], "rsa")) + { + wolfSSL_CTX_load_verify_locations(ctx, "../certifikaty/autorita_rsa.pem", NULL); + if(generovat_rsa_certifikat(ctx, RSA_VELKOST, RSA_EXPONENT, CTC_SHA256wRSA, "SR", "Kosice", "Server.sk", "server@server.sk") == -1) + return -1; + + } + else if(!strcmp(argv[i+1], "ecc")) + { + wolfSSL_CTX_load_verify_locations(ctx, "../certifikaty/autorita_ecc.pem", NULL); + if(generovat_ecc_certifikat(ctx, ECC_VELKOST, ECC_PRIME239V1, CTC_SHAwECDSA, "SR", "Kosice", "Server.sk", "server@server.sk") == -1) + return -1; + + } + else + { + printf("Zadali ste nespravny typ certifikatu\n"); + return -1; + } + } + } + + if(!port) + { + fprintf(stderr, "Nebol urceny port\n"); + return -1; + } + if(!generovanie_certifikatu && !nacitanie_zo_suboru) + { + fprintf(stderr, "Nebola zvolena metoda nacitania certifikatov\n"); + printf("Zadajde prepinac -g (generovanie), alebo -n (nacitanie_zo_suboru) s parametrom rsa alebo ecc\n"); + return -1; + } + + //umoznuje vybrat sifry ktore sa budu nachadzat v sifrovacom subore + //nastav_sifry(ctx, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"); + + cislo_soketu = cakat_na_komunikaciu(cislo_portu); + + while(1) + { + printf("------------\n"); + struct sockaddr_in adresa; + WOLFSSL* ssl; + int velkost = sizeof(adresa); + int cislo_soketu_klienta = accept(cislo_soketu, (struct sockaddr*)&adresa, &velkost); + printf("Spojenie [%s:%d]\n", inet_ntoa(adresa.sin_addr), ntohs(adresa.sin_port)); + ssl = wolfSSL_new(ctx); + wolfSSL_set_fd(ssl, cislo_soketu_klienta); + int uspech; + zobraz_sifru(ssl); + zobraz_certifikat(ssl); + if(wolfSSL_accept(ssl) != SSL_SUCCESS) + { + fprintf(stderr, "Nastala chyba v spojeni.\n"); + printf("Skontrolujte certifikaty.\n"); + return -1; + } + prijat_subor(ssl, ctx); + } + } + ukoncit_soket(cislo_soketu); + return 0; +} diff --git a/tcpip_kanal/server.exe b/tcpip_kanal/server.exe new file mode 100644 index 0000000000000000000000000000000000000000..41bb1fe8e1d5d2a02f1984dd6b620533cd29648e GIT binary patch literal 82392 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 JUR*`k{{Sq1e@OrU literal 0 HcmV?d00001 diff --git a/tcpip_kanal/spustit_klient.bat b/tcpip_kanal/spustit_klient.bat new file mode 100644 index 0000000..2797b2c --- /dev/null +++ b/tcpip_kanal/spustit_klient.bat @@ -0,0 +1,14 @@ +:::::::::::::::::::::::::::::::::::::::::::::::::: +:: Bakalarska praca :: +:: Meno studenta: Tomas Lukac :: +:: Veduci BP: prof. Ing. Milos Drutarovsky CSc. :: +:: Skola: KEMT FEI TUKE :: +:: Datum poslednej upravy: 9.3.2020 :: +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:: Program je mozne spustit s prepinacmi: +:: -g rsa|ecc sluzi na generovanie certifikatu, ak ho neuvedieme program sa pokusi nacitat certifikaty z adresara /certifikaty +:: -s cesta-ku-suboru sluzi na nacitanie cesty k suboru, ktory chceme odoslat (este nie je) + +::Priklady spustenia: +klient -ip 127.0.0.1 -port 8080 diff --git a/tcpip_kanal/spustit_server.bat b/tcpip_kanal/spustit_server.bat new file mode 100644 index 0000000..adc2168 --- /dev/null +++ b/tcpip_kanal/spustit_server.bat @@ -0,0 +1,15 @@ +:::::::::::::::::::::::::::::::::::::::::::::::::: +:: Bakalarska praca :: +:: Meno studenta: Tomas Lukac :: +:: Veduci BP: prof. Ing. Milos Drutarovsky CSc. :: +:: Skola: KEMT FEI TUKE :: +:: Datum poslednej upravy: 9.3.2020 :: +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:: Program server je mozne spustit s prepinacmi: +:: -g rsa|ecc sluzi na generovanie certifikatu, ak ho neuvedieme program sa pokusi nacitat certifikaty z adresara /certifikaty + +::Priklady spustenia: +server -port 8080 +::server -port 8080 -g ecc +::server -port 8080 \ No newline at end of file diff --git a/tcpip_kanal/vcruntime140.dll b/tcpip_kanal/vcruntime140.dll new file mode 100644 index 0000000000000000000000000000000000000000..e8270e1008c6fcabe51d06dfc542645518c18957 GIT binary patch literal 84816 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 I;Q)XB1p{mYUH||9 literal 0 HcmV?d00001 diff --git a/tcpip_kanal/vcruntime140_64.dll b/tcpip_kanal/vcruntime140_64.dll new file mode 100644 index 0000000000000000000000000000000000000000..2158687dce0caed30f71d6d341ecd7a05706062c GIT binary patch literal 88248 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 literal 0 HcmV?d00001 diff --git a/tcpip_kanal/wolfssl.dll b/tcpip_kanal/wolfssl.dll new file mode 100644 index 0000000000000000000000000000000000000000..1d45e0fa786b72ec8f25e981697eb135ee79c786 GIT binary patch literal 811008 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 ~{rKR63PLvi{~HLUt6-i9!ysK)Ia?X1Qx9 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

    ey< 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

    D!L)T>XZaCVGKQ_&U$( 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%0A=Ox?)A_;64Uy= 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 #$JY;Or3SkY_fuGeBYU4}zEk^!sf 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 literal 0 HcmV?d00001 diff --git a/teoria.txt b/teoria.txt new file mode 100644 index 0000000..78d3a09 --- /dev/null +++ b/teoria.txt @@ -0,0 +1,16 @@ +I/O rutiny + - implicitne su pouzite recv() a send() funkcie ktore realizuju citanie zapis do file descriptoru nastavenho pomocou wolfssl_set_fd() + - prototypy vlastnych funkcii + int CBIORecv(CYASSL* ssl, char* buf, int sz, void* ctx) + int CBIOSend(CYASSL* ssl, char* buf, int sz, void* ctx) + - implicitne je descriptor sietoveho soketu posunuty do i/o rutiny v ctx parametri + - ssl je ukazovatel na aktualnu relaciu + - receive + - buf -> ukazuje na buffer, kde prichadzajuci zasifrovany text by mal byt nakopirovany aby ho wolfssl mohla odsifrovat + - sz -> velkost bufferu + - send + - buf -> ukazuje na buffer do ktoreho wolfssl zapisala zasifrovany text na odoslanie + - sz -> velkost bufferu + - registracia funkcii + wolfSSL_SetIORecv(ctx, myCBIORecv) + wolfSSL_SetIOSend(ctx, myCBIOSend) \ No newline at end of file diff --git a/wolfssl_hlavickove_subory/wolfssl/callbacks.h b/wolfssl_hlavickove_subory/wolfssl/callbacks.h new file mode 100644 index 0000000..619f8d2 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/callbacks.h @@ -0,0 +1,91 @@ +/* callbacks.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +#ifndef WOLFSSL_CALLBACKS_H +#define WOLFSSL_CALLBACKS_H + +#include + +#ifdef __cplusplus + extern "C" { +#endif + + +enum { /* CALLBACK CONTSTANTS */ + MAX_PACKETNAME_SZ = 24, + MAX_CIPHERNAME_SZ = 24, + MAX_TIMEOUT_NAME_SZ = 24, + MAX_PACKETS_HANDSHAKE = 14, /* 12 for client auth plus 2 alerts */ + MAX_VALUE_SZ = 128, /* all handshake packets but Cert should + fit here */ +}; + +struct WOLFSSL; + +typedef struct handShakeInfo_st { + struct WOLFSSL* ssl; + char cipherName[MAX_CIPHERNAME_SZ + 1]; /* negotiated cipher */ + char packetNames[MAX_PACKETS_HANDSHAKE][MAX_PACKETNAME_SZ + 1]; + /* SSL packet names */ + int numberPackets; /* actual # of packets */ + int negotiationError; /* cipher/parameter err */ +} HandShakeInfo; + + +#if defined(HAVE_SYS_TIME_H) && !defined(NO_TIMEVAL) + typedef struct timeval Timeval; +#else /* HAVE_SYS_TIME_H */ + /* Define the Timeval explicitly. */ + typedef struct { + long tv_sec; /* Seconds. */ + long tv_usec; /* Microseconds. */ + } Timeval; +#endif /* HAVE_SYS_TIME_H */ + + +typedef struct packetInfo_st { + char packetName[MAX_PACKETNAME_SZ + 1]; /* SSL packet name */ + Timeval timestamp; /* when it occurred */ + unsigned char value[MAX_VALUE_SZ]; /* if fits, it's here */ + unsigned char* bufferValue; /* otherwise here (non 0) */ + int valueSz; /* sz of value or buffer */ +} PacketInfo; + + +typedef struct timeoutInfo_st { + char timeoutName[MAX_TIMEOUT_NAME_SZ + 1]; /* timeout Name */ + int flags; /* for future use */ + int numberPackets; /* actual # of packets */ + PacketInfo packets[MAX_PACKETS_HANDSHAKE]; /* list of all packets */ + Timeval timeoutValue; /* timer that caused it */ +} TimeoutInfo; + + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* WOLFSSL_CALLBACKS_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/certs_test.h b/wolfssl_hlavickove_subory/wolfssl/certs_test.h new file mode 100644 index 0000000..deefb57 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/certs_test.h @@ -0,0 +1,3207 @@ +/* certs_test.h */ + +#ifndef WOLFSSL_CERTS_TEST_H +#define WOLFSSL_CERTS_TEST_H + +#ifdef USE_CERT_BUFFERS_1024 + +/* ./certs/1024/client-key.der, 1024-bit */ +static const unsigned char client_key_der_1024[] = +{ + 0x30, 0x82, 0x02, 0x5C, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, + 0x00, 0xBC, 0x73, 0x0E, 0xA8, 0x49, 0xF3, 0x74, 0xA2, 0xA9, + 0xEF, 0x18, 0xA5, 0xDA, 0x55, 0x99, 0x21, 0xF9, 0xC8, 0xEC, + 0xB3, 0x6D, 0x48, 0xE5, 0x35, 0x35, 0x75, 0x77, 0x37, 0xEC, + 0xD1, 0x61, 0x90, 0x5F, 0x3E, 0xD9, 0xE4, 0xD5, 0xDF, 0x94, + 0xCA, 0xC1, 0xA9, 0xD7, 0x19, 0xDA, 0x86, 0xC9, 0xE8, 0x4D, + 0xC4, 0x61, 0x36, 0x82, 0xFE, 0xAB, 0xAD, 0x7E, 0x77, 0x25, + 0xBB, 0x8D, 0x11, 0xA5, 0xBC, 0x62, 0x3A, 0xA8, 0x38, 0xCC, + 0x39, 0xA2, 0x04, 0x66, 0xB4, 0xF7, 0xF7, 0xF3, 0xAA, 0xDA, + 0x4D, 0x02, 0x0E, 0xBB, 0x5E, 0x8D, 0x69, 0x48, 0xDC, 0x77, + 0xC9, 0x28, 0x0E, 0x22, 0xE9, 0x6B, 0xA4, 0x26, 0xBA, 0x4C, + 0xE8, 0xC1, 0xFD, 0x4A, 0x6F, 0x2B, 0x1F, 0xEF, 0x8A, 0xAE, + 0xF6, 0x90, 0x62, 0xE5, 0x64, 0x1E, 0xEB, 0x2B, 0x3C, 0x67, + 0xC8, 0xDC, 0x27, 0x00, 0xF6, 0x91, 0x68, 0x65, 0xA9, 0x02, + 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x13, 0x97, 0xEA, + 0xE8, 0x38, 0x78, 0x25, 0xA2, 0x5C, 0x04, 0xCE, 0x0D, 0x40, + 0x7C, 0x31, 0xE5, 0xC4, 0x70, 0xCD, 0x9B, 0x82, 0x3B, 0x58, + 0x09, 0x86, 0x3B, 0x66, 0x5F, 0xDC, 0x31, 0x90, 0xF1, 0x4F, + 0xD5, 0xDB, 0x15, 0xDD, 0xDE, 0xD7, 0x3B, 0x95, 0x93, 0x31, + 0x18, 0x31, 0x0E, 0x5E, 0xA3, 0xD6, 0xA2, 0x1A, 0x71, 0x6E, + 0x81, 0x48, 0x1C, 0x4B, 0xCF, 0xDB, 0x8E, 0x7A, 0x86, 0x61, + 0x32, 0xDC, 0xFB, 0x55, 0xC1, 0x16, 0x6D, 0x27, 0x92, 0x24, + 0x45, 0x8B, 0xF1, 0xB8, 0x48, 0xB1, 0x4B, 0x1D, 0xAC, 0xDE, + 0xDA, 0xDD, 0x8E, 0x2F, 0xC2, 0x91, 0xFB, 0xA5, 0xA9, 0x6E, + 0xF8, 0x3A, 0x6A, 0xF1, 0xFD, 0x50, 0x18, 0xEF, 0x9F, 0xE7, + 0xC3, 0xCA, 0x78, 0xEA, 0x56, 0xD3, 0xD3, 0x72, 0x5B, 0x96, + 0xDD, 0x4E, 0x06, 0x4E, 0x3A, 0xC3, 0xD9, 0xBE, 0x72, 0xB6, + 0x65, 0x07, 0x07, 0x4C, 0x01, 0x02, 0x41, 0x00, 0xFA, 0x47, + 0xD4, 0x7A, 0x7C, 0x92, 0x3C, 0x55, 0xEF, 0x81, 0xF0, 0x41, + 0x30, 0x2D, 0xA3, 0xCF, 0x8F, 0x1C, 0xE6, 0x87, 0x27, 0x05, + 0x70, 0x0D, 0xDF, 0x98, 0x35, 0xD6, 0xF1, 0x8B, 0x38, 0x2F, + 0x24, 0xB5, 0xD0, 0x84, 0xB6, 0x79, 0x4F, 0x71, 0x29, 0x94, + 0x5A, 0xF0, 0x64, 0x6A, 0xAC, 0xE7, 0x72, 0xC6, 0xED, 0x4D, + 0x59, 0x98, 0x3E, 0x67, 0x3A, 0xF3, 0x74, 0x2C, 0xF9, 0x61, + 0x17, 0x69, 0x02, 0x41, 0x00, 0xC0, 0xC1, 0x82, 0x0D, 0x0C, + 0xEB, 0xC6, 0x2F, 0xDC, 0x92, 0xF9, 0x9D, 0x82, 0x1A, 0x31, + 0xE9, 0xE9, 0xF7, 0x4B, 0xF2, 0x82, 0x87, 0x1C, 0xEE, 0x16, + 0x6A, 0xD1, 0x1D, 0x18, 0x82, 0x70, 0xF3, 0xC0, 0xB6, 0x2F, + 0xF6, 0xF3, 0xF7, 0x1D, 0xF1, 0x86, 0x23, 0xC8, 0x4E, 0xEB, + 0x8F, 0x56, 0x8E, 0x8F, 0xF5, 0xBF, 0xF1, 0xF7, 0x2B, 0xB5, + 0xCC, 0x3D, 0xC6, 0x57, 0x39, 0x0C, 0x1B, 0x54, 0x41, 0x02, + 0x41, 0x00, 0x9D, 0x7E, 0x05, 0xDE, 0xED, 0xF4, 0xB7, 0xB2, + 0xFB, 0xFC, 0x30, 0x4B, 0x55, 0x1D, 0xE3, 0x2F, 0x01, 0x47, + 0x96, 0x69, 0x05, 0xCD, 0x0E, 0x2E, 0x2C, 0xBD, 0x83, 0x63, + 0xB6, 0xAB, 0x7C, 0xB7, 0x6D, 0xCA, 0x5B, 0x64, 0xA7, 0xCE, + 0xBE, 0x86, 0xDF, 0x3B, 0x53, 0xDE, 0x61, 0xD2, 0x1E, 0xEB, + 0xA5, 0xF6, 0x37, 0xED, 0xAC, 0xAB, 0x78, 0xD9, 0x4C, 0xE7, + 0x55, 0xFB, 0xD7, 0x11, 0x99, 0xC1, 0x02, 0x40, 0x18, 0x98, + 0x18, 0x29, 0xE6, 0x1E, 0x27, 0x39, 0x70, 0x21, 0x68, 0xAC, + 0x0A, 0x2F, 0xA1, 0x72, 0xC1, 0x21, 0x86, 0x95, 0x38, 0xC6, + 0x58, 0x90, 0xA0, 0x57, 0x9C, 0xBA, 0xE3, 0xA7, 0xB1, 0x15, + 0xC8, 0xDE, 0xF6, 0x1B, 0xC2, 0x61, 0x23, 0x76, 0xEF, 0xB0, + 0x9D, 0x1C, 0x44, 0xBE, 0x13, 0x43, 0x39, 0x67, 0x17, 0xC8, + 0x9D, 0xCA, 0xFB, 0xF5, 0x45, 0x64, 0x8B, 0x38, 0x82, 0x2C, + 0xF2, 0x81, 0x02, 0x40, 0x39, 0x89, 0xE5, 0x9C, 0x19, 0x55, + 0x30, 0xBA, 0xB7, 0x48, 0x8C, 0x48, 0x14, 0x0E, 0xF4, 0x9F, + 0x7E, 0x77, 0x97, 0x43, 0xE1, 0xB4, 0x19, 0x35, 0x31, 0x23, + 0x75, 0x9C, 0x3B, 0x44, 0xAD, 0x69, 0x12, 0x56, 0xEE, 0x00, + 0x61, 0x64, 0x16, 0x66, 0xD3, 0x7C, 0x74, 0x2B, 0x15, 0xB4, + 0xA2, 0xFE, 0xBF, 0x08, 0x6B, 0x1A, 0x5D, 0x3F, 0x90, 0x12, + 0xB1, 0x05, 0x86, 0x31, 0x29, 0xDB, 0xD9, 0xE2 +}; +static const int sizeof_client_key_der_1024 = sizeof(client_key_der_1024); + +/* ./certs/1024/client-keyPub.der, 1024-bit */ +static const unsigned char client_keypub_der_1024[] = +{ + 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, + 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, + 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xBC, + 0x73, 0x0E, 0xA8, 0x49, 0xF3, 0x74, 0xA2, 0xA9, 0xEF, 0x18, + 0xA5, 0xDA, 0x55, 0x99, 0x21, 0xF9, 0xC8, 0xEC, 0xB3, 0x6D, + 0x48, 0xE5, 0x35, 0x35, 0x75, 0x77, 0x37, 0xEC, 0xD1, 0x61, + 0x90, 0x5F, 0x3E, 0xD9, 0xE4, 0xD5, 0xDF, 0x94, 0xCA, 0xC1, + 0xA9, 0xD7, 0x19, 0xDA, 0x86, 0xC9, 0xE8, 0x4D, 0xC4, 0x61, + 0x36, 0x82, 0xFE, 0xAB, 0xAD, 0x7E, 0x77, 0x25, 0xBB, 0x8D, + 0x11, 0xA5, 0xBC, 0x62, 0x3A, 0xA8, 0x38, 0xCC, 0x39, 0xA2, + 0x04, 0x66, 0xB4, 0xF7, 0xF7, 0xF3, 0xAA, 0xDA, 0x4D, 0x02, + 0x0E, 0xBB, 0x5E, 0x8D, 0x69, 0x48, 0xDC, 0x77, 0xC9, 0x28, + 0x0E, 0x22, 0xE9, 0x6B, 0xA4, 0x26, 0xBA, 0x4C, 0xE8, 0xC1, + 0xFD, 0x4A, 0x6F, 0x2B, 0x1F, 0xEF, 0x8A, 0xAE, 0xF6, 0x90, + 0x62, 0xE5, 0x64, 0x1E, 0xEB, 0x2B, 0x3C, 0x67, 0xC8, 0xDC, + 0x27, 0x00, 0xF6, 0x91, 0x68, 0x65, 0xA9, 0x02, 0x03, 0x01, + 0x00, 0x01 +}; +static const int sizeof_client_keypub_der_1024 = sizeof(client_keypub_der_1024); + +/* ./certs/1024/client-cert.der, 1024-bit */ +static const unsigned char client_cert_der_1024[] = +{ + 0x30, 0x82, 0x03, 0xC5, 0x30, 0x82, 0x03, 0x2E, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xBB, 0xD3, 0x10, 0x03, + 0xE6, 0x9D, 0x28, 0x03, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, + 0x81, 0x9E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, + 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, + 0x6E, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x77, 0x6F, 0x6C, 0x66, 0x53, 0x53, 0x4C, 0x5F, + 0x31, 0x30, 0x32, 0x34, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x50, 0x72, 0x6F, 0x67, 0x72, + 0x61, 0x6D, 0x6D, 0x69, 0x6E, 0x67, 0x2D, 0x31, 0x30, 0x32, + 0x34, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, + 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, + 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, + 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, + 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x34, 0x31, 0x33, + 0x31, 0x35, 0x32, 0x33, 0x30, 0x39, 0x5A, 0x17, 0x0D, 0x32, + 0x31, 0x30, 0x31, 0x30, 0x37, 0x31, 0x35, 0x32, 0x33, 0x30, + 0x39, 0x5A, 0x30, 0x81, 0x9E, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, + 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, + 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, + 0x55, 0x04, 0x0A, 0x0C, 0x0C, 0x77, 0x6F, 0x6C, 0x66, 0x53, + 0x53, 0x4C, 0x5F, 0x31, 0x30, 0x32, 0x34, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x50, 0x72, + 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x6D, 0x69, 0x6E, 0x67, 0x2D, + 0x31, 0x30, 0x32, 0x34, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, + 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, + 0x63, 0x6F, 0x6D, 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, + 0x81, 0x00, 0xBC, 0x73, 0x0E, 0xA8, 0x49, 0xF3, 0x74, 0xA2, + 0xA9, 0xEF, 0x18, 0xA5, 0xDA, 0x55, 0x99, 0x21, 0xF9, 0xC8, + 0xEC, 0xB3, 0x6D, 0x48, 0xE5, 0x35, 0x35, 0x75, 0x77, 0x37, + 0xEC, 0xD1, 0x61, 0x90, 0x5F, 0x3E, 0xD9, 0xE4, 0xD5, 0xDF, + 0x94, 0xCA, 0xC1, 0xA9, 0xD7, 0x19, 0xDA, 0x86, 0xC9, 0xE8, + 0x4D, 0xC4, 0x61, 0x36, 0x82, 0xFE, 0xAB, 0xAD, 0x7E, 0x77, + 0x25, 0xBB, 0x8D, 0x11, 0xA5, 0xBC, 0x62, 0x3A, 0xA8, 0x38, + 0xCC, 0x39, 0xA2, 0x04, 0x66, 0xB4, 0xF7, 0xF7, 0xF3, 0xAA, + 0xDA, 0x4D, 0x02, 0x0E, 0xBB, 0x5E, 0x8D, 0x69, 0x48, 0xDC, + 0x77, 0xC9, 0x28, 0x0E, 0x22, 0xE9, 0x6B, 0xA4, 0x26, 0xBA, + 0x4C, 0xE8, 0xC1, 0xFD, 0x4A, 0x6F, 0x2B, 0x1F, 0xEF, 0x8A, + 0xAE, 0xF6, 0x90, 0x62, 0xE5, 0x64, 0x1E, 0xEB, 0x2B, 0x3C, + 0x67, 0xC8, 0xDC, 0x27, 0x00, 0xF6, 0x91, 0x68, 0x65, 0xA9, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x82, 0x01, 0x07, 0x30, + 0x82, 0x01, 0x03, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, + 0x04, 0x16, 0x04, 0x14, 0x81, 0x69, 0x0F, 0xF8, 0xDF, 0xDD, + 0xCF, 0x34, 0x29, 0xD5, 0x67, 0x75, 0x71, 0x85, 0xC7, 0x75, + 0x10, 0x69, 0x59, 0xEC, 0x30, 0x81, 0xD3, 0x06, 0x03, 0x55, + 0x1D, 0x23, 0x04, 0x81, 0xCB, 0x30, 0x81, 0xC8, 0x80, 0x14, + 0x81, 0x69, 0x0F, 0xF8, 0xDF, 0xDD, 0xCF, 0x34, 0x29, 0xD5, + 0x67, 0x75, 0x71, 0x85, 0xC7, 0x75, 0x10, 0x69, 0x59, 0xEC, + 0xA1, 0x81, 0xA4, 0xA4, 0x81, 0xA1, 0x30, 0x81, 0x9E, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, + 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0C, 0x77, + 0x6F, 0x6C, 0x66, 0x53, 0x53, 0x4C, 0x5F, 0x31, 0x30, 0x32, + 0x34, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x0C, 0x10, 0x50, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x6D, + 0x69, 0x6E, 0x67, 0x2D, 0x31, 0x30, 0x32, 0x34, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, + 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, + 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, + 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x82, 0x09, 0x00, + 0xBB, 0xD3, 0x10, 0x03, 0xE6, 0x9D, 0x28, 0x03, 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, 0x0B, 0x05, 0x00, 0x03, 0x81, 0x81, + 0x00, 0x84, 0x99, 0xD9, 0xE5, 0x37, 0xC4, 0x44, 0x7D, 0xCE, + 0x29, 0xB8, 0xB6, 0x80, 0x0E, 0xEA, 0xA3, 0xE2, 0xFA, 0xA2, + 0x2F, 0x5C, 0xD2, 0x4A, 0x85, 0x67, 0xB9, 0x8B, 0xFA, 0x9F, + 0x7D, 0xDA, 0x6D, 0x85, 0x2A, 0xC2, 0x20, 0xF3, 0x18, 0xC8, + 0xD4, 0x6B, 0x26, 0xB2, 0x7A, 0x68, 0xE7, 0x82, 0x52, 0x87, + 0xE7, 0x0C, 0x5B, 0x08, 0x47, 0x7A, 0x55, 0xA5, 0x0D, 0xFA, + 0x72, 0xCE, 0x6B, 0xA1, 0xB2, 0xAE, 0x5A, 0xA1, 0x63, 0xFF, + 0x68, 0xDB, 0xE5, 0x49, 0xEF, 0xF1, 0x0E, 0x98, 0x96, 0x09, + 0xB5, 0x04, 0x5F, 0xD4, 0x0A, 0x9B, 0x8A, 0xAF, 0xD2, 0x31, + 0x1F, 0x95, 0xE5, 0x0F, 0xA8, 0xCD, 0xBB, 0xA1, 0x2D, 0x64, + 0xB0, 0xB7, 0xEE, 0x47, 0xA7, 0x58, 0xD9, 0xC7, 0xDB, 0xB0, + 0x92, 0xBB, 0xAA, 0xCF, 0xB8, 0x8A, 0x04, 0x5B, 0x0F, 0x9F, + 0x3E, 0xE0, 0xD2, 0x42, 0x52, 0xBD, 0x5D, 0xA7, 0x48 +}; +static const int sizeof_client_cert_der_1024 = sizeof(client_cert_der_1024); + +/* ./certs/1024/dh1024.der, 1024-bit */ +static const unsigned char dh_key_der_1024[] = +{ + 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0xA4, 0xD2, 0xB8, + 0x6E, 0x78, 0xF5, 0xD9, 0xED, 0x2D, 0x7C, 0xDD, 0xB6, 0x16, + 0x86, 0x5A, 0x4B, 0x05, 0x76, 0x90, 0xDD, 0x66, 0x61, 0xB9, + 0x6D, 0x52, 0xA7, 0x1C, 0xAF, 0x62, 0xC6, 0x69, 0x47, 0x7B, + 0x39, 0xF2, 0xFB, 0x94, 0xEC, 0xBC, 0x79, 0xFF, 0x24, 0x5E, + 0xEF, 0x79, 0xBB, 0x59, 0xB2, 0xFC, 0xCA, 0x07, 0xD6, 0xF4, + 0xE9, 0x34, 0xF7, 0xE8, 0x38, 0xE7, 0xD7, 0x33, 0x44, 0x1D, + 0xA3, 0x64, 0x76, 0x1A, 0x84, 0x97, 0x54, 0x74, 0x40, 0x84, + 0x1F, 0x15, 0xFE, 0x7C, 0x25, 0x2A, 0x2B, 0x25, 0xFD, 0x9E, + 0xC1, 0x89, 0x33, 0x8C, 0x39, 0x25, 0x2B, 0x40, 0xE6, 0xCD, + 0xF8, 0xA8, 0xA1, 0x8A, 0x53, 0xC6, 0x47, 0xB2, 0xA0, 0xD7, + 0x8F, 0xEB, 0x2E, 0x60, 0x0A, 0x0D, 0x4B, 0xF8, 0xB4, 0x94, + 0x8C, 0x63, 0x0A, 0xAD, 0xC7, 0x10, 0xEA, 0xC7, 0xA1, 0xB9, + 0x9D, 0xF2, 0xA8, 0x37, 0x73, 0x02, 0x01, 0x02 +}; +static const int sizeof_dh_key_der_1024 = sizeof(dh_key_der_1024); + +/* ./certs/1024/dsa1024.der, 1024-bit */ +static const unsigned char dsa_key_der_1024[] = +{ + 0x30, 0x82, 0x01, 0xBC, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, + 0x00, 0xF7, 0x4B, 0xF9, 0xBB, 0x15, 0x98, 0xEB, 0xDD, 0xDE, + 0x1E, 0x4E, 0x71, 0x88, 0x85, 0xF2, 0xB7, 0xBA, 0xE2, 0x4A, + 0xDA, 0x76, 0x40, 0xCD, 0x69, 0x48, 0x9E, 0x83, 0x7C, 0x11, + 0xF7, 0x65, 0x31, 0x78, 0xF5, 0x25, 0x2D, 0xF7, 0xB7, 0xF8, + 0x52, 0x3F, 0xBE, 0xD8, 0xB6, 0xC5, 0xFE, 0x18, 0x15, 0x5B, + 0xB9, 0xD5, 0x92, 0x86, 0xBC, 0xB2, 0x17, 0x7C, 0xD8, 0xB0, + 0xBE, 0xA0, 0x7C, 0xF2, 0xD5, 0x73, 0x7A, 0x58, 0x8F, 0x8D, + 0xE5, 0x4A, 0x00, 0x99, 0x83, 0x4A, 0xC0, 0x9E, 0x16, 0x09, + 0xA1, 0x10, 0x34, 0xD5, 0x19, 0xBB, 0x63, 0xE3, 0xDD, 0x83, + 0x74, 0x7F, 0x10, 0xCA, 0x73, 0x75, 0xEE, 0x31, 0x4A, 0xDD, + 0x9F, 0xE0, 0x02, 0x6A, 0x9D, 0xEE, 0xB2, 0x4B, 0xA7, 0x6B, + 0x2A, 0x6C, 0xC7, 0x86, 0x77, 0xE8, 0x04, 0x15, 0xDC, 0x92, + 0xB4, 0x7A, 0x29, 0x1F, 0x4E, 0x83, 0x63, 0x85, 0x55, 0x02, + 0x15, 0x00, 0xD2, 0x05, 0xE4, 0x73, 0xFB, 0xC1, 0x99, 0xC5, + 0xDC, 0x68, 0xA4, 0x8D, 0x92, 0x27, 0x3D, 0xE2, 0x52, 0x5F, + 0x89, 0x8B, 0x02, 0x81, 0x81, 0x00, 0xAA, 0x21, 0x02, 0x09, + 0x43, 0x6E, 0xFB, 0xA2, 0x54, 0x14, 0x85, 0x0A, 0xF4, 0x28, + 0x7C, 0xCB, 0xCC, 0xDB, 0xF5, 0x1E, 0xA2, 0x18, 0xA9, 0x21, + 0xDE, 0x88, 0x88, 0x33, 0x8C, 0x2E, 0xEB, 0x8D, 0xA3, 0xF0, + 0x1D, 0xC8, 0x8F, 0xF6, 0x7E, 0xF8, 0xCF, 0x12, 0xF5, 0xB4, + 0xA1, 0x11, 0x6F, 0x0C, 0xD4, 0xF0, 0x06, 0xAD, 0xC4, 0xFC, + 0x14, 0x45, 0xC7, 0x94, 0x15, 0xBC, 0x19, 0x4B, 0xAE, 0xEF, + 0x93, 0x6A, 0x4F, 0xCC, 0x14, 0xD8, 0x47, 0x8B, 0x39, 0x66, + 0x87, 0x02, 0xD4, 0x28, 0x0A, 0xB8, 0xEE, 0x09, 0x37, 0xF4, + 0x00, 0xA0, 0x04, 0xA7, 0x79, 0xA7, 0xD2, 0x3C, 0xF7, 0x34, + 0x43, 0x56, 0x8E, 0xD0, 0x7C, 0xC2, 0xD8, 0x4D, 0x0F, 0x89, + 0xED, 0x14, 0xC1, 0x2C, 0x9C, 0x4C, 0x19, 0x9B, 0x9E, 0xDC, + 0x53, 0x09, 0x9F, 0xDF, 0x2D, 0xF0, 0x0C, 0x27, 0x54, 0x3A, + 0x77, 0x14, 0x2D, 0xDE, 0x02, 0x81, 0x81, 0x00, 0xE8, 0x1F, + 0x7C, 0xB7, 0xC0, 0x54, 0x51, 0xA7, 0x28, 0x2D, 0x58, 0x7C, + 0xDE, 0xD4, 0x5C, 0xDD, 0xD5, 0x76, 0x84, 0x3C, 0x36, 0x20, + 0xC0, 0xC3, 0x25, 0xD7, 0x3A, 0x38, 0xE1, 0x54, 0xC8, 0xFD, + 0x40, 0x68, 0x1A, 0x21, 0x54, 0x26, 0x39, 0x14, 0xBF, 0xF6, + 0xA3, 0x9C, 0x5E, 0xD9, 0x2B, 0xF7, 0xC9, 0x25, 0xBA, 0x00, + 0x09, 0xCB, 0x7F, 0x0C, 0x4A, 0x24, 0xFD, 0x15, 0x16, 0x15, + 0x48, 0xCD, 0x0B, 0x52, 0x44, 0x40, 0x7B, 0x90, 0x63, 0x2B, + 0x90, 0x22, 0xC5, 0x18, 0x05, 0x80, 0x53, 0xAF, 0x83, 0x1F, + 0x54, 0xE2, 0xB0, 0xA2, 0x0B, 0x5A, 0x92, 0x24, 0xE1, 0x62, + 0x28, 0x3F, 0xB7, 0xCA, 0xB9, 0x89, 0xD6, 0xA0, 0xB7, 0xAD, + 0xAE, 0x05, 0xE1, 0xC1, 0x59, 0x40, 0xED, 0x4A, 0x1B, 0x68, + 0xA7, 0x7B, 0xFB, 0xC3, 0x20, 0x81, 0xEF, 0x4B, 0xF3, 0x69, + 0x91, 0xB0, 0xCE, 0x3A, 0xB0, 0x38, 0x02, 0x14, 0x25, 0x38, + 0x3B, 0xA1, 0x19, 0x75, 0xDF, 0x9B, 0xF5, 0x72, 0x53, 0x4F, + 0x39, 0xE1, 0x1C, 0xEC, 0x13, 0x84, 0x82, 0x18 +}; +static const int sizeof_dsa_key_der_1024 = sizeof(dsa_key_der_1024); + +/* ./certs/1024/rsa1024.der, 1024-bit */ +static const unsigned char rsa_key_der_1024[] = +{ + 0x30, 0x82, 0x02, 0x5D, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, + 0x00, 0xBE, 0x70, 0x70, 0xB8, 0x04, 0x18, 0xE5, 0x28, 0xFE, + 0x66, 0xD8, 0x90, 0x88, 0xE0, 0xF1, 0xB7, 0xC3, 0xD0, 0xD2, + 0x3E, 0xE6, 0x4B, 0x94, 0x74, 0xB0, 0xFF, 0xB0, 0xF7, 0x63, + 0xA5, 0xAB, 0x7E, 0xAF, 0xB6, 0x2B, 0xB7, 0x38, 0x16, 0x1A, + 0x50, 0xBF, 0xF1, 0xCA, 0x87, 0x3A, 0xD5, 0xB0, 0xDA, 0xF8, + 0x43, 0x7A, 0x15, 0xB9, 0x7E, 0xEA, 0x2A, 0x80, 0xD2, 0x51, + 0xB0, 0x35, 0xAF, 0x07, 0xF3, 0xF2, 0x5D, 0x24, 0x3A, 0x4B, + 0x87, 0x56, 0x48, 0x1B, 0x3C, 0x24, 0x9A, 0xDA, 0x70, 0x80, + 0xBD, 0x3C, 0x8B, 0x03, 0x4A, 0x0C, 0x83, 0x71, 0xDE, 0xE3, + 0x03, 0x70, 0xA2, 0xB7, 0x60, 0x09, 0x1B, 0x5E, 0xC7, 0x3D, + 0xA0, 0x64, 0x60, 0xE3, 0xA9, 0x06, 0x8D, 0xD3, 0xFF, 0x42, + 0xBB, 0x0A, 0x94, 0x27, 0x2D, 0x57, 0x42, 0x0D, 0xB0, 0x2D, + 0xE0, 0xBA, 0x18, 0x25, 0x60, 0x92, 0x11, 0x92, 0xF3, 0x02, + 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x0E, 0xEE, 0x1D, + 0xC8, 0x2F, 0x7A, 0x0C, 0x2D, 0x44, 0x94, 0xA7, 0x91, 0xDD, + 0x49, 0x55, 0x6A, 0x04, 0xCE, 0x10, 0x4D, 0xA2, 0x1C, 0x76, + 0xCD, 0x17, 0x3B, 0x54, 0x92, 0x70, 0x9B, 0x82, 0x70, 0x72, + 0x32, 0x24, 0x07, 0x3F, 0x3C, 0x6C, 0x5F, 0xBC, 0x4C, 0xA6, + 0x86, 0x27, 0x94, 0xAD, 0x42, 0xDD, 0x87, 0xDC, 0xC0, 0x6B, + 0x44, 0x89, 0xF3, 0x3F, 0x1A, 0x3E, 0x11, 0x44, 0x84, 0x2E, + 0x69, 0x4C, 0xBB, 0x4A, 0x71, 0x1A, 0xBB, 0x9A, 0x52, 0x3C, + 0x6B, 0xDE, 0xBC, 0xB2, 0x7C, 0x51, 0xEF, 0x4F, 0x8F, 0x3A, + 0xDC, 0x50, 0x04, 0x4E, 0xB6, 0x31, 0x66, 0xA8, 0x8E, 0x06, + 0x3B, 0x51, 0xA9, 0xC1, 0x8A, 0xCB, 0xC4, 0x81, 0xCA, 0x2D, + 0x69, 0xEC, 0x88, 0xFC, 0x33, 0x88, 0xD1, 0xD4, 0x29, 0x47, + 0x87, 0x37, 0xF9, 0x6A, 0x22, 0x69, 0xB9, 0xC9, 0xFE, 0xEB, + 0x8C, 0xC5, 0x21, 0x41, 0x71, 0x02, 0x41, 0x00, 0xFD, 0x17, + 0x98, 0x42, 0x54, 0x1C, 0x23, 0xF8, 0xD7, 0x5D, 0xEF, 0x49, + 0x4F, 0xAF, 0xD9, 0x35, 0x6F, 0x08, 0xC6, 0xC7, 0x40, 0x5C, + 0x7E, 0x58, 0x86, 0xC2, 0xB2, 0x16, 0x39, 0x24, 0xC5, 0x06, + 0xB0, 0x3D, 0xAF, 0x02, 0xD2, 0x87, 0x77, 0xD2, 0x76, 0xBA, + 0xE3, 0x59, 0x60, 0x42, 0xF1, 0x16, 0xEF, 0x33, 0x0B, 0xF2, + 0x0B, 0xBA, 0x99, 0xCC, 0xB6, 0x4C, 0x46, 0x3F, 0x33, 0xE4, + 0xD4, 0x67, 0x02, 0x41, 0x00, 0xC0, 0xA0, 0x91, 0x6D, 0xFE, + 0x28, 0xE0, 0x81, 0x5A, 0x15, 0xA7, 0xC9, 0xA8, 0x98, 0xC6, + 0x0A, 0xAB, 0x00, 0xC5, 0x40, 0xC9, 0x21, 0xBB, 0xB2, 0x33, + 0x5A, 0xA7, 0xCB, 0x6E, 0xB8, 0x08, 0x56, 0x4A, 0x76, 0x28, + 0xE8, 0x6D, 0xBD, 0xF5, 0x26, 0x7B, 0xBF, 0xC5, 0x46, 0x45, + 0x0D, 0xEC, 0x7D, 0xEE, 0x82, 0xD6, 0xCA, 0x5F, 0x3D, 0x6E, + 0xCC, 0x94, 0x73, 0xCD, 0xCE, 0x86, 0x6E, 0x95, 0x95, 0x02, + 0x40, 0x38, 0xFD, 0x28, 0x1E, 0xBF, 0x5B, 0xBA, 0xC9, 0xDC, + 0x8C, 0xDD, 0x45, 0xAF, 0xB8, 0xD3, 0xFB, 0x11, 0x2E, 0x73, + 0xBC, 0x08, 0x05, 0x0B, 0xBA, 0x19, 0x56, 0x1B, 0xCD, 0x9F, + 0x3E, 0x65, 0x53, 0x15, 0x3A, 0x3E, 0x7F, 0x2F, 0x32, 0xAB, + 0xCB, 0x6B, 0x4A, 0xB7, 0xC8, 0xB7, 0x41, 0x3B, 0x92, 0x43, + 0x78, 0x46, 0x17, 0x51, 0x86, 0xC9, 0xFC, 0xEB, 0x8B, 0x8F, + 0x41, 0xCA, 0x08, 0x9B, 0xBF, 0x02, 0x41, 0x00, 0xAD, 0x9B, + 0x89, 0xB6, 0xF2, 0x8C, 0x70, 0xDA, 0xE4, 0x10, 0x04, 0x6B, + 0x11, 0x92, 0xAF, 0x5A, 0xCA, 0x08, 0x25, 0xBF, 0x60, 0x07, + 0x11, 0x1D, 0x68, 0x7F, 0x5A, 0x1F, 0x55, 0x28, 0x74, 0x0B, + 0x21, 0x8D, 0x21, 0x0D, 0x6A, 0x6A, 0xFB, 0xD9, 0xB5, 0x4A, + 0x7F, 0x47, 0xF7, 0xD0, 0xB6, 0xC6, 0x41, 0x02, 0x97, 0x07, + 0x49, 0x93, 0x1A, 0x9B, 0x33, 0x68, 0xB3, 0xA2, 0x61, 0x32, + 0xA5, 0x89, 0x02, 0x41, 0x00, 0x8F, 0xEF, 0xAD, 0xB5, 0xB0, + 0xB0, 0x7E, 0x86, 0x03, 0x43, 0x93, 0x6E, 0xDD, 0x3C, 0x2D, + 0x9B, 0x6A, 0x55, 0xFF, 0x6F, 0x3E, 0x70, 0x2A, 0xD4, 0xBF, + 0x1F, 0x8C, 0x93, 0x60, 0x9E, 0x6D, 0x2F, 0x18, 0x6C, 0x11, + 0x36, 0x98, 0x3F, 0x10, 0x78, 0xE8, 0x3E, 0x8F, 0xFE, 0x55, + 0xB9, 0x9E, 0xD5, 0x5B, 0x2E, 0x87, 0x1C, 0x58, 0xD0, 0x37, + 0x89, 0x96, 0xEC, 0x48, 0x54, 0xF5, 0x9F, 0x0F, 0xB3 +}; +static const int sizeof_rsa_key_der_1024 = sizeof(rsa_key_der_1024); + +/* ./certs/1024/ca-key.der, 1024-bit */ +static const unsigned char ca_key_der_1024[] = +{ + 0x30, 0x82, 0x02, 0x5E, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, + 0x00, 0xCD, 0xAC, 0xDD, 0x47, 0xEC, 0xBE, 0xB7, 0x24, 0xC3, + 0x63, 0x1B, 0x54, 0x98, 0x79, 0xE1, 0xC7, 0x31, 0x16, 0x59, + 0xD6, 0x9D, 0x77, 0x9D, 0x8D, 0xE2, 0x8B, 0xED, 0x04, 0x17, + 0xB2, 0xC6, 0xEB, 0xE4, 0x9B, 0x91, 0xBE, 0x31, 0x50, 0x62, + 0x97, 0x58, 0xB5, 0x7F, 0x29, 0xDE, 0xB3, 0x71, 0x24, 0x0B, + 0xBF, 0x97, 0x09, 0x7F, 0x26, 0xDC, 0x2D, 0xEC, 0xA8, 0x2E, + 0xB2, 0x64, 0x2B, 0x7A, 0x2B, 0x35, 0x19, 0x2D, 0xA2, 0x80, + 0xCB, 0x99, 0xFD, 0x94, 0x71, 0x1B, 0x23, 0x8D, 0x54, 0xDB, + 0x2E, 0x62, 0x8D, 0x81, 0x08, 0x2D, 0xF4, 0x24, 0x72, 0x27, + 0x6C, 0xF9, 0xC9, 0x8E, 0xDB, 0x4C, 0x75, 0xBA, 0x9B, 0x01, + 0xF8, 0x3F, 0x18, 0xF4, 0xE6, 0x7F, 0xFB, 0x57, 0x94, 0x92, + 0xCC, 0x88, 0xC4, 0xB4, 0x00, 0xC2, 0xAA, 0xD4, 0xE5, 0x88, + 0x18, 0xB3, 0x11, 0x2F, 0x73, 0xC0, 0xD6, 0x29, 0x09, 0x02, + 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x52, 0x35, 0x3D, + 0x01, 0x29, 0xA4, 0x95, 0x29, 0x71, 0x9B, 0x64, 0x6A, 0x2C, + 0xC3, 0xD2, 0xB5, 0xBE, 0x6E, 0x13, 0x9C, 0x8F, 0xB6, 0x26, + 0xD8, 0x76, 0x6B, 0xBD, 0x61, 0xBC, 0x63, 0x2D, 0xD5, 0x4D, + 0xBB, 0xCC, 0xC6, 0x3B, 0x89, 0xC8, 0xCE, 0x7B, 0x9B, 0x97, + 0xE7, 0x51, 0x67, 0x61, 0xDA, 0xA9, 0x83, 0x7B, 0xC8, 0x44, + 0xF5, 0x70, 0x5E, 0x3E, 0xD0, 0x7E, 0x51, 0xB9, 0x6E, 0x13, + 0x57, 0x08, 0x5C, 0xE1, 0x67, 0x4F, 0x61, 0x5E, 0xA5, 0x09, + 0xEC, 0x11, 0xDD, 0xE4, 0xB8, 0xB4, 0xF4, 0xE0, 0x63, 0x34, + 0x4C, 0xDA, 0x32, 0x20, 0x1F, 0x85, 0x41, 0x5D, 0xBC, 0xDB, + 0x24, 0xC5, 0xAF, 0xBE, 0x02, 0x5F, 0x22, 0xF1, 0x7C, 0xCC, + 0x05, 0x56, 0xA6, 0xA6, 0x37, 0x9A, 0xEB, 0xFF, 0x52, 0x2D, + 0xBF, 0x30, 0x4B, 0x9A, 0x1D, 0xEE, 0xAB, 0x9C, 0x2C, 0xE2, + 0xC1, 0xB8, 0x9D, 0xC9, 0x31, 0x02, 0x41, 0x00, 0xE9, 0x89, + 0x16, 0xCD, 0xAC, 0x2E, 0xF2, 0x4D, 0x66, 0x17, 0xBD, 0x78, + 0x12, 0x12, 0x8D, 0x8E, 0x84, 0x24, 0xDE, 0x2D, 0x50, 0x41, + 0x85, 0x8C, 0x34, 0x09, 0xFA, 0xFB, 0x6D, 0x87, 0x51, 0x4C, + 0x13, 0x28, 0xF0, 0x60, 0x11, 0x86, 0x3D, 0xC2, 0xA4, 0xCF, + 0x5E, 0xC5, 0x6F, 0x5B, 0x11, 0x32, 0x0A, 0xB5, 0x28, 0xD0, + 0x82, 0x47, 0x44, 0x26, 0x92, 0xE2, 0x78, 0x59, 0xB4, 0x08, + 0xB3, 0xFD, 0x02, 0x41, 0x00, 0xE1, 0x75, 0xB4, 0x6A, 0xB5, + 0x8C, 0x11, 0xFB, 0xCC, 0x42, 0x02, 0xC5, 0xDA, 0x48, 0xCE, + 0x29, 0x43, 0x14, 0x01, 0x9A, 0x2C, 0xB3, 0xA4, 0xCB, 0x73, + 0xEB, 0xA1, 0x35, 0x57, 0xAD, 0xB5, 0x16, 0x17, 0x80, 0x03, + 0x5F, 0x32, 0x37, 0xBE, 0xA2, 0x6F, 0xF9, 0x31, 0x84, 0xBF, + 0x00, 0x6E, 0x8D, 0x03, 0x0E, 0x30, 0x1C, 0xD0, 0x2F, 0x37, + 0xF0, 0x7E, 0xC2, 0x64, 0xBF, 0xEE, 0x4B, 0xE8, 0xFD, 0x02, + 0x41, 0x00, 0xE1, 0x99, 0x8B, 0x2B, 0xD8, 0x9F, 0xE9, 0x76, + 0x97, 0x9F, 0x6B, 0x6B, 0x28, 0x9A, 0x3F, 0xA1, 0x63, 0x4A, + 0x72, 0x4E, 0xF7, 0xEE, 0xB3, 0xE2, 0x43, 0x0B, 0x39, 0x27, + 0xD6, 0x21, 0x18, 0x8A, 0x13, 0x20, 0x43, 0x45, 0xAA, 0xE8, + 0x31, 0x95, 0x6C, 0xBC, 0xDE, 0xE2, 0x7F, 0xB6, 0x4B, 0xA0, + 0x39, 0xF3, 0xD3, 0x9F, 0xC9, 0x9A, 0xAA, 0xDD, 0x50, 0x9B, + 0xF2, 0x83, 0x45, 0x85, 0xFA, 0xC9, 0x02, 0x41, 0x00, 0xAF, + 0xB0, 0xC7, 0x7C, 0xF8, 0x28, 0x44, 0xC3, 0x50, 0xF2, 0x87, + 0xB2, 0xA2, 0x5D, 0x65, 0xBA, 0x25, 0xB9, 0x6B, 0x5E, 0x37, + 0x43, 0x6E, 0x41, 0xD4, 0xFD, 0x63, 0x4C, 0x6C, 0x1C, 0xC3, + 0x26, 0x89, 0xFD, 0x89, 0xA3, 0x1F, 0x40, 0xED, 0x5F, 0x2B, + 0x9E, 0xA6, 0x85, 0xE9, 0x49, 0x6E, 0xDC, 0x97, 0xEA, 0xF0, + 0x77, 0x23, 0x8C, 0x08, 0x2D, 0x72, 0xBA, 0x0D, 0x44, 0xBB, + 0x6F, 0x90, 0x09, 0x02, 0x41, 0x00, 0x91, 0xE4, 0x2E, 0xCA, + 0x8C, 0x0A, 0x69, 0x2F, 0x62, 0xE2, 0x62, 0x3B, 0xA5, 0x8D, + 0x5A, 0x2C, 0x56, 0x3E, 0x7F, 0x67, 0x42, 0x92, 0x12, 0x92, + 0x5F, 0xF3, 0x97, 0xDD, 0xE1, 0xA9, 0x7F, 0xAD, 0x2E, 0x2D, + 0xF4, 0x4A, 0x57, 0xB3, 0x7A, 0x10, 0xBD, 0xD7, 0xE4, 0xEC, + 0x6A, 0x08, 0x21, 0xE9, 0xF2, 0x46, 0x49, 0xD2, 0x69, 0x47, + 0x8A, 0x20, 0x4B, 0xF2, 0xB1, 0x52, 0x83, 0xAB, 0x6F, 0x10 + +}; +static const int sizeof_ca_key_der_1024 = sizeof(ca_key_der_1024); + +/* ./certs/1024/ca-cert.der, 1024-bit */ +static const unsigned char ca_cert_der_1024[] = +{ + 0x30, 0x82, 0x03, 0xB5, 0x30, 0x82, 0x03, 0x1E, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xDA, 0xFB, 0x6A, 0x0D, + 0xFE, 0xCF, 0x9B, 0x47, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, + 0x81, 0x99, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, + 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, + 0x6E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x53, 0x61, 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, + 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, + 0x0F, 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, + 0x67, 0x5F, 0x31, 0x30, 0x32, 0x34, 0x31, 0x18, 0x30, 0x16, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, + 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, + 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, + 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, + 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x1E, 0x17, 0x0D, 0x31, + 0x38, 0x30, 0x34, 0x31, 0x33, 0x31, 0x35, 0x32, 0x33, 0x31, + 0x30, 0x5A, 0x17, 0x0D, 0x32, 0x31, 0x30, 0x31, 0x30, 0x37, + 0x31, 0x35, 0x32, 0x33, 0x31, 0x30, 0x5A, 0x30, 0x81, 0x99, + 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, + 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, + 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x08, + 0x53, 0x61, 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0F, 0x43, + 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x5F, + 0x31, 0x30, 0x32, 0x34, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, + 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, + 0x63, 0x6F, 0x6D, 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, + 0x81, 0x00, 0xCD, 0xAC, 0xDD, 0x47, 0xEC, 0xBE, 0xB7, 0x24, + 0xC3, 0x63, 0x1B, 0x54, 0x98, 0x79, 0xE1, 0xC7, 0x31, 0x16, + 0x59, 0xD6, 0x9D, 0x77, 0x9D, 0x8D, 0xE2, 0x8B, 0xED, 0x04, + 0x17, 0xB2, 0xC6, 0xEB, 0xE4, 0x9B, 0x91, 0xBE, 0x31, 0x50, + 0x62, 0x97, 0x58, 0xB5, 0x7F, 0x29, 0xDE, 0xB3, 0x71, 0x24, + 0x0B, 0xBF, 0x97, 0x09, 0x7F, 0x26, 0xDC, 0x2D, 0xEC, 0xA8, + 0x2E, 0xB2, 0x64, 0x2B, 0x7A, 0x2B, 0x35, 0x19, 0x2D, 0xA2, + 0x80, 0xCB, 0x99, 0xFD, 0x94, 0x71, 0x1B, 0x23, 0x8D, 0x54, + 0xDB, 0x2E, 0x62, 0x8D, 0x81, 0x08, 0x2D, 0xF4, 0x24, 0x72, + 0x27, 0x6C, 0xF9, 0xC9, 0x8E, 0xDB, 0x4C, 0x75, 0xBA, 0x9B, + 0x01, 0xF8, 0x3F, 0x18, 0xF4, 0xE6, 0x7F, 0xFB, 0x57, 0x94, + 0x92, 0xCC, 0x88, 0xC4, 0xB4, 0x00, 0xC2, 0xAA, 0xD4, 0xE5, + 0x88, 0x18, 0xB3, 0x11, 0x2F, 0x73, 0xC0, 0xD6, 0x29, 0x09, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x82, 0x01, 0x01, 0x30, + 0x81, 0xFE, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, + 0x16, 0x04, 0x14, 0xD3, 0x22, 0x8F, 0x28, 0x2C, 0xE0, 0x05, + 0xEE, 0xD3, 0xED, 0xC3, 0x71, 0x3D, 0xC9, 0xB2, 0x36, 0x3A, + 0x1D, 0xBF, 0xA8, 0x30, 0x81, 0xCE, 0x06, 0x03, 0x55, 0x1D, + 0x23, 0x04, 0x81, 0xC6, 0x30, 0x81, 0xC3, 0x80, 0x14, 0xD3, + 0x22, 0x8F, 0x28, 0x2C, 0xE0, 0x05, 0xEE, 0xD3, 0xED, 0xC3, + 0x71, 0x3D, 0xC9, 0xB2, 0x36, 0x3A, 0x1D, 0xBF, 0xA8, 0xA1, + 0x81, 0x9F, 0xA4, 0x81, 0x9C, 0x30, 0x81, 0x99, 0x31, 0x0B, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, + 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x11, 0x30, + 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x08, 0x53, 0x61, + 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, 0x31, 0x18, 0x30, 0x16, + 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0F, 0x43, 0x6F, 0x6E, + 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x5F, 0x31, 0x30, + 0x32, 0x34, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, + 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, + 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, + 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, + 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, + 0x6D, 0x82, 0x09, 0x00, 0xDA, 0xFB, 0x6A, 0x0D, 0xFE, 0xCF, + 0x9B, 0x47, 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, 0x0B, 0x05, + 0x00, 0x03, 0x81, 0x81, 0x00, 0x1D, 0x48, 0xF6, 0x40, 0x41, + 0x04, 0x06, 0xF2, 0xE4, 0x72, 0x2F, 0xEA, 0xFF, 0xC1, 0x67, + 0x6B, 0x15, 0xBB, 0x0A, 0x28, 0x23, 0x28, 0x07, 0xC6, 0xD7, + 0x13, 0x2C, 0xBE, 0x00, 0x00, 0xAC, 0x1D, 0xF7, 0xF4, 0x92, + 0xD3, 0x2B, 0xAF, 0x23, 0xEB, 0x9F, 0x1A, 0xE2, 0x11, 0x3C, + 0x2D, 0x97, 0xF2, 0x0F, 0xAC, 0xAE, 0x97, 0x86, 0x0A, 0xFB, + 0xA8, 0x4F, 0x74, 0x1B, 0xDE, 0x19, 0x51, 0xDB, 0xCD, 0xE2, + 0x11, 0x38, 0xC1, 0xA4, 0x9D, 0x56, 0xAB, 0x47, 0x5C, 0xDE, + 0xBA, 0xEB, 0x27, 0xDF, 0x6D, 0xC8, 0x7E, 0x3A, 0xBD, 0x2E, + 0x9B, 0x2A, 0xAD, 0x22, 0x3B, 0x95, 0xA9, 0xF2, 0x28, 0x03, + 0xBC, 0xE5, 0xEC, 0xCC, 0xF2, 0x08, 0xD4, 0xC8, 0x2F, 0xDB, + 0xEA, 0xFB, 0x2E, 0x52, 0x16, 0x8C, 0x42, 0x02, 0xA4, 0x59, + 0x6D, 0x4C, 0x33, 0xB4, 0x9A, 0xD2, 0x73, 0x4A, 0x1E, 0x9F, + 0xD9, 0xC8, 0x83 +}; +static const int sizeof_ca_cert_der_1024 = sizeof(ca_cert_der_1024); + +/* ./certs/1024/server-key.der, 1024-bit */ +static const unsigned char server_key_der_1024[] = +{ + 0x30, 0x82, 0x02, 0x5D, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, + 0x00, 0xAA, 0x3E, 0xA5, 0x9C, 0xD3, 0x17, 0x49, 0x65, 0x43, + 0xDE, 0xD0, 0xF3, 0x4B, 0x1C, 0xDB, 0x49, 0x0C, 0xFC, 0x7A, + 0x65, 0x05, 0x6D, 0xDE, 0x6A, 0xC4, 0xE4, 0x73, 0x2C, 0x8A, + 0x96, 0x82, 0x8F, 0x23, 0xA5, 0x06, 0x71, 0x1C, 0x06, 0x3E, + 0x2F, 0x92, 0x8D, 0x0B, 0x29, 0x34, 0x45, 0x59, 0xE9, 0xA9, + 0xBC, 0x61, 0xD7, 0x24, 0x37, 0x5D, 0xB5, 0xC4, 0x37, 0x8D, + 0xBA, 0x67, 0xB2, 0xEF, 0x03, 0x27, 0xFA, 0xC1, 0xB4, 0xCD, + 0x6B, 0x00, 0x66, 0xB4, 0xD6, 0x73, 0x70, 0x1F, 0x08, 0x3A, + 0xCC, 0x77, 0xAD, 0xE9, 0xF9, 0x34, 0xD4, 0xF3, 0xA0, 0x2D, + 0xA9, 0xE7, 0x58, 0xA9, 0xC0, 0x61, 0x84, 0xB6, 0xEC, 0x3D, + 0x0A, 0xAD, 0xFD, 0x5C, 0x86, 0x73, 0xAA, 0x6B, 0x47, 0xD8, + 0x8B, 0x2E, 0x58, 0x4B, 0x69, 0x12, 0x82, 0x26, 0x55, 0xE6, + 0x14, 0xBF, 0x55, 0x70, 0x88, 0xFE, 0xF9, 0x75, 0xE1, 0x02, + 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x0A, 0x4C, 0xC1, + 0xFE, 0x4B, 0xF3, 0x23, 0xB8, 0xA1, 0xB3, 0x90, 0x56, 0xB7, + 0xDB, 0xA6, 0x14, 0xB4, 0x59, 0x6E, 0x1A, 0x40, 0x8A, 0xD6, + 0x23, 0x05, 0x88, 0x80, 0xC3, 0x58, 0x1B, 0x25, 0x08, 0xFD, + 0xF2, 0x15, 0x02, 0xB0, 0xDC, 0x5B, 0xD4, 0xCA, 0xFC, 0x07, + 0x89, 0xD5, 0xA4, 0xC0, 0x7C, 0xD7, 0x8D, 0x13, 0x2A, 0x4E, + 0x01, 0x9F, 0x84, 0xC8, 0xBB, 0x47, 0xB2, 0xD8, 0x65, 0x45, + 0xFA, 0x84, 0x9F, 0x88, 0xD0, 0xF4, 0xF5, 0x22, 0x35, 0x77, + 0x11, 0x67, 0x1C, 0xDE, 0x5F, 0x85, 0x6D, 0x55, 0xD8, 0xA7, + 0x07, 0x15, 0x8C, 0xE1, 0xB0, 0xA7, 0x79, 0xB4, 0x47, 0x9D, + 0x70, 0xB3, 0xD2, 0xF1, 0x1F, 0x41, 0x4C, 0x65, 0x72, 0x26, + 0xEB, 0x66, 0xC8, 0x95, 0xF6, 0x6D, 0x87, 0x35, 0x53, 0xFE, + 0xB1, 0x52, 0x4D, 0x76, 0x5B, 0x61, 0x53, 0x89, 0xB1, 0x20, + 0x1A, 0x8B, 0xE4, 0x7D, 0xF1, 0x02, 0x41, 0x00, 0xD9, 0x6E, + 0xE1, 0xD9, 0x06, 0x56, 0xA1, 0xF6, 0xDF, 0x54, 0x45, 0xC5, + 0xEC, 0x6A, 0xC8, 0x2A, 0x38, 0x4E, 0x6B, 0xC6, 0xE8, 0xEA, + 0xFB, 0x6F, 0x65, 0x2D, 0xBA, 0xDE, 0x27, 0x63, 0x37, 0x21, + 0x2E, 0xA4, 0x55, 0xAB, 0xE7, 0xDB, 0xCE, 0x71, 0xE1, 0x08, + 0xFC, 0xF2, 0xCA, 0x52, 0x33, 0x55, 0xE8, 0x39, 0xB3, 0xDA, + 0xC5, 0xB0, 0x69, 0x84, 0x6E, 0xE3, 0xCF, 0x47, 0x80, 0xA6, + 0xB6, 0x85, 0x02, 0x41, 0x00, 0xC8, 0x71, 0x0D, 0x37, 0x47, + 0xE1, 0x7B, 0x21, 0x2D, 0x11, 0x2D, 0x95, 0x2E, 0xC7, 0xD0, + 0xB6, 0xD3, 0x7C, 0x5C, 0x93, 0x3C, 0x5B, 0x22, 0xE5, 0xE0, + 0x8B, 0x6D, 0x47, 0xF9, 0x14, 0x0F, 0x9E, 0x08, 0x1B, 0x53, + 0xAB, 0x0A, 0xA9, 0xE4, 0x7F, 0x40, 0xD3, 0xDF, 0x62, 0x74, + 0x10, 0xA2, 0xFE, 0x83, 0x1F, 0xCF, 0x55, 0x66, 0xEB, 0x5D, + 0xC5, 0x83, 0xBA, 0xEC, 0x9F, 0xD2, 0xB5, 0x06, 0xAD, 0x02, + 0x41, 0x00, 0xB7, 0x68, 0x19, 0xA7, 0xC7, 0xF9, 0xF1, 0x9A, + 0xDD, 0x5D, 0x27, 0x91, 0xC1, 0x4F, 0x7D, 0x52, 0x67, 0xB6, + 0x76, 0xA1, 0x0D, 0x3D, 0x91, 0x23, 0xB0, 0xB3, 0xF7, 0x49, + 0x86, 0xED, 0xE0, 0xC5, 0xE3, 0xA3, 0x09, 0x04, 0xFD, 0x89, + 0xE2, 0xC5, 0x1A, 0x6E, 0x4B, 0x77, 0xBD, 0x03, 0xC3, 0x7B, + 0xB6, 0x6C, 0x5D, 0xF2, 0xAF, 0x08, 0x94, 0xA8, 0xFA, 0x24, + 0xBD, 0x66, 0x71, 0xF5, 0xAE, 0x45, 0x02, 0x40, 0x15, 0x52, + 0xD1, 0x91, 0x1B, 0xF8, 0x84, 0xDC, 0xD6, 0xAA, 0x89, 0x2A, + 0xE1, 0xBB, 0x28, 0x1D, 0x0B, 0x0A, 0xA3, 0xDE, 0x96, 0x01, + 0x2C, 0x09, 0x40, 0x86, 0x14, 0xAE, 0x1F, 0x75, 0x5E, 0xE3, + 0xF5, 0x00, 0xD3, 0x39, 0xD2, 0xFC, 0x97, 0xEE, 0x61, 0xBB, + 0x28, 0x7C, 0x94, 0xD4, 0x60, 0x42, 0xAB, 0x38, 0x6B, 0x1A, + 0x2E, 0xC4, 0xC3, 0x49, 0x0B, 0xE6, 0x8A, 0xDD, 0xC5, 0xD0, + 0xB4, 0x51, 0x02, 0x41, 0x00, 0xA9, 0x8B, 0xA7, 0xA9, 0xEE, + 0xAE, 0xBB, 0x17, 0xCB, 0x72, 0xF2, 0x50, 0x22, 0x9D, 0xB3, + 0xDF, 0xE0, 0x40, 0x37, 0x08, 0xD5, 0x7F, 0x19, 0x58, 0x80, + 0x70, 0x79, 0x69, 0x99, 0xDF, 0x62, 0x0D, 0x21, 0xAB, 0xDD, + 0xB2, 0xCE, 0x68, 0xB3, 0x9F, 0x87, 0xAF, 0x55, 0xF4, 0xAA, + 0xE1, 0x00, 0x72, 0xBE, 0x6E, 0xC3, 0x94, 0x49, 0xDC, 0xBB, + 0x8E, 0x1A, 0x78, 0xE5, 0x49, 0x1F, 0x55, 0x41, 0xA1 +}; +static const int sizeof_server_key_der_1024 = sizeof(server_key_der_1024); + +/* ./certs/1024/server-cert.der, 1024-bit */ +static const unsigned char server_cert_der_1024[] = +{ + 0x30, 0x82, 0x03, 0xA9, 0x30, 0x82, 0x03, 0x12, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, + 0x00, 0x30, 0x81, 0x99, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, + 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, + 0x6D, 0x61, 0x6E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x08, 0x53, 0x61, 0x77, 0x74, 0x6F, 0x6F, + 0x74, 0x68, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x0F, 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, + 0x69, 0x6E, 0x67, 0x5F, 0x31, 0x30, 0x32, 0x34, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, + 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, + 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, + 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x1E, 0x17, + 0x0D, 0x31, 0x38, 0x30, 0x34, 0x31, 0x33, 0x31, 0x35, 0x32, + 0x33, 0x31, 0x30, 0x5A, 0x17, 0x0D, 0x32, 0x31, 0x30, 0x31, + 0x30, 0x37, 0x31, 0x35, 0x32, 0x33, 0x31, 0x30, 0x5A, 0x30, + 0x81, 0x95, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, + 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, + 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x07, 0x77, 0x6F, 0x6C, 0x66, 0x53, 0x53, 0x4C, 0x31, + 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0C, + 0x53, 0x75, 0x70, 0x70, 0x6F, 0x72, 0x74, 0x5F, 0x31, 0x30, + 0x32, 0x34, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, + 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, + 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, + 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, + 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, + 0x6D, 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, + 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, + 0xAA, 0x3E, 0xA5, 0x9C, 0xD3, 0x17, 0x49, 0x65, 0x43, 0xDE, + 0xD0, 0xF3, 0x4B, 0x1C, 0xDB, 0x49, 0x0C, 0xFC, 0x7A, 0x65, + 0x05, 0x6D, 0xDE, 0x6A, 0xC4, 0xE4, 0x73, 0x2C, 0x8A, 0x96, + 0x82, 0x8F, 0x23, 0xA5, 0x06, 0x71, 0x1C, 0x06, 0x3E, 0x2F, + 0x92, 0x8D, 0x0B, 0x29, 0x34, 0x45, 0x59, 0xE9, 0xA9, 0xBC, + 0x61, 0xD7, 0x24, 0x37, 0x5D, 0xB5, 0xC4, 0x37, 0x8D, 0xBA, + 0x67, 0xB2, 0xEF, 0x03, 0x27, 0xFA, 0xC1, 0xB4, 0xCD, 0x6B, + 0x00, 0x66, 0xB4, 0xD6, 0x73, 0x70, 0x1F, 0x08, 0x3A, 0xCC, + 0x77, 0xAD, 0xE9, 0xF9, 0x34, 0xD4, 0xF3, 0xA0, 0x2D, 0xA9, + 0xE7, 0x58, 0xA9, 0xC0, 0x61, 0x84, 0xB6, 0xEC, 0x3D, 0x0A, + 0xAD, 0xFD, 0x5C, 0x86, 0x73, 0xAA, 0x6B, 0x47, 0xD8, 0x8B, + 0x2E, 0x58, 0x4B, 0x69, 0x12, 0x82, 0x26, 0x55, 0xE6, 0x14, + 0xBF, 0x55, 0x70, 0x88, 0xFE, 0xF9, 0x75, 0xE1, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xA3, 0x82, 0x01, 0x01, 0x30, 0x81, 0xFE, + 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, + 0x14, 0xD9, 0x3C, 0x35, 0xEA, 0x74, 0x0E, 0x23, 0xBE, 0x9C, + 0xFC, 0xFA, 0x29, 0x90, 0x09, 0xC1, 0xE7, 0x84, 0x16, 0x9F, + 0x7C, 0x30, 0x81, 0xCE, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, + 0x81, 0xC6, 0x30, 0x81, 0xC3, 0x80, 0x14, 0xD3, 0x22, 0x8F, + 0x28, 0x2C, 0xE0, 0x05, 0xEE, 0xD3, 0xED, 0xC3, 0x71, 0x3D, + 0xC9, 0xB2, 0x36, 0x3A, 0x1D, 0xBF, 0xA8, 0xA1, 0x81, 0x9F, + 0xA4, 0x81, 0x9C, 0x30, 0x81, 0x99, 0x31, 0x0B, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, + 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, + 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x11, 0x30, 0x0F, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x08, 0x53, 0x61, 0x77, 0x74, + 0x6F, 0x6F, 0x74, 0x68, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x0C, 0x0F, 0x43, 0x6F, 0x6E, 0x73, 0x75, + 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x5F, 0x31, 0x30, 0x32, 0x34, + 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, + 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, + 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, + 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, + 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x82, + 0x09, 0x00, 0xDA, 0xFB, 0x6A, 0x0D, 0xFE, 0xCF, 0x9B, 0x47, + 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, 0x0B, 0x05, 0x00, 0x03, + 0x81, 0x81, 0x00, 0x0B, 0xC3, 0xAF, 0x43, 0x85, 0x64, 0x61, + 0xE7, 0xAB, 0x5A, 0x2A, 0x1B, 0xB2, 0x29, 0xD5, 0x66, 0x68, + 0x44, 0x1A, 0x6D, 0x66, 0xFC, 0x3D, 0xB1, 0x88, 0xEC, 0xA5, + 0x41, 0x18, 0x67, 0x62, 0x34, 0xA4, 0x5E, 0xC9, 0x69, 0xCD, + 0x40, 0xC8, 0x56, 0x7E, 0xBF, 0xEB, 0xBC, 0x61, 0x1F, 0x33, + 0x34, 0x58, 0xBE, 0x57, 0xFD, 0xE6, 0x98, 0xDD, 0x51, 0x27, + 0x7C, 0xB7, 0x2C, 0xBC, 0xC9, 0x39, 0xE5, 0xE5, 0x95, 0x82, + 0xE1, 0x3F, 0xD9, 0xB9, 0x97, 0x30, 0x4E, 0x33, 0x2C, 0xEF, + 0xF8, 0xDB, 0xB4, 0xEE, 0x35, 0x75, 0x9E, 0x7A, 0x3F, 0x22, + 0x8F, 0xA5, 0x71, 0xD4, 0x01, 0x64, 0x6C, 0xF2, 0x85, 0xF7, + 0x72, 0x99, 0x2C, 0x80, 0x0F, 0xA4, 0x31, 0x1D, 0xD4, 0x0B, + 0x1E, 0xA5, 0x0F, 0xE7, 0x53, 0x0A, 0xDE, 0x15, 0x0D, 0xB2, + 0xD0, 0x6B, 0xF4, 0xD6, 0x2F, 0xE2, 0x0B, 0xA3, 0x8A, 0x5A, + 0x6E +}; +static const int sizeof_server_cert_der_1024 = sizeof(server_cert_der_1024); + +#endif /* USE_CERT_BUFFERS_1024 */ + +#ifdef USE_CERT_BUFFERS_2048 + +/* ./certs/client-key.der, 2048-bit */ +static const unsigned char client_key_der_2048[] = +{ + 0x30, 0x82, 0x04, 0xA4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xC3, 0x03, 0xD1, 0x2B, 0xFE, 0x39, 0xA4, 0x32, + 0x45, 0x3B, 0x53, 0xC8, 0x84, 0x2B, 0x2A, 0x7C, 0x74, 0x9A, + 0xBD, 0xAA, 0x2A, 0x52, 0x07, 0x47, 0xD6, 0xA6, 0x36, 0xB2, + 0x07, 0x32, 0x8E, 0xD0, 0xBA, 0x69, 0x7B, 0xC6, 0xC3, 0x44, + 0x9E, 0xD4, 0x81, 0x48, 0xFD, 0x2D, 0x68, 0xA2, 0x8B, 0x67, + 0xBB, 0xA1, 0x75, 0xC8, 0x36, 0x2C, 0x4A, 0xD2, 0x1B, 0xF7, + 0x8B, 0xBA, 0xCF, 0x0D, 0xF9, 0xEF, 0xEC, 0xF1, 0x81, 0x1E, + 0x7B, 0x9B, 0x03, 0x47, 0x9A, 0xBF, 0x65, 0xCC, 0x7F, 0x65, + 0x24, 0x69, 0xA6, 0xE8, 0x14, 0x89, 0x5B, 0xE4, 0x34, 0xF7, + 0xC5, 0xB0, 0x14, 0x93, 0xF5, 0x67, 0x7B, 0x3A, 0x7A, 0x78, + 0xE1, 0x01, 0x56, 0x56, 0x91, 0xA6, 0x13, 0x42, 0x8D, 0xD2, + 0x3C, 0x40, 0x9C, 0x4C, 0xEF, 0xD1, 0x86, 0xDF, 0x37, 0x51, + 0x1B, 0x0C, 0xA1, 0x3B, 0xF5, 0xF1, 0xA3, 0x4A, 0x35, 0xE4, + 0xE1, 0xCE, 0x96, 0xDF, 0x1B, 0x7E, 0xBF, 0x4E, 0x97, 0xD0, + 0x10, 0xE8, 0xA8, 0x08, 0x30, 0x81, 0xAF, 0x20, 0x0B, 0x43, + 0x14, 0xC5, 0x74, 0x67, 0xB4, 0x32, 0x82, 0x6F, 0x8D, 0x86, + 0xC2, 0x88, 0x40, 0x99, 0x36, 0x83, 0xBA, 0x1E, 0x40, 0x72, + 0x22, 0x17, 0xD7, 0x52, 0x65, 0x24, 0x73, 0xB0, 0xCE, 0xEF, + 0x19, 0xCD, 0xAE, 0xFF, 0x78, 0x6C, 0x7B, 0xC0, 0x12, 0x03, + 0xD4, 0x4E, 0x72, 0x0D, 0x50, 0x6D, 0x3B, 0xA3, 0x3B, 0xA3, + 0x99, 0x5E, 0x9D, 0xC8, 0xD9, 0x0C, 0x85, 0xB3, 0xD9, 0x8A, + 0xD9, 0x54, 0x26, 0xDB, 0x6D, 0xFA, 0xAC, 0xBB, 0xFF, 0x25, + 0x4C, 0xC4, 0xD1, 0x79, 0xF4, 0x71, 0xD3, 0x86, 0x40, 0x18, + 0x13, 0xB0, 0x63, 0xB5, 0x72, 0x4E, 0x30, 0xC4, 0x97, 0x84, + 0x86, 0x2D, 0x56, 0x2F, 0xD7, 0x15, 0xF7, 0x7F, 0xC0, 0xAE, + 0xF5, 0xFC, 0x5B, 0xE5, 0xFB, 0xA1, 0xBA, 0xD3, 0x02, 0x03, + 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x01, 0x00, 0xA2, 0xE6, + 0xD8, 0x5F, 0x10, 0x71, 0x64, 0x08, 0x9E, 0x2E, 0x6D, 0xD1, + 0x6D, 0x1E, 0x85, 0xD2, 0x0A, 0xB1, 0x8C, 0x47, 0xCE, 0x2C, + 0x51, 0x6A, 0xA0, 0x12, 0x9E, 0x53, 0xDE, 0x91, 0x4C, 0x1D, + 0x6D, 0xEA, 0x59, 0x7B, 0xF2, 0x77, 0xAA, 0xD9, 0xC6, 0xD9, + 0x8A, 0xAB, 0xD8, 0xE1, 0x16, 0xE4, 0x63, 0x26, 0xFF, 0xB5, + 0x6C, 0x13, 0x59, 0xB8, 0xE3, 0xA5, 0xC8, 0x72, 0x17, 0x2E, + 0x0C, 0x9F, 0x6F, 0xE5, 0x59, 0x3F, 0x76, 0x6F, 0x49, 0xB1, + 0x11, 0xC2, 0x5A, 0x2E, 0x16, 0x29, 0x0D, 0xDE, 0xB7, 0x8E, + 0xDC, 0x40, 0xD5, 0xA2, 0xEE, 0xE0, 0x1E, 0xA1, 0xF4, 0xBE, + 0x97, 0xDB, 0x86, 0x63, 0x96, 0x14, 0xCD, 0x98, 0x09, 0x60, + 0x2D, 0x30, 0x76, 0x9C, 0x3C, 0xCD, 0xE6, 0x88, 0xEE, 0x47, + 0x92, 0x79, 0x0B, 0x5A, 0x00, 0xE2, 0x5E, 0x5F, 0x11, 0x7C, + 0x7D, 0xF9, 0x08, 0xB7, 0x20, 0x06, 0x89, 0x2A, 0x5D, 0xFD, + 0x00, 0xAB, 0x22, 0xE1, 0xF0, 0xB3, 0xBC, 0x24, 0xA9, 0x5E, + 0x26, 0x0E, 0x1F, 0x00, 0x2D, 0xFE, 0x21, 0x9A, 0x53, 0x5B, + 0x6D, 0xD3, 0x2B, 0xAB, 0x94, 0x82, 0x68, 0x43, 0x36, 0xD8, + 0xF6, 0x2F, 0xC6, 0x22, 0xFC, 0xB5, 0x41, 0x5D, 0x0D, 0x33, + 0x60, 0xEA, 0xA4, 0x7D, 0x7E, 0xE8, 0x4B, 0x55, 0x91, 0x56, + 0xD3, 0x5C, 0x57, 0x8F, 0x1F, 0x94, 0x17, 0x2F, 0xAA, 0xDE, + 0xE9, 0x9E, 0xA8, 0xF4, 0xCF, 0x8A, 0x4C, 0x8E, 0xA0, 0xE4, + 0x56, 0x73, 0xB2, 0xCF, 0x4F, 0x86, 0xC5, 0x69, 0x3C, 0xF3, + 0x24, 0x20, 0x8B, 0x5C, 0x96, 0x0C, 0xFA, 0x6B, 0x12, 0x3B, + 0x9A, 0x67, 0xC1, 0xDF, 0xC6, 0x96, 0xB2, 0xA5, 0xD5, 0x92, + 0x0D, 0x9B, 0x09, 0x42, 0x68, 0x24, 0x10, 0x45, 0xD4, 0x50, + 0xE4, 0x17, 0x39, 0x48, 0xD0, 0x35, 0x8B, 0x94, 0x6D, 0x11, + 0xDE, 0x8F, 0xCA, 0x59, 0x02, 0x81, 0x81, 0x00, 0xEA, 0x24, + 0xA7, 0xF9, 0x69, 0x33, 0xE9, 0x71, 0xDC, 0x52, 0x7D, 0x88, + 0x21, 0x28, 0x2F, 0x49, 0xDE, 0xBA, 0x72, 0x16, 0xE9, 0xCC, + 0x47, 0x7A, 0x88, 0x0D, 0x94, 0x57, 0x84, 0x58, 0x16, 0x3A, + 0x81, 0xB0, 0x3F, 0xA2, 0xCF, 0xA6, 0x6C, 0x1E, 0xB0, 0x06, + 0x29, 0x00, 0x8F, 0xE7, 0x77, 0x76, 0xAC, 0xDB, 0xCA, 0xC7, + 0xD9, 0x5E, 0x9B, 0x3F, 0x26, 0x90, 0x52, 0xAE, 0xFC, 0x38, + 0x90, 0x00, 0x14, 0xBB, 0xB4, 0x0F, 0x58, 0x94, 0xE7, 0x2F, + 0x6A, 0x7E, 0x1C, 0x4F, 0x41, 0x21, 0xD4, 0x31, 0x59, 0x1F, + 0x4E, 0x8A, 0x1A, 0x8D, 0xA7, 0x57, 0x6C, 0x22, 0xD8, 0xE5, + 0xF4, 0x7E, 0x32, 0xA6, 0x10, 0xCB, 0x64, 0xA5, 0x55, 0x03, + 0x87, 0xA6, 0x27, 0x05, 0x8C, 0xC3, 0xD7, 0xB6, 0x27, 0xB2, + 0x4D, 0xBA, 0x30, 0xDA, 0x47, 0x8F, 0x54, 0xD3, 0x3D, 0x8B, + 0x84, 0x8D, 0x94, 0x98, 0x58, 0xA5, 0x02, 0x81, 0x81, 0x00, + 0xD5, 0x38, 0x1B, 0xC3, 0x8F, 0xC5, 0x93, 0x0C, 0x47, 0x0B, + 0x6F, 0x35, 0x92, 0xC5, 0xB0, 0x8D, 0x46, 0xC8, 0x92, 0x18, + 0x8F, 0xF5, 0x80, 0x0A, 0xF7, 0xEF, 0xA1, 0xFE, 0x80, 0xB9, + 0xB5, 0x2A, 0xBA, 0xCA, 0x18, 0xB0, 0x5D, 0xA5, 0x07, 0xD0, + 0x93, 0x8D, 0xD8, 0x9C, 0x04, 0x1C, 0xD4, 0x62, 0x8E, 0xA6, + 0x26, 0x81, 0x01, 0xFF, 0xCE, 0x8A, 0x2A, 0x63, 0x34, 0x35, + 0x40, 0xAA, 0x6D, 0x80, 0xDE, 0x89, 0x23, 0x6A, 0x57, 0x4D, + 0x9E, 0x6E, 0xAD, 0x93, 0x4E, 0x56, 0x90, 0x0B, 0x6D, 0x9D, + 0x73, 0x8B, 0x0C, 0xAE, 0x27, 0x3D, 0xDE, 0x4E, 0xF0, 0xAA, + 0xC5, 0x6C, 0x78, 0x67, 0x6C, 0x94, 0x52, 0x9C, 0x37, 0x67, + 0x6C, 0x2D, 0xEF, 0xBB, 0xAF, 0xDF, 0xA6, 0x90, 0x3C, 0xC4, + 0x47, 0xCF, 0x8D, 0x96, 0x9E, 0x98, 0xA9, 0xB4, 0x9F, 0xC5, + 0xA6, 0x50, 0xDC, 0xB3, 0xF0, 0xFB, 0x74, 0x17, 0x02, 0x81, + 0x80, 0x5E, 0x83, 0x09, 0x62, 0xBD, 0xBA, 0x7C, 0xA2, 0xBF, + 0x42, 0x74, 0xF5, 0x7C, 0x1C, 0xD2, 0x69, 0xC9, 0x04, 0x0D, + 0x85, 0x7E, 0x3E, 0x3D, 0x24, 0x12, 0xC3, 0x18, 0x7B, 0xF3, + 0x29, 0xF3, 0x5F, 0x0E, 0x76, 0x6C, 0x59, 0x75, 0xE4, 0x41, + 0x84, 0x69, 0x9D, 0x32, 0xF3, 0xCD, 0x22, 0xAB, 0xB0, 0x35, + 0xBA, 0x4A, 0xB2, 0x3C, 0xE5, 0xD9, 0x58, 0xB6, 0x62, 0x4F, + 0x5D, 0xDE, 0xE5, 0x9E, 0x0A, 0xCA, 0x53, 0xB2, 0x2C, 0xF7, + 0x9E, 0xB3, 0x6B, 0x0A, 0x5B, 0x79, 0x65, 0xEC, 0x6E, 0x91, + 0x4E, 0x92, 0x20, 0xF6, 0xFC, 0xFC, 0x16, 0xED, 0xD3, 0x76, + 0x0C, 0xE2, 0xEC, 0x7F, 0xB2, 0x69, 0x13, 0x6B, 0x78, 0x0E, + 0x5A, 0x46, 0x64, 0xB4, 0x5E, 0xB7, 0x25, 0xA0, 0x5A, 0x75, + 0x3A, 0x4B, 0xEF, 0xC7, 0x3C, 0x3E, 0xF7, 0xFD, 0x26, 0xB8, + 0x20, 0xC4, 0x99, 0x0A, 0x9A, 0x73, 0xBE, 0xC3, 0x19, 0x02, + 0x81, 0x81, 0x00, 0xBA, 0x44, 0x93, 0x14, 0xAC, 0x34, 0x19, + 0x3B, 0x5F, 0x91, 0x60, 0xAC, 0xF7, 0xB4, 0xD6, 0x81, 0x05, + 0x36, 0x51, 0x53, 0x3D, 0xE8, 0x65, 0xDC, 0xAF, 0x2E, 0xDC, + 0x61, 0x3E, 0xC9, 0x7D, 0xB8, 0x7F, 0x87, 0xF0, 0x3B, 0x9B, + 0x03, 0x82, 0x29, 0x37, 0xCE, 0x72, 0x4E, 0x11, 0xD5, 0xB1, + 0xC1, 0x0C, 0x07, 0xA0, 0x99, 0x91, 0x4A, 0x8D, 0x7F, 0xEC, + 0x79, 0xCF, 0xF1, 0x39, 0xB5, 0xE9, 0x85, 0xEC, 0x62, 0xF7, + 0xDA, 0x7D, 0xBC, 0x64, 0x4D, 0x22, 0x3C, 0x0E, 0xF2, 0xD6, + 0x51, 0xF5, 0x87, 0xD8, 0x99, 0xC0, 0x11, 0x20, 0x5D, 0x0F, + 0x29, 0xFD, 0x5B, 0xE2, 0xAE, 0xD9, 0x1C, 0xD9, 0x21, 0x56, + 0x6D, 0xFC, 0x84, 0xD0, 0x5F, 0xED, 0x10, 0x15, 0x1C, 0x18, + 0x21, 0xE7, 0xC4, 0x3D, 0x4B, 0xD7, 0xD0, 0x9E, 0x6A, 0x95, + 0xCF, 0x22, 0xC9, 0x03, 0x7B, 0x9E, 0xE3, 0x60, 0x01, 0xFC, + 0x2F, 0x02, 0x81, 0x80, 0x11, 0xD0, 0x4B, 0xCF, 0x1B, 0x67, + 0xB9, 0x9F, 0x10, 0x75, 0x47, 0x86, 0x65, 0xAE, 0x31, 0xC2, + 0xC6, 0x30, 0xAC, 0x59, 0x06, 0x50, 0xD9, 0x0F, 0xB5, 0x70, + 0x06, 0xF7, 0xF0, 0xD3, 0xC8, 0x62, 0x7C, 0xA8, 0xDA, 0x6E, + 0xF6, 0x21, 0x3F, 0xD3, 0x7F, 0x5F, 0xEA, 0x8A, 0xAB, 0x3F, + 0xD9, 0x2A, 0x5E, 0xF3, 0x51, 0xD2, 0xC2, 0x30, 0x37, 0xE3, + 0x2D, 0xA3, 0x75, 0x0D, 0x1E, 0x4D, 0x21, 0x34, 0xD5, 0x57, + 0x70, 0x5C, 0x89, 0xBF, 0x72, 0xEC, 0x4A, 0x6E, 0x68, 0xD5, + 0xCD, 0x18, 0x74, 0x33, 0x4E, 0x8C, 0x3A, 0x45, 0x8F, 0xE6, + 0x96, 0x40, 0xEB, 0x63, 0xF9, 0x19, 0x86, 0x3A, 0x51, 0xDD, + 0x89, 0x4B, 0xB0, 0xF3, 0xF9, 0x9F, 0x5D, 0x28, 0x95, 0x38, + 0xBE, 0x35, 0xAB, 0xCA, 0x5C, 0xE7, 0x93, 0x53, 0x34, 0xA1, + 0x45, 0x5D, 0x13, 0x39, 0x65, 0x42, 0x46, 0xA1, 0x9F, 0xCD, + 0xF5, 0xBF +}; +static const int sizeof_client_key_der_2048 = sizeof(client_key_der_2048); + +/* ./certs/client-keyPub.der, 2048-bit */ +static const unsigned char client_keypub_der_2048[] = +{ + 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, 0xC3, 0x03, 0xD1, 0x2B, 0xFE, 0x39, 0xA4, + 0x32, 0x45, 0x3B, 0x53, 0xC8, 0x84, 0x2B, 0x2A, 0x7C, 0x74, + 0x9A, 0xBD, 0xAA, 0x2A, 0x52, 0x07, 0x47, 0xD6, 0xA6, 0x36, + 0xB2, 0x07, 0x32, 0x8E, 0xD0, 0xBA, 0x69, 0x7B, 0xC6, 0xC3, + 0x44, 0x9E, 0xD4, 0x81, 0x48, 0xFD, 0x2D, 0x68, 0xA2, 0x8B, + 0x67, 0xBB, 0xA1, 0x75, 0xC8, 0x36, 0x2C, 0x4A, 0xD2, 0x1B, + 0xF7, 0x8B, 0xBA, 0xCF, 0x0D, 0xF9, 0xEF, 0xEC, 0xF1, 0x81, + 0x1E, 0x7B, 0x9B, 0x03, 0x47, 0x9A, 0xBF, 0x65, 0xCC, 0x7F, + 0x65, 0x24, 0x69, 0xA6, 0xE8, 0x14, 0x89, 0x5B, 0xE4, 0x34, + 0xF7, 0xC5, 0xB0, 0x14, 0x93, 0xF5, 0x67, 0x7B, 0x3A, 0x7A, + 0x78, 0xE1, 0x01, 0x56, 0x56, 0x91, 0xA6, 0x13, 0x42, 0x8D, + 0xD2, 0x3C, 0x40, 0x9C, 0x4C, 0xEF, 0xD1, 0x86, 0xDF, 0x37, + 0x51, 0x1B, 0x0C, 0xA1, 0x3B, 0xF5, 0xF1, 0xA3, 0x4A, 0x35, + 0xE4, 0xE1, 0xCE, 0x96, 0xDF, 0x1B, 0x7E, 0xBF, 0x4E, 0x97, + 0xD0, 0x10, 0xE8, 0xA8, 0x08, 0x30, 0x81, 0xAF, 0x20, 0x0B, + 0x43, 0x14, 0xC5, 0x74, 0x67, 0xB4, 0x32, 0x82, 0x6F, 0x8D, + 0x86, 0xC2, 0x88, 0x40, 0x99, 0x36, 0x83, 0xBA, 0x1E, 0x40, + 0x72, 0x22, 0x17, 0xD7, 0x52, 0x65, 0x24, 0x73, 0xB0, 0xCE, + 0xEF, 0x19, 0xCD, 0xAE, 0xFF, 0x78, 0x6C, 0x7B, 0xC0, 0x12, + 0x03, 0xD4, 0x4E, 0x72, 0x0D, 0x50, 0x6D, 0x3B, 0xA3, 0x3B, + 0xA3, 0x99, 0x5E, 0x9D, 0xC8, 0xD9, 0x0C, 0x85, 0xB3, 0xD9, + 0x8A, 0xD9, 0x54, 0x26, 0xDB, 0x6D, 0xFA, 0xAC, 0xBB, 0xFF, + 0x25, 0x4C, 0xC4, 0xD1, 0x79, 0xF4, 0x71, 0xD3, 0x86, 0x40, + 0x18, 0x13, 0xB0, 0x63, 0xB5, 0x72, 0x4E, 0x30, 0xC4, 0x97, + 0x84, 0x86, 0x2D, 0x56, 0x2F, 0xD7, 0x15, 0xF7, 0x7F, 0xC0, + 0xAE, 0xF5, 0xFC, 0x5B, 0xE5, 0xFB, 0xA1, 0xBA, 0xD3, 0x02, + 0x03, 0x01, 0x00, 0x01 +}; +static const int sizeof_client_keypub_der_2048 = sizeof(client_keypub_der_2048); + +/* ./certs/client-cert.der, 2048-bit */ +static const unsigned char client_cert_der_2048[] = +{ + 0x30, 0x82, 0x04, 0xCA, 0x30, 0x82, 0x03, 0xB2, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xAA, 0xC4, 0xBF, 0x4C, + 0x50, 0xBD, 0x55, 0x77, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, + 0x81, 0x9E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, + 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, + 0x6E, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x77, 0x6F, 0x6C, 0x66, 0x53, 0x53, 0x4C, 0x5F, + 0x32, 0x30, 0x34, 0x38, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x50, 0x72, 0x6F, 0x67, 0x72, + 0x61, 0x6D, 0x6D, 0x69, 0x6E, 0x67, 0x2D, 0x32, 0x30, 0x34, + 0x38, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, + 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, + 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, + 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, + 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x34, 0x31, 0x33, + 0x31, 0x35, 0x32, 0x33, 0x30, 0x39, 0x5A, 0x17, 0x0D, 0x32, + 0x31, 0x30, 0x31, 0x30, 0x37, 0x31, 0x35, 0x32, 0x33, 0x30, + 0x39, 0x5A, 0x30, 0x81, 0x9E, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, + 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, + 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, + 0x55, 0x04, 0x0A, 0x0C, 0x0C, 0x77, 0x6F, 0x6C, 0x66, 0x53, + 0x53, 0x4C, 0x5F, 0x32, 0x30, 0x34, 0x38, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x50, 0x72, + 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x6D, 0x69, 0x6E, 0x67, 0x2D, + 0x32, 0x30, 0x34, 0x38, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, + 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 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, 0xC3, 0x03, 0xD1, 0x2B, + 0xFE, 0x39, 0xA4, 0x32, 0x45, 0x3B, 0x53, 0xC8, 0x84, 0x2B, + 0x2A, 0x7C, 0x74, 0x9A, 0xBD, 0xAA, 0x2A, 0x52, 0x07, 0x47, + 0xD6, 0xA6, 0x36, 0xB2, 0x07, 0x32, 0x8E, 0xD0, 0xBA, 0x69, + 0x7B, 0xC6, 0xC3, 0x44, 0x9E, 0xD4, 0x81, 0x48, 0xFD, 0x2D, + 0x68, 0xA2, 0x8B, 0x67, 0xBB, 0xA1, 0x75, 0xC8, 0x36, 0x2C, + 0x4A, 0xD2, 0x1B, 0xF7, 0x8B, 0xBA, 0xCF, 0x0D, 0xF9, 0xEF, + 0xEC, 0xF1, 0x81, 0x1E, 0x7B, 0x9B, 0x03, 0x47, 0x9A, 0xBF, + 0x65, 0xCC, 0x7F, 0x65, 0x24, 0x69, 0xA6, 0xE8, 0x14, 0x89, + 0x5B, 0xE4, 0x34, 0xF7, 0xC5, 0xB0, 0x14, 0x93, 0xF5, 0x67, + 0x7B, 0x3A, 0x7A, 0x78, 0xE1, 0x01, 0x56, 0x56, 0x91, 0xA6, + 0x13, 0x42, 0x8D, 0xD2, 0x3C, 0x40, 0x9C, 0x4C, 0xEF, 0xD1, + 0x86, 0xDF, 0x37, 0x51, 0x1B, 0x0C, 0xA1, 0x3B, 0xF5, 0xF1, + 0xA3, 0x4A, 0x35, 0xE4, 0xE1, 0xCE, 0x96, 0xDF, 0x1B, 0x7E, + 0xBF, 0x4E, 0x97, 0xD0, 0x10, 0xE8, 0xA8, 0x08, 0x30, 0x81, + 0xAF, 0x20, 0x0B, 0x43, 0x14, 0xC5, 0x74, 0x67, 0xB4, 0x32, + 0x82, 0x6F, 0x8D, 0x86, 0xC2, 0x88, 0x40, 0x99, 0x36, 0x83, + 0xBA, 0x1E, 0x40, 0x72, 0x22, 0x17, 0xD7, 0x52, 0x65, 0x24, + 0x73, 0xB0, 0xCE, 0xEF, 0x19, 0xCD, 0xAE, 0xFF, 0x78, 0x6C, + 0x7B, 0xC0, 0x12, 0x03, 0xD4, 0x4E, 0x72, 0x0D, 0x50, 0x6D, + 0x3B, 0xA3, 0x3B, 0xA3, 0x99, 0x5E, 0x9D, 0xC8, 0xD9, 0x0C, + 0x85, 0xB3, 0xD9, 0x8A, 0xD9, 0x54, 0x26, 0xDB, 0x6D, 0xFA, + 0xAC, 0xBB, 0xFF, 0x25, 0x4C, 0xC4, 0xD1, 0x79, 0xF4, 0x71, + 0xD3, 0x86, 0x40, 0x18, 0x13, 0xB0, 0x63, 0xB5, 0x72, 0x4E, + 0x30, 0xC4, 0x97, 0x84, 0x86, 0x2D, 0x56, 0x2F, 0xD7, 0x15, + 0xF7, 0x7F, 0xC0, 0xAE, 0xF5, 0xFC, 0x5B, 0xE5, 0xFB, 0xA1, + 0xBA, 0xD3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x82, 0x01, + 0x07, 0x30, 0x82, 0x01, 0x03, 0x30, 0x1D, 0x06, 0x03, 0x55, + 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x33, 0xD8, 0x45, 0x66, + 0xD7, 0x68, 0x87, 0x18, 0x7E, 0x54, 0x0D, 0x70, 0x27, 0x91, + 0xC7, 0x26, 0xD7, 0x85, 0x65, 0xC0, 0x30, 0x81, 0xD3, 0x06, + 0x03, 0x55, 0x1D, 0x23, 0x04, 0x81, 0xCB, 0x30, 0x81, 0xC8, + 0x80, 0x14, 0x33, 0xD8, 0x45, 0x66, 0xD7, 0x68, 0x87, 0x18, + 0x7E, 0x54, 0x0D, 0x70, 0x27, 0x91, 0xC7, 0x26, 0xD7, 0x85, + 0x65, 0xC0, 0xA1, 0x81, 0xA4, 0xA4, 0x81, 0xA1, 0x30, 0x81, + 0x9E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, + 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, + 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0C, 0x77, 0x6F, 0x6C, 0x66, 0x53, 0x53, 0x4C, 0x5F, 0x32, + 0x30, 0x34, 0x38, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, + 0x04, 0x0B, 0x0C, 0x10, 0x50, 0x72, 0x6F, 0x67, 0x72, 0x61, + 0x6D, 0x6D, 0x69, 0x6E, 0x67, 0x2D, 0x32, 0x30, 0x34, 0x38, + 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, + 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, + 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, + 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, + 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x82, + 0x09, 0x00, 0xAA, 0xC4, 0xBF, 0x4C, 0x50, 0xBD, 0x55, 0x77, + 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, 0x0B, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x01, 0x00, 0x80, 0x52, 0x54, 0x61, 0x2A, 0x77, + 0x80, 0x53, 0x44, 0xA9, 0x80, 0x6D, 0x45, 0xFF, 0x0D, 0x25, + 0x7D, 0x1A, 0x8F, 0x23, 0x93, 0x53, 0x74, 0x35, 0x12, 0x6F, + 0xF0, 0x2E, 0x20, 0xEA, 0xED, 0x80, 0x63, 0x69, 0x88, 0xE6, + 0x0C, 0xA1, 0x49, 0x30, 0xE0, 0x82, 0xDB, 0x68, 0x0F, 0x7E, + 0x84, 0xAC, 0xFF, 0xFF, 0x7B, 0x42, 0xFA, 0x7E, 0x2F, 0xB2, + 0x52, 0x9F, 0xD2, 0x79, 0x5E, 0x35, 0x12, 0x27, 0x36, 0xBC, + 0xDF, 0x96, 0x58, 0x44, 0x96, 0x55, 0xC8, 0x4A, 0x94, 0x02, + 0x5F, 0x4A, 0x9D, 0xDC, 0xD3, 0x3A, 0xF7, 0x6D, 0xAC, 0x8B, + 0x79, 0x6E, 0xFC, 0xBE, 0x8F, 0x23, 0x58, 0x6A, 0x8A, 0xF5, + 0x38, 0x0A, 0x42, 0xF6, 0x98, 0x74, 0x88, 0x53, 0x2E, 0x02, + 0xAF, 0xE1, 0x0E, 0xBE, 0x6F, 0xCC, 0x74, 0x33, 0x7C, 0xEC, + 0xB4, 0xCB, 0xA7, 0x49, 0x6D, 0x82, 0x42, 0x4F, 0xEB, 0x73, + 0x29, 0xC3, 0x32, 0x00, 0x2B, 0x15, 0xF8, 0x88, 0x7A, 0x8F, + 0x6D, 0x20, 0x1B, 0xAE, 0x65, 0x5F, 0xC5, 0xD0, 0x8A, 0xD1, + 0xE2, 0x64, 0x6D, 0xA3, 0xA8, 0xFE, 0x64, 0xE1, 0xA9, 0x5B, + 0xE6, 0xD0, 0x23, 0xD6, 0x02, 0x72, 0x5A, 0xEC, 0x03, 0x8E, + 0x87, 0x67, 0x19, 0x8D, 0xE4, 0xA8, 0x99, 0x15, 0xC1, 0x3D, + 0x91, 0x48, 0x99, 0x8D, 0xFE, 0xAE, 0x1C, 0xBF, 0xF6, 0x28, + 0x1B, 0x45, 0xBE, 0xAD, 0xEF, 0x72, 0x83, 0x9A, 0xF6, 0xC7, + 0x3B, 0x51, 0xA3, 0x6E, 0x7A, 0x73, 0xBD, 0x83, 0xAA, 0x97, + 0xFD, 0x63, 0xB4, 0xF4, 0x6B, 0x1C, 0x14, 0x81, 0x9A, 0xEF, + 0x14, 0x24, 0xD3, 0xE1, 0x8B, 0xF4, 0x04, 0x04, 0x84, 0x54, + 0x0F, 0x61, 0xA2, 0xA8, 0xF2, 0x50, 0x37, 0x0C, 0x17, 0x0C, + 0xBC, 0xE0, 0xC2, 0x84, 0x85, 0xF4, 0x0B, 0xAE, 0x00, 0xCA, + 0x9F, 0x27, 0xE2, 0x44, 0x4F, 0x15, 0x0B, 0x8B, 0x1D, 0xB4 + +}; +static const int sizeof_client_cert_der_2048 = sizeof(client_cert_der_2048); + +/* ./certs/dh2048.der, 2048-bit */ +static 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, + 0xEF, 0x4A, 0xC6, 0x25, 0x27, 0x1C, 0xE8, 0xD2, 0x96, 0x53, + 0x0A, 0x5C, 0x91, 0xDD, 0xA2, 0xC2, 0x94, 0x84, 0xBF, 0x7D, + 0xB2, 0x44, 0x9F, 0x9B, 0xD2, 0xC1, 0x8A, 0xC5, 0xBE, 0x72, + 0x5C, 0xA7, 0xE7, 0x91, 0xE6, 0xD4, 0x9F, 0x73, 0x07, 0x85, + 0x5B, 0x66, 0x48, 0xC7, 0x70, 0xFA, 0xB4, 0xEE, 0x02, 0xC9, + 0x3D, 0x9A, 0x4A, 0xDA, 0x3D, 0xC1, 0x46, 0x3E, 0x19, 0x69, + 0xD1, 0x17, 0x46, 0x07, 0xA3, 0x4D, 0x9F, 0x2B, 0x96, 0x17, + 0x39, 0x6D, 0x30, 0x8D, 0x2A, 0xF3, 0x94, 0xD3, 0x75, 0xCF, + 0xA0, 0x75, 0xE6, 0xF2, 0x92, 0x1F, 0x1A, 0x70, 0x05, 0xAA, + 0x04, 0x83, 0x57, 0x30, 0xFB, 0xDA, 0x76, 0x93, 0x38, 0x50, + 0xE8, 0x27, 0xFD, 0x63, 0xEE, 0x3C, 0xE5, 0xB7, 0xC8, 0x09, + 0xAE, 0x6F, 0x50, 0x35, 0x8E, 0x84, 0xCE, 0x4A, 0x00, 0xE9, + 0x12, 0x7E, 0x5A, 0x31, 0xD7, 0x33, 0xFC, 0x21, 0x13, 0x76, + 0xCC, 0x16, 0x30, 0xDB, 0x0C, 0xFC, 0xC5, 0x62, 0xA7, 0x35, + 0xB8, 0xEF, 0xB7, 0xB0, 0xAC, 0xC0, 0x36, 0xF6, 0xD9, 0xC9, + 0x46, 0x48, 0xF9, 0x40, 0x90, 0x00, 0x2B, 0x1B, 0xAA, 0x6C, + 0xE3, 0x1A, 0xC3, 0x0B, 0x03, 0x9E, 0x1B, 0xC2, 0x46, 0xE4, + 0x48, 0x4E, 0x22, 0x73, 0x6F, 0xC3, 0x5F, 0xD4, 0x9A, 0xD6, + 0x30, 0x07, 0x48, 0xD6, 0x8C, 0x90, 0xAB, 0xD4, 0xF6, 0xF1, + 0xE3, 0x48, 0xD3, 0x58, 0x4B, 0xA6, 0xB9, 0xCD, 0x29, 0xBF, + 0x68, 0x1F, 0x08, 0x4B, 0x63, 0x86, 0x2F, 0x5C, 0x6B, 0xD6, + 0xB6, 0x06, 0x65, 0xF7, 0xA6, 0xDC, 0x00, 0x67, 0x6B, 0xBB, + 0xC3, 0xA9, 0x41, 0x83, 0xFB, 0xC7, 0xFA, 0xC8, 0xE2, 0x1E, + 0x7E, 0xAF, 0x00, 0x3F, 0x93, 0x02, 0x01, 0x02 +}; +static const int sizeof_dh_key_der_2048 = sizeof(dh_key_der_2048); + +/* ./certs/dsa2048.der, 2048-bit */ +static const unsigned char dsa_key_der_2048[] = +{ + 0x30, 0x82, 0x03, 0x3F, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xCC, 0x8E, 0xC9, 0xA0, 0xD5, 0x9A, 0x27, 0x1C, + 0xDA, 0x52, 0xDF, 0xC7, 0xC0, 0xE6, 0x06, 0xA4, 0x3E, 0x8A, + 0x66, 0x49, 0xD0, 0x59, 0x33, 0x51, 0x69, 0xC4, 0x9C, 0x5E, + 0x64, 0x85, 0xC7, 0xF1, 0xAB, 0xD5, 0xD9, 0x62, 0xAC, 0xFD, + 0xA1, 0xE0, 0x1B, 0x57, 0xFF, 0x96, 0xEF, 0x0C, 0x9F, 0xC8, + 0x44, 0x87, 0xEB, 0x5C, 0x91, 0xD0, 0x46, 0x42, 0x09, 0x50, + 0x6A, 0x23, 0xCB, 0x89, 0x6F, 0x55, 0xE9, 0x6A, 0x11, 0xA9, + 0xA8, 0x32, 0xAB, 0x33, 0x0D, 0x51, 0xB5, 0x79, 0x51, 0xB4, + 0xAB, 0xA2, 0x25, 0x11, 0x8D, 0xE5, 0x24, 0xBE, 0xD8, 0xF1, + 0x9D, 0x4E, 0x12, 0x6F, 0xAC, 0x44, 0x54, 0x80, 0xA9, 0xB4, + 0x81, 0x68, 0x4E, 0x44, 0x0E, 0xB8, 0x39, 0xF3, 0xBE, 0x83, + 0x08, 0x74, 0xA2, 0xC6, 0x7A, 0xD7, 0x6A, 0x7D, 0x0A, 0x88, + 0x57, 0x83, 0x48, 0xDC, 0xCF, 0x5E, 0x6F, 0xEE, 0x68, 0x0C, + 0xF7, 0xFF, 0x03, 0x04, 0x90, 0xAA, 0xF7, 0x07, 0x98, 0xF8, + 0x67, 0x5A, 0x83, 0x23, 0x66, 0x47, 0x60, 0xC3, 0x43, 0x6E, + 0x03, 0x91, 0xAC, 0x28, 0x66, 0xCB, 0xF0, 0xD3, 0x05, 0xC8, + 0x09, 0x97, 0xB5, 0xAE, 0x01, 0x5E, 0x80, 0x3B, 0x9D, 0x4F, + 0xDE, 0x3E, 0x94, 0xFE, 0xCB, 0x82, 0xB0, 0xB1, 0xFC, 0x91, + 0x8B, 0x1D, 0x8A, 0xEE, 0xC6, 0x06, 0x1F, 0x37, 0x91, 0x48, + 0xD2, 0xF8, 0x6C, 0x5D, 0x60, 0x13, 0x83, 0xA7, 0x81, 0xAC, + 0xCA, 0x8D, 0xD0, 0x6A, 0x04, 0x0A, 0xEA, 0x3E, 0x22, 0x4E, + 0x13, 0xF1, 0x0D, 0xBB, 0x60, 0x6B, 0xCD, 0xBC, 0x5C, 0x87, + 0xA3, 0x67, 0x2B, 0x42, 0xA1, 0x9F, 0xCD, 0x39, 0x58, 0xBE, + 0x55, 0xB1, 0x93, 0x84, 0xCE, 0xB2, 0x10, 0x4E, 0xE4, 0xC3, + 0x9F, 0xB2, 0x53, 0x61, 0x01, 0x29, 0xAA, 0x96, 0xCB, 0x20, + 0x60, 0x42, 0x1D, 0xBA, 0x75, 0x4B, 0x63, 0xC1, 0x02, 0x15, + 0x00, 0xE7, 0xA5, 0x39, 0xD4, 0x6A, 0x37, 0x5E, 0x95, 0x06, + 0x39, 0x07, 0x77, 0x0A, 0xEB, 0xA0, 0x03, 0xEB, 0x78, 0x82, + 0x9B, 0x02, 0x82, 0x01, 0x01, 0x00, 0x9A, 0xD4, 0x4C, 0x71, + 0x2F, 0xEC, 0xFA, 0x32, 0xB2, 0x80, 0x7E, 0x61, 0x4A, 0x6B, + 0x5F, 0x18, 0x76, 0x43, 0xC3, 0x69, 0xBA, 0x41, 0xC7, 0xA7, + 0x1D, 0x79, 0x01, 0xEC, 0xAF, 0x34, 0x87, 0x67, 0x4F, 0x29, + 0x80, 0xA8, 0x3B, 0x87, 0xF6, 0xE8, 0xA1, 0xE8, 0xCD, 0x1B, + 0x1C, 0x86, 0x38, 0xF6, 0xD1, 0x0C, 0x46, 0x2E, 0xC8, 0xE0, + 0xC9, 0x30, 0x26, 0xD5, 0x2C, 0x7F, 0xC1, 0x08, 0xBF, 0xCC, + 0x5A, 0x82, 0x8E, 0xD4, 0xD4, 0x49, 0xAA, 0xA2, 0xFA, 0xE6, + 0xC1, 0x9D, 0xF0, 0xD9, 0x96, 0xB0, 0xFF, 0x0C, 0x5B, 0x33, + 0x8E, 0x06, 0xDD, 0x9D, 0x28, 0xA9, 0xE9, 0x80, 0x41, 0x3B, + 0xD8, 0x7A, 0x94, 0x21, 0x8F, 0x56, 0xF1, 0xA2, 0xB4, 0x2B, + 0x89, 0x1C, 0x74, 0xFF, 0x7E, 0x91, 0xDC, 0x1F, 0x91, 0x13, + 0x98, 0xAF, 0xC7, 0x06, 0xD2, 0x4C, 0x90, 0xA2, 0xBD, 0xDA, + 0x16, 0xBA, 0x65, 0xB0, 0x2D, 0x68, 0x87, 0x3C, 0x6E, 0x25, + 0x8D, 0x90, 0xC7, 0xBC, 0x0D, 0xA9, 0x43, 0x03, 0xC9, 0xBE, + 0xCF, 0x85, 0x6F, 0xDB, 0x07, 0x7B, 0x8C, 0xF8, 0xB1, 0xC2, + 0x49, 0x10, 0x69, 0x63, 0x56, 0x37, 0xC5, 0x30, 0xD2, 0xFB, + 0x71, 0x9A, 0xE8, 0x82, 0x07, 0x2E, 0x3E, 0x95, 0x50, 0xF3, + 0x73, 0xCF, 0x34, 0x5B, 0xD5, 0xAB, 0x02, 0x15, 0xF2, 0xCC, + 0xD7, 0x52, 0xC5, 0x28, 0xD8, 0x41, 0x19, 0x55, 0x6F, 0xB8, + 0x5F, 0xF1, 0x99, 0xB3, 0xC7, 0xD9, 0xB3, 0x71, 0xF4, 0x2D, + 0xDF, 0x22, 0x59, 0x35, 0x86, 0xDB, 0x39, 0xCA, 0x1B, 0x4D, + 0x35, 0x90, 0x19, 0x6B, 0x31, 0xE3, 0xC8, 0xC6, 0x09, 0xBF, + 0x7C, 0xED, 0x01, 0xB4, 0xB2, 0xF5, 0x6E, 0xDA, 0x63, 0x41, + 0x3C, 0xE6, 0x3A, 0x72, 0x2D, 0x65, 0x48, 0xF6, 0x07, 0xCD, + 0x92, 0x84, 0x8B, 0x1D, 0xA7, 0x31, 0x6B, 0xD6, 0xF0, 0xFB, + 0xD9, 0xF4, 0x02, 0x82, 0x01, 0x00, 0x66, 0x4B, 0xBB, 0xB7, + 0xC9, 0x48, 0x95, 0x0D, 0x5A, 0xA6, 0x2D, 0xA1, 0x7F, 0xDF, + 0x1F, 0x67, 0x6D, 0xED, 0x52, 0x4B, 0x16, 0x6C, 0x17, 0xC6, + 0xAE, 0xF8, 0x6A, 0xC4, 0x57, 0xED, 0x2F, 0xB3, 0xF0, 0x2A, + 0x55, 0xAB, 0xBA, 0xCA, 0xEA, 0x17, 0xE8, 0x35, 0x7C, 0xE5, + 0x31, 0x0D, 0x4A, 0x95, 0xFC, 0x43, 0x6F, 0x97, 0x3C, 0x5C, + 0x67, 0xAC, 0xBE, 0x67, 0x7F, 0xE9, 0x4E, 0xAA, 0x48, 0xB3, + 0x92, 0xA1, 0x76, 0x75, 0xEA, 0x04, 0x34, 0x7F, 0x87, 0x33, + 0x2D, 0x24, 0xB6, 0x29, 0x97, 0xE3, 0x04, 0x77, 0x93, 0x89, + 0x13, 0xDB, 0x1B, 0x93, 0xB8, 0x2C, 0x90, 0x1A, 0x09, 0x3B, + 0x26, 0xD9, 0x59, 0xF3, 0x2A, 0x09, 0x58, 0xDC, 0xAC, 0x25, + 0xB4, 0xA9, 0x45, 0x3B, 0xA2, 0x3A, 0x6C, 0x61, 0x84, 0xBF, + 0x68, 0xD4, 0xEA, 0x9B, 0xC5, 0x29, 0x48, 0x60, 0x15, 0x10, + 0x35, 0x2C, 0x44, 0x1D, 0xB5, 0x9A, 0xEE, 0xAC, 0xC1, 0x68, + 0xE8, 0x47, 0xB7, 0x41, 0x34, 0x39, 0x9A, 0xF8, 0xA5, 0x20, + 0xE9, 0x24, 0xC4, 0x2C, 0x58, 0x3F, 0x4C, 0x41, 0x30, 0x3A, + 0x14, 0x6E, 0x8D, 0xEA, 0xAD, 0xBA, 0x9B, 0x43, 0xD3, 0x98, + 0x2F, 0x83, 0xD8, 0x14, 0x67, 0xE8, 0xF8, 0xD5, 0x4F, 0xAC, + 0xE0, 0x3B, 0xBF, 0xA7, 0x54, 0x16, 0x5E, 0x49, 0x64, 0x26, + 0x54, 0xA4, 0x6B, 0x69, 0x7C, 0xBA, 0x8A, 0x83, 0xD9, 0x2E, + 0x65, 0x0A, 0xA2, 0x27, 0xEF, 0x99, 0x99, 0x08, 0xD7, 0xB5, + 0x9F, 0xA0, 0x01, 0xEF, 0x7E, 0x17, 0xBF, 0x83, 0x6B, 0x2E, + 0xDD, 0xC0, 0x39, 0x38, 0x23, 0x68, 0xB4, 0x76, 0x6B, 0xE5, + 0xCA, 0xF7, 0x7C, 0xEE, 0xC0, 0x52, 0xE2, 0xDD, 0xAD, 0x59, + 0x3A, 0x42, 0x06, 0x45, 0xB0, 0xC7, 0xC1, 0x77, 0x05, 0xB2, + 0x0C, 0x32, 0x40, 0x46, 0xAA, 0xDA, 0x79, 0x77, 0x04, 0x71, + 0xDF, 0x7A, 0x02, 0x15, 0x00, 0x98, 0xEE, 0xB9, 0x51, 0x37, + 0x3E, 0x75, 0x13, 0x13, 0x06, 0x8F, 0x94, 0xD3, 0xE6, 0xE9, + 0x00, 0xCB, 0x62, 0x6D, 0x9A +}; +static const int sizeof_dsa_key_der_2048 = sizeof(dsa_key_der_2048); + +/* ./certs/rsa2048.der, 2048-bit */ +static const unsigned char rsa_key_der_2048[] = +{ + 0x30, 0x82, 0x04, 0xA3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xE9, 0x8A, 0x5D, 0x15, 0xA4, 0xD4, 0x34, 0xB9, + 0x59, 0xA2, 0xDA, 0xAF, 0x74, 0xC8, 0xC9, 0x03, 0x26, 0x38, + 0xFA, 0x48, 0xFC, 0x4D, 0x30, 0x6E, 0xEA, 0x76, 0x89, 0xCE, + 0x4F, 0xF6, 0x87, 0xDE, 0x32, 0x3A, 0x46, 0x6E, 0x38, 0x12, + 0x58, 0x37, 0x22, 0x0D, 0x80, 0xAC, 0x2D, 0xAF, 0x2F, 0x12, + 0x3E, 0x62, 0x73, 0x60, 0x66, 0x68, 0x90, 0xB2, 0x6F, 0x47, + 0x17, 0x04, 0x2B, 0xCA, 0xB7, 0x26, 0xB7, 0x10, 0xC2, 0x13, + 0xF9, 0x7A, 0x62, 0x0A, 0x93, 0x32, 0x90, 0x42, 0x0D, 0x16, + 0x2E, 0xFA, 0xD7, 0x29, 0xD7, 0x9F, 0x54, 0xE4, 0xFC, 0x65, + 0x74, 0xF8, 0xF6, 0x43, 0x6B, 0x4E, 0x9E, 0x34, 0x7F, 0xCB, + 0x6B, 0x1C, 0x1A, 0xDE, 0x82, 0x81, 0xBF, 0x08, 0x5D, 0x3F, + 0xC0, 0xB6, 0xB1, 0xA8, 0xA5, 0x9C, 0x81, 0x70, 0xA7, 0x4E, + 0x32, 0x87, 0x15, 0x1C, 0x78, 0x0E, 0xF0, 0x18, 0xFE, 0xEB, + 0x4B, 0x37, 0x2B, 0xE9, 0xE1, 0xF7, 0xFA, 0x51, 0xC6, 0x58, + 0xB9, 0xD8, 0x06, 0x03, 0xED, 0xC0, 0x03, 0x18, 0x55, 0x8B, + 0x98, 0xFE, 0xB1, 0xF6, 0xD0, 0x3D, 0xFA, 0x63, 0xC0, 0x38, + 0x19, 0xC7, 0x00, 0xEF, 0x4D, 0x99, 0x60, 0xB4, 0xBA, 0xCE, + 0xE3, 0xCE, 0xD9, 0x6B, 0x2D, 0x76, 0x94, 0xFF, 0xFB, 0x77, + 0x18, 0x4A, 0xFE, 0x65, 0xF0, 0x0A, 0x91, 0x5C, 0x3B, 0x22, + 0x94, 0x85, 0xD0, 0x20, 0x18, 0x59, 0x2E, 0xA5, 0x33, 0x03, + 0xAC, 0x1B, 0x5F, 0x78, 0x32, 0x11, 0x25, 0xEE, 0x7F, 0x96, + 0x21, 0xA9, 0xD6, 0x76, 0x97, 0x8D, 0x66, 0x7E, 0xB2, 0x91, + 0xD0, 0x36, 0x2E, 0xA3, 0x1D, 0xBF, 0xF1, 0x85, 0xED, 0xC0, + 0x3E, 0x60, 0xB8, 0x5A, 0x9F, 0xAB, 0x80, 0xE0, 0xEA, 0x5D, + 0x5F, 0x75, 0x56, 0xC7, 0x4D, 0x51, 0x8E, 0xD4, 0x1F, 0x34, + 0xA6, 0x36, 0xF1, 0x30, 0x1F, 0x51, 0x99, 0x2F, 0x02, 0x03, + 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x52, 0x11, 0x33, + 0x40, 0xC5, 0xD9, 0x64, 0x65, 0xB5, 0xE0, 0x0A, 0xA5, 0x19, + 0x8E, 0xED, 0x44, 0x54, 0x0C, 0x35, 0xB7, 0xAC, 0x21, 0x9B, + 0xE1, 0x7E, 0x37, 0x05, 0x9A, 0x20, 0x73, 0x6B, 0xAF, 0x63, + 0x4B, 0x23, 0x30, 0xDC, 0x37, 0x66, 0x14, 0x89, 0xBC, 0xE0, + 0xF8, 0xA0, 0x5D, 0x2D, 0x57, 0x65, 0xE0, 0xC6, 0xD6, 0x9B, + 0x66, 0x27, 0x62, 0xEC, 0xC3, 0xB8, 0x8C, 0xD8, 0xAE, 0xB5, + 0xC9, 0xBF, 0x0E, 0xFE, 0x84, 0x72, 0x68, 0xD5, 0x47, 0x0E, + 0x0E, 0xF8, 0xAE, 0x9D, 0x56, 0xAC, 0x4F, 0xAD, 0x88, 0xA0, + 0xA2, 0xF6, 0xFC, 0x38, 0xCD, 0x96, 0x5B, 0x5E, 0x7E, 0xB6, + 0x98, 0xBB, 0xF3, 0x8A, 0xEC, 0xFA, 0xC8, 0xB7, 0x90, 0x75, + 0xA0, 0x0E, 0x77, 0x6B, 0xFD, 0x59, 0x45, 0x5A, 0x0C, 0xFF, + 0x95, 0x8D, 0xCE, 0xFE, 0x9B, 0xF6, 0x19, 0x8E, 0x0B, 0xA1, + 0x0C, 0xEE, 0xC6, 0x79, 0xDD, 0x9D, 0x61, 0x85, 0x5C, 0x19, + 0x6C, 0x47, 0xCC, 0x08, 0xFF, 0xA5, 0x62, 0xDB, 0xE4, 0x2D, + 0x2D, 0xDD, 0x14, 0x67, 0xD6, 0x4A, 0x64, 0x2A, 0x66, 0x49, + 0x54, 0x9C, 0xE3, 0x85, 0x18, 0xE7, 0x31, 0x42, 0xE2, 0xD0, + 0x2C, 0x20, 0xA0, 0x74, 0x0F, 0x1F, 0x20, 0x89, 0xBA, 0xAB, + 0x80, 0xD8, 0x38, 0xD9, 0x46, 0x69, 0xBB, 0xEF, 0xCC, 0x8B, + 0xA1, 0x73, 0xA7, 0xF2, 0xE4, 0x38, 0x5D, 0xD6, 0x75, 0x9F, + 0x88, 0x0E, 0x56, 0xCD, 0xD8, 0x84, 0x59, 0x29, 0x73, 0xF5, + 0xA1, 0x79, 0xDA, 0x7A, 0x1F, 0xBF, 0x73, 0x83, 0xC0, 0x6D, + 0x9F, 0x8B, 0x34, 0x15, 0xC0, 0x6D, 0x69, 0x6A, 0x20, 0xE6, + 0x51, 0xCF, 0x45, 0x6E, 0xCC, 0x05, 0xC4, 0x3A, 0xC0, 0x9E, + 0xAA, 0xC1, 0x06, 0x2F, 0xAB, 0x99, 0x30, 0xE1, 0x6E, 0x9D, + 0x45, 0x7A, 0xFF, 0xA9, 0xCE, 0x70, 0xB8, 0x16, 0x1A, 0x0E, + 0x20, 0xFA, 0xC1, 0x02, 0x81, 0x81, 0x00, 0xFF, 0x30, 0x11, + 0xC2, 0x3C, 0x6B, 0xB4, 0xD6, 0x9E, 0x6B, 0xC1, 0x93, 0xD1, + 0x48, 0xCE, 0x80, 0x2D, 0xBE, 0xAF, 0xF7, 0xBA, 0xB2, 0xD7, + 0xC3, 0xC4, 0x53, 0x6E, 0x15, 0x02, 0xAA, 0x61, 0xB9, 0xEA, + 0x05, 0x9B, 0x79, 0x67, 0x0B, 0xCE, 0xD9, 0xFB, 0x98, 0x8C, + 0x1D, 0x6B, 0xF4, 0x5A, 0xA7, 0xA0, 0x5E, 0x54, 0x18, 0xE9, + 0x31, 0x44, 0x7C, 0xC7, 0x52, 0xD8, 0x6D, 0xA0, 0x3E, 0xD6, + 0x14, 0x2D, 0x7B, 0x15, 0x9D, 0x1E, 0x39, 0x87, 0x96, 0xDD, + 0xA8, 0x33, 0x55, 0x2A, 0x8E, 0x32, 0xC0, 0xC4, 0xE5, 0xB8, + 0xCB, 0xCD, 0x32, 0x8D, 0xAD, 0x7B, 0xE5, 0xC6, 0x7E, 0x4D, + 0x6F, 0xF3, 0xA4, 0xC5, 0xA6, 0x40, 0xBE, 0x90, 0x3A, 0x33, + 0x6A, 0x24, 0xB2, 0x80, 0x81, 0x12, 0xAC, 0xE3, 0x7B, 0x26, + 0x63, 0xCF, 0x88, 0xB9, 0xFF, 0x74, 0x23, 0x37, 0x52, 0xF0, + 0xC4, 0x27, 0x5D, 0x45, 0x1F, 0x02, 0x81, 0x81, 0x00, 0xEA, + 0x48, 0xA7, 0xDD, 0x73, 0x41, 0x56, 0x21, 0x15, 0xF7, 0x42, + 0x45, 0x4D, 0xA9, 0xE1, 0x66, 0x5B, 0xBD, 0x25, 0x7D, 0xF7, + 0xA8, 0x65, 0x13, 0xAE, 0x2D, 0x38, 0x11, 0xCD, 0x93, 0xFC, + 0x30, 0xA3, 0x2C, 0x44, 0xBB, 0xCF, 0xD0, 0x21, 0x8F, 0xFB, + 0xC1, 0xF9, 0xAD, 0x1D, 0xEE, 0x96, 0xCF, 0x97, 0x49, 0x60, + 0x53, 0x80, 0xA5, 0xA2, 0xF8, 0xEE, 0xB9, 0xD5, 0x77, 0x44, + 0xDD, 0xFD, 0x19, 0x2A, 0xF1, 0x81, 0xF4, 0xD9, 0x3C, 0xEC, + 0x73, 0xD0, 0x2A, 0xD8, 0x3C, 0x27, 0x87, 0x79, 0x12, 0x86, + 0xE7, 0x57, 0x0C, 0x59, 0xD1, 0x44, 0x55, 0xAE, 0xC3, 0x4D, + 0x42, 0xAD, 0xA9, 0xB3, 0x28, 0x61, 0xB4, 0x9C, 0xA6, 0x63, + 0xD3, 0x96, 0xB1, 0x75, 0x9F, 0x2A, 0x78, 0x99, 0xE3, 0x1E, + 0x71, 0x47, 0x39, 0xF4, 0x52, 0xE3, 0x66, 0xF1, 0xEB, 0x7F, + 0xEF, 0xC6, 0x81, 0x93, 0x4C, 0x99, 0xF1, 0x02, 0x81, 0x81, + 0x00, 0xC5, 0xB6, 0x20, 0x8C, 0x34, 0xF3, 0xDD, 0xF0, 0x4A, + 0x5D, 0x82, 0x65, 0x5C, 0x48, 0xE4, 0x75, 0x3A, 0xFB, 0xFA, + 0xAA, 0x1C, 0xE4, 0x63, 0x77, 0x31, 0xAC, 0xD2, 0x25, 0x45, + 0x23, 0x6D, 0x03, 0xF5, 0xE4, 0xD2, 0x48, 0x85, 0x26, 0x08, + 0xE5, 0xAA, 0xA0, 0xCE, 0x2E, 0x1D, 0x6D, 0xFC, 0xAE, 0xD2, + 0xF9, 0x42, 0x7E, 0xEA, 0x6D, 0x59, 0x7A, 0xB3, 0x93, 0xE4, + 0x4B, 0x4B, 0x54, 0x63, 0xD8, 0xCE, 0x44, 0x06, 0xC2, 0xEC, + 0x9F, 0xF6, 0x05, 0x55, 0x46, 0xF4, 0x3E, 0x8F, 0xF2, 0x0C, + 0x30, 0x7E, 0x5C, 0xDD, 0x88, 0x49, 0x3B, 0x59, 0xB9, 0x87, + 0xBC, 0xC6, 0xC5, 0x24, 0x8A, 0x10, 0x63, 0x21, 0x1F, 0x66, + 0x1A, 0x3E, 0xF4, 0x58, 0xD1, 0x6C, 0x0D, 0x40, 0xB2, 0xC0, + 0x1D, 0x63, 0x42, 0x0E, 0xC4, 0x56, 0x0E, 0xC0, 0xCC, 0xC2, + 0xD6, 0x66, 0x0E, 0xC4, 0xAB, 0xB5, 0x33, 0xF6, 0x51, 0x02, + 0x81, 0x80, 0x19, 0x7E, 0xE6, 0xA5, 0xB6, 0xD1, 0x39, 0x6A, + 0x48, 0x55, 0xAC, 0x24, 0x96, 0x9B, 0x12, 0x28, 0x6D, 0x7B, + 0x5C, 0x05, 0x25, 0x5A, 0x72, 0x05, 0x7E, 0x42, 0xF5, 0x83, + 0x1A, 0x78, 0x2C, 0x4D, 0xAE, 0xB4, 0x36, 0x96, 0xA9, 0xBA, + 0xE0, 0xAC, 0x26, 0x9D, 0xA9, 0x6A, 0x29, 0x83, 0xB9, 0x6D, + 0xC5, 0xEC, 0xFA, 0x4A, 0x9C, 0x09, 0x6A, 0x7E, 0xE4, 0x9B, + 0xDC, 0x9B, 0x2A, 0x27, 0x6E, 0x4F, 0xBA, 0xD8, 0xA5, 0x67, + 0xDB, 0xEC, 0x41, 0x5F, 0x29, 0x1C, 0x40, 0x83, 0xEB, 0x59, + 0x56, 0xD7, 0xA9, 0x4E, 0xAB, 0xAE, 0x70, 0x67, 0xD1, 0xA3, + 0xF1, 0x6C, 0xD7, 0x8F, 0x96, 0x0E, 0x8D, 0xAC, 0xAB, 0x55, + 0x58, 0x66, 0xD3, 0x1E, 0x47, 0x9B, 0xF0, 0x4C, 0xED, 0xF6, + 0x49, 0xE8, 0xE9, 0x7B, 0x32, 0x61, 0x20, 0x31, 0x95, 0x05, + 0xB2, 0xF6, 0x09, 0xEA, 0x32, 0x14, 0x0F, 0xCF, 0x9A, 0x41, + 0x02, 0x81, 0x80, 0x77, 0x3F, 0xB6, 0x14, 0x8D, 0xC5, 0x13, + 0x08, 0x7E, 0xC9, 0xC4, 0xEA, 0xD4, 0xBA, 0x0D, 0xA4, 0x9E, + 0xB3, 0x6E, 0xDE, 0x1A, 0x7A, 0xF8, 0x89, 0x88, 0xEF, 0x36, + 0x3C, 0x11, 0xBC, 0x83, 0xE8, 0x30, 0x6C, 0x81, 0x7C, 0x47, + 0xF3, 0x4D, 0xCA, 0xEA, 0x56, 0x01, 0x62, 0x55, 0x2E, 0x4B, + 0x89, 0xA9, 0xBD, 0x6F, 0x01, 0xF6, 0x74, 0x02, 0xAA, 0xE3, + 0x84, 0x66, 0x06, 0x95, 0x34, 0xA1, 0xE2, 0xCA, 0x65, 0xFE, + 0xA3, 0x2D, 0x43, 0x97, 0x95, 0x6C, 0x6F, 0xD5, 0xB4, 0x38, + 0xF6, 0xF9, 0x95, 0x30, 0xFA, 0xF8, 0x9C, 0x25, 0x2B, 0xB6, + 0x14, 0x51, 0xCC, 0x2E, 0xB3, 0x5B, 0xD6, 0xDC, 0x1A, 0xEC, + 0x2D, 0x09, 0x5B, 0x3F, 0x3A, 0xD0, 0xB8, 0x4E, 0x27, 0x1F, + 0xDC, 0x2A, 0xEE, 0xAC, 0xA9, 0x59, 0x5D, 0x07, 0x63, 0x11, + 0x83, 0x0B, 0xD4, 0x74, 0x80, 0xB6, 0x7D, 0x62, 0x45, 0xBF, + 0x56 +}; +static const int sizeof_rsa_key_der_2048 = sizeof(rsa_key_der_2048); + +/* ./certs/ca-key.der, 2048-bit */ +static const unsigned char ca_key_der_2048[] = +{ + 0x30, 0x82, 0x04, 0xA4, 0x02, 0x01, 0x00, 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, 0x02, 0x82, 0x01, 0x00, 0x3D, 0x6E, 0x4E, + 0x60, 0x1A, 0x84, 0x7F, 0x9D, 0x85, 0x7C, 0xE1, 0x4B, 0x07, + 0x7C, 0xE0, 0xD6, 0x99, 0x2A, 0xDE, 0x9D, 0xF9, 0x36, 0x34, + 0x0E, 0x77, 0x0E, 0x3E, 0x08, 0xEA, 0x4F, 0xE5, 0x06, 0x26, + 0xD4, 0xF6, 0x38, 0xF7, 0xDF, 0x0D, 0x0F, 0x1C, 0x2E, 0x06, + 0xA2, 0xF4, 0x2A, 0x68, 0x9C, 0x63, 0x72, 0xE3, 0x35, 0xE6, + 0x04, 0x91, 0x91, 0xB5, 0xC1, 0xB1, 0xA4, 0x54, 0xAC, 0xD7, + 0xC6, 0xFB, 0x41, 0xA0, 0xD6, 0x75, 0x6F, 0xBD, 0x0B, 0x4E, + 0xBF, 0xB1, 0x52, 0xE8, 0x5F, 0x49, 0x26, 0x98, 0x56, 0x47, + 0xC7, 0xDE, 0xE9, 0xEA, 0x3C, 0x60, 0x01, 0xBF, 0x28, 0xDC, + 0x31, 0xBF, 0x49, 0x5F, 0x93, 0x49, 0x87, 0x7A, 0x81, 0x5B, + 0x96, 0x4B, 0x4D, 0xCA, 0x5C, 0x38, 0x4F, 0xB7, 0xE1, 0xB2, + 0xD3, 0xC7, 0x21, 0xDA, 0x3C, 0x12, 0x87, 0x07, 0xE4, 0x1B, + 0xDC, 0x43, 0xEC, 0xE8, 0xEC, 0x54, 0x61, 0xE7, 0xF6, 0xED, + 0xA6, 0x0B, 0x2E, 0xF5, 0xDF, 0x82, 0x7F, 0xC6, 0x1F, 0x61, + 0x19, 0x9C, 0xA4, 0x83, 0x39, 0xDF, 0x21, 0x85, 0x89, 0x6F, + 0x77, 0xAF, 0x86, 0x15, 0x32, 0x08, 0xA2, 0x5A, 0x0B, 0x26, + 0x61, 0xFB, 0x70, 0x0C, 0xCA, 0x9C, 0x38, 0x7D, 0xBC, 0x22, + 0xEE, 0xEB, 0xA3, 0xA8, 0x16, 0x00, 0xF9, 0x8A, 0x80, 0x1E, + 0x00, 0x84, 0xA8, 0x4A, 0x41, 0xF8, 0x84, 0x03, 0x67, 0x2F, + 0x23, 0x5B, 0x2F, 0x9B, 0x6B, 0x26, 0xC3, 0x07, 0x34, 0x94, + 0xA3, 0x03, 0x3B, 0x72, 0xD5, 0x9F, 0x72, 0xE0, 0xAD, 0xCC, + 0x34, 0xAB, 0xBD, 0xC7, 0xD5, 0xF5, 0x26, 0x30, 0x85, 0x0F, + 0x30, 0x23, 0x39, 0x52, 0xFF, 0x3C, 0xCB, 0x99, 0x21, 0x4D, + 0x88, 0xA5, 0xAB, 0xEE, 0x62, 0xB9, 0xC7, 0xE0, 0xBB, 0x47, + 0x87, 0xC1, 0x69, 0xCF, 0x73, 0xF3, 0x30, 0xBE, 0xCE, 0x39, + 0x04, 0x9C, 0xE5, 0x02, 0x81, 0x81, 0x00, 0xE1, 0x76, 0x45, + 0x80, 0x59, 0xB6, 0xD3, 0x49, 0xDF, 0x0A, 0xEF, 0x12, 0xD6, + 0x0F, 0xF0, 0xB7, 0xCB, 0x2A, 0x37, 0xBF, 0xA7, 0xF8, 0xB5, + 0x4D, 0xF5, 0x31, 0x35, 0xAD, 0xE4, 0xA3, 0x94, 0xA1, 0xDB, + 0xF1, 0x96, 0xAD, 0xB5, 0x05, 0x64, 0x85, 0x83, 0xFC, 0x1B, + 0x5B, 0x29, 0xAA, 0xBE, 0xF8, 0x26, 0x3F, 0x76, 0x7E, 0xAD, + 0x1C, 0xF0, 0xCB, 0xD7, 0x26, 0xB4, 0x1B, 0x05, 0x8E, 0x56, + 0x86, 0x7E, 0x08, 0x62, 0x21, 0xC1, 0x86, 0xD6, 0x47, 0x79, + 0x3E, 0xB7, 0x5D, 0xA4, 0xC6, 0x3A, 0xD7, 0xB1, 0x74, 0x20, + 0xF6, 0x50, 0x97, 0x41, 0x04, 0x53, 0xED, 0x3F, 0x26, 0xD6, + 0x6F, 0x91, 0xFA, 0x68, 0x26, 0xEC, 0x2A, 0xDC, 0x9A, 0xF1, + 0xE7, 0xDC, 0xFB, 0x73, 0xF0, 0x79, 0x43, 0x1B, 0x21, 0xA3, + 0x59, 0x04, 0x63, 0x52, 0x07, 0xC9, 0xD7, 0xE6, 0xD1, 0x1B, + 0x5D, 0x5E, 0x96, 0xFA, 0x53, 0x02, 0x81, 0x81, 0x00, 0xD8, + 0xED, 0x4E, 0x64, 0x61, 0x6B, 0x91, 0x0C, 0x61, 0x01, 0xB5, + 0x0F, 0xBB, 0x44, 0x67, 0x53, 0x1E, 0xDC, 0x07, 0xC4, 0x24, + 0x7E, 0x9E, 0x6C, 0x84, 0x23, 0x91, 0x0C, 0xE4, 0x12, 0x04, + 0x16, 0x4D, 0x78, 0x98, 0xCC, 0x96, 0x3D, 0x20, 0x4E, 0x0F, + 0x45, 0x9A, 0xB6, 0xF8, 0xB3, 0x93, 0x0D, 0xB2, 0xA2, 0x1B, + 0x29, 0xF2, 0x26, 0x79, 0xC8, 0xC5, 0xD2, 0x78, 0x7E, 0x5E, + 0x73, 0xF2, 0xD7, 0x70, 0x61, 0xBB, 0x40, 0xCE, 0x61, 0x05, + 0xFE, 0x69, 0x1E, 0x82, 0x29, 0xE6, 0x14, 0xB8, 0xA1, 0xE7, + 0x96, 0xD0, 0x23, 0x3F, 0x05, 0x93, 0x00, 0xF2, 0xE1, 0x4D, + 0x7E, 0xED, 0xB7, 0x96, 0x6C, 0xF7, 0xF0, 0xE4, 0xD1, 0xCF, + 0x01, 0x98, 0x4F, 0xDC, 0x74, 0x54, 0xAA, 0x6D, 0x5E, 0x5A, + 0x41, 0x31, 0xFE, 0xFF, 0x9A, 0xB6, 0xA0, 0x05, 0xDD, 0xA9, + 0x10, 0x54, 0xF8, 0x6B, 0xD0, 0xAA, 0x83, 0x02, 0x81, 0x80, + 0x21, 0xD3, 0x04, 0x8A, 0x44, 0xEB, 0x50, 0xB7, 0x7C, 0x66, + 0xBF, 0x87, 0x2B, 0xE6, 0x28, 0x4E, 0xEA, 0x83, 0xE2, 0xE9, + 0x35, 0xE1, 0xF2, 0x11, 0x47, 0xFF, 0xA1, 0xF5, 0xFC, 0x9F, + 0x2D, 0xE5, 0x3A, 0x81, 0xFC, 0x01, 0x03, 0x6F, 0x53, 0xAD, + 0x54, 0x27, 0xB6, 0x52, 0xEE, 0xE5, 0x56, 0xD1, 0x13, 0xAB, + 0xE1, 0xB3, 0x0F, 0x75, 0x90, 0x0A, 0x84, 0xB4, 0xA1, 0xC0, + 0x8C, 0x0C, 0xD6, 0x9E, 0x46, 0xBA, 0x2B, 0x3E, 0xB5, 0x31, + 0xED, 0x63, 0xBB, 0xA4, 0xD5, 0x0D, 0x8F, 0x72, 0xCD, 0xD1, + 0x1E, 0x26, 0x35, 0xEB, 0xBE, 0x1B, 0x72, 0xFD, 0x9B, 0x39, + 0xB4, 0x87, 0xB7, 0x13, 0xF5, 0xEA, 0x83, 0x45, 0x93, 0x98, + 0xBA, 0x8F, 0xE4, 0x4A, 0xCC, 0xB4, 0x4C, 0xA8, 0x7F, 0x08, + 0xBA, 0x41, 0x49, 0xA8, 0x49, 0x28, 0x3D, 0x5E, 0x3D, 0xC1, + 0xCE, 0x37, 0x00, 0xCB, 0xF9, 0x2C, 0xDD, 0x51, 0x02, 0x81, + 0x81, 0x00, 0xA1, 0x57, 0x9F, 0x3E, 0xB9, 0xD6, 0xAF, 0x83, + 0x6D, 0x83, 0x3F, 0x8F, 0xFB, 0xD0, 0xDC, 0xA8, 0xCE, 0x03, + 0x09, 0x23, 0xB1, 0xA1, 0x1B, 0x63, 0xCA, 0xC4, 0x49, 0x56, + 0x35, 0x2B, 0xD1, 0x2E, 0x65, 0x60, 0x95, 0x05, 0x55, 0x99, + 0x11, 0x35, 0xFD, 0xD5, 0xDF, 0x44, 0xC7, 0xA5, 0x88, 0x72, + 0x5F, 0xB2, 0x82, 0x51, 0xA8, 0x71, 0x45, 0x93, 0x36, 0xCF, + 0x5C, 0x1F, 0x61, 0x51, 0x0C, 0x05, 0x80, 0xE8, 0xAF, 0xC5, + 0x7B, 0xBA, 0x5E, 0x22, 0xE3, 0x3C, 0x75, 0xC3, 0x84, 0x05, + 0x55, 0x6D, 0xD6, 0x3A, 0x2D, 0x84, 0x89, 0x93, 0x33, 0xCB, + 0x38, 0xDA, 0xAA, 0x31, 0x05, 0xCD, 0xCE, 0x6C, 0x2D, 0xDD, + 0x55, 0xD3, 0x57, 0x0B, 0xF0, 0xA5, 0x35, 0x6A, 0xB0, 0xAE, + 0x31, 0xBA, 0x43, 0x96, 0xCA, 0x00, 0xC7, 0x4B, 0xE3, 0x19, + 0x12, 0x43, 0xD3, 0x42, 0xFA, 0x6F, 0xEA, 0x80, 0xC0, 0xD1, + 0x02, 0x81, 0x81, 0x00, 0xB9, 0xDB, 0x89, 0x20, 0x34, 0x27, + 0x70, 0x62, 0x34, 0xEA, 0x5F, 0x25, 0x62, 0x12, 0xF3, 0x9D, + 0x81, 0xBF, 0x48, 0xEE, 0x9A, 0x0E, 0xC1, 0x8D, 0x10, 0xFF, + 0x65, 0x9A, 0x9D, 0x2D, 0x1A, 0x8A, 0x94, 0x5A, 0xC8, 0xC0, + 0xA5, 0xA5, 0x84, 0x61, 0x9E, 0xD4, 0x24, 0xB9, 0xEF, 0xA9, + 0x9D, 0xC9, 0x77, 0x0B, 0xC7, 0x70, 0x66, 0x3D, 0xBA, 0xC8, + 0x54, 0xDF, 0xD2, 0x33, 0xE1, 0xF5, 0x7F, 0xF9, 0x27, 0x61, + 0xBE, 0x57, 0x45, 0xDD, 0xB7, 0x45, 0x17, 0x24, 0xF5, 0x23, + 0xE4, 0x38, 0x0E, 0x91, 0x27, 0xEE, 0xE3, 0x20, 0xD8, 0x14, + 0xC8, 0x94, 0x47, 0x77, 0x40, 0x77, 0x45, 0x18, 0x9E, 0x0D, + 0xCE, 0x79, 0x3F, 0x57, 0x31, 0x56, 0x09, 0x49, 0x67, 0xBE, + 0x94, 0x58, 0x4F, 0xF6, 0xC4, 0xAB, 0xE2, 0x89, 0xE3, 0xE3, + 0x8A, 0xC0, 0x05, 0x55, 0x2C, 0x24, 0xC0, 0x4A, 0x97, 0x04, + 0x27, 0x9A +}; +static const int sizeof_ca_key_der_2048 = sizeof(ca_key_der_2048); + +/* ./certs/ca-cert.der, 2048-bit */ +static const unsigned char ca_cert_der_2048[] = +{ + 0x30, 0x82, 0x04, 0xAA, 0x30, 0x82, 0x03, 0x92, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x86, 0xFF, 0xF5, 0x8E, + 0x10, 0xDE, 0xB8, 0xFB, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, + 0x81, 0x94, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, + 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, + 0x6E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x53, 0x61, 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, + 0x0A, 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, + 0x67, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, + 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, + 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, + 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, + 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x34, 0x31, 0x33, + 0x31, 0x35, 0x32, 0x33, 0x30, 0x39, 0x5A, 0x17, 0x0D, 0x32, + 0x31, 0x30, 0x31, 0x30, 0x37, 0x31, 0x35, 0x32, 0x33, 0x30, + 0x39, 0x5A, 0x30, 0x81, 0x94, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, + 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, + 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, + 0x55, 0x04, 0x0A, 0x0C, 0x08, 0x53, 0x61, 0x77, 0x74, 0x6F, + 0x6F, 0x74, 0x68, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x0B, 0x0C, 0x0A, 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, + 0x74, 0x69, 0x6E, 0x67, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, + 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 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, 0xFC, + 0x30, 0x81, 0xF9, 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, 0xC9, 0x06, 0x03, 0x55, + 0x1D, 0x23, 0x04, 0x81, 0xC1, 0x30, 0x81, 0xBE, 0x80, 0x14, + 0x27, 0x8E, 0x67, 0x11, 0x74, 0xC3, 0x26, 0x1D, 0x3F, 0xED, + 0x33, 0x63, 0xB3, 0xA4, 0xD8, 0x1D, 0x30, 0xE5, 0xE8, 0xD5, + 0xA1, 0x81, 0x9A, 0xA4, 0x81, 0x97, 0x30, 0x81, 0x94, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, + 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x11, + 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x08, 0x53, + 0x61, 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0A, 0x43, 0x6F, + 0x6E, 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, + 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, + 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, + 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x82, 0x09, 0x00, + 0x86, 0xFF, 0xF5, 0x8E, 0x10, 0xDE, 0xB8, 0xFB, 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, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x01, + 0x01, 0x00, 0x9E, 0x28, 0x88, 0x72, 0x00, 0xCA, 0xE6, 0xE7, + 0x97, 0xCA, 0xC1, 0xF1, 0x1F, 0x9E, 0x12, 0xB2, 0xB8, 0xC7, + 0x51, 0xEA, 0x28, 0xE1, 0x36, 0xB5, 0x2D, 0xE6, 0x2F, 0x08, + 0x23, 0xCB, 0xA9, 0x4A, 0x87, 0x25, 0xC6, 0x5D, 0x89, 0x45, + 0xEA, 0xF5, 0x00, 0x98, 0xAC, 0x76, 0xFB, 0x1B, 0xAF, 0xF0, + 0xCE, 0x64, 0x9E, 0xDA, 0x08, 0xBF, 0xB6, 0xEB, 0xB4, 0xB5, + 0x0C, 0xA0, 0xE7, 0xF6, 0x47, 0x59, 0x1C, 0x61, 0xCF, 0x2E, + 0x0E, 0x58, 0xA4, 0x82, 0xAC, 0x0F, 0x3F, 0xEC, 0xC4, 0xAE, + 0x80, 0xF7, 0xB0, 0x8A, 0x1E, 0x85, 0x41, 0xE8, 0xFF, 0xFE, + 0xFE, 0x4F, 0x1A, 0x24, 0xD5, 0x49, 0xFA, 0xFB, 0xFE, 0x5E, + 0xE5, 0xD3, 0x91, 0x0E, 0x4F, 0x4E, 0x0C, 0x21, 0x51, 0x71, + 0x83, 0x04, 0x6B, 0x62, 0x7B, 0x4F, 0x59, 0x76, 0x48, 0x81, + 0x1E, 0xB4, 0xF7, 0x04, 0x47, 0x8A, 0x91, 0x57, 0xA3, 0x11, + 0xA9, 0xF2, 0x20, 0xB4, 0x78, 0x33, 0x62, 0x3D, 0xB0, 0x5E, + 0x0D, 0xF9, 0x86, 0x38, 0x82, 0xDA, 0xA1, 0x98, 0x8D, 0x19, + 0x06, 0x87, 0x21, 0x39, 0xB7, 0x02, 0xF7, 0xDA, 0x7D, 0x58, + 0xBA, 0x52, 0x15, 0xD8, 0x3B, 0xC9, 0x7B, 0x58, 0x34, 0xA0, + 0xC7, 0xE2, 0x7C, 0xA9, 0x83, 0x13, 0xE1, 0xB6, 0xEC, 0x01, + 0xBF, 0x52, 0x33, 0x0B, 0xC4, 0xFE, 0x43, 0xD3, 0xC6, 0xA4, + 0x8E, 0x2F, 0x87, 0x7F, 0x7A, 0x44, 0xEA, 0xCA, 0x53, 0x6C, + 0x85, 0xED, 0x65, 0x76, 0x73, 0x31, 0x03, 0x4E, 0xEA, 0xBD, + 0x35, 0x54, 0x13, 0xF3, 0x64, 0x87, 0x6B, 0xDF, 0x34, 0xDD, + 0x34, 0xA1, 0x88, 0x3B, 0xDB, 0x4D, 0xAF, 0x1B, 0x64, 0x90, + 0x92, 0x71, 0x30, 0x8E, 0xC8, 0xCC, 0xE5, 0x60, 0x24, 0xAF, + 0x31, 0x16, 0x39, 0x33, 0x91, 0x50, 0xF9, 0xAB, 0x68, 0x42, + 0x74, 0x7A, 0x35, 0xD9, 0xDD, 0xC8, 0xC4, 0x52 +}; +static const int sizeof_ca_cert_der_2048 = sizeof(ca_cert_der_2048); + +/* ./certs/ca-cert-chain.der, 2048-bit */ +static const unsigned char ca_cert_chain_der[] = +{ + 0x30, 0x82, 0x03, 0xB5, 0x30, 0x82, 0x03, 0x1E, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xDA, 0xFB, 0x6A, 0x0D, + 0xFE, 0xCF, 0x9B, 0x47, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, + 0x81, 0x99, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, + 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, + 0x6E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x53, 0x61, 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, + 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, + 0x0F, 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, + 0x67, 0x5F, 0x31, 0x30, 0x32, 0x34, 0x31, 0x18, 0x30, 0x16, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, + 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, + 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, + 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, + 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x1E, 0x17, 0x0D, 0x31, + 0x38, 0x30, 0x34, 0x31, 0x33, 0x31, 0x35, 0x32, 0x33, 0x31, + 0x30, 0x5A, 0x17, 0x0D, 0x32, 0x31, 0x30, 0x31, 0x30, 0x37, + 0x31, 0x35, 0x32, 0x33, 0x31, 0x30, 0x5A, 0x30, 0x81, 0x99, + 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, + 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, + 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x08, + 0x53, 0x61, 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0F, 0x43, + 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x5F, + 0x31, 0x30, 0x32, 0x34, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, + 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, + 0x63, 0x6F, 0x6D, 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, + 0x81, 0x00, 0xCD, 0xAC, 0xDD, 0x47, 0xEC, 0xBE, 0xB7, 0x24, + 0xC3, 0x63, 0x1B, 0x54, 0x98, 0x79, 0xE1, 0xC7, 0x31, 0x16, + 0x59, 0xD6, 0x9D, 0x77, 0x9D, 0x8D, 0xE2, 0x8B, 0xED, 0x04, + 0x17, 0xB2, 0xC6, 0xEB, 0xE4, 0x9B, 0x91, 0xBE, 0x31, 0x50, + 0x62, 0x97, 0x58, 0xB5, 0x7F, 0x29, 0xDE, 0xB3, 0x71, 0x24, + 0x0B, 0xBF, 0x97, 0x09, 0x7F, 0x26, 0xDC, 0x2D, 0xEC, 0xA8, + 0x2E, 0xB2, 0x64, 0x2B, 0x7A, 0x2B, 0x35, 0x19, 0x2D, 0xA2, + 0x80, 0xCB, 0x99, 0xFD, 0x94, 0x71, 0x1B, 0x23, 0x8D, 0x54, + 0xDB, 0x2E, 0x62, 0x8D, 0x81, 0x08, 0x2D, 0xF4, 0x24, 0x72, + 0x27, 0x6C, 0xF9, 0xC9, 0x8E, 0xDB, 0x4C, 0x75, 0xBA, 0x9B, + 0x01, 0xF8, 0x3F, 0x18, 0xF4, 0xE6, 0x7F, 0xFB, 0x57, 0x94, + 0x92, 0xCC, 0x88, 0xC4, 0xB4, 0x00, 0xC2, 0xAA, 0xD4, 0xE5, + 0x88, 0x18, 0xB3, 0x11, 0x2F, 0x73, 0xC0, 0xD6, 0x29, 0x09, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x82, 0x01, 0x01, 0x30, + 0x81, 0xFE, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, + 0x16, 0x04, 0x14, 0xD3, 0x22, 0x8F, 0x28, 0x2C, 0xE0, 0x05, + 0xEE, 0xD3, 0xED, 0xC3, 0x71, 0x3D, 0xC9, 0xB2, 0x36, 0x3A, + 0x1D, 0xBF, 0xA8, 0x30, 0x81, 0xCE, 0x06, 0x03, 0x55, 0x1D, + 0x23, 0x04, 0x81, 0xC6, 0x30, 0x81, 0xC3, 0x80, 0x14, 0xD3, + 0x22, 0x8F, 0x28, 0x2C, 0xE0, 0x05, 0xEE, 0xD3, 0xED, 0xC3, + 0x71, 0x3D, 0xC9, 0xB2, 0x36, 0x3A, 0x1D, 0xBF, 0xA8, 0xA1, + 0x81, 0x9F, 0xA4, 0x81, 0x9C, 0x30, 0x81, 0x99, 0x31, 0x0B, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, + 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x11, 0x30, + 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x08, 0x53, 0x61, + 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, 0x31, 0x18, 0x30, 0x16, + 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0F, 0x43, 0x6F, 0x6E, + 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x5F, 0x31, 0x30, + 0x32, 0x34, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, + 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, + 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, + 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, + 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, + 0x6D, 0x82, 0x09, 0x00, 0xDA, 0xFB, 0x6A, 0x0D, 0xFE, 0xCF, + 0x9B, 0x47, 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, 0x0B, 0x05, + 0x00, 0x03, 0x81, 0x81, 0x00, 0x1D, 0x48, 0xF6, 0x40, 0x41, + 0x04, 0x06, 0xF2, 0xE4, 0x72, 0x2F, 0xEA, 0xFF, 0xC1, 0x67, + 0x6B, 0x15, 0xBB, 0x0A, 0x28, 0x23, 0x28, 0x07, 0xC6, 0xD7, + 0x13, 0x2C, 0xBE, 0x00, 0x00, 0xAC, 0x1D, 0xF7, 0xF4, 0x92, + 0xD3, 0x2B, 0xAF, 0x23, 0xEB, 0x9F, 0x1A, 0xE2, 0x11, 0x3C, + 0x2D, 0x97, 0xF2, 0x0F, 0xAC, 0xAE, 0x97, 0x86, 0x0A, 0xFB, + 0xA8, 0x4F, 0x74, 0x1B, 0xDE, 0x19, 0x51, 0xDB, 0xCD, 0xE2, + 0x11, 0x38, 0xC1, 0xA4, 0x9D, 0x56, 0xAB, 0x47, 0x5C, 0xDE, + 0xBA, 0xEB, 0x27, 0xDF, 0x6D, 0xC8, 0x7E, 0x3A, 0xBD, 0x2E, + 0x9B, 0x2A, 0xAD, 0x22, 0x3B, 0x95, 0xA9, 0xF2, 0x28, 0x03, + 0xBC, 0xE5, 0xEC, 0xCC, 0xF2, 0x08, 0xD4, 0xC8, 0x2F, 0xDB, + 0xEA, 0xFB, 0x2E, 0x52, 0x16, 0x8C, 0x42, 0x02, 0xA4, 0x59, + 0x6D, 0x4C, 0x33, 0xB4, 0x9A, 0xD2, 0x73, 0x4A, 0x1E, 0x9F, + 0xD9, 0xC8, 0x83, 0x30, 0x82, 0x04, 0xAA, 0x30, 0x82, 0x03, + 0x92, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x86, + 0xFF, 0xF5, 0x8E, 0x10, 0xDE, 0xB8, 0xFB, 0x30, 0x0D, 0x06, + 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, + 0x05, 0x00, 0x30, 0x81, 0x94, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, + 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, + 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, + 0x55, 0x04, 0x0A, 0x0C, 0x08, 0x53, 0x61, 0x77, 0x74, 0x6F, + 0x6F, 0x74, 0x68, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x0B, 0x0C, 0x0A, 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, + 0x74, 0x69, 0x6E, 0x67, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, + 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, + 0x63, 0x6F, 0x6D, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, + 0x34, 0x31, 0x33, 0x31, 0x35, 0x32, 0x33, 0x30, 0x39, 0x5A, + 0x17, 0x0D, 0x32, 0x31, 0x30, 0x31, 0x30, 0x37, 0x31, 0x35, + 0x32, 0x33, 0x30, 0x39, 0x5A, 0x30, 0x81, 0x94, 0x31, 0x0B, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, + 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x11, 0x30, + 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x08, 0x53, 0x61, + 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, 0x31, 0x13, 0x30, 0x11, + 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0A, 0x43, 0x6F, 0x6E, + 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, + 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, + 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, + 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, + 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 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, 0xFC, 0x30, 0x81, 0xF9, 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, 0xC9, + 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x81, 0xC1, 0x30, 0x81, + 0xBE, 0x80, 0x14, 0x27, 0x8E, 0x67, 0x11, 0x74, 0xC3, 0x26, + 0x1D, 0x3F, 0xED, 0x33, 0x63, 0xB3, 0xA4, 0xD8, 0x1D, 0x30, + 0xE5, 0xE8, 0xD5, 0xA1, 0x81, 0x9A, 0xA4, 0x81, 0x97, 0x30, + 0x81, 0x94, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, + 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, + 0x6E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x53, 0x61, 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, + 0x0A, 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, + 0x67, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, + 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, + 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, + 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, + 0x82, 0x09, 0x00, 0x86, 0xFF, 0xF5, 0x8E, 0x10, 0xDE, 0xB8, + 0xFB, 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, 0x0B, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x01, 0x00, 0x9E, 0x28, 0x88, 0x72, 0x00, + 0xCA, 0xE6, 0xE7, 0x97, 0xCA, 0xC1, 0xF1, 0x1F, 0x9E, 0x12, + 0xB2, 0xB8, 0xC7, 0x51, 0xEA, 0x28, 0xE1, 0x36, 0xB5, 0x2D, + 0xE6, 0x2F, 0x08, 0x23, 0xCB, 0xA9, 0x4A, 0x87, 0x25, 0xC6, + 0x5D, 0x89, 0x45, 0xEA, 0xF5, 0x00, 0x98, 0xAC, 0x76, 0xFB, + 0x1B, 0xAF, 0xF0, 0xCE, 0x64, 0x9E, 0xDA, 0x08, 0xBF, 0xB6, + 0xEB, 0xB4, 0xB5, 0x0C, 0xA0, 0xE7, 0xF6, 0x47, 0x59, 0x1C, + 0x61, 0xCF, 0x2E, 0x0E, 0x58, 0xA4, 0x82, 0xAC, 0x0F, 0x3F, + 0xEC, 0xC4, 0xAE, 0x80, 0xF7, 0xB0, 0x8A, 0x1E, 0x85, 0x41, + 0xE8, 0xFF, 0xFE, 0xFE, 0x4F, 0x1A, 0x24, 0xD5, 0x49, 0xFA, + 0xFB, 0xFE, 0x5E, 0xE5, 0xD3, 0x91, 0x0E, 0x4F, 0x4E, 0x0C, + 0x21, 0x51, 0x71, 0x83, 0x04, 0x6B, 0x62, 0x7B, 0x4F, 0x59, + 0x76, 0x48, 0x81, 0x1E, 0xB4, 0xF7, 0x04, 0x47, 0x8A, 0x91, + 0x57, 0xA3, 0x11, 0xA9, 0xF2, 0x20, 0xB4, 0x78, 0x33, 0x62, + 0x3D, 0xB0, 0x5E, 0x0D, 0xF9, 0x86, 0x38, 0x82, 0xDA, 0xA1, + 0x98, 0x8D, 0x19, 0x06, 0x87, 0x21, 0x39, 0xB7, 0x02, 0xF7, + 0xDA, 0x7D, 0x58, 0xBA, 0x52, 0x15, 0xD8, 0x3B, 0xC9, 0x7B, + 0x58, 0x34, 0xA0, 0xC7, 0xE2, 0x7C, 0xA9, 0x83, 0x13, 0xE1, + 0xB6, 0xEC, 0x01, 0xBF, 0x52, 0x33, 0x0B, 0xC4, 0xFE, 0x43, + 0xD3, 0xC6, 0xA4, 0x8E, 0x2F, 0x87, 0x7F, 0x7A, 0x44, 0xEA, + 0xCA, 0x53, 0x6C, 0x85, 0xED, 0x65, 0x76, 0x73, 0x31, 0x03, + 0x4E, 0xEA, 0xBD, 0x35, 0x54, 0x13, 0xF3, 0x64, 0x87, 0x6B, + 0xDF, 0x34, 0xDD, 0x34, 0xA1, 0x88, 0x3B, 0xDB, 0x4D, 0xAF, + 0x1B, 0x64, 0x90, 0x92, 0x71, 0x30, 0x8E, 0xC8, 0xCC, 0xE5, + 0x60, 0x24, 0xAF, 0x31, 0x16, 0x39, 0x33, 0x91, 0x50, 0xF9, + 0xAB, 0x68, 0x42, 0x74, 0x7A, 0x35, 0xD9, 0xDD, 0xC8, 0xC4, + 0x52 +}; +static const int sizeof_ca_cert_chain_der = sizeof(ca_cert_chain_der); + +/* ./certs/server-key.der, 2048-bit */ +static 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 +}; +static const int sizeof_server_key_der_2048 = sizeof(server_key_der_2048); + +/* ./certs/server-cert.der, 2048-bit */ +static const unsigned char server_cert_der_2048[] = +{ + 0x30, 0x82, 0x04, 0x9E, 0x30, 0x82, 0x03, 0x86, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, + 0x00, 0x30, 0x81, 0x94, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, + 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, + 0x6D, 0x61, 0x6E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x08, 0x53, 0x61, 0x77, 0x74, 0x6F, 0x6F, + 0x74, 0x68, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x0A, 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, + 0x69, 0x6E, 0x67, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, + 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, + 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, + 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, + 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, + 0x6F, 0x6D, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x34, + 0x31, 0x33, 0x31, 0x35, 0x32, 0x33, 0x31, 0x30, 0x5A, 0x17, + 0x0D, 0x32, 0x31, 0x30, 0x31, 0x30, 0x37, 0x31, 0x35, 0x32, + 0x33, 0x31, 0x30, 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, 0x0C, + 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, + 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x07, 0x77, 0x6F, 0x6C, + 0x66, 0x53, 0x53, 0x4C, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x53, 0x75, 0x70, 0x70, 0x6F, + 0x72, 0x74, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, + 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, + 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, + 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, + 0x77, 0x6F, 0x6C, 0x66, 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, 0xA3, 0x81, 0xFC, 0x30, 0x81, + 0xF9, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, + 0x04, 0x14, 0xB3, 0x11, 0x32, 0xC9, 0x92, 0x98, 0x84, 0xE2, + 0xC9, 0xF8, 0xD0, 0x3B, 0x6E, 0x03, 0x42, 0xCA, 0x1F, 0x0E, + 0x8E, 0x3C, 0x30, 0x81, 0xC9, 0x06, 0x03, 0x55, 0x1D, 0x23, + 0x04, 0x81, 0xC1, 0x30, 0x81, 0xBE, 0x80, 0x14, 0x27, 0x8E, + 0x67, 0x11, 0x74, 0xC3, 0x26, 0x1D, 0x3F, 0xED, 0x33, 0x63, + 0xB3, 0xA4, 0xD8, 0x1D, 0x30, 0xE5, 0xE8, 0xD5, 0xA1, 0x81, + 0x9A, 0xA4, 0x81, 0x97, 0x30, 0x81, 0x94, 0x31, 0x0B, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, + 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, + 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x11, 0x30, 0x0F, + 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x08, 0x53, 0x61, 0x77, + 0x74, 0x6F, 0x6F, 0x74, 0x68, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0A, 0x43, 0x6F, 0x6E, 0x73, + 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x31, 0x18, 0x30, 0x16, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, + 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, + 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, + 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, + 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x82, 0x09, 0x00, 0x86, 0xFF, + 0xF5, 0x8E, 0x10, 0xDE, 0xB8, 0xFB, 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, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, + 0xB4, 0x54, 0x60, 0xAD, 0xA0, 0x03, 0x32, 0xDE, 0x02, 0x7F, + 0x21, 0x4A, 0x81, 0xC6, 0xED, 0xCD, 0xCD, 0xD8, 0x12, 0x8A, + 0xC0, 0xBA, 0x82, 0x5B, 0x75, 0xAD, 0x54, 0xE3, 0x7C, 0x80, + 0x6A, 0xAC, 0x2E, 0x6C, 0x20, 0x4E, 0xBE, 0x4D, 0x82, 0xA7, + 0x47, 0x13, 0x5C, 0xF4, 0xC6, 0x6A, 0x2B, 0x10, 0x99, 0x58, + 0xDE, 0xAB, 0x6B, 0x7C, 0x22, 0x05, 0xC1, 0x83, 0x9D, 0xCB, + 0xFF, 0x3C, 0xE4, 0x2D, 0x57, 0x6A, 0xA6, 0x96, 0xDF, 0xD3, + 0xC1, 0x68, 0xE3, 0xD2, 0xC6, 0x83, 0x4B, 0x97, 0xE2, 0xC6, + 0x32, 0x0E, 0xBE, 0xC4, 0x03, 0xB9, 0x07, 0x8A, 0x5B, 0xB8, + 0x84, 0xBA, 0xC5, 0x39, 0x3F, 0x1C, 0x58, 0xA7, 0x55, 0xD7, + 0xF0, 0x9B, 0xE8, 0xD2, 0x45, 0xB9, 0xE3, 0x83, 0x2E, 0xEE, + 0xB6, 0x71, 0x56, 0xB9, 0x3A, 0xEE, 0x3F, 0x27, 0xD8, 0x77, + 0xE8, 0xFB, 0x44, 0x48, 0x65, 0x27, 0x47, 0x4C, 0xFB, 0xFE, + 0x72, 0xC3, 0xAC, 0x05, 0x7B, 0x1D, 0xCB, 0xEB, 0x5E, 0x65, + 0x9A, 0xAB, 0x02, 0xE4, 0x88, 0x5B, 0x3B, 0x8B, 0x0B, 0xC7, + 0xCC, 0xA9, 0xA6, 0x8B, 0xE1, 0x87, 0xB0, 0x19, 0x1A, 0x0C, + 0x28, 0x58, 0x6F, 0x99, 0x52, 0x7E, 0xED, 0xB0, 0x3A, 0x68, + 0x3B, 0x8C, 0x0A, 0x08, 0x74, 0x72, 0xAB, 0xB9, 0x09, 0xC5, + 0xED, 0x04, 0x7E, 0x6F, 0x0B, 0x1C, 0x09, 0x21, 0xD0, 0xCD, + 0x7F, 0xF9, 0xC4, 0x5E, 0x27, 0x20, 0xE4, 0x85, 0x73, 0x52, + 0x05, 0xD2, 0xBA, 0xF8, 0xD5, 0x8F, 0x41, 0xCC, 0x23, 0x2E, + 0x12, 0x6D, 0xBC, 0x31, 0x98, 0xE7, 0x63, 0xA3, 0x8E, 0x26, + 0xCD, 0xE8, 0x2B, 0x88, 0xEE, 0xE2, 0xFE, 0x3A, 0x74, 0x52, + 0x34, 0x0E, 0xFD, 0x12, 0xE5, 0x5E, 0x69, 0x50, 0x20, 0x31, + 0x34, 0xE4, 0x31, 0xF1, 0xE7, 0xE4, 0x5B, 0x03, 0x13, 0xDA, + 0xAC, 0x41, 0x6C, 0xE7, 0xCF, 0x2B +}; +static const int sizeof_server_cert_der_2048 = sizeof(server_cert_der_2048); + +#endif /* USE_CERT_BUFFERS_2048 */ + +#ifdef USE_CERT_BUFFERS_3072 + +/* ./certs/dh3072.der, 3072-bit */ +static const unsigned char dh_key_der_3072[] = +{ + 0x30, 0x82, 0x01, 0x88, 0x02, 0x82, 0x01, 0x81, 0x00, 0x89, + 0x1B, 0x75, 0x3F, 0x84, 0xB6, 0x11, 0xED, 0x21, 0xF1, 0x08, + 0x0F, 0xB8, 0x06, 0xC9, 0xA3, 0xC9, 0x41, 0xDB, 0x5A, 0xC8, + 0xF8, 0x82, 0x73, 0x0F, 0xEB, 0x89, 0x1E, 0x54, 0x18, 0xBE, + 0xE6, 0x48, 0x41, 0x9E, 0xFA, 0xC2, 0x0C, 0x50, 0x67, 0xC3, + 0x5D, 0xB5, 0xF5, 0x0F, 0x23, 0x6A, 0x43, 0x33, 0x91, 0xD9, + 0x40, 0xF3, 0x66, 0xC6, 0x99, 0xFF, 0x97, 0xB6, 0x7B, 0xAF, + 0x27, 0x72, 0x3B, 0x9F, 0x7E, 0x58, 0x18, 0x14, 0x9F, 0x91, + 0x6E, 0x2B, 0x11, 0xC1, 0x57, 0x49, 0x27, 0x36, 0x78, 0xE1, + 0x09, 0x68, 0x9C, 0x05, 0x5A, 0xAC, 0xE6, 0x00, 0x38, 0xBE, + 0x95, 0x74, 0x81, 0x53, 0x28, 0xF0, 0xAD, 0xDF, 0xB5, 0x87, + 0x1C, 0x72, 0x17, 0x4E, 0xEC, 0x00, 0x91, 0x22, 0xAA, 0xE4, + 0x88, 0xD7, 0xF5, 0x3D, 0x1F, 0x03, 0x13, 0x2D, 0x1C, 0xFB, + 0xDE, 0x59, 0x68, 0xAD, 0xE0, 0x17, 0xA1, 0xEE, 0x8D, 0xCC, + 0xBF, 0xFE, 0xCF, 0x24, 0x42, 0xED, 0x26, 0xDD, 0x29, 0xD0, + 0x4E, 0x62, 0x3C, 0x85, 0x36, 0x1B, 0x5F, 0x6A, 0x47, 0x88, + 0x21, 0xE5, 0x1B, 0x85, 0x0A, 0x2C, 0xE9, 0x2F, 0xE0, 0x20, + 0xFC, 0x1D, 0xCD, 0x55, 0x66, 0xF5, 0xAC, 0x32, 0x00, 0x8E, + 0xA3, 0xE9, 0xED, 0xFB, 0x35, 0xA7, 0xE6, 0x76, 0x53, 0x42, + 0xC6, 0x77, 0x77, 0xAB, 0x90, 0x99, 0x7C, 0xC2, 0xEC, 0xC9, + 0x18, 0x4A, 0x3C, 0xF4, 0x11, 0x75, 0x27, 0x83, 0xBD, 0x9E, + 0xC2, 0x8F, 0x23, 0xAB, 0x52, 0x46, 0xE2, 0x52, 0x5D, 0x9A, + 0x04, 0xC3, 0x15, 0x1F, 0x69, 0x9C, 0x72, 0x69, 0x59, 0x52, + 0xD4, 0x69, 0x3D, 0x19, 0x77, 0x36, 0x25, 0xAF, 0x07, 0x71, + 0x82, 0xDE, 0xB7, 0x24, 0x60, 0x82, 0x6A, 0x72, 0xBB, 0xED, + 0xB6, 0x76, 0xAE, 0x7E, 0xBC, 0x7D, 0x2F, 0x73, 0x4B, 0x04, + 0x16, 0xD5, 0xA4, 0xF3, 0x03, 0x26, 0xFB, 0xF3, 0xCD, 0x7B, + 0x77, 0x7E, 0x7C, 0x8D, 0x65, 0xAE, 0xA5, 0xDC, 0x6C, 0xE3, + 0x70, 0xD2, 0x29, 0x6B, 0xF2, 0xEB, 0x76, 0xC9, 0xE5, 0x46, + 0x18, 0x12, 0x57, 0xB0, 0x55, 0xA5, 0x7C, 0xCD, 0x41, 0x93, + 0x26, 0x99, 0xF7, 0xA5, 0xC5, 0x34, 0xBE, 0x59, 0x79, 0xDE, + 0x0A, 0x57, 0x5F, 0x21, 0xF8, 0x98, 0x52, 0xF0, 0x2F, 0x7B, + 0x57, 0xB6, 0x9D, 0xFC, 0x40, 0xA6, 0x55, 0xFB, 0xAF, 0xD9, + 0x16, 0x9B, 0x20, 0x4F, 0xA8, 0xA3, 0x0B, 0x04, 0x48, 0xE3, + 0x77, 0x22, 0xC4, 0xCC, 0x57, 0x14, 0x33, 0xA2, 0xF0, 0x9A, + 0xE3, 0x12, 0xBD, 0xFF, 0x72, 0x8B, 0xEE, 0x52, 0xF3, 0xC9, + 0x59, 0xC2, 0xA2, 0x6B, 0xA5, 0x75, 0x48, 0x51, 0x82, 0x0E, + 0x7A, 0xFF, 0xFE, 0x41, 0xCD, 0x7C, 0x63, 0xD2, 0x53, 0xA8, + 0x11, 0x03, 0xB9, 0x03, 0x07, 0xFE, 0x66, 0x38, 0x5F, 0xA2, + 0x3E, 0x9C, 0x1B, 0x02, 0x01, 0x02 +}; +static const int sizeof_dh_key_der_3072 = sizeof(dh_key_der_3072); + +/* ./certs/dsa3072.der, 3072-bit */ +static const unsigned char dsa_key_der_3072[] = +{ + 0x30, 0x82, 0x04, 0xD7, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, + 0x81, 0x00, 0xB5, 0xD0, 0x2F, 0x55, 0xC1, 0x27, 0x4C, 0x5B, + 0x28, 0x81, 0x4E, 0xA4, 0x32, 0x0D, 0x73, 0x54, 0x68, 0x4F, + 0x0A, 0x36, 0x68, 0x4A, 0x51, 0xBE, 0xDE, 0x49, 0xD4, 0x9D, + 0xCE, 0xC6, 0xF7, 0x01, 0x70, 0xD2, 0x88, 0x90, 0x1D, 0x60, + 0x30, 0x9B, 0x0A, 0x9C, 0x23, 0xDA, 0xE0, 0x74, 0x46, 0x5B, + 0xC7, 0x41, 0x40, 0x5C, 0xD9, 0x7A, 0xBE, 0x78, 0xCA, 0x49, + 0xF5, 0x2D, 0x7B, 0xD7, 0xBF, 0x67, 0x0D, 0x84, 0x28, 0xBB, + 0x9D, 0xC2, 0xAB, 0x23, 0x06, 0x28, 0x0C, 0x98, 0x46, 0x43, + 0xCE, 0x6F, 0x9E, 0xD0, 0xE9, 0x0E, 0xF3, 0x7E, 0x30, 0x5D, + 0xD3, 0x45, 0x44, 0x7B, 0x0C, 0x7A, 0x73, 0xA6, 0x95, 0x65, + 0xAA, 0x8B, 0xD8, 0x75, 0x6A, 0x11, 0xB3, 0x10, 0x7C, 0x57, + 0xAF, 0xCE, 0xBE, 0x5B, 0xF7, 0xC8, 0xFE, 0x42, 0xA3, 0x77, + 0xB7, 0x0B, 0x3D, 0x66, 0xB5, 0x08, 0x74, 0x22, 0x74, 0x26, + 0xE6, 0xDB, 0x8E, 0xEF, 0xA3, 0x99, 0xAE, 0x0B, 0x42, 0x8C, + 0x5F, 0x7E, 0x48, 0xE9, 0x19, 0x90, 0xA8, 0x35, 0xA9, 0xFC, + 0x48, 0x0D, 0xC8, 0xB8, 0xE4, 0x1A, 0x0C, 0x26, 0xC7, 0x1A, + 0x20, 0x02, 0xEB, 0x72, 0x2E, 0x94, 0xD6, 0x19, 0x34, 0x39, + 0x55, 0x4E, 0xFC, 0x53, 0x48, 0xD8, 0x10, 0x89, 0xA1, 0x6E, + 0x22, 0x39, 0x71, 0x15, 0xA6, 0x13, 0xBC, 0x77, 0x49, 0x53, + 0xCB, 0x16, 0x4B, 0x56, 0x3D, 0x08, 0xA2, 0x71, 0x0E, 0x06, + 0x0C, 0x3A, 0xDE, 0x82, 0xC0, 0xDF, 0xE7, 0x96, 0x57, 0xD7, + 0x3F, 0x6B, 0xF0, 0xAE, 0xD1, 0x38, 0xB8, 0x5B, 0x83, 0x77, + 0x8B, 0xEB, 0x2B, 0xDA, 0x38, 0xC8, 0x4C, 0xA9, 0x48, 0x52, + 0xD8, 0x41, 0x03, 0xD3, 0x11, 0x1C, 0x66, 0x9E, 0xDE, 0xC9, + 0x78, 0x5A, 0xE1, 0x7B, 0xEA, 0x6F, 0xD6, 0xCA, 0x6A, 0x2F, + 0x01, 0xB2, 0x83, 0x37, 0x25, 0xD9, 0x9C, 0xD4, 0xB0, 0x21, + 0xD9, 0x8F, 0xA6, 0xF8, 0xD6, 0x21, 0x82, 0xBB, 0x08, 0x64, + 0x28, 0x0E, 0x0C, 0x26, 0xE6, 0xA5, 0x69, 0xE0, 0x23, 0xE9, + 0xB3, 0xC4, 0xF9, 0xDE, 0xC6, 0xD6, 0x32, 0x00, 0x66, 0x9B, + 0x8A, 0x0B, 0x6F, 0xDE, 0xB8, 0xDD, 0x68, 0x7F, 0x9D, 0x68, + 0x59, 0x6B, 0x55, 0xD9, 0x53, 0x01, 0x7B, 0x1A, 0x1C, 0x8D, + 0xBF, 0xAF, 0xC0, 0xB1, 0x14, 0x9E, 0xC1, 0x8D, 0x3E, 0x1E, + 0xFB, 0x40, 0xF9, 0x6D, 0x48, 0x43, 0xCD, 0x6C, 0xE8, 0xBC, + 0x3C, 0x7C, 0x35, 0x3C, 0x65, 0x6D, 0xA0, 0x25, 0x87, 0xBF, + 0xEC, 0x9B, 0x12, 0x74, 0x48, 0xC8, 0xE4, 0xBF, 0x53, 0x53, + 0x47, 0x78, 0xD9, 0x9B, 0x1A, 0xA5, 0x07, 0x46, 0x15, 0x16, + 0xD2, 0x33, 0x93, 0xCC, 0x41, 0x9B, 0xB7, 0x22, 0xDF, 0x07, + 0xDD, 0x72, 0xC6, 0x1A, 0x9B, 0x92, 0xE7, 0x32, 0x04, 0xAB, + 0x94, 0x80, 0xBD, 0x58, 0xF2, 0x35, 0x02, 0x21, 0x00, 0x9A, + 0xDD, 0x98, 0x1A, 0x6F, 0xEA, 0xB5, 0x8B, 0xC9, 0x68, 0x18, + 0x81, 0xE4, 0x4C, 0xFD, 0x8E, 0x45, 0xCF, 0x5F, 0x0E, 0x62, + 0x1E, 0x7D, 0x2D, 0x4A, 0x4C, 0x5D, 0x7F, 0xF8, 0xD8, 0x52, + 0xD7, 0x02, 0x82, 0x01, 0x81, 0x00, 0x84, 0xDF, 0xAB, 0x91, + 0x61, 0xE4, 0x2B, 0x07, 0x0A, 0x1C, 0xC7, 0x9C, 0xD7, 0xAC, + 0x8D, 0xA5, 0xAA, 0x41, 0x65, 0x9E, 0x4A, 0xED, 0x21, 0x45, + 0x96, 0xF7, 0xF7, 0xCB, 0x7A, 0x88, 0x19, 0x0F, 0x36, 0x80, + 0x25, 0x2F, 0x23, 0x0D, 0xFF, 0x6C, 0x0D, 0x02, 0xBB, 0x6A, + 0x79, 0x6A, 0xCB, 0x05, 0x00, 0x9B, 0x77, 0xED, 0x6B, 0xF3, + 0xC2, 0xEA, 0x1A, 0xDF, 0xB8, 0x15, 0xA8, 0x92, 0x19, 0x5A, + 0x51, 0x3B, 0x76, 0x06, 0x98, 0x47, 0xC7, 0x6F, 0x76, 0x99, + 0xAD, 0x50, 0xC5, 0x98, 0xE7, 0xFF, 0x88, 0xBC, 0x49, 0x77, + 0xEF, 0x96, 0x75, 0xE2, 0x36, 0x66, 0x1F, 0x0C, 0xFA, 0x57, + 0x1E, 0x11, 0xFF, 0x8F, 0x3C, 0xD0, 0xEA, 0x97, 0x25, 0x3F, + 0xFA, 0xD1, 0x4F, 0xBA, 0xDF, 0xE3, 0x35, 0xFB, 0x6E, 0x5C, + 0x65, 0xF9, 0xA2, 0x26, 0x43, 0xF2, 0xF4, 0xE0, 0x05, 0x3D, + 0xC6, 0x5B, 0xC4, 0x21, 0xE7, 0xB1, 0x02, 0xEB, 0xF2, 0xA9, + 0x06, 0x5E, 0xB7, 0x1B, 0xC1, 0xD8, 0x86, 0x34, 0xED, 0x84, + 0x89, 0xCE, 0xCE, 0xC2, 0x63, 0x78, 0x67, 0xF8, 0xC3, 0xAA, + 0x7C, 0x1C, 0x59, 0x32, 0xE4, 0x77, 0xA2, 0x36, 0x31, 0xFE, + 0x4B, 0x9C, 0x98, 0xCE, 0x01, 0x55, 0x61, 0xCE, 0x23, 0xAE, + 0x0F, 0x7E, 0x24, 0x8B, 0x54, 0x8A, 0xE4, 0xCB, 0x8E, 0xDC, + 0x7A, 0x94, 0x4C, 0xF9, 0x3C, 0xF8, 0x67, 0x68, 0x9D, 0x7A, + 0x82, 0xA1, 0xA0, 0x01, 0xC7, 0x1B, 0x8D, 0xA0, 0xC0, 0x53, + 0x1E, 0x93, 0xC7, 0x86, 0x12, 0xD3, 0x16, 0xDC, 0x28, 0xA0, + 0xD1, 0x0D, 0x1E, 0x42, 0x9A, 0xCB, 0x55, 0x8C, 0x22, 0x7F, + 0x41, 0xC3, 0xC9, 0x14, 0xF2, 0xB0, 0x73, 0xA1, 0x4D, 0x72, + 0xFD, 0x88, 0xB6, 0xDE, 0xE5, 0xF0, 0x3C, 0x3A, 0x7E, 0x68, + 0x3E, 0x82, 0x58, 0x60, 0xCD, 0xB4, 0x08, 0x64, 0x18, 0xB2, + 0x24, 0x97, 0x13, 0xA6, 0x07, 0x75, 0xBE, 0xE0, 0x14, 0x92, + 0x9A, 0x98, 0x6C, 0x08, 0x94, 0xD1, 0x0D, 0x48, 0x44, 0xC3, + 0xE3, 0xD5, 0xC0, 0x93, 0x49, 0x79, 0x2F, 0x67, 0x15, 0x76, + 0xD8, 0x90, 0x11, 0xDB, 0xEC, 0xA7, 0xE2, 0xDB, 0xD4, 0x4F, + 0x49, 0x5E, 0xEF, 0xC5, 0xB9, 0x77, 0x69, 0xDA, 0x02, 0xB7, + 0x23, 0xBC, 0xEA, 0xDC, 0x84, 0xD4, 0xA5, 0x5C, 0xA2, 0x6C, + 0xAD, 0x4A, 0x9F, 0xF0, 0x65, 0x48, 0xE9, 0xBF, 0xDF, 0xA5, + 0xB3, 0x99, 0xD6, 0x76, 0x08, 0x87, 0x2C, 0xF2, 0x29, 0x79, + 0xB2, 0x20, 0x7C, 0x6F, 0xC1, 0xC5, 0x3C, 0xB0, 0x50, 0x3F, + 0x72, 0xA5, 0x57, 0xE3, 0xB0, 0x62, 0x18, 0x80, 0x71, 0xB9, + 0x3F, 0x4D, 0x4E, 0x7C, 0xF6, 0x29, 0xDB, 0xB8, 0xAD, 0xF6, + 0x41, 0x69, 0x06, 0x90, 0x45, 0x7B, 0x95, 0x03, 0xE1, 0x9E, + 0xA5, 0xA1, 0x5A, 0xE3, 0x08, 0x26, 0x73, 0xFC, 0x2B, 0x20, + 0x02, 0x82, 0x01, 0x81, 0x00, 0xA5, 0x52, 0x8F, 0x53, 0xF0, + 0xB9, 0x4F, 0x06, 0xB9, 0xC8, 0xB4, 0x50, 0xA4, 0x39, 0xBA, + 0x12, 0x92, 0x75, 0x27, 0x43, 0xA8, 0x30, 0xA9, 0xF2, 0x2A, + 0xC6, 0x93, 0x26, 0x3C, 0x8C, 0x9F, 0xA2, 0x6F, 0x53, 0xD9, + 0x14, 0xAB, 0x3F, 0x00, 0xC6, 0x11, 0x13, 0x90, 0x6A, 0x42, + 0xF2, 0x9D, 0xA3, 0x8F, 0x31, 0x32, 0x46, 0x73, 0xA3, 0x93, + 0x57, 0x5D, 0x76, 0x45, 0x49, 0x6C, 0xBD, 0xEA, 0xAF, 0xAA, + 0xB3, 0x55, 0x25, 0x11, 0x8E, 0xA5, 0x2A, 0xB1, 0xBA, 0xA5, + 0x06, 0x4A, 0x66, 0xAA, 0x78, 0x9E, 0xF6, 0x5C, 0x1E, 0xB1, + 0x4A, 0xCA, 0x5C, 0x3F, 0x1D, 0x33, 0x75, 0x91, 0xF2, 0xF9, + 0x53, 0x14, 0x2F, 0xDC, 0xF0, 0x4C, 0xA4, 0xF4, 0x50, 0x04, + 0x1F, 0xFF, 0xC9, 0x0C, 0xC6, 0x8A, 0x04, 0x8B, 0x80, 0x87, + 0xA7, 0x70, 0x49, 0xD7, 0xE4, 0xE7, 0x83, 0xF1, 0x86, 0x1A, + 0xB0, 0x85, 0x3C, 0x59, 0x04, 0x96, 0xD1, 0x85, 0x47, 0xA1, + 0x57, 0x7D, 0xC6, 0x8E, 0x60, 0x7D, 0xC6, 0xE8, 0x18, 0xB3, + 0x1F, 0xB8, 0x99, 0xF0, 0xC4, 0xE5, 0x1E, 0xBC, 0x34, 0x07, + 0x8E, 0x40, 0x57, 0xA5, 0x8D, 0x3A, 0xA3, 0x88, 0x96, 0xF1, + 0xB3, 0x61, 0xF1, 0x1C, 0x96, 0x8A, 0xA4, 0x9E, 0xCD, 0x21, + 0xA2, 0x94, 0xAE, 0x5E, 0x1F, 0xCD, 0x5B, 0x5B, 0xE3, 0x88, + 0x1E, 0x17, 0x4A, 0x46, 0xAB, 0x9C, 0xE0, 0x59, 0x03, 0x4A, + 0xB8, 0xC8, 0x83, 0xE7, 0xFF, 0x39, 0x27, 0x68, 0x80, 0xA0, + 0x8E, 0xB3, 0xA2, 0x00, 0xC6, 0x2D, 0x2C, 0x76, 0xBA, 0x90, + 0x7C, 0x03, 0x1B, 0x19, 0xC8, 0x33, 0xB2, 0x12, 0x3A, 0xC8, + 0x8D, 0x32, 0xFE, 0xC0, 0xF9, 0xA5, 0x6A, 0x63, 0xE2, 0xA4, + 0x12, 0x43, 0x19, 0xF5, 0x14, 0xF2, 0x27, 0xF8, 0x0B, 0xBD, + 0x1A, 0x22, 0x64, 0x2D, 0xC9, 0x05, 0xFA, 0xD8, 0xDD, 0x11, + 0x1A, 0xD3, 0xF2, 0xBC, 0x99, 0x3A, 0xCD, 0x21, 0xCF, 0x10, + 0x14, 0x36, 0xDF, 0xED, 0x66, 0x02, 0x03, 0x4A, 0x42, 0x70, + 0x71, 0x22, 0xAD, 0xE7, 0x53, 0x91, 0xF4, 0x40, 0x8F, 0x72, + 0x7E, 0x54, 0xA0, 0x5D, 0x58, 0x93, 0xD6, 0xF6, 0xBC, 0x87, + 0x1A, 0x68, 0x0F, 0xAB, 0x94, 0x20, 0x70, 0xC2, 0x11, 0xA1, + 0x14, 0xBC, 0x06, 0xA8, 0x44, 0xB9, 0x1F, 0x04, 0x49, 0x7E, + 0xB3, 0x9A, 0x53, 0x46, 0x05, 0x75, 0x5D, 0x29, 0x77, 0x28, + 0xA9, 0xB1, 0xDC, 0xF1, 0x0D, 0x8A, 0x1C, 0x5E, 0xCD, 0xD7, + 0x4C, 0x16, 0x6F, 0x88, 0xBF, 0xB3, 0x34, 0xE2, 0xAD, 0x9A, + 0xC4, 0x89, 0xE2, 0x2E, 0x5C, 0x20, 0xE1, 0x5F, 0x39, 0xBF, + 0xB7, 0x45, 0xD3, 0x0F, 0x98, 0xB0, 0xD8, 0xC9, 0x18, 0x91, + 0x17, 0x25, 0xBC, 0x53, 0x62, 0xFF, 0x27, 0x85, 0xBD, 0xE2, + 0xE3, 0x9C, 0xA8, 0x06, 0x7A, 0x54, 0xEA, 0xFD, 0xEA, 0x02, + 0x20, 0x4C, 0xAC, 0x69, 0x62, 0x08, 0xE5, 0xCD, 0x14, 0xC8, + 0x2D, 0x4E, 0xDF, 0x1F, 0x60, 0x1D, 0x93, 0x44, 0x86, 0x5D, + 0x73, 0x99, 0x40, 0x1B, 0xDC, 0xA9, 0xBA, 0xC4, 0x1B, 0x12, + 0x6C, 0xFF, 0x53 +}; +static const int sizeof_dsa_key_der_3072 = sizeof(dsa_key_der_3072); + +/* ./certs/rsa3072.der, 3072-bit */ +static const unsigned char rsa_key_der_3072[] = +{ + 0x30, 0x82, 0x06, 0xE4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, + 0x81, 0x00, 0xBC, 0x6D, 0x68, 0xFF, 0xC0, 0x07, 0x0E, 0x0C, + 0x4A, 0xE6, 0x76, 0x1F, 0x7A, 0x25, 0x3A, 0x75, 0xA7, 0xE2, + 0xF1, 0x17, 0x00, 0xF8, 0x85, 0xE6, 0x8F, 0x59, 0x14, 0xA7, + 0xDE, 0x8C, 0x74, 0x4B, 0xEB, 0x85, 0xEC, 0x49, 0x9B, 0xFF, + 0x4B, 0x43, 0x0A, 0x08, 0xA1, 0xEC, 0x64, 0x58, 0x47, 0x28, + 0xD5, 0xCE, 0x48, 0xE9, 0xCF, 0x34, 0xDF, 0x15, 0x20, 0x37, + 0x99, 0x0E, 0x3C, 0x81, 0xBE, 0x2E, 0xE4, 0x6C, 0xBB, 0xDE, + 0xD1, 0x93, 0xC5, 0xEC, 0x6C, 0xCC, 0x40, 0x0B, 0x46, 0xA1, + 0xE6, 0xCA, 0xA0, 0xD5, 0x3B, 0x44, 0x48, 0x79, 0x67, 0x52, + 0x6F, 0xDA, 0xED, 0x73, 0x8B, 0x7C, 0x33, 0xDA, 0x17, 0x96, + 0xE8, 0xA2, 0x91, 0x3C, 0x57, 0xDD, 0xC9, 0x2E, 0x01, 0x74, + 0x87, 0x33, 0xA0, 0x12, 0x7C, 0xBB, 0xF9, 0x53, 0xF4, 0xC4, + 0x31, 0x48, 0x53, 0xCB, 0xBB, 0x3C, 0x42, 0x43, 0x0C, 0x7A, + 0x7B, 0xB8, 0x2A, 0xFC, 0xDC, 0x70, 0xD5, 0x64, 0x16, 0x74, + 0xA8, 0x80, 0xDE, 0x16, 0xE0, 0xB2, 0x6C, 0x04, 0x47, 0x6C, + 0x25, 0xA6, 0x7F, 0xB4, 0x73, 0x49, 0xBC, 0xF3, 0xAE, 0xE3, + 0x93, 0x36, 0x87, 0x2B, 0xB7, 0x8F, 0xB5, 0x88, 0x88, 0x22, + 0x47, 0xDF, 0xBF, 0x4D, 0x3C, 0x2A, 0xBD, 0x3F, 0x2F, 0x11, + 0x29, 0xCC, 0x1C, 0x33, 0x40, 0x4E, 0x23, 0xF6, 0x25, 0xF0, + 0xAF, 0x02, 0x16, 0x48, 0xED, 0x1C, 0xD8, 0xC9, 0x92, 0x2F, + 0x5B, 0xAF, 0xBA, 0xDB, 0x60, 0x1E, 0x0E, 0xE1, 0x65, 0x91, + 0x96, 0xF8, 0x7D, 0x73, 0x4C, 0x72, 0x23, 0x33, 0xD5, 0x32, + 0x2B, 0x0F, 0x4F, 0xBC, 0x81, 0x45, 0x9E, 0x31, 0x76, 0xEF, + 0xE1, 0x76, 0x2D, 0x3F, 0x8F, 0xC4, 0x19, 0x8F, 0x27, 0x2A, + 0x8F, 0x6E, 0x76, 0xCC, 0xE0, 0x5D, 0xB0, 0x86, 0x66, 0xFE, + 0x72, 0xD9, 0x06, 0x40, 0xB6, 0xCE, 0x85, 0xC6, 0x2D, 0x34, + 0x33, 0xAA, 0x8E, 0xE5, 0x54, 0x8E, 0xB8, 0xBA, 0xEE, 0x92, + 0x07, 0x5D, 0xB5, 0xF1, 0x67, 0xBF, 0xCA, 0xE4, 0xCA, 0xCB, + 0xD9, 0x01, 0x73, 0x22, 0x01, 0x32, 0x39, 0xF4, 0x0A, 0xEC, + 0x5F, 0x4A, 0x00, 0x10, 0x3F, 0x01, 0x3D, 0x15, 0xBB, 0x55, + 0x91, 0x80, 0xBE, 0xD8, 0xD3, 0x59, 0xCC, 0xB0, 0x7C, 0x56, + 0xF7, 0xFF, 0xE0, 0x28, 0x40, 0x02, 0xB3, 0x98, 0x8A, 0x54, + 0x52, 0x60, 0xA5, 0x0B, 0x95, 0x53, 0x86, 0x6B, 0xA4, 0x35, + 0xCA, 0x04, 0xC7, 0xFB, 0x0A, 0xC8, 0x9D, 0x5A, 0x11, 0x40, + 0xF7, 0x60, 0x07, 0xB1, 0xB3, 0x42, 0xB6, 0x80, 0x8F, 0xE4, + 0x25, 0xC9, 0xE8, 0xBC, 0x8E, 0x21, 0x0D, 0x47, 0xCF, 0xB8, + 0x37, 0x09, 0xAF, 0xBF, 0x2C, 0x34, 0x09, 0x22, 0xC2, 0x6E, + 0x0D, 0x06, 0x30, 0x80, 0x1E, 0xA5, 0x8A, 0x46, 0x2D, 0xDC, + 0x57, 0xD4, 0x57, 0x82, 0x6A, 0x11, 0x02, 0x03, 0x01, 0x00, + 0x01, 0x02, 0x82, 0x01, 0x81, 0x00, 0xAD, 0x99, 0xAF, 0xCF, + 0x51, 0x40, 0x2E, 0xB5, 0x2C, 0x9C, 0xBF, 0xDF, 0xA8, 0x4D, + 0x7C, 0x5A, 0xC1, 0xDE, 0xD8, 0x78, 0x75, 0x30, 0x83, 0x4D, + 0x34, 0x6C, 0xC2, 0x17, 0x17, 0x77, 0x17, 0xFE, 0x8A, 0x73, + 0xCC, 0x8A, 0xD4, 0xEA, 0x94, 0x90, 0xA3, 0x41, 0xE8, 0xCD, + 0x3E, 0x76, 0x06, 0xB9, 0x9C, 0xA2, 0x7D, 0x92, 0xCC, 0x90, + 0xCD, 0xA7, 0x4D, 0x13, 0x6C, 0x34, 0x2D, 0x92, 0xEB, 0x81, + 0x90, 0x7A, 0x8D, 0x6C, 0x70, 0x72, 0x51, 0x3B, 0xCD, 0xD1, + 0x30, 0x80, 0x33, 0x07, 0x1E, 0xF7, 0x38, 0xCE, 0xBB, 0xD7, + 0xE1, 0x5D, 0xD8, 0xCF, 0x9E, 0xB6, 0x79, 0x66, 0xA6, 0xF0, + 0x3B, 0x65, 0x87, 0xAE, 0x45, 0x8E, 0xE1, 0x78, 0x53, 0x0B, + 0xC7, 0x3A, 0x57, 0xA4, 0xE0, 0x9B, 0xB3, 0xB2, 0xD4, 0xB0, + 0xEA, 0xB9, 0x6B, 0x1D, 0x06, 0xBA, 0xB8, 0x59, 0x4F, 0x9B, + 0xE9, 0x00, 0x95, 0x12, 0x93, 0xC1, 0xCD, 0xF9, 0x41, 0xAF, + 0xC3, 0x2A, 0x7F, 0x75, 0xE3, 0x79, 0x37, 0x24, 0xA4, 0xC8, + 0x3D, 0xB4, 0x83, 0x89, 0x23, 0xF7, 0x0E, 0x59, 0x56, 0x8E, + 0x6D, 0x43, 0xA5, 0xB1, 0x8E, 0x04, 0x02, 0xED, 0x48, 0x25, + 0x62, 0xFE, 0xF3, 0x4D, 0x82, 0x22, 0xA6, 0xC1, 0xA5, 0xD9, + 0x4A, 0x9A, 0x57, 0xE6, 0xDC, 0x37, 0x6D, 0x13, 0xDA, 0xFF, + 0x23, 0x2A, 0xB9, 0x31, 0xD2, 0x4B, 0x7D, 0xF3, 0x02, 0x90, + 0xF6, 0x28, 0x3D, 0x98, 0x3C, 0xF6, 0x43, 0x45, 0xAE, 0xAB, + 0x91, 0x15, 0xC7, 0xC4, 0x90, 0x9C, 0x3E, 0xDA, 0xD4, 0x20, + 0x12, 0xB2, 0xE1, 0x2B, 0x56, 0xE2, 0x38, 0x32, 0x9C, 0xE6, + 0xA9, 0x1D, 0xFE, 0xA5, 0xEE, 0xD7, 0x52, 0xB4, 0xE3, 0xE4, + 0x65, 0xEA, 0x41, 0x9D, 0xD4, 0x91, 0x83, 0x5D, 0xFF, 0x52, + 0xA7, 0xC3, 0x42, 0x9F, 0x14, 0x70, 0x9F, 0x98, 0x14, 0xB2, + 0x33, 0xEE, 0x4C, 0x5A, 0xC9, 0x5F, 0x16, 0xF6, 0x06, 0xE9, + 0xF3, 0x39, 0xD2, 0xC5, 0x31, 0x53, 0x2A, 0x39, 0xED, 0x3A, + 0x4D, 0x2A, 0xC1, 0x4C, 0x87, 0x82, 0xC6, 0xCA, 0xCF, 0xF5, + 0x9A, 0x71, 0x27, 0xAE, 0xFB, 0xFE, 0xD0, 0x66, 0xDB, 0xAA, + 0x03, 0x16, 0x4B, 0xEF, 0xB4, 0x28, 0xAB, 0xCF, 0xBE, 0x9B, + 0x58, 0xCF, 0xA4, 0x58, 0x82, 0xD2, 0x37, 0x8C, 0xEA, 0x3D, + 0x75, 0x4D, 0x0B, 0x46, 0x7A, 0x04, 0xDE, 0xF1, 0x6E, 0xBB, + 0x03, 0xBF, 0xF7, 0x8E, 0xE6, 0xF4, 0x9A, 0xE1, 0xCA, 0x26, + 0x2C, 0x41, 0x08, 0xAD, 0x21, 0xA7, 0xC2, 0x40, 0xF5, 0x9C, + 0xDD, 0xAB, 0xC5, 0x5A, 0x4C, 0xF4, 0xE6, 0x9A, 0x50, 0xFD, + 0xAA, 0x47, 0xD6, 0xA6, 0x07, 0x25, 0xB2, 0x4B, 0x9C, 0x1D, + 0x90, 0xA2, 0x4A, 0x98, 0xE0, 0x05, 0x8A, 0x5C, 0xD1, 0x2C, + 0xC0, 0x28, 0xD1, 0x84, 0x3C, 0x72, 0xFF, 0x83, 0xEA, 0xB1, + 0x02, 0x81, 0xC1, 0x00, 0xF8, 0xA0, 0x5F, 0x25, 0x2E, 0x23, + 0x73, 0x30, 0xB6, 0x97, 0xAF, 0x08, 0xE7, 0xD2, 0xD8, 0xC3, + 0x95, 0xEA, 0x9D, 0x8E, 0x9F, 0xF1, 0x36, 0x81, 0xD7, 0x7A, + 0x21, 0x2B, 0x90, 0x38, 0x9C, 0xA6, 0x08, 0x40, 0xEA, 0xD2, + 0x6E, 0x29, 0xB5, 0x0B, 0x3E, 0x91, 0xB2, 0x04, 0x92, 0xCF, + 0x94, 0xFF, 0xA6, 0xA7, 0x1A, 0x5F, 0x93, 0x0C, 0x86, 0xE6, + 0x4B, 0x61, 0xD4, 0x5E, 0xD7, 0xE3, 0x66, 0x0B, 0x83, 0xDB, + 0x16, 0x49, 0x27, 0xD5, 0xA3, 0xB3, 0xF5, 0x5D, 0x8F, 0xC9, + 0x48, 0x10, 0xD7, 0x77, 0x1E, 0x7B, 0x01, 0xC4, 0xFD, 0x14, + 0x0C, 0xAB, 0x40, 0xF7, 0x9B, 0x07, 0xDE, 0x55, 0xEF, 0x36, + 0x4C, 0x22, 0x37, 0x37, 0x09, 0x9D, 0x2A, 0x73, 0xA6, 0xA5, + 0xF4, 0xAF, 0x39, 0x2B, 0x87, 0xB4, 0xB2, 0x28, 0x9E, 0x08, + 0xA6, 0xCA, 0xB4, 0x39, 0x5A, 0x3A, 0xFB, 0x41, 0x93, 0xEC, + 0x44, 0xBB, 0xD2, 0x7C, 0x3B, 0x27, 0x3E, 0x26, 0xFD, 0x7B, + 0x20, 0xFC, 0x44, 0x67, 0xC0, 0x84, 0xD1, 0xA0, 0xCC, 0xBB, + 0x26, 0xC7, 0x32, 0x0E, 0x01, 0x9B, 0x2B, 0x1F, 0x58, 0x85, + 0x5A, 0x6C, 0xD0, 0xC1, 0xAC, 0x14, 0x5E, 0x06, 0x07, 0xCA, + 0x69, 0x52, 0xF5, 0xA6, 0x16, 0x75, 0x42, 0x8A, 0xE1, 0xBA, + 0x8B, 0x46, 0x38, 0x17, 0x7B, 0xF1, 0x7D, 0x79, 0x1F, 0x7E, + 0x4C, 0x6A, 0x75, 0xDC, 0xA8, 0x3B, 0x02, 0x81, 0xC1, 0x00, + 0xC2, 0x03, 0xFE, 0x57, 0xDF, 0x26, 0xD8, 0x79, 0xDC, 0x2C, + 0x47, 0x9B, 0x92, 0x9B, 0x53, 0x40, 0x82, 0xEC, 0xBD, 0x0B, + 0xC0, 0x96, 0x89, 0x21, 0xC5, 0x26, 0x7E, 0x7A, 0x59, 0xA7, + 0x85, 0x11, 0xCC, 0x39, 0x33, 0xA7, 0xE6, 0x42, 0x9C, 0x12, + 0x81, 0xA0, 0x87, 0xBC, 0x57, 0x07, 0xC4, 0x51, 0x93, 0x59, + 0xC6, 0xAB, 0x11, 0xCC, 0xCB, 0xC8, 0xC1, 0x40, 0xDF, 0xCB, + 0xE8, 0x45, 0x31, 0x20, 0x91, 0x88, 0x5F, 0x76, 0x76, 0xEE, + 0x30, 0x37, 0xFA, 0xA7, 0x22, 0x72, 0x82, 0x50, 0x31, 0xE9, + 0xA0, 0x44, 0xCA, 0xDD, 0xD6, 0xAC, 0xEC, 0x82, 0xE8, 0x62, + 0xD8, 0x43, 0xFD, 0x77, 0x0F, 0x1C, 0x23, 0x12, 0x91, 0x1C, + 0xFE, 0x93, 0x2C, 0x87, 0x52, 0xBF, 0x96, 0x79, 0x5E, 0x3A, + 0x5A, 0x33, 0x28, 0x27, 0x3F, 0x20, 0x2C, 0xB3, 0x26, 0xE2, + 0x0D, 0x44, 0xA9, 0x2F, 0x39, 0x7B, 0x7B, 0xAD, 0xA3, 0x21, + 0xD2, 0x7F, 0x3C, 0x89, 0x63, 0xDD, 0x13, 0xB1, 0x2E, 0xD6, + 0x34, 0xFB, 0x2A, 0x83, 0x29, 0xE7, 0x8A, 0x88, 0xD7, 0xA3, + 0x38, 0x3C, 0x43, 0x62, 0x8F, 0x69, 0xFA, 0x4B, 0x15, 0xB5, + 0xF6, 0x59, 0x90, 0x62, 0x7D, 0xCF, 0x1D, 0xDD, 0x49, 0x43, + 0x33, 0x96, 0xA9, 0xF7, 0x76, 0x9F, 0xE4, 0x0D, 0x6E, 0x1C, + 0xEA, 0x18, 0x5B, 0xBD, 0x5C, 0x98, 0x90, 0x09, 0xCA, 0x59, + 0x9E, 0x23, 0x02, 0x81, 0xC0, 0x66, 0xFF, 0x99, 0x2A, 0xFF, + 0xF8, 0x33, 0xAA, 0x44, 0x9A, 0x86, 0x2A, 0xBC, 0x4F, 0x3E, + 0xF9, 0x97, 0xCB, 0xC0, 0x45, 0xEB, 0xC0, 0xB4, 0x02, 0x0A, + 0x50, 0x50, 0x19, 0x89, 0xFF, 0xC9, 0xF5, 0x86, 0x89, 0xCE, + 0x3E, 0x2A, 0xE1, 0x20, 0x5D, 0x6E, 0x28, 0x51, 0x85, 0x4F, + 0x84, 0xAB, 0x87, 0x55, 0x74, 0xF8, 0x9A, 0x0B, 0x83, 0x2F, + 0x07, 0x8C, 0xC7, 0x14, 0x81, 0xCE, 0x12, 0x28, 0x9E, 0x30, + 0x9B, 0xBC, 0x99, 0xC5, 0xE4, 0xDD, 0x92, 0x99, 0xDD, 0x8E, + 0xC9, 0xA6, 0x0F, 0x44, 0x13, 0xD7, 0x0E, 0xC2, 0x66, 0xE7, + 0x29, 0x3D, 0x2E, 0x5D, 0x15, 0xB6, 0xA6, 0x05, 0xD7, 0xB7, + 0xE7, 0xD8, 0x96, 0x7C, 0x25, 0x52, 0xD8, 0x47, 0x53, 0xED, + 0xFF, 0xE6, 0x64, 0x08, 0xDD, 0x1D, 0xB5, 0x1F, 0xF1, 0x6F, + 0xB6, 0xC9, 0xD2, 0x43, 0xE3, 0x56, 0x9C, 0x04, 0xA6, 0xE0, + 0x2F, 0x0B, 0x32, 0x7C, 0x3A, 0x77, 0x0F, 0x04, 0xD2, 0x86, + 0x44, 0x52, 0x1F, 0xEF, 0xFE, 0xC3, 0x64, 0xC2, 0xAB, 0x48, + 0xE5, 0x67, 0x65, 0x32, 0x39, 0x57, 0x34, 0xFF, 0x22, 0x57, + 0x3B, 0xB7, 0x80, 0x48, 0xE3, 0x52, 0xF4, 0x85, 0x17, 0x1E, + 0x77, 0x1E, 0x36, 0xFE, 0x09, 0x36, 0x58, 0x91, 0x9E, 0x93, + 0x71, 0x02, 0x6D, 0xAE, 0xA3, 0x1B, 0xF7, 0xA9, 0x31, 0x5A, + 0x78, 0xAA, 0x13, 0x98, 0x8C, 0x37, 0x2D, 0x02, 0x81, 0xC1, + 0x00, 0xBE, 0x01, 0xD9, 0x3A, 0xC7, 0x81, 0xAC, 0xAA, 0x13, + 0x75, 0x8E, 0x1F, 0x8F, 0x41, 0xED, 0x13, 0x95, 0xE5, 0x31, + 0xF3, 0x6B, 0x86, 0x42, 0x00, 0xBF, 0xAA, 0xC6, 0x5D, 0x1E, + 0xA6, 0x90, 0x0C, 0xF1, 0x1B, 0xE8, 0x39, 0xFB, 0xA8, 0xAA, + 0x5E, 0xF9, 0x72, 0x74, 0xDC, 0x7F, 0xC3, 0x4C, 0x81, 0xB3, + 0xB4, 0x4D, 0x7B, 0xC6, 0x2F, 0xF2, 0x37, 0xC7, 0x03, 0xB8, + 0xE9, 0x62, 0xAD, 0x38, 0xC2, 0xB3, 0xA4, 0x82, 0x11, 0x6B, + 0xC2, 0x33, 0x98, 0xEF, 0x32, 0x75, 0xEA, 0xFD, 0x32, 0x7A, + 0xDF, 0x59, 0xA5, 0x65, 0xA4, 0x42, 0x95, 0x11, 0xFF, 0xD6, + 0x84, 0xCF, 0x56, 0x2E, 0xCA, 0x46, 0x13, 0x01, 0x4A, 0x32, + 0xB1, 0xD9, 0xA3, 0xDB, 0x0D, 0x20, 0x7E, 0x1F, 0x68, 0xF7, + 0x5E, 0x60, 0x6E, 0x0F, 0x59, 0xF8, 0x59, 0x93, 0x4D, 0x54, + 0xBC, 0x37, 0xD0, 0x51, 0x7C, 0xBD, 0x67, 0xF0, 0xA5, 0x09, + 0xC9, 0x9A, 0xF4, 0x1F, 0x1E, 0x52, 0x9D, 0xF5, 0xA6, 0x25, + 0xBF, 0x85, 0x1D, 0xA1, 0xF1, 0xD8, 0xBD, 0x39, 0x10, 0x71, + 0x57, 0x19, 0x40, 0xF3, 0xA1, 0x77, 0xE0, 0x8B, 0x4E, 0xB3, + 0x91, 0x84, 0x15, 0x0C, 0xF1, 0x58, 0x52, 0xD9, 0xE5, 0x98, + 0xD5, 0x66, 0x95, 0x9C, 0x19, 0x8D, 0xA4, 0x63, 0x5C, 0xBF, + 0xC5, 0x33, 0x81, 0xED, 0x7E, 0x93, 0x4B, 0x9A, 0x6C, 0xEC, + 0x2E, 0x3E, 0x4F, 0x02, 0x81, 0xC0, 0x34, 0xF8, 0xDF, 0x74, + 0xC6, 0xC1, 0xD9, 0x03, 0x9B, 0x3B, 0x53, 0x19, 0xEB, 0x43, + 0xC4, 0xAA, 0x1E, 0x73, 0xE3, 0x13, 0x25, 0x32, 0x04, 0x22, + 0x79, 0x4A, 0x07, 0xF0, 0x06, 0x38, 0xBD, 0x57, 0xE6, 0x01, + 0x33, 0x8C, 0xF1, 0x02, 0xCC, 0x34, 0x2C, 0x60, 0x32, 0xA4, + 0x22, 0x1D, 0x0E, 0x39, 0x6B, 0xAB, 0xF7, 0xCE, 0xDB, 0xA7, + 0xC3, 0xD8, 0xA2, 0x3B, 0x70, 0x31, 0x91, 0x68, 0xB9, 0xBF, + 0xE0, 0xA1, 0x39, 0x80, 0xFE, 0x47, 0x99, 0x56, 0x6D, 0x76, + 0x90, 0x17, 0xF5, 0x67, 0x41, 0x44, 0x27, 0x10, 0x07, 0x98, + 0x4D, 0x4C, 0x53, 0xD4, 0x15, 0xDC, 0x0A, 0x2F, 0xE0, 0x83, + 0x28, 0x22, 0x8D, 0x61, 0x3B, 0xE4, 0x8E, 0xE5, 0xE7, 0x24, + 0x98, 0x19, 0xA8, 0xA3, 0xED, 0x70, 0x59, 0x06, 0x86, 0x76, + 0xC2, 0x4B, 0xCB, 0x17, 0xC5, 0x77, 0x12, 0x07, 0xB8, 0xAB, + 0x1A, 0x91, 0xFC, 0x72, 0x8E, 0xB7, 0xB1, 0xE6, 0x74, 0xDD, + 0x3D, 0x92, 0xA7, 0xDE, 0x6C, 0x6E, 0xCB, 0x50, 0x44, 0x2F, + 0xAC, 0x99, 0xF7, 0x36, 0x4D, 0x62, 0xC7, 0xAC, 0xCE, 0x7D, + 0x26, 0xC9, 0xD2, 0x4E, 0x49, 0xD7, 0x8E, 0x66, 0x6C, 0xC1, + 0x53, 0xDF, 0x31, 0xAB, 0x25, 0x35, 0xCA, 0xD6, 0xC4, 0xA3, + 0xA6, 0x9F, 0x7E, 0x3D, 0x2D, 0x1A, 0x44, 0x31, 0x3D, 0x81, + 0x91, 0xB8, 0x36, 0x08, 0x27, 0x42, 0x9E, 0x08 +}; +static const int sizeof_rsa_key_der_3072 = sizeof(rsa_key_der_3072); + +#endif /* USE_CERT_BUFFERS_3072 */ + +#if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256) + +/* ./certs/ecc-client-key.der, ECC */ +static const unsigned char ecc_clikey_der_256[] = +{ + 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0xF8, 0xCF, 0x92, + 0x6B, 0xBD, 0x1E, 0x28, 0xF1, 0xA8, 0xAB, 0xA1, 0x23, 0x4F, + 0x32, 0x74, 0x18, 0x88, 0x50, 0xAD, 0x7E, 0xC7, 0xEC, 0x92, + 0xF8, 0x8F, 0x97, 0x4D, 0xAF, 0x56, 0x89, 0x65, 0xC7, 0xA0, + 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, + 0x07, 0xA1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x55, 0xBF, 0xF4, + 0x0F, 0x44, 0x50, 0x9A, 0x3D, 0xCE, 0x9B, 0xB7, 0xF0, 0xC5, + 0x4D, 0xF5, 0x70, 0x7B, 0xD4, 0xEC, 0x24, 0x8E, 0x19, 0x80, + 0xEC, 0x5A, 0x4C, 0xA2, 0x24, 0x03, 0x62, 0x2C, 0x9B, 0xDA, + 0xEF, 0xA2, 0x35, 0x12, 0x43, 0x84, 0x76, 0x16, 0xC6, 0x56, + 0x95, 0x06, 0xCC, 0x01, 0xA9, 0xBD, 0xF6, 0x75, 0x1A, 0x42, + 0xF7, 0xBD, 0xA9, 0xB2, 0x36, 0x22, 0x5F, 0xC7, 0x5D, 0x7F, + 0xB4 +}; +static const int sizeof_ecc_clikey_der_256 = sizeof(ecc_clikey_der_256); + +/* ./certs/ecc-client-keyPub.der, ECC */ +static const unsigned char ecc_clikeypub_der_256[] = +{ + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, + 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, + 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x55, 0xBF, 0xF4, + 0x0F, 0x44, 0x50, 0x9A, 0x3D, 0xCE, 0x9B, 0xB7, 0xF0, 0xC5, + 0x4D, 0xF5, 0x70, 0x7B, 0xD4, 0xEC, 0x24, 0x8E, 0x19, 0x80, + 0xEC, 0x5A, 0x4C, 0xA2, 0x24, 0x03, 0x62, 0x2C, 0x9B, 0xDA, + 0xEF, 0xA2, 0x35, 0x12, 0x43, 0x84, 0x76, 0x16, 0xC6, 0x56, + 0x95, 0x06, 0xCC, 0x01, 0xA9, 0xBD, 0xF6, 0x75, 0x1A, 0x42, + 0xF7, 0xBD, 0xA9, 0xB2, 0x36, 0x22, 0x5F, 0xC7, 0x5D, 0x7F, + 0xB4 +}; +static const int sizeof_ecc_clikeypub_der_256 = sizeof(ecc_clikeypub_der_256); + +/* ./certs/client-ecc-cert.der, ECC */ +static const unsigned char cliecc_cert_der_256[] = +{ + 0x30, 0x82, 0x03, 0x08, 0x30, 0x82, 0x02, 0xAF, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x93, 0xBF, 0x6A, 0xDE, + 0x9B, 0x41, 0x9D, 0xAD, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, + 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x81, 0x8D, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x06, 0x4F, 0x72, 0x65, 0x67, 0x6F, 0x6E, 0x31, + 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x05, + 0x53, 0x61, 0x6C, 0x65, 0x6D, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0A, 0x43, 0x6C, 0x69, 0x65, + 0x6E, 0x74, 0x20, 0x45, 0x43, 0x43, 0x31, 0x0D, 0x30, 0x0B, + 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x04, 0x46, 0x61, 0x73, + 0x74, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, + 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, + 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, + 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, + 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x34, 0x31, 0x33, + 0x31, 0x35, 0x32, 0x33, 0x31, 0x30, 0x5A, 0x17, 0x0D, 0x32, + 0x31, 0x30, 0x31, 0x30, 0x37, 0x31, 0x35, 0x32, 0x33, 0x31, + 0x30, 0x5A, 0x30, 0x81, 0x8D, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0F, + 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x06, 0x4F, + 0x72, 0x65, 0x67, 0x6F, 0x6E, 0x31, 0x0E, 0x30, 0x0C, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x05, 0x53, 0x61, 0x6C, 0x65, + 0x6D, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0A, 0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x45, + 0x43, 0x43, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x04, 0x46, 0x61, 0x73, 0x74, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, + 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, + 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, + 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, + 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, + 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x59, 0x30, 0x13, + 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, + 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, + 0x42, 0x00, 0x04, 0x55, 0xBF, 0xF4, 0x0F, 0x44, 0x50, 0x9A, + 0x3D, 0xCE, 0x9B, 0xB7, 0xF0, 0xC5, 0x4D, 0xF5, 0x70, 0x7B, + 0xD4, 0xEC, 0x24, 0x8E, 0x19, 0x80, 0xEC, 0x5A, 0x4C, 0xA2, + 0x24, 0x03, 0x62, 0x2C, 0x9B, 0xDA, 0xEF, 0xA2, 0x35, 0x12, + 0x43, 0x84, 0x76, 0x16, 0xC6, 0x56, 0x95, 0x06, 0xCC, 0x01, + 0xA9, 0xBD, 0xF6, 0x75, 0x1A, 0x42, 0xF7, 0xBD, 0xA9, 0xB2, + 0x36, 0x22, 0x5F, 0xC7, 0x5D, 0x7F, 0xB4, 0xA3, 0x81, 0xF5, + 0x30, 0x81, 0xF2, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, + 0x04, 0x16, 0x04, 0x14, 0xEB, 0xD4, 0x4B, 0x59, 0x6B, 0x95, + 0x61, 0x3F, 0x51, 0x57, 0xB6, 0x04, 0x4D, 0x89, 0x41, 0x88, + 0x44, 0x5C, 0xAB, 0xF2, 0x30, 0x81, 0xC2, 0x06, 0x03, 0x55, + 0x1D, 0x23, 0x04, 0x81, 0xBA, 0x30, 0x81, 0xB7, 0x80, 0x14, + 0xEB, 0xD4, 0x4B, 0x59, 0x6B, 0x95, 0x61, 0x3F, 0x51, 0x57, + 0xB6, 0x04, 0x4D, 0x89, 0x41, 0x88, 0x44, 0x5C, 0xAB, 0xF2, + 0xA1, 0x81, 0x93, 0xA4, 0x81, 0x90, 0x30, 0x81, 0x8D, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x06, 0x4F, 0x72, 0x65, 0x67, 0x6F, 0x6E, 0x31, + 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x05, + 0x53, 0x61, 0x6C, 0x65, 0x6D, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0A, 0x43, 0x6C, 0x69, 0x65, + 0x6E, 0x74, 0x20, 0x45, 0x43, 0x43, 0x31, 0x0D, 0x30, 0x0B, + 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x04, 0x46, 0x61, 0x73, + 0x74, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, + 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, + 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, + 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, + 0x82, 0x09, 0x00, 0x93, 0xBF, 0x6A, 0xDE, 0x9B, 0x41, 0x9D, + 0xAD, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04, 0x05, + 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0A, 0x06, 0x08, 0x2A, + 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, + 0x30, 0x44, 0x02, 0x20, 0x61, 0xBC, 0x9D, 0x4D, 0x88, 0x64, + 0x86, 0xB8, 0x71, 0xAA, 0x35, 0x59, 0x68, 0xB8, 0xEE, 0x2C, + 0xF3, 0x23, 0xB5, 0x1A, 0xB9, 0xBA, 0x41, 0x50, 0xA8, 0xC6, + 0xC3, 0x58, 0xEB, 0x58, 0xBD, 0x60, 0x02, 0x20, 0x61, 0xAA, + 0xEB, 0xB5, 0x73, 0x0D, 0x01, 0xDB, 0x69, 0x8F, 0x52, 0xF5, + 0x72, 0x6D, 0x37, 0x42, 0xB5, 0xFD, 0x94, 0xB6, 0x6E, 0xB1, + 0xC4, 0x25, 0x2E, 0x96, 0x96, 0xF3, 0x39, 0xB2, 0x5D, 0xEA + +}; +static const int sizeof_cliecc_cert_der_256 = sizeof(cliecc_cert_der_256); + +/* ./certs/ecc-key.der, ECC */ +static const unsigned char ecc_key_der_256[] = +{ + 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x45, 0xB6, 0x69, + 0x02, 0x73, 0x9C, 0x6C, 0x85, 0xA1, 0x38, 0x5B, 0x72, 0xE8, + 0xE8, 0xC7, 0xAC, 0xC4, 0x03, 0x8D, 0x53, 0x35, 0x04, 0xFA, + 0x6C, 0x28, 0xDC, 0x34, 0x8D, 0xE1, 0xA8, 0x09, 0x8C, 0xA0, + 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, + 0x07, 0xA1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xBB, 0x33, 0xAC, + 0x4C, 0x27, 0x50, 0x4A, 0xC6, 0x4A, 0xA5, 0x04, 0xC3, 0x3C, + 0xDE, 0x9F, 0x36, 0xDB, 0x72, 0x2D, 0xCE, 0x94, 0xEA, 0x2B, + 0xFA, 0xCB, 0x20, 0x09, 0x39, 0x2C, 0x16, 0xE8, 0x61, 0x02, + 0xE9, 0xAF, 0x4D, 0xD3, 0x02, 0x93, 0x9A, 0x31, 0x5B, 0x97, + 0x92, 0x21, 0x7F, 0xF0, 0xCF, 0x18, 0xDA, 0x91, 0x11, 0x02, + 0x34, 0x86, 0xE8, 0x20, 0x58, 0x33, 0x0B, 0x80, 0x34, 0x89, + 0xD8 +}; +static const int sizeof_ecc_key_der_256 = sizeof(ecc_key_der_256); + +/* ./certs/ecc-keyPub.der, ECC */ +static const unsigned char ecc_key_pub_der_256[] = +{ + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, + 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, + 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xBB, 0x33, 0xAC, + 0x4C, 0x27, 0x50, 0x4A, 0xC6, 0x4A, 0xA5, 0x04, 0xC3, 0x3C, + 0xDE, 0x9F, 0x36, 0xDB, 0x72, 0x2D, 0xCE, 0x94, 0xEA, 0x2B, + 0xFA, 0xCB, 0x20, 0x09, 0x39, 0x2C, 0x16, 0xE8, 0x61, 0x02, + 0xE9, 0xAF, 0x4D, 0xD3, 0x02, 0x93, 0x9A, 0x31, 0x5B, 0x97, + 0x92, 0x21, 0x7F, 0xF0, 0xCF, 0x18, 0xDA, 0x91, 0x11, 0x02, + 0x34, 0x86, 0xE8, 0x20, 0x58, 0x33, 0x0B, 0x80, 0x34, 0x89, + 0xD8 +}; +static const int sizeof_ecc_key_pub_der_256 = sizeof(ecc_key_pub_der_256); + +/* ./certs/server-ecc-comp.der, ECC */ +static const unsigned char serv_ecc_comp_der_256[] = +{ + 0x30, 0x82, 0x03, 0x23, 0x30, 0x82, 0x02, 0xCA, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x80, 0x78, 0xC9, 0xB7, + 0x06, 0x5A, 0xC5, 0x83, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, + 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x81, 0xA0, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, + 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, 0x45, + 0x6C, 0x6C, 0x69, 0x70, 0x74, 0x69, 0x63, 0x20, 0x2D, 0x20, + 0x63, 0x6F, 0x6D, 0x70, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x0C, 0x0F, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x45, 0x43, 0x43, 0x2D, 0x63, 0x6F, 0x6D, 0x70, + 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, + 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, + 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, + 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, + 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, + 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x34, 0x31, 0x33, 0x31, + 0x35, 0x32, 0x33, 0x31, 0x30, 0x5A, 0x17, 0x0D, 0x32, 0x31, + 0x30, 0x31, 0x30, 0x37, 0x31, 0x35, 0x32, 0x33, 0x31, 0x30, + 0x5A, 0x30, 0x81, 0xA0, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, + 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, + 0x6D, 0x61, 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x0F, 0x45, 0x6C, 0x6C, 0x69, 0x70, 0x74, + 0x69, 0x63, 0x20, 0x2D, 0x20, 0x63, 0x6F, 0x6D, 0x70, 0x31, + 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0F, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x45, 0x43, 0x43, + 0x2D, 0x63, 0x6F, 0x6D, 0x70, 0x31, 0x18, 0x30, 0x16, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, + 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, + 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, + 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, + 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, + 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x39, 0x30, 0x13, 0x06, 0x07, + 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, + 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x22, 0x00, + 0x02, 0xBB, 0x33, 0xAC, 0x4C, 0x27, 0x50, 0x4A, 0xC6, 0x4A, + 0xA5, 0x04, 0xC3, 0x3C, 0xDE, 0x9F, 0x36, 0xDB, 0x72, 0x2D, + 0xCE, 0x94, 0xEA, 0x2B, 0xFA, 0xCB, 0x20, 0x09, 0x39, 0x2C, + 0x16, 0xE8, 0x61, 0xA3, 0x82, 0x01, 0x09, 0x30, 0x82, 0x01, + 0x05, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, + 0x04, 0x14, 0x8C, 0x38, 0x3A, 0x6B, 0xB8, 0x24, 0xB7, 0xDF, + 0x6E, 0xF4, 0x59, 0xAC, 0x56, 0x4E, 0xAA, 0xE2, 0x58, 0xA6, + 0x5A, 0x18, 0x30, 0x81, 0xD5, 0x06, 0x03, 0x55, 0x1D, 0x23, + 0x04, 0x81, 0xCD, 0x30, 0x81, 0xCA, 0x80, 0x14, 0x8C, 0x38, + 0x3A, 0x6B, 0xB8, 0x24, 0xB7, 0xDF, 0x6E, 0xF4, 0x59, 0xAC, + 0x56, 0x4E, 0xAA, 0xE2, 0x58, 0xA6, 0x5A, 0x18, 0xA1, 0x81, + 0xA6, 0xA4, 0x81, 0xA3, 0x30, 0x81, 0xA0, 0x31, 0x0B, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, + 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, + 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x18, 0x30, 0x16, + 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, 0x45, 0x6C, 0x6C, + 0x69, 0x70, 0x74, 0x69, 0x63, 0x20, 0x2D, 0x20, 0x63, 0x6F, + 0x6D, 0x70, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x0F, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, + 0x45, 0x43, 0x43, 0x2D, 0x63, 0x6F, 0x6D, 0x70, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, + 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, + 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, + 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x82, 0x09, 0x00, + 0x80, 0x78, 0xC9, 0xB7, 0x06, 0x5A, 0xC5, 0x83, 0x30, 0x0C, + 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, + 0x01, 0xFF, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, + 0x3D, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, + 0x20, 0x31, 0x44, 0xD0, 0x4E, 0xD7, 0xC4, 0xB4, 0x96, 0xA3, + 0xE6, 0x25, 0xFD, 0xFA, 0xD6, 0x28, 0xA8, 0x67, 0x51, 0x72, + 0x90, 0x95, 0x31, 0xF9, 0xCD, 0x10, 0xBF, 0x11, 0xE4, 0xEC, + 0xB7, 0x42, 0x5B, 0x02, 0x20, 0x45, 0xDB, 0x45, 0x0A, 0x24, + 0x58, 0x8E, 0x2E, 0xE6, 0xEA, 0x0C, 0x6C, 0xBC, 0x72, 0x4F, + 0x0A, 0x1B, 0xF3, 0x2D, 0x97, 0xE9, 0xC2, 0x19, 0xF9, 0x97, + 0x3A, 0x60, 0xDD, 0x08, 0xD3, 0x52, 0x3E +}; +static const int sizeof_serv_ecc_comp_der_256 = sizeof(serv_ecc_comp_der_256); + +/* ./certs/server-ecc-rsa.der, ECC */ +static const unsigned char serv_ecc_rsa_der_256[] = +{ + 0x30, 0x82, 0x03, 0xE0, 0x30, 0x82, 0x02, 0xC8, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, + 0x00, 0x30, 0x81, 0x94, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, + 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, + 0x6D, 0x61, 0x6E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x08, 0x53, 0x61, 0x77, 0x74, 0x6F, 0x6F, + 0x74, 0x68, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x0A, 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, + 0x69, 0x6E, 0x67, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, + 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, + 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, + 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, + 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, + 0x6F, 0x6D, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x34, + 0x31, 0x33, 0x31, 0x35, 0x32, 0x33, 0x31, 0x30, 0x5A, 0x17, + 0x0D, 0x32, 0x31, 0x30, 0x31, 0x30, 0x37, 0x31, 0x35, 0x32, + 0x33, 0x31, 0x30, 0x5A, 0x30, 0x81, 0x9D, 0x31, 0x0B, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, + 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, + 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x1A, 0x30, 0x18, + 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x11, 0x45, 0x6C, 0x6C, + 0x69, 0x70, 0x74, 0x69, 0x63, 0x20, 0x2D, 0x20, 0x52, 0x53, + 0x41, 0x73, 0x69, 0x67, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x0C, 0x0A, 0x45, 0x43, 0x43, 0x2D, 0x52, + 0x53, 0x41, 0x73, 0x69, 0x67, 0x31, 0x18, 0x30, 0x16, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, + 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, + 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, + 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, + 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, + 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, + 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, + 0x04, 0xBB, 0x33, 0xAC, 0x4C, 0x27, 0x50, 0x4A, 0xC6, 0x4A, + 0xA5, 0x04, 0xC3, 0x3C, 0xDE, 0x9F, 0x36, 0xDB, 0x72, 0x2D, + 0xCE, 0x94, 0xEA, 0x2B, 0xFA, 0xCB, 0x20, 0x09, 0x39, 0x2C, + 0x16, 0xE8, 0x61, 0x02, 0xE9, 0xAF, 0x4D, 0xD3, 0x02, 0x93, + 0x9A, 0x31, 0x5B, 0x97, 0x92, 0x21, 0x7F, 0xF0, 0xCF, 0x18, + 0xDA, 0x91, 0x11, 0x02, 0x34, 0x86, 0xE8, 0x20, 0x58, 0x33, + 0x0B, 0x80, 0x34, 0x89, 0xD8, 0xA3, 0x81, 0xFC, 0x30, 0x81, + 0xF9, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, + 0x04, 0x14, 0x5D, 0x5D, 0x26, 0xEF, 0xAC, 0x7E, 0x36, 0xF9, + 0x9B, 0x76, 0x15, 0x2B, 0x4A, 0x25, 0x02, 0x23, 0xEF, 0xB2, + 0x89, 0x30, 0x30, 0x81, 0xC9, 0x06, 0x03, 0x55, 0x1D, 0x23, + 0x04, 0x81, 0xC1, 0x30, 0x81, 0xBE, 0x80, 0x14, 0x27, 0x8E, + 0x67, 0x11, 0x74, 0xC3, 0x26, 0x1D, 0x3F, 0xED, 0x33, 0x63, + 0xB3, 0xA4, 0xD8, 0x1D, 0x30, 0xE5, 0xE8, 0xD5, 0xA1, 0x81, + 0x9A, 0xA4, 0x81, 0x97, 0x30, 0x81, 0x94, 0x31, 0x0B, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, + 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, + 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x11, 0x30, 0x0F, + 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x08, 0x53, 0x61, 0x77, + 0x74, 0x6F, 0x6F, 0x74, 0x68, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0A, 0x43, 0x6F, 0x6E, 0x73, + 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x31, 0x18, 0x30, 0x16, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, + 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, + 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, + 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, + 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x82, 0x09, 0x00, 0x86, 0xFF, + 0xF5, 0x8E, 0x10, 0xDE, 0xB8, 0xFB, 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, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x0C, 0xBB, 0x67, 0xBD, 0xFC, 0xCD, 0x53, 0x6C, 0xFB, 0x4E, + 0x58, 0xC8, 0xEA, 0x52, 0x92, 0xEB, 0xE4, 0xC8, 0xBC, 0x57, + 0x0F, 0x08, 0x20, 0xC8, 0x83, 0xB0, 0xD5, 0xEA, 0x57, 0x27, + 0xBD, 0x68, 0x91, 0xFB, 0x99, 0x84, 0x8D, 0x15, 0x9E, 0x4F, + 0x8F, 0xC4, 0xCB, 0x34, 0x61, 0xC0, 0x59, 0x12, 0x9B, 0xC8, + 0x82, 0x17, 0x38, 0x4F, 0x9E, 0x53, 0x08, 0xA3, 0x69, 0x2E, + 0x2F, 0xC0, 0xB4, 0x2F, 0xA2, 0x4E, 0x10, 0x64, 0xB0, 0x07, + 0xA1, 0x51, 0x08, 0x1D, 0x91, 0x53, 0xA2, 0x79, 0x55, 0x20, + 0x41, 0x65, 0x35, 0x3E, 0x0B, 0x38, 0x01, 0x57, 0x02, 0x8C, + 0x25, 0xE7, 0xAB, 0x4F, 0x8B, 0x59, 0xF0, 0xED, 0x8E, 0x4A, + 0x15, 0x0B, 0x32, 0xFB, 0x7A, 0x8B, 0x02, 0xEA, 0x9D, 0xE1, + 0xAB, 0xC4, 0x07, 0xCC, 0xDA, 0x0F, 0xA3, 0x16, 0xDB, 0x8E, + 0x5B, 0xBC, 0x96, 0xAB, 0x10, 0xB8, 0xDE, 0x09, 0x8B, 0xF7, + 0xCB, 0xA7, 0x78, 0x66, 0x17, 0xE3, 0x25, 0x6E, 0x57, 0x9D, + 0x13, 0x61, 0x7B, 0x55, 0x1A, 0xDF, 0x8F, 0x39, 0x15, 0x4E, + 0x42, 0x22, 0x00, 0x85, 0xC4, 0x51, 0x0B, 0x6B, 0xA6, 0x67, + 0xC0, 0xFB, 0xEA, 0x22, 0x77, 0x7D, 0x48, 0x76, 0xAB, 0x39, + 0x20, 0x09, 0xD5, 0x52, 0x89, 0x3E, 0x6B, 0x30, 0x7B, 0x50, + 0x18, 0xE8, 0x62, 0x05, 0xBE, 0xBB, 0x7F, 0x16, 0x77, 0x9C, + 0xBB, 0x5A, 0x22, 0x96, 0x99, 0xB0, 0x96, 0x83, 0xB7, 0x43, + 0x31, 0x97, 0xCF, 0xFD, 0x85, 0x52, 0xD8, 0x52, 0xC8, 0x67, + 0x5C, 0xF8, 0x22, 0x72, 0x35, 0x93, 0x92, 0x6C, 0xEC, 0x3C, + 0x6A, 0xC6, 0x81, 0x20, 0xA5, 0xCD, 0x50, 0xF9, 0x21, 0x7A, + 0xA6, 0x7A, 0x1E, 0xE7, 0x59, 0x22, 0x5D, 0x8A, 0x93, 0x51, + 0x8E, 0xFB, 0x29, 0x56, 0xFB, 0xBE, 0x9B, 0x87, 0x48, 0x5F, + 0xA5, 0x72, 0xE7, 0x4E, 0xFE, 0x5E +}; +static const int sizeof_serv_ecc_rsa_der_256 = sizeof(serv_ecc_rsa_der_256); + +/* ./certs/server-ecc.der, ECC */ +static const unsigned char serv_ecc_der_256[] = +{ + 0x30, 0x82, 0x03, 0x50, 0x30, 0x82, 0x02, 0xF5, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x02, 0x10, 0x00, 0x30, 0x0A, 0x06, + 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, + 0x81, 0x97, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0C, 0x0A, 0x57, 0x61, 0x73, 0x68, + 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x53, 0x65, 0x61, + 0x74, 0x74, 0x6C, 0x65, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x0A, 0x0C, 0x07, 0x77, 0x6F, 0x6C, 0x66, 0x53, + 0x53, 0x4C, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x0B, 0x44, 0x65, 0x76, 0x65, 0x6C, 0x6F, 0x70, + 0x6D, 0x65, 0x6E, 0x74, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, + 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, + 0x63, 0x6F, 0x6D, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x37, 0x31, + 0x30, 0x32, 0x30, 0x31, 0x38, 0x31, 0x39, 0x30, 0x36, 0x5A, + 0x17, 0x0D, 0x32, 0x37, 0x31, 0x30, 0x31, 0x38, 0x31, 0x38, + 0x31, 0x39, 0x30, 0x36, 0x5A, 0x30, 0x81, 0x8F, 0x31, 0x0B, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x0A, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, + 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6C, 0x65, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x07, 0x45, 0x6C, 0x69, 0x70, 0x74, 0x69, 0x63, 0x31, 0x0C, + 0x30, 0x0A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x03, 0x45, + 0x43, 0x43, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, + 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, + 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, + 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, + 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, + 0x6D, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, + 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, + 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xBB, 0x33, + 0xAC, 0x4C, 0x27, 0x50, 0x4A, 0xC6, 0x4A, 0xA5, 0x04, 0xC3, + 0x3C, 0xDE, 0x9F, 0x36, 0xDB, 0x72, 0x2D, 0xCE, 0x94, 0xEA, + 0x2B, 0xFA, 0xCB, 0x20, 0x09, 0x39, 0x2C, 0x16, 0xE8, 0x61, + 0x02, 0xE9, 0xAF, 0x4D, 0xD3, 0x02, 0x93, 0x9A, 0x31, 0x5B, + 0x97, 0x92, 0x21, 0x7F, 0xF0, 0xCF, 0x18, 0xDA, 0x91, 0x11, + 0x02, 0x34, 0x86, 0xE8, 0x20, 0x58, 0x33, 0x0B, 0x80, 0x34, + 0x89, 0xD8, 0xA3, 0x82, 0x01, 0x35, 0x30, 0x82, 0x01, 0x31, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04, 0x02, 0x30, + 0x00, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, + 0xF8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40, + 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, + 0x14, 0x5D, 0x5D, 0x26, 0xEF, 0xAC, 0x7E, 0x36, 0xF9, 0x9B, + 0x76, 0x15, 0x2B, 0x4A, 0x25, 0x02, 0x23, 0xEF, 0xB2, 0x89, + 0x30, 0x30, 0x81, 0xCC, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, + 0x81, 0xC4, 0x30, 0x81, 0xC1, 0x80, 0x14, 0x56, 0x8E, 0x9A, + 0xC3, 0xF0, 0x42, 0xDE, 0x18, 0xB9, 0x45, 0x55, 0x6E, 0xF9, + 0x93, 0xCF, 0xEA, 0xC3, 0xF3, 0xA5, 0x21, 0xA1, 0x81, 0x9D, + 0xA4, 0x81, 0x9A, 0x30, 0x81, 0x97, 0x31, 0x0B, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x0A, + 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, + 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6C, 0x65, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x07, 0x77, + 0x6F, 0x6C, 0x66, 0x53, 0x53, 0x4C, 0x31, 0x14, 0x30, 0x12, + 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0B, 0x44, 0x65, 0x76, + 0x65, 0x6C, 0x6F, 0x70, 0x6D, 0x65, 0x6E, 0x74, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, + 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, + 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, + 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x82, 0x09, 0x00, + 0x97, 0xB4, 0xBD, 0x16, 0x78, 0xF8, 0x47, 0xF2, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, + 0x03, 0x02, 0x03, 0xA8, 0x30, 0x13, 0x06, 0x03, 0x55, 0x1D, + 0x25, 0x04, 0x0C, 0x30, 0x0A, 0x06, 0x08, 0x2B, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x0A, 0x06, 0x08, 0x2A, + 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x49, 0x00, + 0x30, 0x46, 0x02, 0x21, 0x00, 0xBE, 0xB8, 0x58, 0xF0, 0xE4, + 0x15, 0x01, 0x1F, 0xDF, 0x70, 0x54, 0x73, 0x4A, 0x6C, 0x40, + 0x1F, 0x77, 0xA8, 0xB4, 0xEB, 0x52, 0x1E, 0xBF, 0xF5, 0x0D, + 0xB1, 0x33, 0xCA, 0x6A, 0xC4, 0x76, 0xB9, 0x02, 0x21, 0x00, + 0x97, 0x08, 0xDE, 0x2C, 0x28, 0xC1, 0x45, 0x71, 0xB6, 0x2C, + 0x54, 0x87, 0x98, 0x63, 0x76, 0xA8, 0x21, 0x34, 0x90, 0xA8, + 0xF7, 0x9E, 0x3F, 0xFC, 0x02, 0xB0, 0xE7, 0xD3, 0x09, 0x31, + 0x27, 0xE4 +}; +static const int sizeof_serv_ecc_der_256 = sizeof(serv_ecc_der_256); + +/* ./certs/ca-ecc-key.der, ECC */ +static const unsigned char ca_ecc_key_der_256[] = +{ + 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x02, 0xE1, 0x33, + 0x98, 0x77, 0x97, 0xAC, 0x4A, 0x59, 0x6D, 0x28, 0x9B, 0x6E, + 0xA0, 0x93, 0x9B, 0x07, 0x71, 0x8B, 0x4D, 0x60, 0x63, 0x85, + 0x99, 0xE6, 0xBB, 0x16, 0x70, 0xE9, 0x0A, 0xF6, 0x80, 0xA0, + 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, + 0x07, 0xA1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x02, 0xD3, 0xD9, + 0x6E, 0xD6, 0x01, 0x8E, 0x45, 0xC8, 0xB9, 0x90, 0x31, 0xE5, + 0xC0, 0x4C, 0xE3, 0x9E, 0xAD, 0x29, 0x38, 0x98, 0xBA, 0x10, + 0xD6, 0xE9, 0x09, 0x2A, 0x80, 0xA9, 0x2E, 0x17, 0x2A, 0xB9, + 0x8A, 0xBF, 0x33, 0x83, 0x46, 0xE3, 0x95, 0x0B, 0xE4, 0x77, + 0x40, 0xB5, 0x3B, 0x43, 0x45, 0x33, 0x0F, 0x61, 0x53, 0x7C, + 0x37, 0x44, 0xC1, 0xCB, 0xFC, 0x80, 0xCA, 0xE8, 0x43, 0xEA, + 0xA7 +}; +static const int sizeof_ca_ecc_key_der_256 = sizeof(ca_ecc_key_der_256); + +/* ./certs/ca-ecc-cert.der, ECC */ +static const unsigned char ca_ecc_cert_der_256[] = +{ + 0x30, 0x82, 0x02, 0x8B, 0x30, 0x82, 0x02, 0x30, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xFD, 0x0E, 0x29, 0x21, + 0x66, 0xCB, 0x48, 0xA3, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, + 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x81, 0x97, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x0A, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, + 0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x0C, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6C, + 0x65, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x07, 0x77, 0x6F, 0x6C, 0x66, 0x53, 0x53, 0x4C, 0x31, + 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0B, + 0x44, 0x65, 0x76, 0x65, 0x6C, 0x6F, 0x70, 0x6D, 0x65, 0x6E, + 0x74, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, + 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, + 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, + 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, + 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x34, 0x31, 0x33, + 0x31, 0x35, 0x32, 0x33, 0x31, 0x30, 0x5A, 0x17, 0x0D, 0x32, + 0x31, 0x30, 0x31, 0x30, 0x37, 0x31, 0x35, 0x32, 0x33, 0x31, + 0x30, 0x5A, 0x30, 0x81, 0x97, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x0A, 0x57, + 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, + 0x53, 0x65, 0x61, 0x74, 0x74, 0x6C, 0x65, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x07, 0x77, 0x6F, + 0x6C, 0x66, 0x53, 0x53, 0x4C, 0x31, 0x14, 0x30, 0x12, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0B, 0x44, 0x65, 0x76, 0x65, + 0x6C, 0x6F, 0x70, 0x6D, 0x65, 0x6E, 0x74, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, + 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, + 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, + 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, + 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, + 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x59, 0x30, 0x13, + 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, + 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, + 0x42, 0x00, 0x04, 0x02, 0xD3, 0xD9, 0x6E, 0xD6, 0x01, 0x8E, + 0x45, 0xC8, 0xB9, 0x90, 0x31, 0xE5, 0xC0, 0x4C, 0xE3, 0x9E, + 0xAD, 0x29, 0x38, 0x98, 0xBA, 0x10, 0xD6, 0xE9, 0x09, 0x2A, + 0x80, 0xA9, 0x2E, 0x17, 0x2A, 0xB9, 0x8A, 0xBF, 0x33, 0x83, + 0x46, 0xE3, 0x95, 0x0B, 0xE4, 0x77, 0x40, 0xB5, 0x3B, 0x43, + 0x45, 0x33, 0x0F, 0x61, 0x53, 0x7C, 0x37, 0x44, 0xC1, 0xCB, + 0xFC, 0x80, 0xCA, 0xE8, 0x43, 0xEA, 0xA7, 0xA3, 0x63, 0x30, + 0x61, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, + 0x04, 0x14, 0x56, 0x8E, 0x9A, 0xC3, 0xF0, 0x42, 0xDE, 0x18, + 0xB9, 0x45, 0x55, 0x6E, 0xF9, 0x93, 0xCF, 0xEA, 0xC3, 0xF3, + 0xA5, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, + 0x18, 0x30, 0x16, 0x80, 0x14, 0x56, 0x8E, 0x9A, 0xC3, 0xF0, + 0x42, 0xDE, 0x18, 0xB9, 0x45, 0x55, 0x6E, 0xF9, 0x93, 0xCF, + 0xEA, 0xC3, 0xF3, 0xA5, 0x21, 0x30, 0x0F, 0x06, 0x03, 0x55, + 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, + 0x01, 0xFF, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, + 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0A, + 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, + 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0xF0, 0x7B, + 0xCC, 0x24, 0x73, 0x19, 0x3F, 0x61, 0x68, 0xED, 0xC8, 0x0A, + 0x54, 0x4A, 0xB8, 0xAC, 0x79, 0xEF, 0x10, 0x32, 0x91, 0x52, + 0x2C, 0x3E, 0xBF, 0x50, 0xAA, 0x5F, 0x18, 0xC1, 0x97, 0xF5, + 0x02, 0x21, 0x00, 0xD9, 0x4B, 0x63, 0x67, 0x6F, 0x9B, 0x29, + 0xA9, 0xD7, 0x6B, 0x63, 0x9B, 0x98, 0x9F, 0x32, 0x82, 0x36, + 0xDA, 0xF0, 0xA9, 0xF7, 0x51, 0xB4, 0x97, 0xAA, 0xFA, 0xFA, + 0xDD, 0xEF, 0xEF, 0x4A, 0xAE +}; +static const int sizeof_ca_ecc_cert_der_256 = sizeof(ca_ecc_cert_der_256); + +/* ./certs/ca-ecc384-key.der, ECC */ +static const unsigned char ca_ecc_key_der_384[] = +{ + 0x30, 0x81, 0xA4, 0x02, 0x01, 0x01, 0x04, 0x30, 0x7B, 0x16, + 0xE3, 0xD6, 0xD2, 0x81, 0x94, 0x6C, 0x8A, 0xDD, 0xA8, 0x78, + 0xEE, 0xC7, 0x7E, 0xB3, 0xC5, 0xD1, 0xDB, 0x2E, 0xF3, 0xED, + 0x0E, 0x48, 0x85, 0xB1, 0xF2, 0xE1, 0x7A, 0x39, 0x56, 0xC0, + 0xF1, 0x62, 0x12, 0x0F, 0x35, 0xB7, 0x39, 0xBC, 0x9C, 0x25, + 0xC0, 0x76, 0xEB, 0xFE, 0x55, 0x70, 0xA0, 0x07, 0x06, 0x05, + 0x2B, 0x81, 0x04, 0x00, 0x22, 0xA1, 0x64, 0x03, 0x62, 0x00, + 0x04, 0xEE, 0x82, 0xD4, 0x39, 0x9A, 0xB1, 0x27, 0x82, 0xF4, + 0xD7, 0xEA, 0xC6, 0xBC, 0x03, 0x1D, 0x4D, 0x83, 0x61, 0xF4, + 0x03, 0xAE, 0x7E, 0xBD, 0xD8, 0x5A, 0xA5, 0xB9, 0xF0, 0x8E, + 0xA2, 0xA5, 0xDA, 0xCE, 0x87, 0x3B, 0x5A, 0xAB, 0x44, 0x16, + 0x9C, 0xF5, 0x9F, 0x62, 0xDD, 0xF6, 0x20, 0xCD, 0x9C, 0x76, + 0x3C, 0x40, 0xB1, 0x3F, 0x97, 0x17, 0xDF, 0x59, 0xF6, 0xCD, + 0xDE, 0xCD, 0x46, 0x35, 0xC0, 0xED, 0x5E, 0x2E, 0x48, 0xB6, + 0x66, 0x91, 0x71, 0x74, 0xB7, 0x0C, 0x3F, 0xB9, 0x9A, 0xB7, + 0x83, 0xBD, 0x93, 0x3F, 0x5F, 0x50, 0x2D, 0x70, 0x3F, 0xDE, + 0x35, 0x25, 0xE1, 0x90, 0x3B, 0x86, 0xE0 +}; +static const int sizeof_ca_ecc_key_der_384 = sizeof(ca_ecc_key_der_384); + +/* ./certs/ca-ecc384-cert.der, ECC */ +static const unsigned char ca_ecc_cert_der_384[] = +{ + 0x30, 0x82, 0x02, 0xC7, 0x30, 0x82, 0x02, 0x4D, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xFC, 0x39, 0x04, 0xA4, + 0x0E, 0xA5, 0x6C, 0x87, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, + 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03, 0x30, 0x81, 0x97, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x0A, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, + 0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x0C, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6C, + 0x65, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x07, 0x77, 0x6F, 0x6C, 0x66, 0x53, 0x53, 0x4C, 0x31, + 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0B, + 0x44, 0x65, 0x76, 0x65, 0x6C, 0x6F, 0x70, 0x6D, 0x65, 0x6E, + 0x74, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, + 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, + 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, + 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, + 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x34, 0x31, 0x33, + 0x31, 0x35, 0x32, 0x33, 0x31, 0x30, 0x5A, 0x17, 0x0D, 0x32, + 0x31, 0x30, 0x31, 0x30, 0x37, 0x31, 0x35, 0x32, 0x33, 0x31, + 0x30, 0x5A, 0x30, 0x81, 0x97, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x0A, 0x57, + 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, + 0x53, 0x65, 0x61, 0x74, 0x74, 0x6C, 0x65, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x07, 0x77, 0x6F, + 0x6C, 0x66, 0x53, 0x53, 0x4C, 0x31, 0x14, 0x30, 0x12, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0B, 0x44, 0x65, 0x76, 0x65, + 0x6C, 0x6F, 0x70, 0x6D, 0x65, 0x6E, 0x74, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, + 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, + 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, + 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, + 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, + 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x76, 0x30, 0x10, + 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, + 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00, 0x04, + 0xEE, 0x82, 0xD4, 0x39, 0x9A, 0xB1, 0x27, 0x82, 0xF4, 0xD7, + 0xEA, 0xC6, 0xBC, 0x03, 0x1D, 0x4D, 0x83, 0x61, 0xF4, 0x03, + 0xAE, 0x7E, 0xBD, 0xD8, 0x5A, 0xA5, 0xB9, 0xF0, 0x8E, 0xA2, + 0xA5, 0xDA, 0xCE, 0x87, 0x3B, 0x5A, 0xAB, 0x44, 0x16, 0x9C, + 0xF5, 0x9F, 0x62, 0xDD, 0xF6, 0x20, 0xCD, 0x9C, 0x76, 0x3C, + 0x40, 0xB1, 0x3F, 0x97, 0x17, 0xDF, 0x59, 0xF6, 0xCD, 0xDE, + 0xCD, 0x46, 0x35, 0xC0, 0xED, 0x5E, 0x2E, 0x48, 0xB6, 0x66, + 0x91, 0x71, 0x74, 0xB7, 0x0C, 0x3F, 0xB9, 0x9A, 0xB7, 0x83, + 0xBD, 0x93, 0x3F, 0x5F, 0x50, 0x2D, 0x70, 0x3F, 0xDE, 0x35, + 0x25, 0xE1, 0x90, 0x3B, 0x86, 0xE0, 0xA3, 0x63, 0x30, 0x61, + 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, + 0x14, 0xAB, 0xE0, 0xC3, 0x26, 0x4C, 0x18, 0xD4, 0x72, 0xBB, + 0xD2, 0x84, 0x8C, 0x9C, 0x0A, 0x05, 0x92, 0x80, 0x12, 0x53, + 0x52, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, + 0x30, 0x16, 0x80, 0x14, 0xAB, 0xE0, 0xC3, 0x26, 0x4C, 0x18, + 0xD4, 0x72, 0xBB, 0xD2, 0x84, 0x8C, 0x9C, 0x0A, 0x05, 0x92, + 0x80, 0x12, 0x53, 0x52, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, + 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, + 0xFF, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, + 0xFF, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0A, 0x06, + 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03, 0x03, + 0x68, 0x00, 0x30, 0x65, 0x02, 0x30, 0x0D, 0x0A, 0x62, 0xFB, + 0xE6, 0x3A, 0xFE, 0x71, 0xD8, 0x2B, 0x44, 0xE5, 0x97, 0x34, + 0x04, 0xA9, 0x8C, 0x0A, 0x99, 0x88, 0xA0, 0xBD, 0x1F, 0xB0, + 0xDF, 0x94, 0x59, 0x27, 0xBB, 0x2B, 0xC6, 0x2A, 0xBE, 0xA4, + 0x69, 0x1B, 0xCF, 0x97, 0x78, 0x2A, 0x28, 0x96, 0xEE, 0xBA, + 0xD4, 0x87, 0x45, 0xFD, 0x02, 0x31, 0x00, 0xC0, 0x73, 0x19, + 0x66, 0x76, 0x5E, 0x9F, 0xA3, 0x65, 0x85, 0x41, 0xEF, 0xB7, + 0x7B, 0x3D, 0x63, 0x6D, 0x98, 0x71, 0x99, 0x6F, 0x9C, 0xDB, + 0xA8, 0x5E, 0x53, 0x6E, 0xA0, 0x68, 0x11, 0x65, 0xBC, 0x78, + 0x74, 0x28, 0x69, 0xC7, 0x64, 0x9D, 0x88, 0xF2, 0xD8, 0xC2, + 0x3D, 0x29, 0x03, 0x83, 0x23 +}; +static const int sizeof_ca_ecc_cert_der_384 = sizeof(ca_ecc_cert_der_384); + +#endif /* HAVE_ECC && USE_CERT_BUFFERS_256 */ + +/* dh1024 p */ +static const unsigned char dh_p[] = +{ + 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3, + 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E, + 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59, + 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2, + 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD, + 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF, + 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02, + 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C, + 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7, + 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50, + 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B, +}; + +/* dh1024 g */ +static const unsigned char dh_g[] = +{ + 0x02, +}; + +#if defined(HAVE_ED25519) + +/* ./certs/ed25519/server-ed25519.der, ED25519 */ +static const unsigned char server_ed25519_cert[] = +{ + 0x30, 0x82, 0x02, 0x52, 0x30, 0x82, 0x02, 0x04, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x10, 0x00, 0xCD, 0xF2, 0x2F, 0xBE, + 0xDC, 0x07, 0xFA, 0xBB, 0x65, 0x03, 0xE2, 0xFF, 0xEA, 0x6A, + 0x99, 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70, 0x30, 0x81, + 0x9D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, + 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, + 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x04, 0x0C, + 0x02, 0x43, 0x41, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x07, 0x77, 0x6F, 0x6C, 0x66, 0x53, 0x53, + 0x4C, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x0C, 0x07, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x31, + 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, + 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, + 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, + 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, + 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x22, + 0x18, 0x0F, 0x32, 0x30, 0x31, 0x38, 0x30, 0x34, 0x31, 0x32, + 0x31, 0x36, 0x32, 0x32, 0x31, 0x37, 0x5A, 0x18, 0x0F, 0x32, + 0x30, 0x32, 0x31, 0x30, 0x31, 0x30, 0x37, 0x31, 0x35, 0x32, + 0x32, 0x31, 0x37, 0x5A, 0x30, 0x81, 0x9F, 0x31, 0x0B, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, + 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, + 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x0D, 0x30, 0x0B, + 0x06, 0x03, 0x55, 0x04, 0x04, 0x0C, 0x04, 0x4C, 0x65, 0x61, + 0x66, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x07, 0x77, 0x6F, 0x6C, 0x66, 0x53, 0x53, 0x4C, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, + 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, + 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, + 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, + 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, + 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, + 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x2A, 0x30, 0x05, + 0x06, 0x03, 0x2B, 0x65, 0x70, 0x03, 0x21, 0x00, 0x61, 0x5D, + 0xEC, 0xB7, 0x45, 0x93, 0xC9, 0x84, 0x7B, 0x68, 0x21, 0x4A, + 0x4D, 0xF4, 0x04, 0x8B, 0xBD, 0xCD, 0x6C, 0x5D, 0x3D, 0xB7, + 0x62, 0x2C, 0x2D, 0x25, 0xC3, 0x22, 0x49, 0xC8, 0x86, 0xF2, + 0xA3, 0x52, 0x30, 0x50, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, + 0x0E, 0x04, 0x16, 0x04, 0x14, 0x33, 0xC8, 0x28, 0x63, 0x8C, + 0xF4, 0x57, 0xEE, 0x1E, 0xB0, 0xC7, 0x12, 0x12, 0x76, 0x8A, + 0x80, 0x30, 0x3A, 0xCB, 0x10, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x92, 0x3F, + 0x96, 0x72, 0x02, 0xFA, 0x61, 0x1C, 0x21, 0x6D, 0x88, 0xDD, + 0xEB, 0xDD, 0x3C, 0x9B, 0x17, 0xC4, 0x9F, 0xB7, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, + 0x03, 0x02, 0x06, 0xC0, 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, + 0x70, 0x03, 0x41, 0x00, 0x15, 0x88, 0x86, 0xFC, 0x66, 0xD1, + 0xE0, 0xF6, 0xCF, 0xC9, 0x09, 0x46, 0xD0, 0x50, 0xE2, 0x01, + 0x5D, 0xF7, 0xCF, 0x57, 0xB8, 0xBA, 0x90, 0x84, 0xCB, 0xF1, + 0x24, 0x4B, 0xEF, 0xA5, 0x95, 0x7D, 0x69, 0x92, 0x88, 0xA8, + 0x89, 0x63, 0xCC, 0x90, 0x40, 0xC2, 0x41, 0x3A, 0x40, 0x76, + 0xB1, 0x2D, 0xA8, 0xA8, 0x97, 0xC9, 0x73, 0xC7, 0x82, 0x30, + 0x24, 0x61, 0xB0, 0xAA, 0xCA, 0xAA, 0x68, 0x00 +}; +static const int sizeof_server_ed25519_cert = sizeof(server_ed25519_cert); + +/* ./certs/ed25519/server-ed25519-key.der, ED25519 */ +static const unsigned char server_ed25519_key[] = +{ + 0x30, 0x52, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2B, + 0x65, 0x70, 0x04, 0x22, 0x04, 0x20, 0x02, 0x2F, 0xC5, 0xFF, + 0xBA, 0x8E, 0xD0, 0xD2, 0xBF, 0x03, 0x8E, 0x76, 0x8F, 0xC8, + 0x86, 0x80, 0x71, 0x87, 0x97, 0x31, 0xE2, 0x40, 0xAC, 0xDF, + 0xBB, 0x90, 0x15, 0x52, 0x6E, 0x24, 0xA1, 0x39, 0xA1, 0x22, + 0x04, 0x20, 0x61, 0x5D, 0xEC, 0xB7, 0x45, 0x93, 0xC9, 0x84, + 0x7B, 0x68, 0x21, 0x4A, 0x4D, 0xF4, 0x04, 0x8B, 0xBD, 0xCD, + 0x6C, 0x5D, 0x3D, 0xB7, 0x62, 0x2C, 0x2D, 0x25, 0xC3, 0x22, + 0x49, 0xC8, 0x86, 0xF2 +}; +static const int sizeof_server_ed25519_key = sizeof(server_ed25519_key); + +/* ./certs/ed25519/ca-ed25519.der, ED25519 */ +static const unsigned char ca_ed25519_cert[] = +{ + 0x30, 0x82, 0x02, 0x60, 0x30, 0x82, 0x02, 0x12, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x10, 0x00, 0x80, 0xBA, 0x68, 0x77, + 0xEF, 0xA5, 0xE5, 0x42, 0x7D, 0xC6, 0x73, 0x2C, 0x54, 0x85, + 0xB8, 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70, 0x30, 0x81, + 0x9F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, + 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, + 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x04, 0x0C, + 0x04, 0x52, 0x6F, 0x6F, 0x74, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x07, 0x77, 0x6F, 0x6C, 0x66, + 0x53, 0x53, 0x4C, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x04, 0x0B, 0x0C, 0x07, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, + 0x39, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, + 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, + 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, + 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, + 0x30, 0x22, 0x18, 0x0F, 0x32, 0x30, 0x31, 0x38, 0x30, 0x34, + 0x31, 0x32, 0x31, 0x36, 0x32, 0x32, 0x31, 0x37, 0x5A, 0x18, + 0x0F, 0x32, 0x30, 0x32, 0x31, 0x30, 0x31, 0x30, 0x37, 0x31, + 0x35, 0x32, 0x32, 0x31, 0x37, 0x5A, 0x30, 0x81, 0x9D, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, + 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x0B, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x04, 0x0C, 0x02, 0x43, + 0x41, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x07, 0x77, 0x6F, 0x6C, 0x66, 0x53, 0x53, 0x4C, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, + 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, + 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, + 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, + 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, + 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, + 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x2A, 0x30, 0x05, + 0x06, 0x03, 0x2B, 0x65, 0x70, 0x03, 0x21, 0x00, 0x65, 0xAA, + 0x7F, 0x05, 0xA4, 0x04, 0x34, 0xA0, 0xEA, 0xAD, 0x1F, 0xA9, + 0x86, 0xF0, 0xD8, 0x7F, 0x72, 0xDF, 0xA9, 0x0E, 0x13, 0xA0, + 0x38, 0x66, 0x26, 0x5E, 0xEB, 0x48, 0x30, 0x80, 0x48, 0x49, + 0xA3, 0x60, 0x30, 0x5E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x1D, + 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x1D, + 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x92, + 0x3F, 0x96, 0x72, 0x02, 0xFA, 0x61, 0x1C, 0x21, 0x6D, 0x88, + 0xDD, 0xEB, 0xDD, 0x3C, 0x9B, 0x17, 0xC4, 0x9F, 0xB7, 0x30, + 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0xFE, 0x01, 0x46, 0x7F, 0x6F, 0x2B, 0x3E, 0x1C, + 0xB0, 0x6F, 0xE1, 0xCC, 0x4D, 0x02, 0x25, 0xF7, 0x4D, 0x0A, + 0x95, 0xB8, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, + 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, 0x01, 0xC6, 0x30, 0x05, + 0x06, 0x03, 0x2B, 0x65, 0x70, 0x03, 0x41, 0x00, 0x4C, 0x40, + 0xD0, 0x7F, 0xBC, 0xFB, 0xF4, 0xA2, 0x1A, 0x58, 0xF6, 0x72, + 0xE3, 0xE8, 0xDA, 0x18, 0x0D, 0x94, 0xDC, 0x0E, 0xFD, 0xC1, + 0xE7, 0x02, 0xA5, 0x7A, 0xEE, 0xCB, 0xC2, 0x7E, 0xFA, 0xA1, + 0xFC, 0x15, 0x9A, 0xFE, 0x1E, 0xE0, 0x37, 0xDF, 0x7F, 0xAB, + 0x76, 0x50, 0x06, 0xD4, 0x3D, 0x1A, 0x65, 0x73, 0x3F, 0x92, + 0xD4, 0x44, 0x62, 0xA7, 0x4C, 0xB3, 0x2A, 0x01, 0x87, 0xE3, + 0x06, 0x06 +}; +static const int sizeof_ca_ed25519_cert = sizeof(ca_ed25519_cert); + +/* ./certs/ed25519/client-ed25519.der, ED25519 */ +static const unsigned char client_ed25519_cert[] = +{ + 0x30, 0x82, 0x02, 0x58, 0x30, 0x82, 0x02, 0x0A, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x10, 0x00, 0x8F, 0x2F, 0x35, 0xB2, + 0x53, 0xBD, 0x4F, 0x92, 0xD1, 0xFF, 0x1D, 0x4B, 0x40, 0xA5, + 0x49, 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70, 0x30, 0x81, + 0xA1, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, + 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, + 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x04, 0x0C, + 0x06, 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x07, 0x77, 0x6F, + 0x6C, 0x66, 0x53, 0x53, 0x4C, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x45, 0x44, 0x32, 0x35, + 0x35, 0x31, 0x39, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, + 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, + 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, + 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, + 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, + 0x6F, 0x6D, 0x30, 0x22, 0x18, 0x0F, 0x32, 0x30, 0x31, 0x38, + 0x30, 0x34, 0x31, 0x32, 0x31, 0x36, 0x32, 0x32, 0x31, 0x37, + 0x5A, 0x18, 0x0F, 0x32, 0x30, 0x32, 0x31, 0x30, 0x31, 0x30, + 0x37, 0x31, 0x35, 0x32, 0x32, 0x31, 0x37, 0x5A, 0x30, 0x81, + 0xA1, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, + 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, + 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x04, 0x0C, + 0x06, 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x07, 0x77, 0x6F, + 0x6C, 0x66, 0x53, 0x53, 0x4C, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x45, 0x44, 0x32, 0x35, + 0x35, 0x31, 0x39, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, + 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, + 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, + 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, + 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, + 0x6F, 0x6D, 0x30, 0x2A, 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, + 0x70, 0x03, 0x21, 0x00, 0xA2, 0xF1, 0x26, 0x40, 0x9B, 0xA2, + 0x59, 0xDA, 0xDB, 0xE6, 0x15, 0x7F, 0x9A, 0x11, 0xB5, 0x48, + 0x5F, 0x55, 0xBA, 0x5E, 0xED, 0x46, 0xF7, 0x98, 0x67, 0xBE, + 0x0C, 0x93, 0xE3, 0xA4, 0x8E, 0x18, 0xA3, 0x52, 0x30, 0x50, + 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, + 0x14, 0xFE, 0x01, 0x46, 0x7F, 0x6F, 0x2B, 0x3E, 0x1C, 0xB0, + 0x6F, 0xE1, 0xCC, 0x4D, 0x02, 0x25, 0xF7, 0x4D, 0x0A, 0x95, + 0xB8, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, + 0x30, 0x16, 0x80, 0x14, 0xFE, 0x01, 0x46, 0x7F, 0x6F, 0x2B, + 0x3E, 0x1C, 0xB0, 0x6F, 0xE1, 0xCC, 0x4D, 0x02, 0x25, 0xF7, + 0x4D, 0x0A, 0x95, 0xB8, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, + 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, 0x06, 0xC0, + 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70, 0x03, 0x41, 0x00, + 0x29, 0xF6, 0x69, 0xE2, 0xB9, 0x73, 0x12, 0xD1, 0x64, 0xEB, + 0x8F, 0xE9, 0x6B, 0x61, 0xDB, 0x5F, 0xE9, 0xA7, 0x62, 0x6C, + 0x10, 0x89, 0x41, 0x80, 0xE3, 0xE8, 0xFD, 0x1F, 0xD0, 0x13, + 0xAE, 0x95, 0x00, 0xAF, 0xF7, 0x77, 0xE1, 0x22, 0x32, 0xAD, + 0x46, 0x4F, 0xDC, 0x7E, 0xFE, 0xAE, 0xBC, 0x8A, 0x1F, 0x96, + 0x0A, 0xDA, 0x9F, 0xC9, 0x93, 0x52, 0x27, 0x18, 0xB0, 0x8B, + 0xDA, 0xBE, 0x81, 0x09 +}; +static const int sizeof_client_ed25519_cert = sizeof(client_ed25519_cert); + +/* ./certs/ed25519/client-ed25519-key.der, ED25519 */ +static const unsigned char client_ed25519_key[] = +{ + 0x30, 0x52, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2B, + 0x65, 0x70, 0x04, 0x22, 0x04, 0x20, 0x27, 0xA3, 0x34, 0x2A, + 0x35, 0xD4, 0xBB, 0xB8, 0xE1, 0xDC, 0xD8, 0xEC, 0x0F, 0xC1, + 0xA0, 0xD1, 0xA2, 0x5C, 0xF9, 0x06, 0xF0, 0x44, 0x5D, 0x3B, + 0x97, 0x4D, 0xBD, 0xDF, 0x4A, 0x3B, 0xA3, 0x4E, 0xA1, 0x22, + 0x04, 0x20, 0xA2, 0xF1, 0x26, 0x40, 0x9B, 0xA2, 0x59, 0xDA, + 0xDB, 0xE6, 0x15, 0x7F, 0x9A, 0x11, 0xB5, 0x48, 0x5F, 0x55, + 0xBA, 0x5E, 0xED, 0x46, 0xF7, 0x98, 0x67, 0xBE, 0x0C, 0x93, + 0xE3, 0xA4, 0x8E, 0x18 +}; +static const int sizeof_client_ed25519_key = sizeof(client_ed25519_key); + +#endif /* HAVE_ED25519 */ + +#endif /* WOLFSSL_CERTS_TEST_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/crl.h b/wolfssl_hlavickove_subory/wolfssl/crl.h new file mode 100644 index 0000000..48b488f --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/crl.h @@ -0,0 +1,50 @@ +/* crl.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +#ifndef WOLFSSL_CRL_H +#define WOLFSSL_CRL_H + + +#ifdef HAVE_CRL + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +WOLFSSL_LOCAL int InitCRL(WOLFSSL_CRL*, WOLFSSL_CERT_MANAGER*); +WOLFSSL_LOCAL void FreeCRL(WOLFSSL_CRL*, int dynamic); + +WOLFSSL_LOCAL int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int mon); +WOLFSSL_LOCAL int BufferLoadCRL(WOLFSSL_CRL*, const byte*, long, int, int); +WOLFSSL_LOCAL int CheckCertCRL(WOLFSSL_CRL*, DecodedCert*); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_CRL */ +#endif /* WOLFSSL_CRL_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/error-ssl.h b/wolfssl_hlavickove_subory/wolfssl/error-ssl.h new file mode 100644 index 0000000..c1e14c3 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/error-ssl.h @@ -0,0 +1,203 @@ +/* error-ssl.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +#ifndef WOLFSSL_ERROR_H +#define WOLFSSL_ERROR_H + +#include /* pull in wolfCrypt errors */ + +#ifdef __cplusplus + extern "C" { +#endif + +enum wolfSSL_ErrorCodes { + 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 = -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 = -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 */ + IPADDR_MISMATCH = -325, /* peer ip address mismatch */ + 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 */ + + 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_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_SETUP_E = -363, /* CRL Monitor setup error */ + 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 */ + + 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 */ + SECURE_RENEGOTIATION_E = -388, /* Invalid Renegotiation Info */ + SESSION_TICKET_LEN_E = -389, /* Session Ticket too large */ + SESSION_TICKET_EXPECT_E = -390, /* Session Ticket missing */ + SCR_DIFFERENT_CERT_E = -391, /* SCR Different cert error */ + SESSION_SECRET_CB_E = -392, /* Session secret Cb fcn failure */ + NO_CHANGE_CIPHER_E = -393, /* Finished before change cipher */ + SANITY_MSG_E = -394, /* Sanity check on msg order error */ + DUPLICATE_MSG_E = -395, /* Duplicate message error */ + SNI_UNSUPPORTED = -396, /* SSL 3.0 does not support SNI */ + SOCKET_PEER_CLOSED_E = -397, /* Underlying transport closed */ + BAD_TICKET_KEY_CB_SZ = -398, /* Bad session ticket key cb size */ + BAD_TICKET_MSG_SZ = -399, /* Bad session ticket msg size */ + BAD_TICKET_ENCRYPT = -400, /* Bad user ticket encrypt */ + DH_KEY_SIZE_E = -401, /* DH Key too small */ + SNI_ABSENT_ERROR = -402, /* No SNI request. */ + RSA_SIGN_FAULT = -403, /* RSA Sign fault */ + HANDSHAKE_SIZE_ERROR = -404, /* Handshake message too large */ + UNKNOWN_ALPN_PROTOCOL_NAME_E = -405, /* Unrecognized protocol name Error*/ + BAD_CERTIFICATE_STATUS_ERROR = -406, /* Bad certificate status message */ + OCSP_INVALID_STATUS = -407, /* Invalid OCSP Status */ + OCSP_WANT_READ = -408, /* OCSP callback response WOLFSSL_CBIO_ERR_WANT_READ */ + RSA_KEY_SIZE_E = -409, /* RSA key too small */ + ECC_KEY_SIZE_E = -410, /* ECC key too small */ + DTLS_EXPORT_VER_E = -411, /* export version error */ + INPUT_SIZE_E = -412, /* input size too big error */ + CTX_INIT_MUTEX_E = -413, /* initialize ctx mutex error */ + EXT_MASTER_SECRET_NEEDED_E = -414, /* need EMS enabled to resume */ + DTLS_POOL_SZ_E = -415, /* exceeded DTLS pool size */ + DECODE_E = -416, /* decode handshake message error */ + HTTP_TIMEOUT = -417, /* HTTP timeout for OCSP or CRL req */ + WRITE_DUP_READ_E = -418, /* Write dup write side can't read */ + WRITE_DUP_WRITE_E = -419, /* Write dup read side can't write */ + INVALID_CERT_CTX_E = -420, /* TLS cert ctx not matching */ + BAD_KEY_SHARE_DATA = -421, /* Key Share data invalid */ + MISSING_HANDSHAKE_DATA = -422, /* Handshake message missing data */ + BAD_BINDER = -423, /* Binder does not match */ + EXT_NOT_ALLOWED = -424, /* Extension not allowed in msg */ + INVALID_PARAMETER = -425, /* Security parameter invalid */ + MCAST_HIGHWATER_CB_E = -426, /* Multicast highwater cb err */ + ALERT_COUNT_E = -427, /* Alert Count exceeded err */ + EXT_MISSING = -428, /* Required extension not found */ + UNSUPPORTED_EXTENSION = -429, /* TLSX not requested by client */ + PRF_MISSING = -430, /* PRF not compiled in */ + DTLS_RETX_OVER_TX = -431, /* Retransmit DTLS flight over */ + DH_PARAMS_NOT_FFDHE_E = -432, /* DH params from server not FFDHE */ + TCA_INVALID_ID_TYPE = -433, /* TLSX TCA ID type invalid */ + TCA_ABSENT_ERROR = -434, /* TLSX TCA ID no response */ + TSIP_MAC_DIGSZ_E = -435, /* Invalid MAC size for TSIP */ + CLIENT_CERT_CB_ERROR = -436, /* Client cert callback error */ + SSL_SHUTDOWN_ALREADY_DONE_E = -437, /* Shutdown called redundantly */ + + /* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */ + + /* begin negotiation parameter errors */ + UNSUPPORTED_SUITE = -500, /* unsupported cipher suite */ + MATCH_SUITE_ERROR = -501, /* can't match cipher suite */ + COMPRESSION_ERROR = -502, /* compression mismatch */ + KEY_SHARE_ERROR = -503, /* key share mismatch */ + POST_HAND_AUTH_ERROR = -504, /* client won't do post-hand auth */ + HRR_COOKIE_ERROR = -505 /* HRR msg cookie mismatch */ + /* end negotiation parameter errors only 10 for now */ + /* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */ + + /* no error stings go down here, add above negotiation errors !!!! */ +}; + + +#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA) + enum { + MIN_PARAM_ERR = UNSUPPORTED_SUITE, + MAX_PARAM_ERR = MIN_PARAM_ERR - 10 + }; +#endif + + +WOLFSSL_LOCAL +void SetErrorString(int err, char* buff); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* wolfSSL_ERROR_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/include.am b/wolfssl_hlavickove_subory/wolfssl/include.am new file mode 100644 index 0000000..201a96f --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/include.am @@ -0,0 +1,32 @@ +# vim:ft=automake +# All paths should be given relative to the root +# + +include wolfssl/wolfcrypt/include.am +include wolfssl/openssl/include.am + +EXTRA_DIST+= wolfssl/sniffer_error.rc + +nobase_include_HEADERS+= \ + wolfssl/error-ssl.h \ + wolfssl/ssl.h \ + wolfssl/sniffer_error.h \ + wolfssl/sniffer.h \ + wolfssl/callbacks.h \ + wolfssl/certs_test.h \ + wolfssl/test.h \ + wolfssl/version.h \ + wolfssl/ocsp.h \ + wolfssl/crl.h \ + wolfssl/wolfio.h + +noinst_HEADERS+= \ + wolfssl/internal.h + +# For distro build don't install options.h. +# It depends on the architecture and conflicts with Multi-Arch. +if BUILD_DISTRO +noinst_HEADERS+= wolfssl/options.h +else +nobase_include_HEADERS+= wolfssl/options.h +endif diff --git a/wolfssl_hlavickove_subory/wolfssl/internal.h b/wolfssl_hlavickove_subory/wolfssl/internal.h new file mode 100644 index 0000000..694607d --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/internal.h @@ -0,0 +1,4430 @@ +/* internal.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +#ifndef WOLFSSL_INT_H +#define WOLFSSL_INT_H + + +#include +#include +#ifdef HAVE_CRL + #include +#endif +#include +#ifndef NO_DES3 + #include +#endif +#ifndef NO_HC128 + #include +#endif +#ifndef NO_RABBIT + #include +#endif +#ifdef HAVE_CHACHA + #include +#endif +#ifndef NO_ASN + #include + #include +#endif +#ifndef NO_MD5 + #include +#endif +#ifndef NO_SHA + #include +#endif +#ifndef NO_AES + #include +#endif +#ifdef HAVE_POLY1305 + #include +#endif +#ifdef HAVE_CAMELLIA + #include +#endif +#include +#ifndef NO_HMAC + #include +#endif +#ifndef NO_RC4 + #include +#endif +#ifndef NO_SHA256 + #include +#endif +#ifdef HAVE_OCSP + #include +#endif +#ifdef WOLFSSL_SHA384 + #include +#endif +#ifdef WOLFSSL_SHA512 + #include +#endif +#ifdef HAVE_AESGCM + #include +#endif +#ifdef WOLFSSL_RIPEMD + #include +#endif +#ifdef HAVE_IDEA + #include +#endif +#ifndef NO_RSA + #include +#endif +#ifdef HAVE_ECC + #include +#endif +#ifndef NO_DH + #include +#endif +#ifdef HAVE_ED25519 + #include +#endif +#ifdef HAVE_CURVE25519 + #include +#endif + +#include +#include + +#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA) + #include +#endif +#ifdef WOLFSSL_CALLBACKS + #include +#endif + +#ifdef USE_WINDOWS_API + #ifdef WOLFSSL_GAME_BUILD + #include "system/xtl.h" + #else + #if defined(_WIN32_WCE) || defined(WIN32_LEAN_AND_MEAN) + /* On WinCE winsock2.h must be included before windows.h */ + #include + #endif + #include + #endif +#elif defined(THREADX) + #ifndef SINGLE_THREADED + #include "tx_api.h" + #endif + +#elif defined(WOLFSSL_DEOS) + /* do nothing, just don't pick Unix */ +#elif defined(MICRIUM) + /* do nothing, just don't pick Unix */ +#elif defined(FREERTOS) || defined(FREERTOS_TCP) || defined(WOLFSSL_SAFERTOS) + /* do nothing */ +#elif defined(EBSNET) + /* do nothing */ +#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) + /* do nothing */ +#elif defined(FREESCALE_FREE_RTOS) + #include "fsl_os_abstraction.h" +#elif defined(WOLFSSL_uITRON4) + /* do nothing */ +#elif defined(WOLFSSL_uTKERNEL2) + /* do nothing */ +#elif defined(WOLFSSL_CMSIS_RTOS) + #include "cmsis_os.h" +#elif defined(WOLFSSL_CMSIS_RTOSv2) + #include "cmsis_os2.h" +#elif defined(WOLFSSL_MDK_ARM) + #if defined(WOLFSSL_MDK5) + #include "cmsis_os.h" + #else + #include + #endif +#elif defined(MBED) +#elif defined(WOLFSSL_TIRTOS) + /* do nothing */ +#elif defined(INTIME_RTOS) + #include +#elif defined(WOLFSSL_NUCLEUS_1_2) + /* do nothing */ +#elif defined(WOLFSSL_APACHE_MYNEWT) + #if !defined(WOLFSSL_LWIP) + void mynewt_ctx_clear(void *ctx); + void* mynewt_ctx_new(); + #endif +#elif defined(WOLFSSL_ZEPHYR) + #ifndef SINGLE_THREADED + #include + #endif +#elif defined(WOLFSSL_TELIT_M2MB) + /* do nothing */ +#else + #ifndef SINGLE_THREADED + #define WOLFSSL_PTHREADS + #include + #endif + #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) + #include /* for close of BIO */ + #endif +#endif + +#ifndef CHAR_BIT + /* Needed for DTLS without big math */ + #include +#endif + + +#ifdef HAVE_LIBZ + #include "zlib.h" +#endif + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif + +#ifdef OPENSSL_EXTRA + #ifdef WOLFCRYPT_HAVE_SRP + #include + #endif +#endif + +#ifdef _MSC_VER + /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */ + #pragma warning(disable: 4996) +#endif + +#ifdef NO_SHA + #define WC_SHA_DIGEST_SIZE 20 +#endif + +#ifdef NO_SHA256 + #define WC_SHA256_DIGEST_SIZE 32 +#endif + +#ifdef NO_MD5 + #define WC_MD5_DIGEST_SIZE 16 +#endif + + +#ifdef __cplusplus + extern "C" { +#endif + +/* Define or comment out the cipher suites you'd like to be compiled in + make sure to use at least one BUILD_SSL_xxx or BUILD_TLS_xxx is defined + + When adding cipher suites, add name to cipher_names, idx to cipher_name_idx + + Now that there is a maximum strength crypto build, the following BUILD_XXX + flags need to be divided into two groups selected by WOLFSSL_MAX_STRENGTH. + Those that do not use Perfect Forward Security and do not use AEAD ciphers + need to be switched off. Allowed suites use (EC)DHE, AES-GCM|CCM, or + CHACHA-POLY. +*/ + +/* Check that if WOLFSSL_MAX_STRENGTH is set that all the required options are + * not turned off. */ +#if defined(WOLFSSL_MAX_STRENGTH) && \ + ((!defined(HAVE_ECC) && (defined(NO_DH) || defined(NO_RSA))) || \ + (!defined(HAVE_AESGCM) && !defined(HAVE_AESCCM) && \ + (!defined(HAVE_POLY1305) || !defined(HAVE_CHACHA))) || \ + (defined(NO_SHA256) && !defined(WOLFSSL_SHA384)) || \ + !defined(NO_OLD_TLS)) + + #error "You are trying to build max strength with requirements disabled." +#endif + +/* Have QSH : Quantum-safe Handshake */ +#if defined(HAVE_QSH) + #define BUILD_TLS_QSH +#endif + +#ifndef WOLFSSL_NO_TLS12 + +#ifndef WOLFSSL_MAX_STRENGTH + +#ifdef WOLFSSL_AEAD_ONLY + /* AES CBC ciphers are not allowed in AEAD only mode */ + #undef HAVE_AES_CBC +#endif + +#ifndef WOLFSSL_AEAD_ONLY + #if !defined(NO_RSA) && !defined(NO_RC4) + #if defined(WOLFSSL_STATIC_RSA) + #if !defined(NO_SHA) + #define BUILD_SSL_RSA_WITH_RC4_128_SHA + #endif + #if !defined(NO_MD5) + #define BUILD_SSL_RSA_WITH_RC4_128_MD5 + #endif + #endif + #if !defined(NO_TLS) && defined(HAVE_NTRU) && !defined(NO_SHA) \ + && defined(WOLFSSL_STATIC_RSA) + #define BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA + #endif + #endif + + #if !defined(NO_RSA) && !defined(NO_DES3) + #if !defined(NO_SHA) + #if defined(WOLFSSL_STATIC_RSA) + #define BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA + #endif + #if !defined(NO_TLS) && defined(HAVE_NTRU) \ + && defined(WOLFSSL_STATIC_RSA) + #define BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA + #endif + #endif + #endif + + #if !defined(NO_RSA) && defined(HAVE_IDEA) + #if !defined(NO_SHA) && defined(WOLFSSL_STATIC_RSA) + #define BUILD_SSL_RSA_WITH_IDEA_CBC_SHA + #endif + #endif +#endif /* !WOLFSSL_AEAD_ONLY */ + + #if !defined(NO_RSA) && !defined(NO_AES) && !defined(NO_TLS) + #if !defined(NO_SHA) && defined(HAVE_AES_CBC) + #if defined(WOLFSSL_STATIC_RSA) + #ifdef WOLFSSL_AES_128 + #define BUILD_TLS_RSA_WITH_AES_128_CBC_SHA + #endif + #ifdef WOLFSSL_AES_256 + #define BUILD_TLS_RSA_WITH_AES_256_CBC_SHA + #endif + #endif + #if defined(HAVE_NTRU) && defined(WOLFSSL_STATIC_RSA) + #ifdef WOLFSSL_AES_128 + #define BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA + #endif + #ifdef WOLFSSL_AES_256 + #define BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA + #endif + #endif + #endif + #if defined(WOLFSSL_STATIC_RSA) + #if !defined (NO_SHA256) && defined(HAVE_AES_CBC) + #ifdef WOLFSSL_AES_128 + #define BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256 + #endif + #ifdef WOLFSSL_AES_256 + #define BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256 + #endif + #endif + #if defined (HAVE_AESGCM) + #ifdef WOLFSSL_AES_128 + #define BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256 + #endif + #if defined (WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) + #define BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384 + #endif + #endif + #if defined (HAVE_AESCCM) + #ifdef WOLFSSL_AES_128 + #define BUILD_TLS_RSA_WITH_AES_128_CCM_8 + #endif + #ifdef WOLFSSL_AES_256 + #define BUILD_TLS_RSA_WITH_AES_256_CCM_8 + #endif + #endif + #endif + #endif + + #if defined(HAVE_CAMELLIA) && !defined(NO_TLS) && !defined(NO_CAMELLIA_CBC) + #ifndef NO_RSA + #if defined(WOLFSSL_STATIC_RSA) + #if !defined(NO_SHA) + #define BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + #define BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + #endif + #ifndef NO_SHA256 + #define BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + #define BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + #endif + #endif + #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 + #endif + #ifndef NO_SHA256 + #define BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + #define BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + #endif + #endif + #endif + #endif + +#if defined(WOLFSSL_STATIC_PSK) + #if !defined(NO_PSK) && !defined(NO_AES) && !defined(NO_TLS) + #if !defined(NO_SHA) + #ifdef WOLFSSL_AES_128 + #define BUILD_TLS_PSK_WITH_AES_128_CBC_SHA + #endif + #ifdef WOLFSSL_AES_256 + #define BUILD_TLS_PSK_WITH_AES_256_CBC_SHA + #endif + #endif + #ifndef NO_SHA256 + #ifdef WOLFSSL_AES_128 + #ifdef HAVE_AES_CBC + #define BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256 + #endif + #ifdef HAVE_AESGCM + #define BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256 + #endif + #endif /* WOLFSSL_AES_128 */ + #ifdef HAVE_AESCCM + #ifdef WOLFSSL_AES_128 + #define BUILD_TLS_PSK_WITH_AES_128_CCM_8 + #define BUILD_TLS_PSK_WITH_AES_128_CCM + #endif + #ifdef WOLFSSL_AES_256 + #define BUILD_TLS_PSK_WITH_AES_256_CCM_8 + #define BUILD_TLS_PSK_WITH_AES_256_CCM + #endif + #endif + #endif + #if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) + #ifdef HAVE_AES_CBC + #define BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384 + #endif + #ifdef HAVE_AESGCM + #define BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384 + #endif + #endif + #endif +#endif + + #if !defined(NO_TLS) && defined(HAVE_NULL_CIPHER) + #if !defined(NO_RSA) + #if defined(WOLFSSL_STATIC_RSA) + #ifndef NO_MD5 + #define BUILD_TLS_RSA_WITH_NULL_MD5 + #endif + #if !defined(NO_SHA) + #define BUILD_TLS_RSA_WITH_NULL_SHA + #endif + #ifndef NO_SHA256 + #define BUILD_TLS_RSA_WITH_NULL_SHA256 + #endif + #endif + #endif + #if !defined(NO_PSK) && defined(WOLFSSL_STATIC_PSK) + #if !defined(NO_SHA) + #define BUILD_TLS_PSK_WITH_NULL_SHA + #endif + #ifndef NO_SHA256 + #define BUILD_TLS_PSK_WITH_NULL_SHA256 + #endif + #ifdef WOLFSSL_SHA384 + #define BUILD_TLS_PSK_WITH_NULL_SHA384 + #endif + #endif + #endif + +#if defined(WOLFSSL_STATIC_RSA) + #if !defined(NO_HC128) && !defined(NO_RSA) && !defined(NO_TLS) + #ifndef NO_MD5 + #define BUILD_TLS_RSA_WITH_HC_128_MD5 + #endif + #if !defined(NO_SHA) + #define BUILD_TLS_RSA_WITH_HC_128_SHA + #endif + #endif + + #if !defined(NO_RABBIT) && !defined(NO_TLS) && !defined(NO_RSA) + #if !defined(NO_SHA) + #define BUILD_TLS_RSA_WITH_RABBIT_SHA + #endif + #endif +#endif + + #if !defined(NO_DH) && !defined(NO_AES) && !defined(NO_TLS) && \ + !defined(NO_RSA) + + #if !defined(NO_SHA) + #if defined(WOLFSSL_AES_128) && defined(HAVE_AES_CBC) + #define BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA + #endif + #if defined(WOLFSSL_AES_256) && defined(HAVE_AES_CBC) + #define BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA + #endif + #if !defined(NO_DES3) + #define BUILD_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + #endif + #endif + #if !defined(NO_SHA256) && defined(HAVE_AES_CBC) + #ifdef WOLFSSL_AES_128 + #define BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + #endif + #ifdef WOLFSSL_AES_256 + #define BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + #endif + #endif + #endif + + #if defined(HAVE_ANON) && !defined(NO_TLS) && !defined(NO_DH) && \ + !defined(NO_AES) && !defined(NO_SHA) && defined(WOLFSSL_AES_128) + #ifdef HAVE_AES_CBC + #define BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA + #endif + + #if defined(WOLFSSL_SHA384) && defined(HAVE_AESGCM) + #define BUILD_TLS_DH_anon_WITH_AES_256_GCM_SHA384 + #endif + #endif + + #if !defined(NO_DH) && !defined(NO_PSK) && !defined(NO_TLS) + #ifndef NO_SHA256 + #if !defined(NO_AES) && defined(WOLFSSL_AES_128) && \ + defined(HAVE_AES_CBC) + #define BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + #endif + #ifdef HAVE_NULL_CIPHER + #define BUILD_TLS_DHE_PSK_WITH_NULL_SHA256 + #endif + #endif + #ifdef WOLFSSL_SHA384 + #if !defined(NO_AES) && defined(WOLFSSL_AES_256) && \ + defined(HAVE_AES_CBC) + #define BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + #endif + #ifdef HAVE_NULL_CIPHER + #define BUILD_TLS_DHE_PSK_WITH_NULL_SHA384 + #endif + #endif + #endif + + #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && !defined(NO_TLS) + #if !defined(NO_AES) + #if !defined(NO_SHA) && defined(HAVE_AES_CBC) + #if !defined(NO_RSA) + #ifdef WOLFSSL_AES_128 + #define BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + #endif + #ifdef WOLFSSL_AES_256 + #define BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + #endif + #if defined(WOLFSSL_STATIC_DH) && defined(HAVE_ECC) + #ifdef WOLFSSL_AES_128 + #define BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + #endif + #ifdef WOLFSSL_AES_256 + #define BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + #endif + #endif + #endif + + #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ + defined(HAVE_ED25519)) + #ifdef WOLFSSL_AES_128 + #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + #endif + #ifdef WOLFSSL_AES_256 + #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + #endif + #endif + + #if defined(WOLFSSL_STATIC_DH) && defined(HAVE_ECC) + #ifdef WOLFSSL_AES_128 + #define BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + #endif + #ifdef WOLFSSL_AES_256 + #define BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + #endif + #endif + #endif /* NO_SHA */ + #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128) && \ + defined(HAVE_AES_CBC) + #if !defined(NO_RSA) + #define BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + #if defined(WOLFSSL_STATIC_DH) && defined(HAVE_ECC) + #define BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + #endif + #endif + #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ + defined(HAVE_ED25519)) + #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + #endif + #if defined(WOLFSSL_STATIC_DH) && defined(HAVE_ECC) + #define BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + #endif + #endif + + #if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) && \ + defined(HAVE_AES_CBC) + #if !defined(NO_RSA) + #define BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + #if defined(WOLFSSL_STATIC_DH) && defined(HAVE_ECC) + #define BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + #endif + #endif + #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ + defined(HAVE_ED25519)) + #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + #endif + #if defined(WOLFSSL_STATIC_DH) && defined(HAVE_ECC) + #define BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + #endif + #endif + + #if defined (HAVE_AESGCM) + #if !defined(NO_RSA) + #if defined(WOLFSSL_STATIC_DH) && defined(HAVE_ECC) + #ifdef WOLFSSL_AES_128 + #define BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + #endif + #endif + #if defined(WOLFSSL_SHA384) + #if defined(WOLFSSL_STATIC_DH) && defined(HAVE_ECC) + #ifdef WOLFSSL_AES_256 + #define BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + #endif + #endif + #endif + #endif + + #if defined(WOLFSSL_STATIC_DH) && defined(WOLFSSL_AES_128) && \ + defined(HAVE_ECC) + #define BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + #endif + + #if defined(WOLFSSL_SHA384) + #if defined(WOLFSSL_STATIC_DH) && \ + defined(WOLFSSL_AES_256) && defined(HAVE_ECC) + #define BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + #endif + #endif + #endif + #endif /* NO_AES */ + #if !defined(NO_RC4) + #if !defined(NO_SHA) + #if !defined(NO_RSA) + #define BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA + #if defined(WOLFSSL_STATIC_DH) && defined(HAVE_ECC) + #define BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA + #endif + #endif + + #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ + defined(HAVE_ED25519)) + #define BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + #endif + #if defined(WOLFSSL_STATIC_DH) && defined(HAVE_ECC) + #define BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA + #endif + #endif + #endif + #if !defined(NO_DES3) + #ifndef NO_SHA + #if !defined(NO_RSA) + #define BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + #if defined(WOLFSSL_STATIC_DH) && defined(HAVE_ECC) + #define BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + #endif + #endif + + #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ + defined(HAVE_ED25519)) + #define BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + #endif + #if defined(WOLFSSL_STATIC_DH) && defined(HAVE_ECC) + #define BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + #endif + #endif /* NO_SHA */ + #endif + #if defined(HAVE_NULL_CIPHER) + #if !defined(NO_SHA) + #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ + defined(HAVE_ED25519)) + #define BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA + #endif + #endif + #if !defined(NO_PSK) && !defined(NO_SHA256) + #define BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256 + #endif + #endif + #if !defined(NO_PSK) && !defined(NO_SHA256) && !defined(NO_AES) && \ + defined(WOLFSSL_AES_128) && defined(HAVE_AES_CBC) + #define BUILD_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + #endif + #endif + #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && !defined(NO_SHA256) + #if !defined(NO_OLD_POLY1305) + #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ + defined(HAVE_ED25519)) + #define BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + #endif + #if !defined(NO_RSA) && defined(HAVE_ECC) + #define BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + #endif + #if !defined(NO_DH) && !defined(NO_RSA) + #define BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + #endif + #endif /* NO_OLD_POLY1305 */ + #if !defined(NO_PSK) + #define BUILD_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 + #if defined(HAVE_ECC) || defined(HAVE_ED25519) + #define BUILD_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 + #endif + #ifndef NO_DH + #define BUILD_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 + #endif + #endif /* !NO_PSK */ + #endif + +#endif /* !WOLFSSL_MAX_STRENGTH */ + +#if !defined(NO_DH) && !defined(NO_AES) && !defined(NO_TLS) && \ + !defined(NO_RSA) && defined(HAVE_AESGCM) + + #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128) + #define BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + #endif + + #if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) + #define BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + #endif +#endif + +#if !defined(NO_DH) && !defined(NO_PSK) && !defined(NO_TLS) + #ifndef NO_SHA256 + #if defined(HAVE_AESGCM) && defined(WOLFSSL_AES_128) + #define BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + #endif + #ifdef HAVE_AESCCM + #ifdef WOLFSSL_AES_128 + #define BUILD_TLS_DHE_PSK_WITH_AES_128_CCM + #endif + #ifdef WOLFSSL_AES_256 + #define BUILD_TLS_DHE_PSK_WITH_AES_256_CCM + #endif + #endif + #endif + #if defined(WOLFSSL_SHA384) && defined(HAVE_AESGCM) && \ + defined(WOLFSSL_AES_256) + #define BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + #endif +#endif + +#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && !defined(NO_TLS) && \ + !defined(NO_AES) + #ifdef HAVE_AESGCM + #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128) + #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ + defined(HAVE_ED25519)) + #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + #endif + #ifndef NO_RSA + #define BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + #endif + #endif + #if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) + #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ + defined(HAVE_ED25519)) + #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + #endif + #ifndef NO_RSA + #define BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + #endif + #endif + #endif + #if defined(HAVE_AESCCM) && !defined(NO_SHA256) + #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ + defined(HAVE_ED25519)) + #ifdef WOLFSSL_AES_128 + #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM + #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 + #endif + #ifdef WOLFSSL_AES_256 + #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 + #endif + #endif + #endif +#endif + +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && !defined(NO_SHA256) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ + defined(HAVE_ED25519)) + #define BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + #endif + #ifndef NO_RSA + #define BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + #endif + #endif + #if !defined(NO_DH) && !defined(NO_RSA) + #define BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + #endif +#endif + +#endif + +#if defined(WOLFSSL_TLS13) + #ifdef HAVE_AESGCM + #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128) + #define BUILD_TLS_AES_128_GCM_SHA256 + #endif + #if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) + #define BUILD_TLS_AES_256_GCM_SHA384 + #endif + #endif + + #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + #ifndef NO_SHA256 + #define BUILD_TLS_CHACHA20_POLY1305_SHA256 + #endif + #endif + + #ifdef HAVE_AESCCM + #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128) + #define BUILD_TLS_AES_128_CCM_SHA256 + #define BUILD_TLS_AES_128_CCM_8_SHA256 + #endif + #endif + #ifdef HAVE_NULL_CIPHER + #ifndef NO_SHA256 + #define BUILD_TLS_SHA256_SHA256 + #endif + #ifdef WOLFSSL_SHA384 + #define BUILD_TLS_SHA384_SHA384 + #endif + #endif +#endif + +#ifdef WOLFSSL_MULTICAST + #if defined(HAVE_NULL_CIPHER) && !defined(NO_SHA256) + #define BUILD_WDM_WITH_NULL_SHA256 + #endif +#endif + +#if defined(BUILD_SSL_RSA_WITH_RC4_128_SHA) || \ + defined(BUILD_SSL_RSA_WITH_RC4_128_MD5) + #define BUILD_ARC4 +#endif + +#if defined(BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA) + #define BUILD_DES3 +#endif + +#if defined(BUILD_TLS_RSA_WITH_AES_128_CBC_SHA) || \ + defined(BUILD_TLS_RSA_WITH_AES_256_CBC_SHA) || \ + defined(BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256) || \ + defined(BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256) + #undef BUILD_AES + #define BUILD_AES +#endif + +#if defined(BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256) || \ + defined(BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256) || \ + defined(BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) || \ + defined(BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256) || \ + defined(BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256) || \ + defined(BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384) || \ + defined(BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384) || \ + defined(BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) || \ + defined(BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384) || \ + defined(BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384) || \ + defined(BUILD_TLS_AES_128_GCM_SHA256) || \ + defined(BUILD_TLS_AES_256_GCM_SHA384) + #define BUILD_AESGCM +#else + /* No AES-GCM cipher suites available with build */ + #define NO_AESGCM_AEAD +#endif + +#if defined(BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256) || \ + defined(BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256) || \ + defined(BUILD_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256) || \ + defined(BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256) || \ + defined(BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256) || \ + defined(BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256) || \ + defined(BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256) || \ + defined(BUILD_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256) || \ + defined(BUILD_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256) || \ + defined(BUILD_TLS_CHACHA20_POLY1305_SHA256) + /* Have an available ChaCha Poly cipher suite */ +#else + /* No ChaCha Poly cipher suites available with build */ + #define NO_CHAPOL_AEAD +#endif + +#if defined(BUILD_TLS_RSA_WITH_HC_128_SHA) || \ + defined(BUILD_TLS_RSA_WITH_HC_128_MD5) + #define BUILD_HC128 +#endif + +#if defined(BUILD_TLS_RSA_WITH_RABBIT_SHA) + #define BUILD_RABBIT +#endif + +#ifdef NO_DES3 + #define DES_BLOCK_SIZE 8 +#else + #undef BUILD_DES3 + #define BUILD_DES3 +#endif + +#if defined(NO_AES) || defined(NO_AES_DECRYPT) + #define AES_BLOCK_SIZE 16 + #undef BUILD_AES +#else + #undef BUILD_AES + #define BUILD_AES +#endif + +#ifndef NO_RC4 + #undef BUILD_ARC4 + #define BUILD_ARC4 +#endif + +#ifdef HAVE_CHACHA + #define CHACHA20_BLOCK_SIZE 16 +#endif + +#if defined(WOLFSSL_MAX_STRENGTH) || \ + (defined(HAVE_AESGCM) && !defined(NO_AESGCM_AEAD)) || \ + defined(HAVE_AESCCM) || \ + (defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && \ + !defined(NO_CHAPOL_AEAD)) || \ + (defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER)) + + #define HAVE_AEAD +#endif + +#if defined(WOLFSSL_MAX_STRENGTH) || \ + defined(HAVE_ECC) || !defined(NO_DH) + + #define HAVE_PFS +#endif + +#if defined(BUILD_SSL_RSA_WITH_IDEA_CBC_SHA) + #define BUILD_IDEA +#endif + +/* actual cipher values, 2nd byte */ +enum { + TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x16, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x39, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x33, + TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x34, + TLS_RSA_WITH_AES_256_CBC_SHA = 0x35, + TLS_RSA_WITH_AES_128_CBC_SHA = 0x2F, + TLS_RSA_WITH_NULL_MD5 = 0x01, + 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, + SSL_RSA_WITH_3DES_EDE_CBC_SHA = 0x0A, + SSL_RSA_WITH_IDEA_CBC_SHA = 0x07, + + /* ECC suites, first byte is 0xC0 (ECC_BYTE) */ + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0x14, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0x13, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0x0A, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0x09, + TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0x11, + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = 0x07, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x12, + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0x08, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0x27, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0x23, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0x28, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0x24, + TLS_ECDHE_ECDSA_WITH_NULL_SHA = 0x06, + TLS_ECDHE_PSK_WITH_NULL_SHA256 = 0x3a, + TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 = 0x37, + + /* static ECDH, first byte is 0xC0 (ECC_BYTE) */ + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0x0F, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = 0x0E, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0x05, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0x04, + TLS_ECDH_RSA_WITH_RC4_128_SHA = 0x0C, + TLS_ECDH_ECDSA_WITH_RC4_128_SHA = 0x02, + TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = 0x0D, + TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0x03, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 = 0x29, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 = 0x25, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 = 0x2A, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0x26, + + /* wolfSSL extension - eSTREAM */ + TLS_RSA_WITH_HC_128_MD5 = 0xFB, + TLS_RSA_WITH_HC_128_SHA = 0xFC, + TLS_RSA_WITH_RABBIT_SHA = 0xFD, + WDM_WITH_NULL_SHA256 = 0xFE, /* wolfSSL DTLS Multicast */ + + /* wolfSSL 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, /* clashes w/official SHA-256 */ + TLS_NTRU_RSA_WITH_AES_256_CBC_SHA = 0xe8, + + /* wolfSSL extension - NTRU , Quantum-safe Handshake + first byte is 0xD0 (QSH_BYTE) */ + TLS_QSH = 0x01, + + /* SHA256 */ + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x6b, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x67, + 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_DH_anon_WITH_AES_256_GCM_SHA384 = 0xa7, + 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, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0x2c, + TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 0x2d, + TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = 0x2e, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0x2f, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0x30, + TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0x31, + TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0x32, + + /* AES-CCM, first byte is 0xC0 but isn't ECC, + * also, in some of the other AES-CCM suites + * there will be second byte number conflicts + * with non-ECC AES-GCM */ + TLS_RSA_WITH_AES_128_CCM_8 = 0xa0, + TLS_RSA_WITH_AES_256_CCM_8 = 0xa1, + TLS_ECDHE_ECDSA_WITH_AES_128_CCM = 0xac, + TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xae, + TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 = 0xaf, + TLS_PSK_WITH_AES_128_CCM = 0xa4, + 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, + TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0xc0, + TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x45, + TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x88, + TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xbe, + TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0xc4, + + /* chacha20-poly1305 suites first byte is 0xCC (CHACHA_BYTE) */ + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xa8, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xa9, + TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xaa, + TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xac, + TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xab, + TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xad, + + /* chacha20-poly1305 earlier version of nonce and padding (CHACHA_BYTE) */ + TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 = 0x13, + TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 = 0x14, + TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 = 0x15, + + /* TLS v1.3 cipher suites */ + TLS_AES_128_GCM_SHA256 = 0x01, + TLS_AES_256_GCM_SHA384 = 0x02, + TLS_CHACHA20_POLY1305_SHA256 = 0x03, + TLS_AES_128_CCM_SHA256 = 0x04, + TLS_AES_128_CCM_8_SHA256 = 0x05, + + /* TLS v1.3 Integity only cipher suites - 0xC0 (ECC) first byte */ + TLS_SHA256_SHA256 = 0xB4, + TLS_SHA384_SHA384 = 0xB5, + + /* Fallback SCSV (Signaling Cipher Suite Value) */ + TLS_FALLBACK_SCSV = 0x56, + /* Renegotiation Indication Extension Special Suite */ + TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0xff +}; + + +#ifndef WOLFSSL_SESSION_TIMEOUT + #define WOLFSSL_SESSION_TIMEOUT 500 + /* default session resumption cache timeout in seconds */ +#endif + + +#ifndef WOLFSSL_DTLS_WINDOW_WORDS + #define WOLFSSL_DTLS_WINDOW_WORDS 2 +#endif /* WOLFSSL_DTLS_WINDOW_WORDS */ +#define DTLS_WORD_BITS (sizeof(word32) * CHAR_BIT) +#define DTLS_SEQ_BITS (WOLFSSL_DTLS_WINDOW_WORDS * DTLS_WORD_BITS) +#define DTLS_SEQ_SZ (sizeof(word32) * WOLFSSL_DTLS_WINDOW_WORDS) + +#ifndef WOLFSSL_MULTICAST + #define WOLFSSL_DTLS_PEERSEQ_SZ 1 +#else + #ifndef WOLFSSL_MULTICAST_PEERS + /* max allowed multicast group peers */ + #define WOLFSSL_MULTICAST_PEERS 100 + #endif + #define WOLFSSL_DTLS_PEERSEQ_SZ WOLFSSL_MULTICAST_PEERS +#endif /* WOLFSSL_MULTICAST */ + +#ifndef WOLFSSL_MAX_MTU + #define WOLFSSL_MAX_MTU 1500 +#endif /* WOLFSSL_MAX_MTU */ + + +/* set minimum DH key size allowed */ +#ifndef WOLFSSL_MIN_DHKEY_BITS + #ifdef WOLFSSL_MAX_STRENGTH + #define WOLFSSL_MIN_DHKEY_BITS 2048 + #else + #define WOLFSSL_MIN_DHKEY_BITS 1024 + #endif +#endif +#if (WOLFSSL_MIN_DHKEY_BITS % 8) + #error DH minimum bit size must be multiple of 8 +#endif +#if (WOLFSSL_MIN_DHKEY_BITS > 16000) + #error DH minimum bit size must not be greater than 16000 +#endif +#define MIN_DHKEY_SZ (WOLFSSL_MIN_DHKEY_BITS / 8) +/* set maximum DH key size allowed */ +#ifndef WOLFSSL_MAX_DHKEY_BITS + #if (defined(USE_FAST_MATH) && defined(FP_MAX_BITS) && FP_MAX_BITS >= 16384) + #define WOLFSSL_MAX_DHKEY_BITS 8192 + #else + #define WOLFSSL_MAX_DHKEY_BITS 4096 + #endif +#endif +#if (WOLFSSL_MAX_DHKEY_BITS % 8) + #error DH maximum bit size must be multiple of 8 +#endif +#if (WOLFSSL_MAX_DHKEY_BITS > 16000) + #error DH maximum bit size must not be greater than 16000 +#endif +#define MAX_DHKEY_SZ (WOLFSSL_MAX_DHKEY_BITS / 8) + +#ifndef MAX_PSK_ID_LEN + /* max psk identity/hint supported */ + #if defined(WOLFSSL_TLS13) + #define MAX_PSK_ID_LEN 256 + #else + #define MAX_PSK_ID_LEN 128 + #endif +#endif + +#ifndef MAX_EARLY_DATA_SZ + /* maximum early data size */ + #define MAX_EARLY_DATA_SZ 4096 +#endif + +enum Misc { + CIPHER_BYTE = 0x00, /* Default ciphers */ + ECC_BYTE = 0xC0, /* ECC first cipher suite byte */ + QSH_BYTE = 0xD0, /* Quantum-safe Handshake cipher suite */ + CHACHA_BYTE = 0xCC, /* ChaCha first cipher suite */ + TLS13_BYTE = 0x13, /* TLS v1.3 first byte of cipher suite */ + + SEND_CERT = 1, + SEND_BLANK_CERT = 2, + + DTLS_MAJOR = 0xfe, /* DTLS major version number */ + DTLS_MINOR = 0xff, /* DTLS minor version number */ + DTLSv1_2_MINOR = 0xfd, /* DTLS minor version number */ + SSLv3_MAJOR = 3, /* SSLv3 and TLSv1+ major version number */ + SSLv3_MINOR = 0, /* TLSv1 minor version number */ + TLSv1_MINOR = 1, /* TLSv1 minor version number */ + TLSv1_1_MINOR = 2, /* TLSv1_1 minor version number */ + TLSv1_2_MINOR = 3, /* TLSv1_2 minor version number */ + TLSv1_3_MINOR = 4, /* TLSv1_3 minor version number */ + TLS_DRAFT_MAJOR = 0x7f, /* Draft TLS major version number */ +#ifdef WOLFSSL_TLS13_DRAFT +#ifdef WOLFSSL_TLS13_DRAFT_18 + TLS_DRAFT_MINOR = 0x12, /* Minor version number of TLS draft */ +#elif defined(WOLFSSL_TLS13_DRAFT_22) + TLS_DRAFT_MINOR = 0x16, /* Minor version number of TLS draft */ +#elif defined(WOLFSSL_TLS13_DRAFT_23) + TLS_DRAFT_MINOR = 0x17, /* Minor version number of TLS draft */ +#elif defined(WOLFSSL_TLS13_DRAFT_26) + TLS_DRAFT_MINOR = 0x1a, /* Minor version number of TLS draft */ +#else + TLS_DRAFT_MINOR = 0x1c, /* Minor version number of TLS draft */ +#endif +#endif + OLD_HELLO_ID = 0x01, /* SSLv2 Client Hello Indicator */ + INVALID_BYTE = 0xff, /* Used to initialize cipher specs values */ + NO_COMPRESSION = 0, + ZLIB_COMPRESSION = 221, /* wolfSSL zlib compression */ + HELLO_EXT_SIG_ALGO = 13, /* ID for the sig_algo hello extension */ + HELLO_EXT_EXTMS = 0x0017, /* ID for the extended master secret ext */ + SECRET_LEN = WOLFSSL_MAX_MASTER_KEY_LENGTH, + /* pre RSA and all master */ +#if defined(WOLFSSL_MYSQL_COMPATIBLE) || \ + (defined(USE_FAST_MATH) && defined(FP_MAX_BITS) && FP_MAX_BITS > 8192) +#ifndef NO_PSK + ENCRYPT_LEN = 1024 + MAX_PSK_ID_LEN + 2, /* 8192 bit static buffer */ +#else + ENCRYPT_LEN = 1024, /* allow 8192 bit static buffer */ +#endif +#else +#ifndef NO_PSK + ENCRYPT_LEN = 512 + MAX_PSK_ID_LEN + 2, /* 4096 bit static buffer */ +#else + ENCRYPT_LEN = 512, /* allow 4096 bit static buffer */ +#endif +#endif + SIZEOF_SENDER = 4, /* clnt or srvr */ + FINISHED_SZ = 36, /* WC_MD5_DIGEST_SIZE + WC_SHA_DIGEST_SIZE */ + MAX_RECORD_SIZE = 16384, /* 2^14, max size by standard */ + MAX_PLAINTEXT_SZ = (1 << 14), /* Max plaintext sz */ + MAX_TLS_CIPHER_SZ = (1 << 14) + 2048, /* Max TLS encrypted data sz */ +#ifdef WOLFSSL_TLS13 + MAX_TLS13_PLAIN_SZ = (1 << 14) + 1, /* Max unencrypted data sz */ + MAX_TLS13_ENC_SZ = (1 << 14) + 256, /* Max encrypted data sz */ +#endif + MAX_MSG_EXTRA = 38 + WC_MAX_DIGEST_SIZE, + /* max added to msg, mac + pad from */ + /* RECORD_HEADER_SZ + BLOCK_SZ (pad) + Max + digest sz + BLOC_SZ (iv) + pad byte (1) */ + MAX_COMP_EXTRA = 1024, /* max compression extra */ + MAX_MTU = WOLFSSL_MAX_MTU, /* max expected MTU */ + MAX_UDP_SIZE = 8192 - 100, /* was MAX_MTU - 100 */ + MAX_DH_SZ = (MAX_DHKEY_SZ * 3) + 12, /* DH_P, DH_G and DH_Pub */ + /* 4096 p, pub, g + 2 byte size for each */ + MAX_STR_VERSION = 8, /* string rep of protocol version */ + + PAD_MD5 = 48, /* pad length for finished */ + PAD_SHA = 40, /* pad length for finished */ + MAX_PAD_SIZE = 256, /* maximum length of padding */ + + LENGTH_SZ = 2, /* length field for HMAC, data only */ + VERSION_SZ = 2, /* length of proctocol version */ + SEQ_SZ = 8, /* 64 bit sequence number */ + ALERT_SIZE = 2, /* level + description */ + VERIFY_HEADER = 2, /* always use 2 bytes */ + EXTS_SZ = 2, /* always use 2 bytes */ + EXT_ID_SZ = 2, /* always use 2 bytes */ + MAX_DH_SIZE = MAX_DHKEY_SZ+1, + /* Max size plus possible leading 0 */ + NAMED_DH_MASK = 0x100, /* Named group mask for DH parameters */ + MIN_FFHDE_GROUP = 0x100, /* Named group minimum for FFDHE parameters */ + MAX_FFHDE_GROUP = 0x1FF, /* Named group maximum for FFDHE parameters */ + SESSION_HINT_SZ = 4, /* session timeout hint */ + SESSION_ADD_SZ = 4, /* session age add */ + TICKET_NONCE_LEN_SZ = 1, /* Ticket nonce length size */ + DEF_TICKET_NONCE_SZ = 1, /* Default ticket nonce size */ + MAX_TICKET_NONCE_SZ = 8, /* maximum ticket nonce size */ + MAX_LIFETIME = 604800, /* maximum ticket lifetime */ + + RAN_LEN = 32, /* random length */ + SEED_LEN = RAN_LEN * 2, /* tls prf seed length */ + ID_LEN = 32, /* session id length */ + COOKIE_SECRET_SZ = 14, /* dtls cookie secret size */ + MAX_COOKIE_LEN = 32, /* max dtls cookie size */ + COOKIE_SZ = 20, /* use a 20 byte cookie */ + SUITE_LEN = 2, /* cipher suite sz length */ + ENUM_LEN = 1, /* always a byte */ + OPAQUE8_LEN = 1, /* 1 byte */ + OPAQUE16_LEN = 2, /* 2 bytes */ + OPAQUE24_LEN = 3, /* 3 bytes */ + OPAQUE32_LEN = 4, /* 4 bytes */ + OPAQUE64_LEN = 8, /* 8 bytes */ + COMP_LEN = 1, /* compression length */ + CURVE_LEN = 2, /* ecc named curve length */ + KE_GROUP_LEN = 2, /* key exchange group length */ + SERVER_ID_LEN = 20, /* server session id length */ + + HANDSHAKE_HEADER_SZ = 4, /* type + length(3) */ + RECORD_HEADER_SZ = 5, /* type + version + len(2) */ + CERT_HEADER_SZ = 3, /* always 3 bytes */ + REQ_HEADER_SZ = 2, /* cert request header sz */ + HINT_LEN_SZ = 2, /* length of hint size field */ + TRUNCATED_HMAC_SZ = 10, /* length of hmac w/ truncated hmac extension */ + HELLO_EXT_SZ = 4, /* base length of a hello extension */ + HELLO_EXT_TYPE_SZ = 2, /* length of a hello extension type */ + HELLO_EXT_SZ_SZ = 2, /* length of a hello extension size */ + HELLO_EXT_SIGALGO_SZ = 2, /* length of number of items in sigalgo list */ + + DTLS_HANDSHAKE_HEADER_SZ = 12, /* normal + seq(2) + offset(3) + length(3) */ + DTLS_RECORD_HEADER_SZ = 13, /* normal + epoch(2) + seq_num(6) */ + DTLS_HANDSHAKE_EXTRA = 8, /* diff from normal */ + DTLS_RECORD_EXTRA = 8, /* diff from normal */ + DTLS_HANDSHAKE_SEQ_SZ = 2, /* handshake header sequence number */ + DTLS_HANDSHAKE_FRAG_SZ = 3, /* fragment offset and length are 24 bit */ + DTLS_POOL_SZ = 255,/* allowed number of list items in TX pool */ + DTLS_EXPORT_PRO = 165,/* wolfSSL protocol for serialized session */ + DTLS_EXPORT_STATE_PRO = 166,/* wolfSSL protocol for serialized state */ + DTLS_EXPORT_VERSION = 4, /* wolfSSL version for serialized session */ + DTLS_EXPORT_OPT_SZ = 60, /* amount of bytes used from Options */ + DTLS_EXPORT_VERSION_3 = 3, /* wolfSSL version before TLS 1.3 addition */ + DTLS_EXPORT_OPT_SZ_3 = 59, /* amount of bytes used from Options */ + DTLS_EXPORT_KEY_SZ = 325 + (DTLS_SEQ_SZ * 2), + /* max amount of bytes used from Keys */ + DTLS_EXPORT_MIN_KEY_SZ = 85 + (DTLS_SEQ_SZ * 2), + /* min amount of bytes used from Keys */ + DTLS_EXPORT_SPC_SZ = 16, /* amount of bytes used from CipherSpecs */ + DTLS_EXPORT_LEN = 2, /* 2 bytes for length and protocol */ + DTLS_EXPORT_IP = 46, /* max ip size IPv4 mapped IPv6 */ + MAX_EXPORT_BUFFER = 514, /* max size of buffer for exporting */ + MAX_EXPORT_STATE_BUFFER = (DTLS_EXPORT_MIN_KEY_SZ) + (3 * DTLS_EXPORT_LEN), + /* max size of buffer for exporting state */ + FINISHED_LABEL_SZ = 15, /* TLS finished label size */ + TLS_FINISHED_SZ = 12, /* TLS has a shorter size */ + EXT_MASTER_LABEL_SZ = 22, /* TLS extended master secret label sz */ + MASTER_LABEL_SZ = 13, /* TLS master secret label sz */ + KEY_LABEL_SZ = 13, /* TLS key block expansion sz */ + PROTOCOL_LABEL_SZ = 9, /* Length of the protocol label */ + MAX_LABEL_SZ = 34, /* Maximum length of a label */ + MAX_HKDF_LABEL_SZ = OPAQUE16_LEN + + OPAQUE8_LEN + PROTOCOL_LABEL_SZ + MAX_LABEL_SZ + + OPAQUE8_LEN + WC_MAX_DIGEST_SIZE, + MAX_REQUEST_SZ = 256, /* Maximum cert req len (no auth yet */ + SESSION_FLUSH_COUNT = 256, /* Flush session cache unless user turns off */ + TLS_MAX_PAD_SZ = 255, /* Max padding in TLS */ + +#if defined(HAVE_FIPS) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) + MAX_SYM_KEY_SIZE = AES_256_KEY_SIZE, +#else + MAX_SYM_KEY_SIZE = WC_MAX_SYM_KEY_SIZE, +#endif + +#ifdef HAVE_SELFTEST + #define WOLFSSL_AES_KEY_SIZE_ENUM + AES_IV_SIZE = 16, + AES_128_KEY_SIZE = 16, + AES_192_KEY_SIZE = 24, + AES_256_KEY_SIZE = 32, +#endif + + MAX_IV_SZ = AES_BLOCK_SIZE, + + AEAD_SEQ_OFFSET = 4, /* Auth Data: Sequence number */ + AEAD_TYPE_OFFSET = 8, /* Auth Data: Type */ + AEAD_VMAJ_OFFSET = 9, /* Auth Data: Major Version */ + AEAD_VMIN_OFFSET = 10, /* Auth Data: Minor Version */ + AEAD_LEN_OFFSET = 11, /* Auth Data: Length */ + AEAD_AUTH_DATA_SZ = 13, /* Size of the data to authenticate */ + AEAD_NONCE_SZ = 12, + AESGCM_IMP_IV_SZ = 4, /* Size of GCM/CCM AEAD implicit IV */ + AESGCM_EXP_IV_SZ = 8, /* Size of GCM/CCM AEAD explicit IV */ + AESGCM_NONCE_SZ = AESGCM_EXP_IV_SZ + AESGCM_IMP_IV_SZ, + + CHACHA20_IMP_IV_SZ = 12, /* Size of ChaCha20 AEAD implicit IV */ + CHACHA20_NONCE_SZ = 12, /* Size of ChacCha20 nonce */ + CHACHA20_OLD_OFFSET = 4, /* Offset for seq # in old poly1305 */ + + /* For any new implicit/explicit IV size adjust AEAD_MAX_***_SZ */ + + AES_GCM_AUTH_SZ = 16, /* AES-GCM Auth Tag length */ + AES_CCM_16_AUTH_SZ = 16, /* AES-CCM-16 Auth Tag length */ + AES_CCM_8_AUTH_SZ = 8, /* AES-CCM-8 Auth Tag Length */ + AESCCM_NONCE_SZ = 12, + + CAMELLIA_128_KEY_SIZE = 16, /* for 128 bit */ + CAMELLIA_192_KEY_SIZE = 24, /* for 192 bit */ + CAMELLIA_256_KEY_SIZE = 32, /* for 256 bit */ + CAMELLIA_IV_SIZE = 16, /* always block size */ + + CHACHA20_256_KEY_SIZE = 32, /* for 256 bit */ + CHACHA20_128_KEY_SIZE = 16, /* for 128 bit */ + CHACHA20_IV_SIZE = 12, /* 96 bits for iv */ + + POLY1305_AUTH_SZ = 16, /* 128 bits */ + + HMAC_NONCE_SZ = 12, /* Size of HMAC nonce */ + + HC_128_KEY_SIZE = 16, /* 128 bits */ + HC_128_IV_SIZE = 16, /* also 128 bits */ + + RABBIT_KEY_SIZE = 16, /* 128 bits */ + RABBIT_IV_SIZE = 8, /* 64 bits for iv */ + + EVP_SALT_SIZE = 8, /* evp salt size 64 bits */ + +#ifndef ECDHE_SIZE /* allow this to be overridden at compile-time */ + ECDHE_SIZE = 32, /* ECHDE server size defaults to 256 bit */ +#endif + MAX_EXPORT_ECC_SZ = 256, /* Export ANS X9.62 max future size */ + MAX_CURVE_NAME_SZ = 16, /* Maximum size of curve name string */ + + NEW_SA_MAJOR = 8, /* Most significant byte used with new sig algos */ + ED25519_SA_MAJOR = 8, /* Most significant byte for ED25519 */ + ED25519_SA_MINOR = 7, /* Least significant byte for ED25519 */ + ED448_SA_MAJOR = 8, /* Most significant byte for ED448 */ + ED448_SA_MINOR = 8, /* Least significant byte for ED448 */ + + MIN_RSA_SHA512_PSS_BITS = 512 * 2 + 8 * 8, /* Min key size */ + MIN_RSA_SHA384_PSS_BITS = 384 * 2 + 8 * 8, /* Min key size */ + +#ifndef NO_RSA + MAX_CERT_VERIFY_SZ = 4096 / 8, /* max RSA - default 4096-bits */ +#elif defined(HAVE_ECC) + MAX_CERT_VERIFY_SZ = ECC_MAX_SIG_SIZE, /* max ECC */ +#elif defined(HAVE_ED25519) + MAX_CERT_VERIFY_SZ = ED25519_SIG_SIZE, /* max Ed25519 */ +#else + MAX_CERT_VERIFY_SZ = 1024, /* max default */ +#endif + CLIENT_HELLO_FIRST = 35, /* Protocol + RAN_LEN + sizeof(id_len) */ + MAX_SUITE_NAME = 48, /* maximum length of cipher suite string */ + + DTLS_TIMEOUT_INIT = 1, /* default timeout init for DTLS receive */ + DTLS_TIMEOUT_MAX = 64, /* default max timeout for DTLS receive */ + DTLS_TIMEOUT_MULTIPLIER = 2, /* default timeout multiplier for DTLS recv */ + + NULL_TERM_LEN = 1, /* length of null '\0' termination character */ + MAX_PSK_KEY_LEN = 64, /* max psk key supported */ + MIN_PSK_ID_LEN = 6, /* min length of identities */ + MIN_PSK_BINDERS_LEN= 33, /* min length of binders */ + MAX_TICKET_AGE_SECS= 10, /* maximum ticket age in seconds */ + +#ifndef MAX_WOLFSSL_FILE_SIZE + MAX_WOLFSSL_FILE_SIZE = 1024ul * 1024ul * 4, /* 4 mb file size alloc limit */ +#endif + + MAX_X509_SIZE = 2048, /* max static x509 buffer size */ + CERT_MIN_SIZE = 256, /* min PEM cert size with header/footer */ + + MAX_NTRU_PUB_KEY_SZ = 1027, /* NTRU max for now */ + MAX_NTRU_ENCRYPT_SZ = 1027, /* NTRU max for now */ + MAX_NTRU_BITS = 256, /* max symmetric bit strength */ + NO_SNIFF = 0, /* not sniffing */ + SNIFF = 1, /* currently sniffing */ + + HASH_SIG_SIZE = 2, /* default SHA1 RSA */ + + NO_COPY = 0, /* should we copy static buffer for write */ + COPY = 1, /* should we copy static buffer for write */ + + INVALID_PEER_ID = 0xFFFF, /* Initialize value for peer ID. */ + + PREV_ORDER = -1, /* Sequence number is in previous epoch. */ + PEER_ORDER = 1, /* Peer sequence number for verify. */ + CUR_ORDER = 0, /* Current sequence number. */ + WRITE_PROTO = 1, /* writing a protocol message */ + READ_PROTO = 0 /* reading a protocol message */ +}; + +/* minimum Downgrade Minor version */ +#ifndef WOLFSSL_MIN_DOWNGRADE + #ifndef NO_OLD_TLS + #define WOLFSSL_MIN_DOWNGRADE TLSv1_MINOR + #else + #define WOLFSSL_MIN_DOWNGRADE TLSv1_2_MINOR + #endif +#endif + +/* Set max implicit IV size for AEAD cipher suites */ +#define AEAD_MAX_IMP_SZ 12 + +/* Set max explicit IV size for AEAD cipher suites */ +#define AEAD_MAX_EXP_SZ 8 + + +#ifndef WOLFSSL_MAX_SUITE_SZ + #define WOLFSSL_MAX_SUITE_SZ 300 + /* 150 suites for now! */ +#endif + +/* number of items in the signature algo list */ +#ifndef WOLFSSL_MAX_SIGALGO + #define WOLFSSL_MAX_SIGALGO 32 +#endif + + +/* set minimum ECC key size allowed */ +#ifndef WOLFSSL_MIN_ECC_BITS + #ifdef WOLFSSL_MAX_STRENGTH + #define WOLFSSL_MIN_ECC_BITS 256 + #else + #define WOLFSSL_MIN_ECC_BITS 224 + #endif +#endif /* WOLFSSL_MIN_ECC_BITS */ +#if (WOLFSSL_MIN_ECC_BITS % 8) + /* Some ECC keys are not divisible by 8 such as prime239v1 or sect131r1. + In these cases round down to the nearest value divisible by 8. The + restriction of being divisible by 8 is in place to match wc_ecc_size + function from wolfSSL. + */ + #error ECC minimum bit size must be a multiple of 8 +#endif +#define MIN_ECCKEY_SZ (WOLFSSL_MIN_ECC_BITS / 8) + +/* set minimum RSA key size allowed */ +#ifndef WOLFSSL_MIN_RSA_BITS + #ifdef WOLFSSL_MAX_STRENGTH + #define WOLFSSL_MIN_RSA_BITS 2048 + #else + #define WOLFSSL_MIN_RSA_BITS 1024 + #endif +#endif /* WOLFSSL_MIN_RSA_BITS */ +#if (WOLFSSL_MIN_RSA_BITS % 8) + /* This is to account for the example case of a min size of 2050 bits but + still allows 2049 bit key. So we need the measurement to be in bytes. */ + #error RSA minimum bit size must be a multiple of 8 +#endif +#define MIN_RSAKEY_SZ (WOLFSSL_MIN_RSA_BITS / 8) + +#ifdef SESSION_INDEX +/* Shift values for making a session index */ +#define SESSIDX_ROW_SHIFT 4 +#define SESSIDX_IDX_MASK 0x0F +#endif + + +/* max cert chain peer depth */ +#ifndef MAX_CHAIN_DEPTH + #define MAX_CHAIN_DEPTH 9 +#endif + +/* max size of a certificate message payload */ +/* assumes MAX_CHAIN_DEPTH number of certificates at 2kb per certificate */ +#ifndef MAX_CERTIFICATE_SZ + #define MAX_CERTIFICATE_SZ \ + CERT_HEADER_SZ + \ + (MAX_X509_SIZE + CERT_HEADER_SZ) * MAX_CHAIN_DEPTH +#endif + +/* max size of a handshake message, currently set to the certificate */ +#ifndef MAX_HANDSHAKE_SZ + #define MAX_HANDSHAKE_SZ MAX_CERTIFICATE_SZ +#endif + +#ifndef SESSION_TICKET_LEN + #define SESSION_TICKET_LEN 256 +#endif + +#ifndef SESSION_TICKET_HINT_DEFAULT + #define SESSION_TICKET_HINT_DEFAULT 300 +#endif + + +/* don't use extra 3/4k stack space unless need to */ +#ifdef HAVE_NTRU + #define MAX_ENCRYPT_SZ MAX_NTRU_ENCRYPT_SZ +#else + #define MAX_ENCRYPT_SZ ENCRYPT_LEN +#endif + + +/* states */ +enum states { + NULL_STATE = 0, + + SERVER_HELLOVERIFYREQUEST_COMPLETE, + SERVER_HELLO_RETRY_REQUEST_COMPLETE, + SERVER_HELLO_COMPLETE, + SERVER_ENCRYPTED_EXTENSIONS_COMPLETE, + SERVER_CERT_COMPLETE, + SERVER_KEYEXCHANGE_COMPLETE, + SERVER_HELLODONE_COMPLETE, + SERVER_CHANGECIPHERSPEC_COMPLETE, + SERVER_FINISHED_COMPLETE, + + CLIENT_HELLO_RETRY, + CLIENT_HELLO_COMPLETE, + CLIENT_KEYEXCHANGE_COMPLETE, + CLIENT_CHANGECIPHERSPEC_COMPLETE, + CLIENT_FINISHED_COMPLETE, + + HANDSHAKE_DONE +}; + +/* SSL Version */ +typedef struct ProtocolVersion { + byte major; + byte minor; +} WOLFSSL_PACK ProtocolVersion; + + +WOLFSSL_LOCAL ProtocolVersion MakeSSLv3(void); +WOLFSSL_LOCAL ProtocolVersion MakeTLSv1(void); +WOLFSSL_LOCAL ProtocolVersion MakeTLSv1_1(void); +WOLFSSL_LOCAL ProtocolVersion MakeTLSv1_2(void); +WOLFSSL_LOCAL ProtocolVersion MakeTLSv1_3(void); + +#ifdef WOLFSSL_DTLS + WOLFSSL_LOCAL ProtocolVersion MakeDTLSv1(void); + WOLFSSL_LOCAL ProtocolVersion MakeDTLSv1_2(void); + + #ifdef WOLFSSL_SESSION_EXPORT + WOLFSSL_LOCAL int wolfSSL_dtls_import_internal(WOLFSSL* ssl, byte* buf, + word32 sz); + WOLFSSL_LOCAL int wolfSSL_dtls_export_internal(WOLFSSL* ssl, byte* buf, + word32 sz); + WOLFSSL_LOCAL int wolfSSL_dtls_export_state_internal(WOLFSSL* ssl, + byte* buf, word32 sz); + WOLFSSL_LOCAL int wolfSSL_dtls_import_state_internal(WOLFSSL* ssl, + byte* buf, word32 sz); + WOLFSSL_LOCAL int wolfSSL_send_session(WOLFSSL* ssl); + #endif +#endif + + +/* wolfSSL method type */ +struct WOLFSSL_METHOD { + ProtocolVersion version; + byte side; /* connection side, server or client */ + byte downgrade; /* whether to downgrade version, default no */ +}; + +/* wolfSSL buffer type - internal uses "buffer" type */ +typedef WOLFSSL_BUFFER_INFO buffer; + +typedef struct Suites Suites; + + +/* defaults to client */ +WOLFSSL_LOCAL void InitSSL_Method(WOLFSSL_METHOD*, ProtocolVersion); + +WOLFSSL_LOCAL int InitSSL_Suites(WOLFSSL* ssl); +WOLFSSL_LOCAL int InitSSL_Side(WOLFSSL* ssl, word16 side); + +/* for sniffer */ +WOLFSSL_LOCAL int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, + word32 size, word32 totalSz, int sniff); +WOLFSSL_LOCAL int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx); +/* TLS v1.3 needs these */ +WOLFSSL_LOCAL int HandleTlsResumption(WOLFSSL* ssl, int bogusID, + Suites* clSuites); +#ifdef WOLFSSL_TLS13 +WOLFSSL_LOCAL int FindSuite(Suites* suites, byte first, byte second); +#endif +WOLFSSL_LOCAL int DoClientHello(WOLFSSL* ssl, const byte* input, word32*, + word32); +#ifdef WOLFSSL_TLS13 +WOLFSSL_LOCAL int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, + word32* inOutIdx, word32 helloSz); +#endif +WOLFSSL_LOCAL int DoServerHello(WOLFSSL* ssl, const byte* input, word32*, + word32); +WOLFSSL_LOCAL int CompleteServerHello(WOLFSSL *ssl); +WOLFSSL_LOCAL int CheckVersion(WOLFSSL *ssl, ProtocolVersion pv); +WOLFSSL_LOCAL int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, + word32 hashSigAlgoSz); +WOLFSSL_LOCAL int DecodePrivateKey(WOLFSSL *ssl, word16* length); +#ifdef HAVE_PK_CALLBACKS +WOLFSSL_LOCAL int GetPrivateKeySigSize(WOLFSSL* ssl); +#ifndef NO_ASN + WOLFSSL_LOCAL int InitSigPkCb(WOLFSSL* ssl, SignatureCtx* sigCtx); +#endif +#endif +WOLFSSL_LOCAL void FreeKeyExchange(WOLFSSL* ssl); +WOLFSSL_LOCAL void FreeSuites(WOLFSSL* ssl); +WOLFSSL_LOCAL int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 size); +WOLFSSL_LOCAL int MatchDomainName(const char* pattern, int len, const char* str); +#ifndef NO_CERTS +WOLFSSL_LOCAL int CheckAltNames(DecodedCert* dCert, char* domain); +#ifdef OPENSSL_EXTRA +WOLFSSL_LOCAL int CheckIPAddr(DecodedCert* dCert, char* ipasc); +#endif +#endif +WOLFSSL_LOCAL int CreateTicket(WOLFSSL* ssl); +WOLFSSL_LOCAL int HashOutputRaw(WOLFSSL* ssl, const byte* output, int sz); +WOLFSSL_LOCAL int HashOutput(WOLFSSL* ssl, const byte* output, int sz, + int ivSz); +WOLFSSL_LOCAL int HashInput(WOLFSSL* ssl, const byte* input, int sz); +#if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) +WOLFSSL_LOCAL int SNI_Callback(WOLFSSL* ssl); +#endif +#ifdef WOLFSSL_TLS13 +WOLFSSL_LOCAL int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, + word16 sz, const byte* aad, word16 aadSz); +WOLFSSL_LOCAL int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, + word32* inOutIdx, byte type, + word32 size, word32 totalSz); +WOLFSSL_LOCAL int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, + word32* inOutIdx, word32 totalSz); +WOLFSSL_LOCAL int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, + word32* inOutIdx, word32 helloSz, + byte* extMsgType); +#endif +int TimingPadVerify(WOLFSSL* ssl, const byte* input, int padLen, int t, + int pLen, int content); + + +enum { + FORCED_FREE = 1, + NO_FORCED_FREE = 0 +}; + + +/* only use compression extra if using compression */ +#ifdef HAVE_LIBZ + #define COMP_EXTRA MAX_COMP_EXTRA +#else + #define COMP_EXTRA 0 +#endif + +/* only the sniffer needs space in the buffer for extra MTU record(s) */ +#ifdef WOLFSSL_SNIFFER + #define MTU_EXTRA MAX_MTU * 3 +#else + #define MTU_EXTRA 0 +#endif + + +/* embedded callbacks require large static buffers, make sure on */ +#ifdef WOLFSSL_CALLBACKS + #undef LARGE_STATIC_BUFFERS + #define LARGE_STATIC_BUFFERS +#endif + + +/* give user option to use 16K static buffers */ +#if defined(LARGE_STATIC_BUFFERS) + #define RECORD_SIZE MAX_RECORD_SIZE +#else + #ifdef WOLFSSL_DTLS + #define RECORD_SIZE MAX_MTU + #else + #define RECORD_SIZE 128 + #endif +#endif + + +/* user option to turn off 16K output option */ +/* if using small static buffers (default) and SSL_write tries to write data + larger than the record we have, dynamically get it, unless user says only + write in static buffer chunks */ +#ifndef STATIC_CHUNKS_ONLY + #define OUTPUT_RECORD_SIZE MAX_RECORD_SIZE +#else + #define OUTPUT_RECORD_SIZE RECORD_SIZE +#endif + +/* wolfSSL input buffer + + RFC 2246: + + length + The length (in bytes) of the following TLSPlaintext.fragment. + The length should not exceed 2^14. +*/ +#if defined(LARGE_STATIC_BUFFERS) + #define STATIC_BUFFER_LEN RECORD_HEADER_SZ + RECORD_SIZE + COMP_EXTRA + \ + MTU_EXTRA + MAX_MSG_EXTRA +#else + /* don't fragment memory from the record header */ + #define STATIC_BUFFER_LEN RECORD_HEADER_SZ +#endif + +typedef struct { + ALIGN16 byte staticBuffer[STATIC_BUFFER_LEN]; + byte* buffer; /* place holder for static or dynamic buffer */ + word32 length; /* total buffer length used */ + word32 idx; /* idx to part of length already consumed */ + word32 bufferSize; /* current buffer size */ + byte dynamicFlag; /* dynamic memory currently in use */ + byte offset; /* alignment offset attempt */ +} bufferStatic; + +/* Cipher Suites holder */ +struct Suites { + word16 suiteSz; /* suite length in bytes */ + word16 hashSigAlgoSz; /* SigAlgo extension length in bytes */ + byte suites[WOLFSSL_MAX_SUITE_SZ]; + byte hashSigAlgo[WOLFSSL_MAX_SIGALGO]; /* sig/algo to offer */ + byte setSuites; /* user set suites from default */ + byte hashAlgo; /* selected hash algorithm */ + byte sigAlgo; /* selected sig algorithm */ +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) + WOLF_STACK_OF(WOLFSSL_CIPHER)* stack; /* stack of available cipher suites */ +#endif +}; + + +WOLFSSL_LOCAL void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, + int haveRSAsig, int haveAnon, + int tls1_2, int keySz); +WOLFSSL_LOCAL void InitSuites(Suites*, ProtocolVersion, int, word16, word16, + word16, word16, word16, word16, word16, int); +WOLFSSL_LOCAL int MatchSuite(WOLFSSL* ssl, Suites* peerSuites); +WOLFSSL_LOCAL int SetCipherList(WOLFSSL_CTX*, Suites*, const char* list); + +#ifndef PSK_TYPES_DEFINED + typedef unsigned int (*wc_psk_client_callback)(WOLFSSL*, const char*, char*, + unsigned int, unsigned char*, unsigned int); + typedef unsigned int (*wc_psk_server_callback)(WOLFSSL*, const char*, + unsigned char*, unsigned int); +#ifdef WOLFSSL_TLS13 + typedef unsigned int (*wc_psk_client_tls13_callback)(WOLFSSL*, const char*, + char*, unsigned int, unsigned char*, unsigned int, + const char**); + typedef unsigned int (*wc_psk_server_tls13_callback)(WOLFSSL*, const char*, + unsigned char*, unsigned int, const char**); +#endif +#endif /* PSK_TYPES_DEFINED */ +#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SESSION_EXPORT) && \ + !defined(WOLFSSL_DTLS_EXPORT_TYPES) + typedef int (*wc_dtls_export)(WOLFSSL* ssl, + unsigned char* exportBuffer, unsigned int sz, void* userCtx); +#define WOLFSSL_DTLS_EXPORT_TYPES +#endif /* WOLFSSL_DTLS_EXPORT_TYPES */ + + +/* wolfSSL Cipher type just points back to SSL */ +struct WOLFSSL_CIPHER { + byte cipherSuite0; + byte cipherSuite; + WOLFSSL* ssl; +#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) + char description[MAX_CIPHERNAME_SZ]; + unsigned long offset; + unsigned int in_stack; /* TRUE if added to stack in wolfSSL_get_ciphers_compat */ + int bits; +#endif +}; + + +#ifdef NO_ASN + /* no_asn won't have */ + typedef struct CertStatus CertStatus; +#endif + +#ifndef HAVE_OCSP + typedef struct WOLFSSL_OCSP WOLFSSL_OCSP; +#endif + +/* wolfSSL OCSP controller */ +#ifdef HAVE_OCSP +struct WOLFSSL_OCSP { + WOLFSSL_CERT_MANAGER* cm; /* pointer back to cert manager */ + OcspEntry* ocspList; /* OCSP response list */ + wolfSSL_Mutex ocspLock; /* OCSP list lock */ + int error; +#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \ + defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) + int(*statusCb)(WOLFSSL*, void*); +#endif +}; +#endif + +#ifndef MAX_DATE_SIZE +#define MAX_DATE_SIZE 32 +#endif + +typedef struct CRL_Entry CRL_Entry; + +#ifdef NO_SHA + #define CRL_DIGEST_SIZE WC_SHA256_DIGEST_SIZE +#else + #define CRL_DIGEST_SIZE WC_SHA_DIGEST_SIZE +#endif + +#ifdef NO_ASN + typedef struct RevokedCert RevokedCert; +#endif + +/* Complete CRL */ +struct CRL_Entry { + CRL_Entry* next; /* next entry */ + byte issuerHash[CRL_DIGEST_SIZE]; /* issuer hash */ + /* byte crlHash[CRL_DIGEST_SIZE]; raw crl data hash */ + /* restore the hash here if needed for optimized comparisons */ + byte lastDate[MAX_DATE_SIZE]; /* last date updated */ + byte nextDate[MAX_DATE_SIZE]; /* next update date */ + byte lastDateFormat; /* last date format */ + byte nextDateFormat; /* next date format */ + RevokedCert* certs; /* revoked cert list */ + int totalCerts; /* number on list */ + int verified; + byte* toBeSigned; + word32 tbsSz; + byte* signature; + word32 signatureSz; + word32 signatureOID; +#if !defined(NO_SKID) && !defined(NO_ASN) + byte extAuthKeyIdSet; + byte extAuthKeyId[KEYID_SIZE]; +#endif +}; + + +typedef struct CRL_Monitor CRL_Monitor; + +/* CRL directory monitor */ +struct CRL_Monitor { + char* path; /* full dir path, if valid pointer we're using */ + int type; /* PEM or ASN1 type */ +}; + + +#if defined(HAVE_CRL) && defined(NO_FILESYSTEM) + #undef HAVE_CRL_MONITOR +#endif + +/* wolfSSL CRL controller */ +struct WOLFSSL_CRL { + WOLFSSL_CERT_MANAGER* cm; /* pointer back to cert manager */ + CRL_Entry* crlList; /* our CRL list */ +#ifdef HAVE_CRL_IO + CbCrlIO crlIOCb; +#endif + wolfSSL_Mutex crlLock; /* CRL list lock */ + CRL_Monitor monitors[2]; /* PEM and DER possible */ +#ifdef HAVE_CRL_MONITOR + pthread_cond_t cond; /* condition to signal setup */ + pthread_t tid; /* monitoring thread */ + int mfd; /* monitor fd, -1 if no init yet */ + int setup; /* thread is setup predicate */ +#endif + void* heap; /* heap hint for dynamic memory */ +}; + + +#ifdef NO_ASN + typedef struct Signer Signer; +#ifdef WOLFSSL_TRUST_PEER_CERT + typedef struct TrustedPeerCert TrustedPeerCert; +#endif +#endif + + +#ifndef CA_TABLE_SIZE + #define CA_TABLE_SIZE 11 +#endif +#ifdef WOLFSSL_TRUST_PEER_CERT + #define TP_TABLE_SIZE 11 +#endif + +/* wolfSSL Certificate Manager */ +struct WOLFSSL_CERT_MANAGER { + Signer* caTable[CA_TABLE_SIZE]; /* the CA signer table */ + void* heap; /* heap helper */ +#ifdef WOLFSSL_TRUST_PEER_CERT + TrustedPeerCert* tpTable[TP_TABLE_SIZE]; /* table of trusted peer certs */ + wolfSSL_Mutex tpLock; /* trusted peer list lock */ +#endif + WOLFSSL_CRL* crl; /* CRL checker */ + WOLFSSL_OCSP* ocsp; /* OCSP checker */ +#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) + WOLFSSL_OCSP* ocsp_stapling; /* OCSP checker for OCSP stapling */ +#endif + char* ocspOverrideURL; /* use this responder */ + void* ocspIOCtx; /* I/O callback CTX */ + CallbackCACache caCacheCallback; /* CA cache addition callback */ + CbMissingCRL cbMissingCRL; /* notify through cb of missing crl */ + CbOCSPIO ocspIOCb; /* I/O callback for OCSP lookup */ + CbOCSPRespFree ocspRespFreeCb; /* Frees OCSP Response from IO Cb */ + wolfSSL_Mutex caLock; /* CA list lock */ + byte crlEnabled; /* is CRL on ? */ + byte crlCheckAll; /* always leaf, but all ? */ + byte ocspEnabled; /* is OCSP on ? */ + byte ocspCheckAll; /* always leaf, but all ? */ + byte ocspSendNonce; /* send the OCSP nonce ? */ + byte ocspUseOverrideURL; /* ignore cert's responder, override */ + byte ocspStaplingEnabled; /* is OCSP Stapling on ? */ + +#ifndef NO_RSA + short minRsaKeySz; /* minimum allowed RSA key size */ +#endif +#if defined(HAVE_ECC) || defined(HAVE_ED25519) + short minEccKeySz; /* minimum allowed ECC key size */ +#endif +}; + +WOLFSSL_LOCAL int CM_SaveCertCache(WOLFSSL_CERT_MANAGER*, const char*); +WOLFSSL_LOCAL int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER*, const char*); +WOLFSSL_LOCAL int CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER*, void*, int, int*); +WOLFSSL_LOCAL int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER*, const void*, int); +WOLFSSL_LOCAL int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER*); + +/* wolfSSL Sock Addr */ +struct WOLFSSL_SOCKADDR { + unsigned int sz; /* sockaddr size */ + void* sa; /* pointer to the sockaddr_in or sockaddr_in6 */ +}; + +typedef struct WOLFSSL_DTLS_CTX { + WOLFSSL_SOCKADDR peer; + int rfd; + int wfd; +} WOLFSSL_DTLS_CTX; + + +typedef struct WOLFSSL_DTLS_PEERSEQ { + word32 window[WOLFSSL_DTLS_WINDOW_WORDS]; + /* Sliding window for current epoch */ + word16 nextEpoch; /* Expected epoch in next record */ + word16 nextSeq_hi; /* Expected sequence in next record */ + word32 nextSeq_lo; + + word32 prevWindow[WOLFSSL_DTLS_WINDOW_WORDS]; + /* Sliding window for old epoch */ + word32 prevSeq_lo; + word16 prevSeq_hi; /* Next sequence in allowed old epoch */ + +#ifdef WOLFSSL_MULTICAST + word16 peerId; + word32 highwaterMark; +#endif +} WOLFSSL_DTLS_PEERSEQ; + + +#define MAX_WRITE_IV_SZ 16 /* max size of client/server write_IV */ + +/* keys and secrets + * keep as a constant size (no additional ifdefs) for session export */ +typedef struct Keys { +#if !defined(WOLFSSL_AEAD_ONLY) || defined(WOLFSSL_TLS13) + byte client_write_MAC_secret[WC_MAX_DIGEST_SIZE]; /* max sizes */ + byte server_write_MAC_secret[WC_MAX_DIGEST_SIZE]; +#endif + byte client_write_key[MAX_SYM_KEY_SIZE]; /* max sizes */ + byte server_write_key[MAX_SYM_KEY_SIZE]; + byte client_write_IV[MAX_WRITE_IV_SZ]; /* max sizes */ + byte server_write_IV[MAX_WRITE_IV_SZ]; +#if defined(HAVE_AEAD) || defined(WOLFSSL_SESSION_EXPORT) + byte aead_exp_IV[AEAD_MAX_EXP_SZ]; + byte aead_enc_imp_IV[AEAD_MAX_IMP_SZ]; + byte aead_dec_imp_IV[AEAD_MAX_IMP_SZ]; +#endif + + word32 peer_sequence_number_hi; + word32 peer_sequence_number_lo; + word32 sequence_number_hi; + word32 sequence_number_lo; + +#ifdef WOLFSSL_DTLS + word16 curEpoch; /* Received epoch in current record */ + word16 curSeq_hi; /* Received sequence in current record */ + word32 curSeq_lo; +#ifdef WOLFSSL_MULTICAST + byte curPeerId; /* Received peer group ID in current record */ +#endif + WOLFSSL_DTLS_PEERSEQ peerSeq[WOLFSSL_DTLS_PEERSEQ_SZ]; + + word16 dtls_peer_handshake_number; + word16 dtls_expected_peer_handshake_number; + + word16 dtls_epoch; /* Current epoch */ + word16 dtls_sequence_number_hi; /* Current epoch */ + word32 dtls_sequence_number_lo; + word16 dtls_prev_sequence_number_hi; /* Previous epoch */ + word32 dtls_prev_sequence_number_lo; + word16 dtls_handshake_number; /* Current tx handshake seq */ +#endif + + word32 encryptSz; /* last size of encrypted data */ + word32 padSz; /* how much to advance after decrypt part */ + byte encryptionOn; /* true after change cipher spec */ + byte decryptedCur; /* only decrypt current record once */ +#ifdef WOLFSSL_TLS13 + byte updateResponseReq:1; /* KeyUpdate response from peer required. */ + byte keyUpdateRespond:1; /* KeyUpdate is to be responded to. */ +#endif +#ifdef WOLFSSL_RENESAS_TSIP_TLS + byte tsip_client_write_MAC_secret[TSIP_TLS_HMAC_KEY_INDEX_WORDSIZE]; + byte tsip_server_write_MAC_secret[TSIP_TLS_HMAC_KEY_INDEX_WORDSIZE]; +#endif +} Keys; + + + +/** TLS Extensions - RFC 6066 */ +#ifdef HAVE_TLS_EXTENSIONS + +typedef enum { + TLSX_SERVER_NAME = 0x0000, /* a.k.a. SNI */ + TLSX_MAX_FRAGMENT_LENGTH = 0x0001, + TLSX_TRUSTED_CA_KEYS = 0x0003, + TLSX_TRUNCATED_HMAC = 0x0004, + TLSX_STATUS_REQUEST = 0x0005, /* a.k.a. OCSP stapling */ + TLSX_SUPPORTED_GROUPS = 0x000a, /* a.k.a. Supported Curves */ + TLSX_EC_POINT_FORMATS = 0x000b, +#if !defined(WOLFSSL_NO_SIGALG) + TLSX_SIGNATURE_ALGORITHMS = 0x000d, +#endif + TLSX_APPLICATION_LAYER_PROTOCOL = 0x0010, /* a.k.a. ALPN */ + TLSX_STATUS_REQUEST_V2 = 0x0011, /* a.k.a. OCSP stapling v2 */ +#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) + TLSX_ENCRYPT_THEN_MAC = 0x0016, /* RFC 7366 */ +#endif + TLSX_QUANTUM_SAFE_HYBRID = 0x0018, /* a.k.a. QSH */ + TLSX_SESSION_TICKET = 0x0023, +#ifdef WOLFSSL_TLS13 + #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) + TLSX_PRE_SHARED_KEY = 0x0029, + #endif + #ifdef WOLFSSL_EARLY_DATA + TLSX_EARLY_DATA = 0x002a, + #endif + TLSX_SUPPORTED_VERSIONS = 0x002b, + TLSX_COOKIE = 0x002c, + #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) + TLSX_PSK_KEY_EXCHANGE_MODES = 0x002d, + #endif + #ifdef WOLFSSL_POST_HANDSHAKE_AUTH + TLSX_POST_HANDSHAKE_AUTH = 0x0031, + #endif + #if defined(WOLFSSL_TLS13_DRAFT_18) || defined(WOLFSSL_TLS13_DRAFT_22) + TLSX_KEY_SHARE = 0x0028, + #else + TLSX_SIGNATURE_ALGORITHMS_CERT = 0x0032, + TLSX_KEY_SHARE = 0x0033, + #endif +#endif + TLSX_RENEGOTIATION_INFO = 0xff01 +} TLSX_Type; + +typedef struct TLSX { + TLSX_Type type; /* Extension Type */ + void* data; /* Extension Data */ + word32 val; /* Extension Value */ + byte resp; /* IsResponse Flag */ + struct TLSX* next; /* List Behavior */ +} TLSX; + +WOLFSSL_LOCAL TLSX* TLSX_Find(TLSX* list, TLSX_Type type); +WOLFSSL_LOCAL void TLSX_Remove(TLSX** list, TLSX_Type type, void* heap); +WOLFSSL_LOCAL void TLSX_FreeAll(TLSX* list, void* heap); +WOLFSSL_LOCAL int TLSX_SupportExtensions(WOLFSSL* ssl); +WOLFSSL_LOCAL int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isRequest); + +#if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_CLIENT) +WOLFSSL_LOCAL int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, + word16* pLength); +WOLFSSL_LOCAL int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, + byte msgType, word16* pOffset); +#endif + +#if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_SERVER) +/* TLS 1.3 Certificate messages have extensions. */ +WOLFSSL_LOCAL int TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType, + word16* pLength); +WOLFSSL_LOCAL int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, + word16* pOffset); +#endif + +WOLFSSL_LOCAL int TLSX_ParseVersion(WOLFSSL* ssl, byte* input, word16 length, + byte msgType, int* found); +WOLFSSL_LOCAL int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, + byte msgType, Suites *suites); + +#elif defined(HAVE_SNI) \ + || defined(HAVE_MAX_FRAGMENT) \ + || defined(HAVE_TRUSTED_CA) \ + || defined(HAVE_TRUNCATED_HMAC) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) \ + || defined(HAVE_SUPPORTED_CURVES) \ + || defined(HAVE_ALPN) \ + || defined(HAVE_QSH) \ + || defined(HAVE_SESSION_TICKET) \ + || defined(HAVE_SECURE_RENEGOTIATION) \ + || defined(HAVE_SERVER_RENEGOTIATION_INFO) + +#error Using TLS extensions requires HAVE_TLS_EXTENSIONS to be defined. + +#endif /* HAVE_TLS_EXTENSIONS */ + +/** Server Name Indication - RFC 6066 (session 3) */ +#ifdef HAVE_SNI + +typedef struct SNI { + byte type; /* SNI Type */ + union { char* host_name; } data; /* SNI Data */ + struct SNI* next; /* List Behavior */ + byte status; /* Matching result */ +#ifndef NO_WOLFSSL_SERVER + byte options; /* Behavior options */ +#endif +} SNI; + +WOLFSSL_LOCAL int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, + word16 size, void* heap); +WOLFSSL_LOCAL byte TLSX_SNI_Status(TLSX* extensions, byte type); +WOLFSSL_LOCAL word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, + void** data); + +#ifndef NO_WOLFSSL_SERVER +WOLFSSL_LOCAL void TLSX_SNI_SetOptions(TLSX* extensions, byte type, + byte options); +WOLFSSL_LOCAL int TLSX_SNI_GetFromBuffer(const byte* buffer, word32 bufferSz, + byte type, byte* sni, word32* inOutSz); +#endif + +#endif /* HAVE_SNI */ + +/* Trusted CA Key Indication - RFC 6066 (section 6) */ +#ifdef HAVE_TRUSTED_CA + +typedef struct TCA { + byte type; /* TCA Type */ + byte* id; /* TCA identifier */ + word16 idSz; /* TCA identifier size */ + struct TCA* next; /* List Behavior */ +} TCA; + +WOLFSSL_LOCAL int TLSX_UseTrustedCA(TLSX** extensions, byte type, + const byte* id, word16 idSz, void* heap); + +#endif /* HAVE_TRUSTED_CA */ + +/* Application-Layer Protocol Negotiation - RFC 7301 */ +#ifdef HAVE_ALPN +typedef struct ALPN { + char* protocol_name; /* ALPN protocol name */ + struct ALPN* next; /* List Behavior */ + byte options; /* Behavior options */ + byte negotiated; /* ALPN protocol negotiated or not */ +} ALPN; + +WOLFSSL_LOCAL int TLSX_ALPN_GetRequest(TLSX* extensions, + void** data, word16 *dataSz); + +WOLFSSL_LOCAL int TLSX_UseALPN(TLSX** extensions, const void* data, + word16 size, byte options, void* heap); + +WOLFSSL_LOCAL int TLSX_ALPN_SetOptions(TLSX** extensions, const byte option); + +#endif /* HAVE_ALPN */ + +/** Maximum Fragment Length Negotiation - RFC 6066 (session 4) */ +#ifdef HAVE_MAX_FRAGMENT + +WOLFSSL_LOCAL int TLSX_UseMaxFragment(TLSX** extensions, byte mfl, void* heap); + +#endif /* HAVE_MAX_FRAGMENT */ + +/** Truncated HMAC - RFC 6066 (session 7) */ +#ifdef HAVE_TRUNCATED_HMAC + +WOLFSSL_LOCAL int TLSX_UseTruncatedHMAC(TLSX** extensions, void* heap); + +#endif /* HAVE_TRUNCATED_HMAC */ + +/** Certificate Status Request - RFC 6066 (session 8) */ +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST + +typedef struct { + byte status_type; + byte options; + WOLFSSL* ssl; + union { + OcspRequest ocsp; + } request; +#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER) + buffer response; +#endif +} CertificateStatusRequest; + +WOLFSSL_LOCAL int TLSX_UseCertificateStatusRequest(TLSX** extensions, + byte status_type, byte options, WOLFSSL* ssl, void* heap, int devId); +#ifndef NO_CERTS +WOLFSSL_LOCAL int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert, + void* heap); +#endif +WOLFSSL_LOCAL void* TLSX_CSR_GetRequest(TLSX* extensions); +WOLFSSL_LOCAL int TLSX_CSR_ForceRequest(WOLFSSL* ssl); + +#endif + +/** Certificate Status Request v2 - RFC 6961 */ +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 + +typedef struct CSRIv2 { + byte status_type; + byte options; + word16 requests; + union { + OcspRequest ocsp[1 + MAX_CHAIN_DEPTH]; + } request; + struct CSRIv2* next; +} CertificateStatusRequestItemV2; + +WOLFSSL_LOCAL int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, + byte status_type, byte options, void* heap, int devId); +#ifndef NO_CERTS +WOLFSSL_LOCAL int TLSX_CSR2_InitRequests(TLSX* extensions, DecodedCert* cert, + byte isPeer, void* heap); +#endif +WOLFSSL_LOCAL void* TLSX_CSR2_GetRequest(TLSX* extensions, byte status_type, + byte index); +WOLFSSL_LOCAL int TLSX_CSR2_ForceRequest(WOLFSSL* ssl); + +#endif + +/** Supported Elliptic Curves - RFC 4492 (session 4) */ +#ifdef HAVE_SUPPORTED_CURVES + +typedef struct SupportedCurve { + word16 name; /* Curve Names */ + struct SupportedCurve* next; /* List Behavior */ +} SupportedCurve; + +typedef struct PointFormat { + byte format; /* PointFormat */ + struct PointFormat* next; /* List Behavior */ +} PointFormat; + +WOLFSSL_LOCAL int TLSX_UseSupportedCurve(TLSX** extensions, word16 name, + void* heap); + +WOLFSSL_LOCAL int TLSX_UsePointFormat(TLSX** extensions, byte point, + void* heap); + +#ifndef NO_WOLFSSL_SERVER +WOLFSSL_LOCAL int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, + byte second); +WOLFSSL_LOCAL int TLSX_SupportedCurve_CheckPriority(WOLFSSL* ssl); +WOLFSSL_LOCAL int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl); +#endif +WOLFSSL_LOCAL int TLSX_SupportedCurve_Preferred(WOLFSSL* ssl, + int checkSupported); + +#endif /* HAVE_SUPPORTED_CURVES */ + +/** Renegotiation Indication - RFC 5746 */ +#if defined(HAVE_SECURE_RENEGOTIATION) \ + || defined(HAVE_SERVER_RENEGOTIATION_INFO) + +enum key_cache_state { + SCR_CACHE_NULL = 0, /* empty / begin state */ + SCR_CACHE_NEEDED, /* need to cache keys */ + SCR_CACHE_COPY, /* we have a cached copy */ + SCR_CACHE_PARTIAL, /* partial restore to real keys */ + SCR_CACHE_COMPLETE /* complete restore to real keys */ +}; + +/* Additional Connection State according to rfc5746 section 3.1 */ +typedef struct SecureRenegotiation { + byte enabled; /* secure_renegotiation flag in rfc */ + byte verifySet; + byte startScr; /* server requested client to start scr */ + enum key_cache_state cache_status; /* track key cache state */ + byte client_verify_data[TLS_FINISHED_SZ]; /* cached */ + byte server_verify_data[TLS_FINISHED_SZ]; /* cached */ + byte subject_hash_set; /* if peer cert hash is set */ + byte subject_hash[KEYID_SIZE]; /* peer cert hash */ + Keys tmp_keys; /* can't overwrite real keys yet */ +} SecureRenegotiation; + +WOLFSSL_LOCAL int TLSX_UseSecureRenegotiation(TLSX** extensions, void* heap); + +#ifdef HAVE_SERVER_RENEGOTIATION_INFO +WOLFSSL_LOCAL int TLSX_AddEmptyRenegotiationInfo(TLSX** extensions, void* heap); +#endif + +#endif /* HAVE_SECURE_RENEGOTIATION */ + +/** Session Ticket - RFC 5077 (session 3.2) */ +#ifdef HAVE_SESSION_TICKET + +typedef struct SessionTicket { + word32 lifetime; +#ifdef WOLFSSL_TLS13 + word64 seen; + word32 ageAdd; +#endif + byte* data; + word16 size; +} SessionTicket; + +WOLFSSL_LOCAL int TLSX_UseSessionTicket(TLSX** extensions, + SessionTicket* ticket, void* heap); +WOLFSSL_LOCAL SessionTicket* TLSX_SessionTicket_Create(word32 lifetime, + byte* data, word16 size, void* heap); +WOLFSSL_LOCAL void TLSX_SessionTicket_Free(SessionTicket* ticket, void* heap); + +#endif /* HAVE_SESSION_TICKET */ + +/** Quantum-Safe-Hybrid - draft-whyte-qsh-tls12-00 */ +#ifdef HAVE_QSH + +typedef struct QSHScheme { + struct QSHScheme* next; /* List Behavior */ + byte* PK; + word16 name; /* QSHScheme Names */ + word16 PKLen; +} QSHScheme; + +typedef struct QSHkey { + struct QSHKey* next; + word16 name; + buffer pub; + buffer pri; +} QSHKey; + +typedef struct QSHSecret { + QSHScheme* list; + buffer* SerSi; + buffer* CliSi; +} QSHSecret; + +/* used in key exchange during handshake */ +WOLFSSL_LOCAL int TLSX_QSHCipher_Parse(WOLFSSL* ssl, const byte* input, + word16 length, byte isServer); +WOLFSSL_LOCAL word16 TLSX_QSHPK_Write(QSHScheme* list, byte* output); +WOLFSSL_LOCAL word16 TLSX_QSH_GetSize(QSHScheme* list, byte isRequest); + +/* used by api for setting a specific QSH scheme */ +WOLFSSL_LOCAL int TLSX_UseQSHScheme(TLSX** extensions, word16 name, + byte* pKey, word16 pKeySz, void* heap); + +/* used when parsing in QSHCipher structs */ +WOLFSSL_LOCAL int QSH_Decrypt(QSHKey* key, byte* in, word32 szIn, + byte* out, word16* szOut); +#ifndef NO_WOLFSSL_SERVER +WOLFSSL_LOCAL int TLSX_ValidateQSHScheme(TLSX** extensions, word16 name); +#endif + +#endif /* HAVE_QSH */ + +#ifdef WOLFSSL_TLS13 +/* Cookie extension information - cookie data. */ +typedef struct Cookie { + word16 len; + byte data; +} Cookie; + +WOLFSSL_LOCAL int TLSX_Cookie_Use(WOLFSSL* ssl, byte* data, word16 len, + byte* mac, byte macSz, int resp); + + +/* Key Share - TLS v1.3 Specification */ + +/* The KeyShare extension information - entry in a linked list. */ +typedef struct KeyShareEntry { + word16 group; /* NamedGroup */ + byte* ke; /* Key exchange data */ + word32 keLen; /* Key exchange data length */ + void* key; /* Private key */ + word32 keyLen; /* Private key length */ + byte* pubKey; /* Public key */ + word32 pubKeyLen; /* Public key length */ + struct KeyShareEntry* next; /* List pointer */ +} KeyShareEntry; + +WOLFSSL_LOCAL int TLSX_KeyShare_Use(WOLFSSL* ssl, word16 group, word16 len, + byte* data, KeyShareEntry **kse); +WOLFSSL_LOCAL int TLSX_KeyShare_Empty(WOLFSSL* ssl); +WOLFSSL_LOCAL int TLSX_KeyShare_Establish(WOLFSSL* ssl); +WOLFSSL_LOCAL int TLSX_KeyShare_DeriveSecret(WOLFSSL* ssl); + + +#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) +#ifndef WOLFSSL_TLS13_DRAFT_18 +/* Ticket nonce - for deriving PSK. + * Length allowed to be: 1..255. Only support 4 bytes. + */ +typedef struct TicketNonce { + byte len; + byte data[MAX_TICKET_NONCE_SZ]; +} TicketNonce; +#endif + +/* The PreSharedKey extension information - entry in a linked list. */ +typedef struct PreSharedKey { + word16 identityLen; /* Length of identity */ + byte* identity; /* PSK identity */ + word32 ticketAge; /* Age of the ticket */ + byte cipherSuite0; /* Cipher Suite */ + byte cipherSuite; /* Cipher Suite */ + word32 binderLen; /* Length of HMAC */ + byte binder[WC_MAX_DIGEST_SIZE]; /* HMAC of handshake */ + byte hmac; /* HMAC algorithm */ + byte resumption:1; /* Resumption PSK */ + byte chosen:1; /* Server's choice */ + struct PreSharedKey* next; /* List pointer */ +} PreSharedKey; + +WOLFSSL_LOCAL int TLSX_PreSharedKey_WriteBinders(PreSharedKey* list, + byte* output, byte msgType, + word16* pSz); +WOLFSSL_LOCAL int TLSX_PreSharedKey_GetSizeBinders(PreSharedKey* list, + byte msgType, word16* pSz); +WOLFSSL_LOCAL int TLSX_PreSharedKey_Use(WOLFSSL* ssl, byte* identity, + word16 len, word32 age, byte hmac, + byte cipherSuite0, byte cipherSuite, + byte resumption, + PreSharedKey **preSharedKey); + +/* The possible Pre-Shared Key key exchange modes. */ +enum PskKeyExchangeMode { + PSK_KE, + PSK_DHE_KE +}; + +/* User can define this. */ +#ifndef WOLFSSL_DEF_PSK_CIPHER +#define WOLFSSL_DEF_PSK_CIPHER TLS_AES_128_GCM_SHA256 +#endif + +WOLFSSL_LOCAL int TLSX_PskKeModes_Use(WOLFSSL* ssl, byte modes); + +#ifdef WOLFSSL_EARLY_DATA +WOLFSSL_LOCAL int TLSX_EarlyData_Use(WOLFSSL* ssl, word32 max); +#endif +#endif /* HAVE_SESSION_TICKET || !NO_PSK */ + + +/* The types of keys to derive for. */ +enum DeriveKeyType { + no_key, + early_data_key, + handshake_key, + traffic_key, + update_traffic_key +}; + +/* The key update request values for KeyUpdate message. */ +enum KeyUpdateRequest { + update_not_requested, + update_requested +}; +#endif /* WOLFSSL_TLS13 */ + + +#ifdef OPENSSL_EXTRA +enum SetCBIO { + WOLFSSL_CBIO_NONE = 0, + WOLFSSL_CBIO_RECV = 0x1, + WOLFSSL_CBIO_SEND = 0x2, +}; +#endif + +/* wolfSSL context type */ +struct WOLFSSL_CTX { + WOLFSSL_METHOD* method; +#ifdef SINGLE_THREADED + WC_RNG* rng; /* to be shared with WOLFSSL w/o locking */ +#endif + wolfSSL_Mutex countMutex; /* reference count mutex */ + int refCount; /* reference count */ + int err; /* error code in case of mutex not created */ +#ifndef NO_DH + buffer serverDH_P; + buffer serverDH_G; +#endif +#ifndef NO_CERTS + DerBuffer* certificate; + DerBuffer* certChain; + /* chain after self, in DER, with leading size for each cert */ + #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) + WOLF_STACK_OF(WOLFSSL_X509_NAME)* ca_names; + #endif + #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \ + defined(WOLFSSL_NGINX) || defined (WOLFSSL_HAPROXY) + WOLF_STACK_OF(WOLFSSL_X509)* x509Chain; + client_cert_cb CBClientCert; /* client certificate callback */ + #endif +#ifdef WOLFSSL_TLS13 + int certChainCnt; +#endif + DerBuffer* privateKey; + byte privateKeyType:7; + byte privateKeyId:1; + int privateKeySz; + int privateKeyDevId; + WOLFSSL_CERT_MANAGER* cm; /* our cert manager, ctx owns SSL will use */ +#endif +#ifdef KEEP_OUR_CERT + WOLFSSL_X509* ourCert; /* keep alive a X509 struct of cert */ + int ownOurCert; /* Dispose of certificate if we own */ +#endif + Suites* suites; /* make dynamic, user may not need/set */ + void* heap; /* for user memory overrides */ + byte verifyDepth; + byte verifyPeer:1; + byte verifyNone:1; + byte failNoCert:1; + byte failNoCertxPSK:1; /* fail if no cert with the exception of PSK*/ + byte sessionCacheOff:1; + byte sessionCacheFlushOff:1; +#ifdef HAVE_EXT_CACHE + byte internalCacheOff:1; +#endif + byte sendVerify:2; /* for client side (can not be single bit) */ + byte haveRSA:1; /* RSA available */ + byte haveECC:1; /* ECC available */ + byte haveDH:1; /* server DH parms set by user */ + byte haveNTRU:1; /* server private NTRU key loaded */ + byte haveECDSAsig:1; /* server cert signed w/ ECDSA */ + byte haveStaticECC:1; /* static server ECC private key */ + byte partialWrite:1; /* only one msg per write call */ + byte quietShutdown:1; /* don't send close notify */ + byte groupMessages:1; /* group handshake messages before sending */ + byte minDowngrade; /* minimum downgrade version */ + byte haveEMS:1; /* have extended master secret extension */ + byte useClientOrder:1; /* Use client's cipher preference order */ +#ifdef WOLFSSL_TLS13 + byte noTicketTls13:1; /* Server won't create new Ticket */ + byte noPskDheKe:1; /* Don't use (EC)DHE with PSK */ +#endif +#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) + byte postHandshakeAuth:1; /* Post-handshake auth supported. */ +#endif +#ifndef NO_DH + #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \ + !defined(HAVE_SELFTEST) + byte dhKeyTested:1; /* Set when key has been tested. */ + #endif +#endif +#ifdef HAVE_SECURE_RENEGOTIATION + byte useSecureReneg:1; /* when set will set WOLFSSL objects generated to enable */ +#endif +#ifdef HAVE_ENCRYPT_THEN_MAC + byte disallowEncThenMac:1; /* Don't do Encrypt-Then-MAC */ +#endif +#ifdef WOLFSSL_STATIC_MEMORY + byte onHeap:1; /* whether the ctx/method is put on heap hint */ +#endif +#ifdef WOLFSSL_MULTICAST + byte haveMcast; /* multicast requested */ + byte mcastID; /* multicast group ID */ +#endif +#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS) + byte dtlsSctp; /* DTLS-over-SCTP mode */ + word16 dtlsMtuSz; /* DTLS MTU size */ +#endif +#ifndef NO_DH + word16 minDhKeySz; /* minimum DH key size */ + word16 maxDhKeySz; /* maximum DH key size */ +#endif +#ifndef NO_RSA + short minRsaKeySz; /* minimum RSA key size */ +#endif +#if defined(HAVE_ECC) || defined(HAVE_ED25519) + short minEccKeySz; /* minimum ECC key size */ +#endif +#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) + unsigned long mask; /* store SSL_OP_ flags */ +#endif +#ifdef OPENSSL_EXTRA + byte sessionCtx[ID_LEN]; /* app session context ID */ + word32 disabledCurves; /* curves disabled by user */ + const unsigned char *alpn_cli_protos;/* ALPN client protocol list */ + unsigned int alpn_cli_protos_len; + byte sessionCtxSz; + byte cbioFlag; /* WOLFSSL_CBIO_RECV/SEND: CBIORecv/Send is set */ + CallbackInfoState* CBIS; /* used to get info about SSL state */ +#endif + CallbackIORecv CBIORecv; + CallbackIOSend CBIOSend; +#ifdef WOLFSSL_DTLS + CallbackGenCookie CBIOCookie; /* gen cookie callback */ +#ifdef WOLFSSL_SESSION_EXPORT + wc_dtls_export dtls_export; /* export function for DTLS session */ + CallbackGetPeer CBGetPeer; + CallbackSetPeer CBSetPeer; +#endif +#endif /* WOLFSSL_DTLS */ + VerifyCallback verifyCallback; /* cert verification callback */ +#ifdef OPENSSL_ALL + CertVerifyCallback verifyCertCb; + void* verifyCertCbArg; +#endif /* OPENSSL_ALL */ + word32 timeout; /* session timeout */ +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + word32 ecdhCurveOID; /* curve Ecc_Sum */ +#endif +#ifdef HAVE_ECC + word16 eccTempKeySz; /* in octets 20 - 66 */ +#endif +#if defined(HAVE_ECC) || defined(HAVE_ED25519) + word32 pkCurveOID; /* curve Ecc_Sum */ +#endif +#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) + byte havePSK; /* psk key set by user */ + wc_psk_client_callback client_psk_cb; /* client callback */ + wc_psk_server_callback server_psk_cb; /* server callback */ +#ifdef WOLFSSL_TLS13 + wc_psk_client_tls13_callback client_psk_tls13_cb; /* client callback */ + wc_psk_server_tls13_callback server_psk_tls13_cb; /* server callback */ +#endif + char server_hint[MAX_PSK_ID_LEN + NULL_TERM_LEN]; +#endif /* HAVE_SESSION_TICKET || !NO_PSK */ +#ifdef WOLFSSL_TLS13 + word16 group[WOLFSSL_MAX_GROUP_COUNT]; + byte numGroups; +#endif +#ifdef WOLFSSL_EARLY_DATA + word32 maxEarlyDataSz; +#endif +#ifdef HAVE_ANON + byte haveAnon; /* User wants to allow Anon suites */ +#endif /* HAVE_ANON */ +#ifdef WOLFSSL_ENCRYPTED_KEYS + pem_password_cb* passwd_cb; + void* passwd_userdata; +#endif +#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) + WOLFSSL_X509_STORE x509_store; /* points to ctx->cm */ + WOLFSSL_X509_STORE* x509_store_pt; /* take ownership of external store */ + byte readAhead; + void* userPRFArg; /* passed to prf callback */ +#endif +#ifdef HAVE_EX_DATA + void* ex_data[MAX_EX_DATA]; +#endif +#if defined(HAVE_ALPN) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) + CallbackALPNSelect alpnSelect; + void* alpnSelectArg; +#endif +#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \ + defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \ + defined(WOLFSSL_HAPROXY))) + CallbackSniRecv sniRecvCb; + void* sniRecvCbArg; +#endif +#if defined(WOLFSSL_MULTICAST) && defined(WOLFSSL_DTLS) + CallbackMcastHighwater mcastHwCb; /* Sequence number highwater callback */ + word32 mcastFirstSeq; /* first trigger level */ + word32 mcastSecondSeq; /* second trigger level */ + word32 mcastMaxSeq; /* max level */ +#endif +#ifdef HAVE_OCSP + WOLFSSL_OCSP ocsp; +#endif + int devId; /* async device id to use */ +#ifdef HAVE_TLS_EXTENSIONS + TLSX* extensions; /* RFC 6066 TLS Extensions data */ + #ifndef NO_WOLFSSL_SERVER + #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + OcspRequest* certOcspRequest; + #endif + #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + OcspRequest* chainOcspRequest[MAX_CHAIN_DEPTH]; + #endif + #endif + #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER) + SessionTicketEncCb ticketEncCb; /* enc/dec session ticket Cb */ + void* ticketEncCtx; /* session encrypt context */ + int ticketHint; /* ticket hint in seconds */ + #endif + #ifdef HAVE_SUPPORTED_CURVES + byte userCurves; /* indicates user called wolfSSL_CTX_UseSupportedCurve */ + #endif +#endif +#ifdef ATOMIC_USER + CallbackMacEncrypt MacEncryptCb; /* Atomic User Mac/Encrypt Cb */ + CallbackDecryptVerify DecryptVerifyCb; /* Atomic User Decrypt/Verify Cb */ + #ifdef HAVE_ENCRYPT_THEN_MAC + CallbackEncryptMac EncryptMacCb; /* Atomic User Mac/Enc Cb */ + CallbackVerifyDecrypt VerifyDecryptCb; /* Atomic User Dec/Verify Cb */ + #endif +#endif +#ifdef HAVE_PK_CALLBACKS + #ifdef HAVE_ECC + CallbackEccKeyGen EccKeyGenCb; /* User EccKeyGen Callback Handler */ + CallbackEccSign EccSignCb; /* User EccSign Callback handler */ + CallbackEccVerify EccVerifyCb; /* User EccVerify Callback handler */ + CallbackEccSharedSecret EccSharedSecretCb; /* User EccVerify Callback handler */ + #ifdef HAVE_ED25519 + /* User Ed25519Sign Callback handler */ + CallbackEd25519Sign Ed25519SignCb; + /* User Ed25519Verify Callback handler */ + CallbackEd25519Verify Ed25519VerifyCb; + #endif + #ifdef HAVE_CURVE25519 + /* User X25519 KeyGen Callback Handler */ + CallbackX25519KeyGen X25519KeyGenCb; + /* User X25519 SharedSecret Callback handler */ + CallbackX25519SharedSecret X25519SharedSecretCb; + #endif + #endif /* HAVE_ECC */ + #ifndef NO_DH + CallbackDhAgree DhAgreeCb; /* User DH Agree Callback handler */ + #endif + #ifndef NO_RSA + CallbackRsaSign RsaSignCb; /* User RsaSign Callback handler (priv key) */ + CallbackRsaVerify RsaVerifyCb; /* User RsaVerify Callback handler (pub key) */ + CallbackRsaVerify RsaSignCheckCb; /* User VerifyRsaSign Callback handler (priv key) */ + #ifdef WC_RSA_PSS + CallbackRsaPssSign RsaPssSignCb; /* User RsaSign (priv key) */ + CallbackRsaPssVerify RsaPssVerifyCb; /* User RsaVerify (pub key) */ + CallbackRsaPssVerify RsaPssSignCheckCb; /* User VerifyRsaSign (priv key) */ + #endif + CallbackRsaEnc RsaEncCb; /* User Rsa Public Encrypt handler */ + CallbackRsaDec RsaDecCb; /* User Rsa Private Decrypt handler */ + #endif /* NO_RSA */ +#endif /* HAVE_PK_CALLBACKS */ +#ifdef HAVE_WOLF_EVENT + WOLF_EVENT_QUEUE event_queue; +#endif /* HAVE_WOLF_EVENT */ +#ifdef HAVE_EXT_CACHE + WOLFSSL_SESSION*(*get_sess_cb)(WOLFSSL*, unsigned char*, int, int*); + int (*new_sess_cb)(WOLFSSL*, WOLFSSL_SESSION*); + void (*rem_sess_cb)(WOLFSSL_CTX*, WOLFSSL_SESSION*); +#endif +#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) + Srp* srp; /* TLS Secure Remote Password Protocol*/ + byte* srp_password; +#endif +}; + +WOLFSSL_LOCAL +int InitSSL_Ctx(WOLFSSL_CTX*, WOLFSSL_METHOD*, void* heap); +WOLFSSL_LOCAL +void FreeSSL_Ctx(WOLFSSL_CTX*); +WOLFSSL_LOCAL +void SSL_CtxResourceFree(WOLFSSL_CTX*); + +WOLFSSL_LOCAL +int DeriveTlsKeys(WOLFSSL* ssl); +WOLFSSL_LOCAL +int ProcessOldClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, + word32 inSz, word16 sz); + +#ifndef NO_CERTS + WOLFSSL_LOCAL + int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify); + WOLFSSL_LOCAL + int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash); +#ifdef WOLFSSL_TRUST_PEER_CERT + WOLFSSL_LOCAL + int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify); + WOLFSSL_LOCAL + int AlreadyTrustedPeer(WOLFSSL_CERT_MANAGER* cm, byte* hash); +#endif +#endif + +/* All cipher suite related info + * Keep as a constant size (no ifdefs) for session export */ +typedef struct CipherSpecs { + word16 key_size; + word16 iv_size; + word16 block_size; + word16 aead_mac_size; + byte bulk_cipher_algorithm; + byte cipher_type; /* block, stream, or aead */ + byte mac_algorithm; + byte kea; /* key exchange algo */ + byte sig_algo; + byte hash_size; + byte pad_size; + byte static_ecdh; +} CipherSpecs; + + +void InitCipherSpecs(CipherSpecs* cs); + + +/* Supported Key Exchange Protocols */ +enum KeyExchangeAlgorithm { + no_kea, + rsa_kea, + diffie_hellman_kea, + fortezza_kea, + psk_kea, + dhe_psk_kea, + ecdhe_psk_kea, + ntru_kea, + ecc_diffie_hellman_kea, + ecc_static_diffie_hellman_kea /* for verify suite only */ +}; + + +/* Supported Authentication Schemes */ +enum SignatureAlgorithm { + anonymous_sa_algo = 0, + rsa_sa_algo = 1, + dsa_sa_algo = 2, + ecc_dsa_sa_algo = 3, + rsa_pss_sa_algo = 8, + ed25519_sa_algo = 9, + rsa_pss_pss_algo = 10 +}; + +#define PSS_RSAE_TO_PSS_PSS(macAlgo) \ + (macAlgo + (pss_sha256 - sha256_mac)) + +#define PSS_PSS_HASH_TO_MAC(macAlgo) \ + (macAlgo - (pss_sha256 - sha256_mac)) + +enum SigAlgRsaPss { + pss_sha256 = 0x09, + pss_sha384 = 0x0a, + pss_sha512 = 0x0b, +}; + + +/* Supprted ECC Curve Types */ +enum EccCurves { + named_curve = 3 +}; + + +/* Valid client certificate request types from page 27 */ +enum ClientCertificateType { + rsa_sign = 1, + dss_sign = 2, + rsa_fixed_dh = 3, + dss_fixed_dh = 4, + rsa_ephemeral_dh = 5, + dss_ephemeral_dh = 6, + fortezza_kea_cert = 20, + ecdsa_sign = 64, + rsa_fixed_ecdh = 65, + ecdsa_fixed_ecdh = 66 +}; + + +#ifndef WOLFSSL_AEAD_ONLY +enum CipherType { stream, block, aead }; +#else +enum CipherType { aead }; +#endif + + +#if defined(BUILD_AES) || defined(BUILD_AESGCM) || (defined(HAVE_CHACHA) && \ + defined(HAVE_POLY1305)) || defined(WOLFSSL_TLS13) + #define CIPHER_NONCE +#endif + + +/* cipher for now */ +typedef struct Ciphers { +#ifdef BUILD_ARC4 + Arc4* arc4; +#endif +#ifdef BUILD_DES3 + Des3* des3; +#endif +#if defined(BUILD_AES) || defined(BUILD_AESGCM) + Aes* aes; + #if (defined(BUILD_AESGCM) || defined(HAVE_AESCCM)) && \ + !defined(WOLFSSL_NO_TLS12) + byte* additional; + #endif +#endif +#ifdef CIPHER_NONCE + byte* nonce; +#endif +#ifdef HAVE_CAMELLIA + Camellia* cam; +#endif +#ifdef HAVE_CHACHA + ChaCha* chacha; +#endif +#ifdef HAVE_HC128 + HC128* hc128; +#endif +#ifdef BUILD_RABBIT + Rabbit* rabbit; +#endif +#ifdef HAVE_IDEA + Idea* idea; +#endif +#if defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER) + Hmac* hmac; +#endif + byte state; + byte setup; /* have we set it up flag for detection */ +} Ciphers; + + +#ifdef HAVE_ONE_TIME_AUTH +/* Ciphers for one time authentication such as poly1305 */ +typedef struct OneTimeAuth { +#ifdef HAVE_POLY1305 + Poly1305* poly1305; +#endif + byte setup; /* flag for if a cipher has been set */ + +} OneTimeAuth; +#endif + + +WOLFSSL_LOCAL void InitCiphers(WOLFSSL* ssl); +WOLFSSL_LOCAL void FreeCiphers(WOLFSSL* ssl); + + +/* hashes type */ +typedef struct Hashes { + #if !defined(NO_MD5) && !defined(NO_OLD_TLS) + byte md5[WC_MD5_DIGEST_SIZE]; + #endif + #if !defined(NO_SHA) + byte sha[WC_SHA_DIGEST_SIZE]; + #endif + #ifndef NO_SHA256 + byte sha256[WC_SHA256_DIGEST_SIZE]; + #endif + #ifdef WOLFSSL_SHA384 + byte sha384[WC_SHA384_DIGEST_SIZE]; + #endif + #ifdef WOLFSSL_SHA512 + byte sha512[WC_SHA512_DIGEST_SIZE]; + #endif +} Hashes; + +WOLFSSL_LOCAL int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes); + +#ifdef WOLFSSL_TLS13 +typedef union Digest { +#ifndef NO_WOLFSSL_SHA256 + wc_Sha256 sha256; +#endif +#ifdef WOLFSSL_SHA384 + wc_Sha384 sha384; +#endif +#ifdef WOLFSSL_SHA512 + wc_Sha512 sha512; +#endif +} Digest; +#endif + +/* Static x509 buffer */ +typedef struct x509_buffer { + int length; /* actual size */ + byte buffer[MAX_X509_SIZE]; /* max static cert size */ +} x509_buffer; + + +/* wolfSSL X509_CHAIN, for no dynamic memory SESSION_CACHE */ +struct WOLFSSL_X509_CHAIN { + int count; /* total number in chain */ + x509_buffer certs[MAX_CHAIN_DEPTH]; /* only allow max depth 4 for now */ +}; + + +/* wolfSSL session type */ +struct WOLFSSL_SESSION { + word32 bornOn; /* create time in seconds */ + word32 timeout; /* timeout in seconds */ + byte sessionID[ID_LEN]; /* id for protocol */ + byte sessionIDSz; + byte masterSecret[SECRET_LEN]; /* stored secret */ + word16 haveEMS; /* ext master secret flag */ +#ifdef SESSION_CERTS + WOLFSSL_X509_CHAIN chain; /* peer cert chain, static */ + #ifdef WOLFSSL_ALT_CERT_CHAINS + WOLFSSL_X509_CHAIN altChain; /* peer alt cert chain, static */ + #endif +#endif +#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \ + defined(HAVE_SESSION_TICKET)) + ProtocolVersion version; /* which version was used */ +#endif +#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \ + (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)) + byte cipherSuite0; /* first byte, normally 0 */ + byte cipherSuite; /* 2nd byte, actual suite */ +#endif +#ifndef NO_CLIENT_CACHE + word16 idLen; /* serverID length */ + byte serverID[SERVER_ID_LEN]; /* for easier client lookup */ +#endif +#ifdef OPENSSL_EXTRA + byte sessionCtxSz; /* sessionCtx length */ + byte sessionCtx[ID_LEN]; /* app specific context id */ +#endif +#ifdef WOLFSSL_TLS13 + word16 namedGroup; +#endif +#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) + #ifdef WOLFSSL_TLS13 + word32 ticketSeen; /* Time ticket seen (ms) */ + word32 ticketAdd; /* Added by client */ + #ifndef WOLFSSL_TLS13_DRAFT_18 + TicketNonce ticketNonce; /* Nonce used to derive PSK */ + #endif + #endif + #ifdef WOLFSSL_EARLY_DATA + word32 maxEarlyDataSz; + #endif +#endif +#ifdef HAVE_SESSION_TICKET + byte* ticket; + word16 ticketLen; + byte staticTicket[SESSION_TICKET_LEN]; + byte isDynamic; +#endif +#ifdef HAVE_EXT_CACHE + byte isAlloced; +#endif +#ifdef HAVE_EX_DATA + void* ex_data[MAX_EX_DATA]; +#endif +}; + + +WOLFSSL_LOCAL +WOLFSSL_SESSION* GetSession(WOLFSSL*, byte*, byte); +WOLFSSL_LOCAL +int SetSession(WOLFSSL*, WOLFSSL_SESSION*); + +typedef int (*hmacfp) (WOLFSSL*, byte*, const byte*, word32, int, int, int); + +#ifndef NO_CLIENT_CACHE + WOLFSSL_SESSION* GetSessionClient(WOLFSSL*, const byte*, int); +#endif + +/* client connect state for nonblocking restart */ +enum ConnectState { + CONNECT_BEGIN = 0, + CLIENT_HELLO_SENT, + HELLO_AGAIN, /* HELLO_AGAIN s for DTLS case */ + HELLO_AGAIN_REPLY, + FIRST_REPLY_DONE, + FIRST_REPLY_FIRST, + FIRST_REPLY_SECOND, + FIRST_REPLY_THIRD, + FIRST_REPLY_FOURTH, + FINISHED_DONE, + SECOND_REPLY_DONE +}; + + +/* server accept state for nonblocking restart */ +enum AcceptState { + ACCEPT_BEGIN = 0, + ACCEPT_BEGIN_RENEG, + ACCEPT_CLIENT_HELLO_DONE, + ACCEPT_HELLO_RETRY_REQUEST_DONE, + ACCEPT_FIRST_REPLY_DONE, + SERVER_HELLO_SENT, + SERVER_EXTENSIONS_SENT, + CERT_SENT, + CERT_VERIFY_SENT, + CERT_STATUS_SENT, + KEY_EXCHANGE_SENT, + CERT_REQ_SENT, + SERVER_HELLO_DONE, + ACCEPT_SECOND_REPLY_DONE, + TICKET_SENT, + CHANGE_CIPHER_SENT, + ACCEPT_FINISHED_DONE, + ACCEPT_THIRD_REPLY_DONE +}; + +/* TLS 1.3 server accept state for nonblocking restart */ +enum AcceptStateTls13 { + TLS13_ACCEPT_BEGIN = 0, + TLS13_ACCEPT_BEGIN_RENEG, + TLS13_ACCEPT_CLIENT_HELLO_DONE, + TLS13_ACCEPT_HELLO_RETRY_REQUEST_DONE, + TLS13_ACCEPT_FIRST_REPLY_DONE, + TLS13_ACCEPT_SECOND_REPLY_DONE, + TLS13_SERVER_HELLO_SENT, + TLS13_ACCEPT_THIRD_REPLY_DONE, + TLS13_SERVER_EXTENSIONS_SENT, + TLS13_CERT_REQ_SENT, + TLS13_CERT_SENT, + TLS13_CERT_VERIFY_SENT, + TLS13_ACCEPT_FINISHED_SENT, + TLS13_PRE_TICKET_SENT, + TLS13_ACCEPT_FINISHED_DONE, + TLS13_TICKET_SENT +}; + +/* buffers for struct WOLFSSL */ +typedef struct Buffers { + bufferStatic inputBuffer; + bufferStatic outputBuffer; + buffer domainName; /* for client check */ + buffer clearOutputBuffer; + buffer sig; /* signature data */ + buffer digest; /* digest data */ + int prevSent; /* previous plain text bytes sent + when got WANT_WRITE */ + 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 */ +#ifndef NO_DH + buffer serverDH_P; /* WOLFSSL_CTX owns, unless we own */ + buffer serverDH_G; /* WOLFSSL_CTX owns, unless we own */ + buffer serverDH_Pub; + buffer serverDH_Priv; + DhKey* serverDH_Key; +#endif +#ifndef NO_CERTS + DerBuffer* certificate; /* WOLFSSL_CTX owns, unless we own */ + DerBuffer* key; /* WOLFSSL_CTX owns, unless we own */ + byte keyType:7; /* Type of key: RSA, ECC, Ed25519 */ + byte keyId:1; /* Key data is an id not data */ + int keySz; /* Size of RSA key */ + int keyDevId; /* Device Id for key */ + DerBuffer* certChain; /* WOLFSSL_CTX owns, unless we own */ + /* chain after self, in DER, with leading size for each cert */ +#ifdef WOLFSSL_TLS13 + int certChainCnt; + DerBuffer* certExts; +#endif +#endif +#ifdef WOLFSSL_SEND_HRR_COOKIE + buffer tls13CookieSecret; /* HRR cookie secret */ +#endif +#ifdef WOLFSSL_DTLS + WOLFSSL_DTLS_CTX dtlsCtx; /* DTLS connection context */ + #ifndef NO_WOLFSSL_SERVER + buffer dtlsCookieSecret; /* DTLS cookie secret */ + #endif /* NO_WOLFSSL_SERVER */ +#endif +#ifdef HAVE_PK_CALLBACKS + #ifdef HAVE_ECC + buffer peerEccDsaKey; /* we own for Ecc Verify Callbacks */ + #endif /* HAVE_ECC */ + #ifdef HAVE_ED25519 + buffer peerEd25519Key; /* for Ed25519 Verify Callbacks */ + #endif /* HAVE_ED25519 */ + #ifndef NO_RSA + buffer peerRsaKey; /* we own for Rsa Verify Callbacks */ + #endif /* NO_RSA */ +#endif /* HAVE_PK_CALLBACKS */ +} Buffers; + +/* sub-states for send/do key share (key exchange) */ +enum asyncState { + TLS_ASYNC_BEGIN = 0, + TLS_ASYNC_BUILD, + TLS_ASYNC_DO, + TLS_ASYNC_VERIFY, + TLS_ASYNC_FINALIZE, + TLS_ASYNC_END +}; + +/* sub-states for build message */ +enum buildMsgState { + BUILD_MSG_BEGIN = 0, + BUILD_MSG_SIZE, + BUILD_MSG_HASH, + BUILD_MSG_VERIFY_MAC, + BUILD_MSG_ENCRYPT, + BUILD_MSG_ENCRYPTED_VERIFY_MAC, +}; + +/* sub-states for cipher operations */ +enum cipherState { + CIPHER_STATE_BEGIN = 0, + CIPHER_STATE_DO, + CIPHER_STATE_END, +}; + +typedef struct Options { +#ifndef NO_PSK + wc_psk_client_callback client_psk_cb; + wc_psk_server_callback server_psk_cb; +#ifdef WOLFSSL_TLS13 + wc_psk_client_tls13_callback client_psk_tls13_cb; /* client callback */ + wc_psk_server_tls13_callback server_psk_tls13_cb; /* server callback */ +#endif +#endif /* NO_PSK */ +#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) + unsigned long mask; /* store SSL_OP_ flags */ +#endif + + /* on/off or small bit flags, optimize layout */ +#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) + word16 havePSK:1; /* psk key set by user */ +#endif /* HAVE_SESSION_TICKET || !NO_PSK */ + word16 sendVerify:2; /* false = 0, true = 1, sendBlank = 2 */ + word16 sessionCacheOff:1; + word16 sessionCacheFlushOff:1; +#ifdef HAVE_EXT_CACHE + word16 internalCacheOff:1; +#endif + word16 side:2; /* client, server or neither end */ + word16 verifyPeer:1; + word16 verifyNone:1; + word16 failNoCert:1; + word16 failNoCertxPSK:1; /* fail for no cert except with PSK */ + word16 downgrade:1; /* allow downgrade of versions */ + word16 resuming:1; + word16 haveSessionId:1; /* server may not send */ + word16 tls:1; /* using TLS ? */ + word16 tls1_1:1; /* using TLSv1.1+ ? */ + word16 tls1_3:1; /* using TLSv1.3+ ? */ + word16 dtls:1; /* using datagrams ? */ + word16 connReset:1; /* has the peer reset */ + word16 isClosed:1; /* if we consider conn closed */ + word16 closeNotify:1; /* we've received a close notify */ + word16 sentNotify:1; /* we've sent a close notify */ + word16 usingCompression:1; /* are we using compression */ + word16 haveRSA:1; /* RSA available */ + word16 haveECC:1; /* ECC available */ + word16 haveDH:1; /* server DH parms set by user */ + word16 haveNTRU:1; /* server NTRU private key loaded */ + word16 haveQSH:1; /* have QSH ability */ + word16 haveECDSAsig:1; /* server ECDSA signed cert */ + word16 haveStaticECC:1; /* static server ECC private key */ + word16 havePeerCert:1; /* do we have peer's cert */ + word16 havePeerVerify:1; /* and peer's cert verify */ + word16 usingPSK_cipher:1; /* are using psk as cipher */ + word16 usingAnon_cipher:1; /* are we using an anon cipher */ + word16 noPskDheKe:1; /* Don't use (EC)DHE with PSK */ + word16 sendAlertState:1; /* nonblocking resume */ + word16 partialWrite:1; /* only one msg per write call */ + word16 quietShutdown:1; /* don't send close notify */ + word16 certOnly:1; /* stop once we get cert */ + word16 groupMessages:1; /* group handshake messages */ + word16 saveArrays:1; /* save array Memory for user get keys + or psk */ + word16 weOwnRng:1; /* will be true unless CTX owns */ + word16 haveEMS:1; /* using extended master secret */ +#ifdef HAVE_POLY1305 + word16 oldPoly:1; /* set when to use old rfc way of poly*/ +#endif +#ifdef HAVE_ANON + word16 haveAnon:1; /* User wants to allow Anon suites */ +#endif +#ifdef HAVE_SESSION_TICKET + word16 createTicket:1; /* Server to create new Ticket */ + word16 useTicket:1; /* Use Ticket not session cache */ + word16 rejectTicket:1; /* Callback rejected ticket */ +#ifdef WOLFSSL_TLS13 + word16 noTicketTls13:1; /* Server won't create new Ticket */ +#endif +#endif +#ifdef WOLFSSL_DTLS + word16 dtlsUseNonblock:1; /* are we using nonblocking socket */ + word16 dtlsHsRetain:1; /* DTLS retaining HS data */ + word16 haveMcast:1; /* using multicast ? */ +#ifdef WOLFSSL_SCTP + word16 dtlsSctp:1; /* DTLS-over-SCTP mode */ +#endif +#endif +#if defined(HAVE_TLS_EXTENSIONS) && defined(HAVE_SUPPORTED_CURVES) + word16 userCurves:1; /* indicates user called wolfSSL_UseSupportedCurve */ +#endif + word16 keepResources:1; /* Keep resources after handshake */ + word16 useClientOrder:1; /* Use client's cipher order */ +#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) + word16 postHandshakeAuth:1;/* Client send post_handshake_auth + * extension */ +#endif +#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER) + word16 sendCookie:1; /* Server creates a Cookie in HRR */ +#endif +#ifdef WOLFSSL_ALT_CERT_CHAINS + word16 usingAltCertChain:1;/* Alternate cert chain was used */ +#endif +#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT) + word16 sentChangeCipher:1; /* Change Cipher Spec sent */ +#endif +#if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ + !defined(NO_ED25519_CLIENT_AUTH) + word16 cacheMessages:1; /* Cache messages for sign/verify */ +#endif +#ifndef NO_DH + #if !defined(WOLFSSL_OLD_PRIME_CHECK) && \ + !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + word16 dhDoKeyTest:1; /* Need to do the DH Key prime test */ + word16 dhKeyTested:1; /* Set when key has been tested. */ + #endif +#endif +#ifdef SINGLE_THREADED + word16 ownSuites:1; /* if suites are malloced in ssl object */ +#endif +#ifdef HAVE_ENCRYPT_THEN_MAC + word16 disallowEncThenMac:1; /* Don't do Encrypt-Then-MAC */ + word16 encThenMac:1; /* Doing Encrypt-Then-MAC */ + word16 startedETMRead:1; /* Doing Encrypt-Then-MAC read */ + word16 startedETMWrite:1; /* Doing Encrypt-Then-MAC write */ +#endif + + /* need full byte values for this section */ + byte processReply; /* nonblocking resume */ + byte cipherSuite0; /* first byte, normally 0 */ + byte cipherSuite; /* second byte, actual suite */ + byte serverState; + byte clientState; + byte handShakeState; + byte handShakeDone; /* at least one handshake complete */ + byte minDowngrade; /* minimum downgrade version */ + byte connectState; /* nonblocking resume */ + byte acceptState; /* nonblocking resume */ + byte asyncState; /* sub-state for enum asyncState */ + byte buildMsgState; /* sub-state for enum buildMsgState */ + byte alertCount; /* detect warning dos attempt */ +#ifdef WOLFSSL_MULTICAST + word16 mcastID; /* Multicast group ID */ +#endif +#ifndef NO_DH + word16 minDhKeySz; /* minimum DH key size */ + word16 maxDhKeySz; /* minimum DH key size */ + word16 dhKeySz; /* actual DH key size */ +#endif +#ifndef NO_RSA + short minRsaKeySz; /* minimum RSA key size */ +#endif +#if defined(HAVE_ECC) || defined(HAVE_ED25519) + short minEccKeySz; /* minimum ECC key size */ +#endif +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + byte verifyDepth; /* maximum verification depth */ +#endif +#ifdef WOLFSSL_EARLY_DATA + word16 pskIdIndex; + word32 maxEarlyDataSz; +#endif +#ifdef WOLFSSL_TLS13 + byte oldMinor; /* client preferred version < TLS 1.3 */ +#endif +} Options; + +typedef struct Arrays { + byte* pendingMsg; /* defrag buffer */ + byte* preMasterSecret; + word32 preMasterSz; /* differs for DH, actual size */ + word32 pendingMsgSz; /* defrag buffer size */ + word32 pendingMsgOffset; /* current offset into defrag buffer */ +#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) + word32 psk_keySz; /* actual size */ + char client_identity[MAX_PSK_ID_LEN + NULL_TERM_LEN]; + char server_hint[MAX_PSK_ID_LEN + NULL_TERM_LEN]; + byte psk_key[MAX_PSK_KEY_LEN]; +#endif + byte clientRandom[RAN_LEN]; + byte serverRandom[RAN_LEN]; + byte sessionID[ID_LEN]; + byte sessionIDSz; +#ifdef WOLFSSL_TLS13 + byte secret[SECRET_LEN]; +#endif + byte masterSecret[SECRET_LEN]; +#if defined(WOLFSSL_RENESAS_TSIP_TLS) && \ + !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION) + byte tsip_masterSecret[TSIP_TLS_MASTERSECRET_SIZE]; +#endif +#ifdef WOLFSSL_DTLS + byte cookie[MAX_COOKIE_LEN]; + byte cookieSz; +#endif + byte pendingMsgType; /* defrag buffer message type */ +} Arrays; + +#ifndef ASN_NAME_MAX +#define ASN_NAME_MAX 256 +#endif + +#ifndef MAX_DATE_SZ +#define MAX_DATE_SZ 32 +#endif + +#define STACK_TYPE_X509 0 +#define STACK_TYPE_GEN_NAME 1 +#define STACK_TYPE_BIO 2 +#define STACK_TYPE_OBJ 3 +#define STACK_TYPE_STRING 4 +#define STACK_TYPE_CIPHER 5 +#define STACK_TYPE_ACCESS_DESCRIPTION 6 +#define STACK_TYPE_X509_EXT 7 +#define STACK_TYPE_NULL 8 +#define STACK_TYPE_X509_NAME 9 +#define STACK_TYPE_CONF_VALUE 10 +#define STACK_TYPE_X509_INFO 11 + +struct WOLFSSL_STACK { + unsigned long num; /* number of nodes in stack + * (safety measure for freeing and shortcut for count) */ + #if defined(OPENSSL_ALL) + wolf_sk_compare_cb comp; + #endif + + union { + WOLFSSL_X509* x509; + WOLFSSL_X509_NAME* name; + WOLFSSL_X509_INFO* info; + WOLFSSL_BIO* bio; + WOLFSSL_ASN1_OBJECT* obj; + WOLFSSL_CIPHER cipher; + WOLFSSL_ACCESS_DESCRIPTION* access; + WOLFSSL_X509_EXTENSION* ext; + WOLFSSL_CONF_VALUE* conf; + void* generic; + char* string; + WOLFSSL_GENERAL_NAME* gn; + } data; + void* heap; /* memory heap hint */ + WOLFSSL_STACK* next; + byte type; /* Identifies type of stack. */ +}; + +struct WOLFSSL_X509_NAME { + char *name; + int dynamicName; + int sz; + char staticName[ASN_NAME_MAX]; +#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ + !defined(NO_ASN) + DecodedName fullName; + WOLFSSL_X509_NAME_ENTRY cnEntry; + WOLFSSL_X509_NAME_ENTRY extra[MAX_NAME_ENTRIES]; /* extra entries added */ + WOLFSSL_X509* x509; /* x509 that struct belongs to */ +#endif /* OPENSSL_EXTRA */ +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) + byte raw[ASN_NAME_MAX]; + int rawLen; +#endif +}; + +#ifndef EXTERNAL_SERIAL_SIZE + #define EXTERNAL_SERIAL_SIZE 32 +#endif + +#ifdef NO_ASN + typedef struct DNS_entry DNS_entry; +#endif + +struct WOLFSSL_X509 { + int version; + int serialSz; +#ifdef WOLFSSL_SEP + int deviceTypeSz; + int hwTypeSz; + byte deviceType[EXTERNAL_SERIAL_SIZE]; + byte hwType[EXTERNAL_SERIAL_SIZE]; + int hwSerialNumSz; + byte hwSerialNum[EXTERNAL_SERIAL_SIZE]; +#endif /* WOLFSSL_SEP */ +#if (defined(WOLFSSL_SEP) || defined(WOLFSSL_QT) || defined (OPENSSL_ALL)) && \ + (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) + byte certPolicySet; + byte certPolicyCrit; +#endif /* (WOLFSSL_SEP || WOLFSSL_QT) && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */ +#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) + WOLFSSL_STACK* ext_sk; /* Store X509_EXTENSIONS from wolfSSL_X509_get_ext */ + WOLFSSL_STACK* ext_d2i;/* Store d2i extensions from wolfSSL_X509_get_ext_d2i */ +#endif /* WOLFSSL_QT || OPENSSL_ALL */ +#ifdef OPENSSL_EXTRA + WOLFSSL_ASN1_INTEGER* serialNumber; /* Stores SN from wolfSSL_X509_get_serialNumber */ +#endif + WOLFSSL_ASN1_TIME notBefore; + WOLFSSL_ASN1_TIME notAfter; + buffer sig; + int sigOID; + DNS_entry* altNames; /* alt names list */ + buffer pubKey; + int pubKeyOID; + DNS_entry* altNamesNext; /* hint for retrieval */ +#if defined(HAVE_ECC) || defined(HAVE_ED25519) + word32 pkCurveOID; +#endif /* HAVE_ECC */ +#ifndef NO_CERTS + DerBuffer* derCert; /* may need */ +#endif + void* heap; /* heap hint */ + byte dynamicMemory; /* dynamic memory flag */ + byte isCa:1; +#ifdef WOLFSSL_CERT_EXT + char certPolicies[MAX_CERTPOL_NB][MAX_CERTPOL_SZ]; + int certPoliciesNb; +#endif /* WOLFSSL_CERT_EXT */ +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) + wolfSSL_Mutex refMutex; /* ref count mutex */ + int refCount; /* reference count */ +#endif +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) +#ifdef HAVE_EX_DATA + void* ex_data[MAX_EX_DATA]; +#endif + byte* authKeyId; + byte* subjKeyId; + byte* extKeyUsageSrc; + const byte* CRLInfo; + byte* authInfo; +#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) + byte* authInfoCaIssuer; + int authInfoCaIssuerSz; +#endif + word32 pathLength; + word16 keyUsage; + int CRLInfoSz; + int authInfoSz; + word32 authKeyIdSz; + word32 subjKeyIdSz; + word32 extKeyUsageSz; + word32 extKeyUsageCount; + + byte CRLdistSet:1; + byte CRLdistCrit:1; + byte authInfoSet:1; + byte authInfoCrit:1; + byte keyUsageSet:1; + byte keyUsageCrit:1; + byte extKeyUsageCrit:1; + byte subjKeyIdSet:1; + + byte subjKeyIdCrit:1; + byte basicConstSet:1; + byte basicConstCrit:1; + byte basicConstPlSet:1; + byte subjAltNameSet:1; + byte subjAltNameCrit:1; + byte authKeyIdSet:1; + byte authKeyIdCrit:1; +#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ + byte serial[EXTERNAL_SERIAL_SIZE]; + char subjectCN[ASN_NAME_MAX]; /* common name short cut */ +#ifdef WOLFSSL_CERT_REQ + char challengePw[CTC_NAME_SIZE]; /* for REQ certs */ +#endif + WOLFSSL_X509_NAME issuer; + WOLFSSL_X509_NAME subject; +#if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY) + WOLFSSL_X509_ALGOR algor; + WOLFSSL_X509_PUBKEY key; +#endif +}; + + +/* record layer header for PlainText, Compressed, and CipherText */ +typedef struct RecordLayerHeader { + byte type; + byte pvMajor; + byte pvMinor; + byte length[2]; +} RecordLayerHeader; + + +/* record layer header for DTLS PlainText, Compressed, and CipherText */ +typedef struct DtlsRecordLayerHeader { + byte type; + byte pvMajor; + byte pvMinor; + byte sequence_number[8]; /* per record */ + byte length[2]; +} DtlsRecordLayerHeader; + + +typedef struct DtlsFrag { + word32 begin; + word32 end; + struct DtlsFrag* next; +} DtlsFrag; + + +typedef struct DtlsMsg { + struct DtlsMsg* next; + byte* buf; + byte* msg; + DtlsFrag* fragList; + word32 fragSz; /* Length of fragments received */ + word32 seq; /* Handshake sequence number */ + word32 sz; /* Length of whole message */ + byte type; +} DtlsMsg; + + +#ifdef HAVE_NETX + + /* NETX I/O Callback default */ + typedef struct NetX_Ctx { + NX_TCP_SOCKET* nxSocket; /* send/recv socket handle */ + NX_PACKET* nxPacket; /* incoming packet handle for short reads */ + ULONG nxOffset; /* offset already read from nxPacket */ + ULONG nxWait; /* wait option flag */ + } NetX_Ctx; + +#endif + +/* Handshake messages received from peer (plus change cipher */ +typedef struct MsgsReceived { + word16 got_hello_request:1; + word16 got_client_hello:2; + word16 got_server_hello:2; + word16 got_hello_verify_request:1; + word16 got_session_ticket:1; + word16 got_end_of_early_data:1; + word16 got_hello_retry_request:1; + word16 got_encrypted_extensions:1; + word16 got_certificate:1; + word16 got_certificate_status:1; + word16 got_server_key_exchange:1; + word16 got_certificate_request:1; + word16 got_server_hello_done:1; + word16 got_certificate_verify:1; + word16 got_client_key_exchange:1; + word16 got_finished:1; + word16 got_key_update:1; + word16 got_change_cipher:1; +} MsgsReceived; + + +/* Handshake hashes */ +typedef struct HS_Hashes { + Hashes verifyHashes; + Hashes certHashes; /* for cert verify */ +#ifndef NO_SHA + wc_Sha hashSha; /* sha hash of handshake msgs */ +#endif +#if !defined(NO_MD5) && !defined(NO_OLD_TLS) + wc_Md5 hashMd5; /* md5 hash of handshake msgs */ +#endif +#ifndef NO_SHA256 + wc_Sha256 hashSha256; /* sha256 hash of handshake msgs */ +#endif +#ifdef WOLFSSL_SHA384 + wc_Sha384 hashSha384; /* sha384 hash of handshake msgs */ +#endif +#ifdef WOLFSSL_SHA512 + wc_Sha512 hashSha512; /* sha512 hash of handshake msgs */ +#endif +#if defined(HAVE_ED25519) && !defined(WOLFSSL_NO_CLIENT_AUTH) + byte* messages; /* handshake messages */ + int length; /* length of handshake messages' data */ + int prevLen; /* length of messages but last */ +#endif +} HS_Hashes; + + +#ifdef WOLFSSL_ASYNC_CRYPT + #define MAX_ASYNC_ARGS 18 + typedef void (*FreeArgsCb)(struct WOLFSSL* ssl, void* pArgs); + + struct WOLFSSL_ASYNC { + WC_ASYNC_DEV* dev; + FreeArgsCb freeArgs; /* function pointer to cleanup args */ + word32 args[MAX_ASYNC_ARGS]; /* holder for current args */ + }; +#endif + +#ifdef HAVE_WRITE_DUP + + #define WRITE_DUP_SIDE 1 + #define READ_DUP_SIDE 2 + + typedef struct WriteDup { + wolfSSL_Mutex dupMutex; /* reference count mutex */ + int dupCount; /* reference count */ + int dupErr; /* under dupMutex, pass to other side */ + } WriteDup; + + WOLFSSL_LOCAL void FreeWriteDup(WOLFSSL* ssl); + WOLFSSL_LOCAL int NotifyWriteSide(WOLFSSL* ssl, int err); +#endif /* HAVE_WRITE_DUP */ + +#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) +typedef struct CertReqCtx CertReqCtx; + +struct CertReqCtx { + CertReqCtx* next; + byte len; + byte ctx; +}; +#endif + +#ifdef WOLFSSL_EARLY_DATA +typedef enum EarlyDataState { + no_early_data, + early_data_ext, + expecting_early_data, + process_early_data, + done_early_data +} EarlyDataState; +#endif + +/* wolfSSL ssl type */ +struct WOLFSSL { + WOLFSSL_CTX* ctx; + Suites* suites; /* only need during handshake */ + Arrays* arrays; +#ifdef WOLFSSL_TLS13 + byte clientSecret[SECRET_LEN]; + byte serverSecret[SECRET_LEN]; +#endif + HS_Hashes* hsHashes; + void* IOCB_ReadCtx; + void* IOCB_WriteCtx; + WC_RNG* rng; + void* verifyCbCtx; /* cert verify callback user ctx*/ + VerifyCallback verifyCallback; /* cert verification callback */ + void* heap; /* for user overrides */ +#ifdef HAVE_WRITE_DUP + WriteDup* dupWrite; /* valid pointer indicates ON */ + /* side that decrements dupCount to zero frees overall structure */ + byte dupSide; /* write side or read side */ +#endif +#ifdef OPENSSL_EXTRA + byte cbioFlag; /* WOLFSSL_CBIO_RECV/SEND: CBIORecv/Send is set */ +#endif + CallbackIORecv CBIORecv; + CallbackIOSend CBIOSend; +#ifdef WOLFSSL_STATIC_MEMORY + WOLFSSL_HEAP_HINT heap_hint; +#endif +#ifndef NO_HANDSHAKE_DONE_CB + HandShakeDoneCb hsDoneCb; /* notify user handshake done */ + void* hsDoneCtx; /* user handshake cb context */ +#endif +#ifdef WOLFSSL_ASYNC_CRYPT + struct WOLFSSL_ASYNC async; +#elif defined(WOLFSSL_NONBLOCK_OCSP) + void* nonblockarg; /* dynamic arg for handling non-block resume */ +#endif + void* hsKey; /* Handshake key (RsaKey or ecc_key) allocated from heap */ + word32 hsType; /* Type of Handshake key (hsKey) */ + WOLFSSL_CIPHER cipher; +#ifndef WOLFSSL_AEAD_ONLY + hmacfp hmac; +#endif + Ciphers encrypt; + Ciphers decrypt; + Buffers buffers; + WOLFSSL_SESSION session; +#ifdef HAVE_EXT_CACHE + WOLFSSL_SESSION* extSession; +#endif + WOLFSSL_ALERT_HISTORY alert_history; + int error; + int rfd; /* read file descriptor */ + int wfd; /* write file descriptor */ + int rflags; /* user read flags */ + int wflags; /* user write flags */ + word32 timeout; /* session timeout */ + word32 fragOffset; /* fragment offset */ + word16 curSize; + byte verifyDepth; + RecordLayerHeader curRL; + MsgsReceived msgsReceived; /* peer messages received */ + ProtocolVersion version; /* negotiated version */ + ProtocolVersion chVersion; /* client hello version */ + CipherSpecs specs; + Keys keys; + Options options; +#ifdef OPENSSL_EXTRA + CallbackInfoState* CBIS; /* used to get info about SSL state */ + int cbmode; /* read or write on info callback */ + int cbtype; /* event type in info callback */ + WOLFSSL_BIO* biord; /* socket bio read to free/close */ + WOLFSSL_BIO* biowr; /* socket bio write to free/close */ + byte sessionCtx[ID_LEN]; /* app session context ID */ + WOLFSSL_X509_VERIFY_PARAM* param; /* verification parameters*/ +#endif +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + unsigned long peerVerifyRet; +#endif +#ifdef OPENSSL_EXTRA + byte readAhead; + byte sessionCtxSz; /* size of sessionCtx stored */ +#ifdef HAVE_PK_CALLBACKS + void* loggingCtx; /* logging callback argument */ +#endif +#endif /* OPENSSL_EXTRA */ +#ifndef NO_RSA + RsaKey* peerRsaKey; +#ifdef WOLFSSL_RENESAS_TSIP_TLS + byte *peerTsipEncRsaKeyIndex; +#endif + byte peerRsaKeyPresent; +#endif +#ifdef HAVE_QSH + QSHKey* QSH_Key; + QSHKey* peerQSHKey; + QSHSecret* QSH_secret; + byte isQSH; /* is the handshake a QSH? */ + byte sendQSHKeys; /* flag for if the client should sen + public keys */ + byte peerQSHKeyPresent; + byte minRequest; + byte maxRequest; + byte user_set_QSHSchemes; +#endif +#if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) + word16 namedGroup; +#endif +#ifdef WOLFSSL_TLS13 + word16 group[WOLFSSL_MAX_GROUP_COUNT]; + byte numGroups; +#endif + word16 pssAlgo; +#ifdef WOLFSSL_TLS13 + #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22) + word16 certHashSigAlgoSz; /* SigAlgoCert ext length in bytes */ + byte certHashSigAlgo[WOLFSSL_MAX_SIGALGO]; /* cert sig/algo to + * offer */ + #endif /* !WOLFSSL_TLS13_DRAFT_18 && !WOLFSSL_TLS13_DRAFT_22 */ +#endif +#ifdef HAVE_NTRU + word16 peerNtruKeyLen; + byte peerNtruKey[MAX_NTRU_PUB_KEY_SZ]; + byte peerNtruKeyPresent; +#endif +#if defined(HAVE_ECC) || defined(HAVE_ED25519) + int eccVerifyRes; +#endif +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + word32 ecdhCurveOID; /* curve Ecc_Sum */ + ecc_key* eccTempKey; /* private ECDHE key */ + byte eccTempKeyPresent; /* also holds type */ + byte peerEccKeyPresent; +#endif +#ifdef HAVE_ECC + ecc_key* peerEccKey; /* peer's ECDHE key */ + ecc_key* peerEccDsaKey; /* peer's ECDSA key */ + word16 eccTempKeySz; /* in octets 20 - 66 */ + byte peerEccDsaKeyPresent; +#endif +#if defined(HAVE_ECC) || defined(HAVE_ED25519) + word32 pkCurveOID; /* curve Ecc_Sum */ +#endif +#ifdef HAVE_ED25519 + ed25519_key* peerEd25519Key; + byte peerEd25519KeyPresent; +#endif +#ifdef HAVE_CURVE25519 + curve25519_key* peerX25519Key; + byte peerX25519KeyPresent; +#endif +#ifdef HAVE_LIBZ + z_stream c_stream; /* compression stream */ + z_stream d_stream; /* decompression stream */ + byte didStreamInit; /* for stream init and end */ +#endif +#ifdef WOLFSSL_DTLS + int dtls_timeout_init; /* starting timeout value */ + int dtls_timeout_max; /* maximum timeout value */ + int dtls_timeout; /* current timeout value, changes */ + word32 dtls_tx_msg_list_sz; + word32 dtls_rx_msg_list_sz; + DtlsMsg* dtls_tx_msg_list; + DtlsMsg* dtls_tx_msg; + DtlsMsg* dtls_rx_msg_list; + void* IOCB_CookieCtx; /* gen cookie ctx */ + word32 dtls_expected_rx; +#ifdef WOLFSSL_SESSION_EXPORT + wc_dtls_export dtls_export; /* export function for session */ +#endif +#ifdef WOLFSSL_SCTP + word16 dtlsMtuSz; +#endif /* WOLFSSL_SCTP */ +#ifdef WOLFSSL_MULTICAST + void* mcastHwCbCtx; /* Multicast highwater callback ctx */ +#endif /* WOLFSSL_MULTICAST */ +#ifdef WOLFSSL_DTLS_DROP_STATS + word32 macDropCount; + word32 replayDropCount; +#endif /* WOLFSSL_DTLS_DROP_STATS */ +#endif /* WOLFSSL_DTLS */ +#ifdef WOLFSSL_CALLBACKS + TimeoutInfo timeoutInfo; /* info saved during handshake */ + HandShakeInfo handShakeInfo; /* info saved during handshake */ +#endif +#ifdef OPENSSL_EXTRA + SSL_Msg_Cb protoMsgCb; /* inspect protocol message callback */ + void* protoMsgCtx; /* user set context with msg callback */ +#endif +#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA) + byte hsInfoOn; /* track handshake info */ + byte toInfoOn; /* track timeout info */ +#endif +#ifdef HAVE_FUZZER + CallbackFuzzer fuzzerCb; /* for testing with using fuzzer */ + void* fuzzerCtx; /* user defined pointer */ +#endif +#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) + CertReqCtx* certReqCtx; +#endif +#ifdef KEEP_PEER_CERT + WOLFSSL_X509 peerCert; /* X509 peer cert */ +#endif +#ifdef KEEP_OUR_CERT + WOLFSSL_X509* ourCert; /* keep alive a X509 struct of cert. + points to ctx if not owned (owned + flag found in buffers.weOwnCert) */ +#endif + byte keepCert; /* keep certificate after handshake */ +#if defined(HAVE_EX_DATA) || defined(FORTRESS) + void* ex_data[MAX_EX_DATA]; /* external data, for Fortress */ +#endif + int devId; /* async device id to use */ +#ifdef HAVE_ONE_TIME_AUTH + OneTimeAuth auth; +#endif +#ifdef HAVE_TLS_EXTENSIONS + TLSX* extensions; /* RFC 6066 TLS Extensions data */ + #ifdef HAVE_MAX_FRAGMENT + word16 max_fragment; + #endif + #ifdef HAVE_TRUNCATED_HMAC + byte truncated_hmac; + #endif + #ifdef HAVE_CERTIFICATE_STATUS_REQUEST + byte status_request; + #endif + #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 + byte status_request_v2; + #endif + #if defined(HAVE_SECURE_RENEGOTIATION) \ + || defined(HAVE_SERVER_RENEGOTIATION_INFO) + int secure_rene_count; /* how many times */ + SecureRenegotiation* secure_renegotiation; /* valid pointer indicates */ + #endif /* user turned on */ + #ifdef HAVE_ALPN + char* alpn_client_list; /* keep the client's list */ + #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) + CallbackALPNSelect alpnSelect; + void* alpnSelectArg; + #endif + #endif /* of accepted protocols */ + #if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET) + CallbackSessionTicket session_ticket_cb; + void* session_ticket_ctx; + byte expect_session_ticket; + #endif +#endif /* HAVE_TLS_EXTENSIONS */ +#ifdef HAVE_OCSP + void* ocspIOCtx; + #ifdef OPENSSL_EXTRA + byte* ocspResp; + int ocspRespSz; + #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) + char* url; + #endif + #endif +#endif +#ifdef HAVE_NETX + NetX_Ctx nxCtx; /* NetX IO Context */ +#endif +#if defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP) + void* mnCtx; /* mynewt mn_socket IO Context */ +#endif /* defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP) */ +#ifdef WOLFSSL_GNRC + struct gnrc_wolfssl_ctx *gnrcCtx; /* Riot-OS GNRC UDP/IP context */ +#endif +#ifdef SESSION_INDEX + int sessionIndex; /* Session's location in the cache. */ +#endif +#ifdef ATOMIC_USER + void* MacEncryptCtx; /* Atomic User Mac/Encrypt Callback Context */ + void* DecryptVerifyCtx; /* Atomic User Decrypt/Verify Callback Context */ + #ifdef HAVE_ENCRYPT_THEN_MAC + void* EncryptMacCtx; /* Atomic User Encrypt/Mac Callback Ctx */ + void* VerifyDecryptCtx; /* Atomic User Verify/Decrypt Callback Ctx */ + #endif +#endif +#ifdef HAVE_PK_CALLBACKS + #ifdef HAVE_ECC + void* EccKeyGenCtx; /* EccKeyGen Callback Context */ + void* EccSignCtx; /* Ecc Sign Callback Context */ + void* EccVerifyCtx; /* Ecc Verify Callback Context */ + void* EccSharedSecretCtx; /* Ecc Pms Callback Context */ + #ifdef HAVE_ED25519 + void* Ed25519SignCtx; /* ED25519 Sign Callback Context */ + void* Ed25519VerifyCtx; /* ED25519 Verify Callback Context */ + #endif + #ifdef HAVE_CURVE25519 + void* X25519KeyGenCtx; /* X25519 KeyGen Callback Context */ + void* X25519SharedSecretCtx; /* X25519 Pms Callback Context */ + #endif + #endif /* HAVE_ECC */ + #ifndef NO_DH + void* DhAgreeCtx; /* DH Pms Callback Context */ + #endif /* !NO_DH */ + #ifndef NO_RSA + void* RsaSignCtx; /* Rsa Sign Callback Context */ + void* RsaVerifyCtx; /* Rsa Verify Callback Context */ + #ifdef WC_RSA_PSS + void* RsaPssSignCtx; /* Rsa PSS Sign Callback Context */ + void* RsaPssVerifyCtx; /* Rsa PSS Verify Callback Context */ + #endif + void* RsaEncCtx; /* Rsa Public Encrypt Callback Context */ + void* RsaDecCtx; /* Rsa Private Decrypt Callback Context */ + #endif /* NO_RSA */ +#endif /* HAVE_PK_CALLBACKS */ +#ifdef HAVE_SECRET_CALLBACK + SessionSecretCb sessionSecretCb; + void* sessionSecretCtx; +#endif /* HAVE_SECRET_CALLBACK */ +#ifdef WOLFSSL_JNI + void* jObjectRef; /* reference to WolfSSLSession in JNI wrapper */ +#endif /* WOLFSSL_JNI */ +#ifdef WOLFSSL_EARLY_DATA + EarlyDataState earlyData; + word32 earlyDataSz; +#endif +#ifdef OPENSSL_ALL + long verifyCallbackResult; +#endif +}; + + +WOLFSSL_LOCAL int SSL_CTX_RefCount(WOLFSSL_CTX* ctx, int incr); +WOLFSSL_LOCAL int SetSSL_CTX(WOLFSSL*, WOLFSSL_CTX*, int); +WOLFSSL_LOCAL int InitSSL(WOLFSSL*, WOLFSSL_CTX*, int); +WOLFSSL_LOCAL void FreeSSL(WOLFSSL*, void* heap); +WOLFSSL_API void SSL_ResourceFree(WOLFSSL*); /* Micrium uses */ + + +#ifndef NO_CERTS + + WOLFSSL_LOCAL int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, + long sz, int format, int type, WOLFSSL* ssl, + long* used, int userChain, int verify); + WOLFSSL_LOCAL int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, + int type, WOLFSSL* ssl, int userChain, + WOLFSSL_CRL* crl, int verify); + + #ifdef OPENSSL_EXTRA + WOLFSSL_LOCAL int CheckHostName(DecodedCert* dCert, char *domainName, + size_t domainNameLen); + #endif +#endif + + +#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA) + WOLFSSL_LOCAL + void InitHandShakeInfo(HandShakeInfo*, WOLFSSL*); + WOLFSSL_LOCAL + void FinishHandShakeInfo(HandShakeInfo*); + WOLFSSL_LOCAL + void AddPacketName(WOLFSSL* ssl, const char* name); + + WOLFSSL_LOCAL + void InitTimeoutInfo(TimeoutInfo*); + WOLFSSL_LOCAL + void FreeTimeoutInfo(TimeoutInfo*, void*); + WOLFSSL_LOCAL + void AddPacketInfo(WOLFSSL* ssl, const char* name, int type, + const byte* data, int sz, int write, void* heap); + WOLFSSL_LOCAL + void AddLateName(const char*, TimeoutInfo*); + WOLFSSL_LOCAL + void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info); +#endif + + +/* Record Layer Header identifier from page 12 */ +enum ContentType { + no_type = 0, + change_cipher_spec = 20, + alert = 21, + handshake = 22, + application_data = 23 +}; + + +/* handshake header, same for each message type, pgs 20/21 */ +typedef struct HandShakeHeader { + byte type; + word24 length; +} HandShakeHeader; + + +/* DTLS handshake header, same for each message type */ +typedef struct DtlsHandShakeHeader { + byte type; + word24 length; + byte message_seq[2]; /* start at 0, retransmit gets same # */ + word24 fragment_offset; /* bytes in previous fragments */ + word24 fragment_length; /* length of this fragment */ +} DtlsHandShakeHeader; + + +enum HandShakeType { + hello_request = 0, + client_hello = 1, + server_hello = 2, + hello_verify_request = 3, /* DTLS addition */ + session_ticket = 4, + end_of_early_data = 5, + hello_retry_request = 6, + encrypted_extensions = 8, + certificate = 11, + server_key_exchange = 12, + certificate_request = 13, + server_hello_done = 14, + certificate_verify = 15, + client_key_exchange = 16, + finished = 20, + certificate_status = 22, + key_update = 24, + change_cipher_hs = 55, /* simulate unique handshake type for sanity + checks. record layer change_cipher + conflicts with handshake finished */ + message_hash = 254, /* synthetic message type for TLS v1.3 */ + no_shake = 255 /* used to initialize the DtlsMsg record */ +}; + +enum ProvisionSide { + PROVISION_CLIENT = 1, + PROVISION_SERVER = 2, + PROVISION_CLIENT_SERVER = 3 +}; + + +static const byte client[SIZEOF_SENDER] = { 0x43, 0x4C, 0x4E, 0x54 }; +static const byte server[SIZEOF_SENDER] = { 0x53, 0x52, 0x56, 0x52 }; + +static const byte tls_client[FINISHED_LABEL_SZ + 1] = "client finished"; +static const byte tls_server[FINISHED_LABEL_SZ + 1] = "server finished"; + + +/* internal functions */ +WOLFSSL_LOCAL int SendChangeCipher(WOLFSSL*); +WOLFSSL_LOCAL int SendTicket(WOLFSSL*); +WOLFSSL_LOCAL int DoClientTicket(WOLFSSL*, const byte*, word32); +WOLFSSL_LOCAL int SendData(WOLFSSL*, const void*, int); +#ifdef WOLFSSL_TLS13 +#ifdef WOLFSSL_TLS13_DRAFT_18 +WOLFSSL_LOCAL int SendTls13HelloRetryRequest(WOLFSSL*); +#else +WOLFSSL_LOCAL int SendTls13ServerHello(WOLFSSL*, byte); +#endif +#endif +WOLFSSL_LOCAL int SendCertificate(WOLFSSL*); +WOLFSSL_LOCAL int SendCertificateRequest(WOLFSSL*); +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) +WOLFSSL_LOCAL int CreateOcspResponse(WOLFSSL*, OcspRequest**, buffer*); +#endif +#if defined(HAVE_SECURE_RENEGOTIATION) && \ + defined(HAVE_SERVER_RENEGOTIATION_INFO) +WOLFSSL_LOCAL int SendHelloRequest(WOLFSSL*); +#endif +WOLFSSL_LOCAL int SendCertificateStatus(WOLFSSL*); +WOLFSSL_LOCAL int SendServerKeyExchange(WOLFSSL*); +WOLFSSL_LOCAL int SendBuffered(WOLFSSL*); +WOLFSSL_LOCAL int ReceiveData(WOLFSSL*, byte*, int, int); +WOLFSSL_LOCAL int SendFinished(WOLFSSL*); +WOLFSSL_LOCAL int SendAlert(WOLFSSL*, int, int); +WOLFSSL_LOCAL int ProcessReply(WOLFSSL*); + +WOLFSSL_LOCAL int SetCipherSpecs(WOLFSSL*); +WOLFSSL_LOCAL int MakeMasterSecret(WOLFSSL*); + +WOLFSSL_LOCAL int AddSession(WOLFSSL*); +WOLFSSL_LOCAL int DeriveKeys(WOLFSSL* ssl); +WOLFSSL_LOCAL int StoreKeys(WOLFSSL* ssl, const byte* keyData, int side); + +WOLFSSL_LOCAL int IsTLS(const WOLFSSL* ssl); +WOLFSSL_LOCAL int IsAtLeastTLSv1_2(const WOLFSSL* ssl); +WOLFSSL_LOCAL int IsAtLeastTLSv1_3(const ProtocolVersion pv); + +WOLFSSL_LOCAL void FreeHandshakeResources(WOLFSSL* ssl); +WOLFSSL_LOCAL void ShrinkInputBuffer(WOLFSSL* ssl, int forcedFree); +WOLFSSL_LOCAL void ShrinkOutputBuffer(WOLFSSL* ssl); + +WOLFSSL_LOCAL int VerifyClientSuite(WOLFSSL* ssl); + +WOLFSSL_LOCAL int SetTicket(WOLFSSL*, const byte*, word32); +WOLFSSL_LOCAL int wolfSSL_GetMaxRecordSize(WOLFSSL* ssl, int maxFragment); + +#ifndef NO_CERTS + #ifndef NO_RSA + #ifdef WC_RSA_PSS + WOLFSSL_LOCAL int CheckRsaPssPadding(const byte* plain, word32 plainSz, + byte* out, word32 sigSz, enum wc_HashType hashType); + WOLFSSL_LOCAL int ConvertHashPss(int hashAlgo, + enum wc_HashType* hashType, int* mgf); + #endif + WOLFSSL_LOCAL int VerifyRsaSign(WOLFSSL* ssl, byte* verifySig, + word32 sigSz, const byte* plain, word32 plainSz, int sigAlgo, + int hashAlgo, RsaKey* key, DerBuffer* keyBufInfo); + WOLFSSL_LOCAL int RsaSign(WOLFSSL* ssl, const byte* in, word32 inSz, + byte* out, word32* outSz, int sigAlgo, int hashAlgo, RsaKey* key, + DerBuffer* keyBufInfo); + WOLFSSL_LOCAL int RsaVerify(WOLFSSL* ssl, byte* in, word32 inSz, + byte** out, int sigAlgo, int hashAlgo, RsaKey* key, + buffer* keyBufInfo); + WOLFSSL_LOCAL int RsaDec(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, + word32* outSz, RsaKey* key, DerBuffer* keyBufInfo); + WOLFSSL_LOCAL int RsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out, + word32* outSz, RsaKey* key, buffer* keyBufInfo); + #endif /* !NO_RSA */ + + #ifdef HAVE_ECC + WOLFSSL_LOCAL int EccSign(WOLFSSL* ssl, const byte* in, word32 inSz, + byte* out, word32* outSz, ecc_key* key, DerBuffer* keyBufInfo); + WOLFSSL_LOCAL int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, + const byte* out, word32 outSz, ecc_key* key, buffer* keyBufInfo); + WOLFSSL_LOCAL int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, + ecc_key* pub_key, byte* pubKeyDer, word32* pubKeySz, byte* out, + word32* outlen, int side); + #endif /* HAVE_ECC */ + #ifdef HAVE_ED25519 + WOLFSSL_LOCAL int Ed25519CheckPubKey(WOLFSSL* ssl); + WOLFSSL_LOCAL int Ed25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz, + byte* out, word32* outSz, ed25519_key* key, DerBuffer* keyBufInfo); + WOLFSSL_LOCAL int Ed25519Verify(WOLFSSL* ssl, const byte* in, + word32 inSz, const byte* msg, word32 msgSz, ed25519_key* key, + buffer* keyBufInfo); + #endif /* HAVE_ED25519 */ + + + #ifdef WOLFSSL_TRUST_PEER_CERT + + /* options for searching hash table for a matching trusted peer cert */ + #define WC_MATCH_SKID 0 + #define WC_MATCH_NAME 1 + + WOLFSSL_LOCAL TrustedPeerCert* GetTrustedPeer(void* vp, byte* hash, + int type); + WOLFSSL_LOCAL int MatchTrustedPeer(TrustedPeerCert* tp, + DecodedCert* cert); + #endif + + WOLFSSL_LOCAL Signer* GetCA(void* cm, byte* hash); + #ifndef NO_SKID + WOLFSSL_LOCAL Signer* GetCAByName(void* cm, byte* hash); + #endif +#endif /* !NO_CERTS */ +WOLFSSL_LOCAL int BuildTlsHandshakeHash(WOLFSSL* ssl, byte* hash, + word32* hashLen); +WOLFSSL_LOCAL int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, + const byte* sender); +WOLFSSL_LOCAL void FreeArrays(WOLFSSL* ssl, int keep); +WOLFSSL_LOCAL int CheckAvailableSize(WOLFSSL *ssl, int size); +WOLFSSL_LOCAL int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength); + +#ifndef NO_TLS + WOLFSSL_LOCAL int MakeTlsMasterSecret(WOLFSSL*); +#ifndef WOLFSSL_AEAD_ONLY + WOLFSSL_LOCAL int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, + word32 sz, int padSz, int content, int verify); +#endif +#endif + +#ifndef NO_WOLFSSL_CLIENT + WOLFSSL_LOCAL int SendClientHello(WOLFSSL*); + #ifdef WOLFSSL_TLS13 + WOLFSSL_LOCAL int SendTls13ClientHello(WOLFSSL*); + #endif + WOLFSSL_LOCAL int SendClientKeyExchange(WOLFSSL*); + WOLFSSL_LOCAL int SendCertificateVerify(WOLFSSL*); +#endif /* NO_WOLFSSL_CLIENT */ + +#ifndef NO_WOLFSSL_SERVER + WOLFSSL_LOCAL int SendServerHello(WOLFSSL*); + WOLFSSL_LOCAL int SendServerHelloDone(WOLFSSL*); +#endif /* NO_WOLFSSL_SERVER */ + +#ifdef WOLFSSL_DTLS + WOLFSSL_LOCAL DtlsMsg* DtlsMsgNew(word32, void*); + WOLFSSL_LOCAL void DtlsMsgDelete(DtlsMsg*, void*); + WOLFSSL_LOCAL void DtlsMsgListDelete(DtlsMsg*, void*); + WOLFSSL_LOCAL int DtlsMsgSet(DtlsMsg*, word32, const byte*, byte, + word32, word32, void*); + WOLFSSL_LOCAL DtlsMsg* DtlsMsgFind(DtlsMsg*, word32); + WOLFSSL_LOCAL void DtlsMsgStore(WOLFSSL*, word32, const byte*, word32, + byte, word32, word32, void*); + WOLFSSL_LOCAL DtlsMsg* DtlsMsgInsert(DtlsMsg*, DtlsMsg*); + + WOLFSSL_LOCAL int DtlsMsgPoolSave(WOLFSSL*, const byte*, word32); + WOLFSSL_LOCAL int DtlsMsgPoolTimeout(WOLFSSL*); + WOLFSSL_LOCAL int VerifyForDtlsMsgPoolSend(WOLFSSL*, byte, word32); + WOLFSSL_LOCAL void DtlsMsgPoolReset(WOLFSSL*); + WOLFSSL_LOCAL int DtlsMsgPoolSend(WOLFSSL*, int); +#endif /* WOLFSSL_DTLS */ + +#ifndef NO_TLS + + +#endif /* NO_TLS */ + +#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)) + WOLFSSL_LOCAL word32 TimeNowInMilliseconds(void); +#endif +WOLFSSL_LOCAL word32 LowResTimer(void); + +#ifndef NO_CERTS + WOLFSSL_LOCAL void InitX509Name(WOLFSSL_X509_NAME*, int); + WOLFSSL_LOCAL void FreeX509Name(WOLFSSL_X509_NAME* name, void* heap); + WOLFSSL_LOCAL void InitX509(WOLFSSL_X509*, int, void* heap); + WOLFSSL_LOCAL void FreeX509(WOLFSSL_X509*); + WOLFSSL_LOCAL int CopyDecodedToX509(WOLFSSL_X509*, DecodedCert*); +#endif + +typedef struct CipherSuiteInfo { + const char* name; +#ifndef NO_ERROR_STRINGS + const char* name_iana; +#endif + byte cipherSuite0; + byte cipherSuite; +} CipherSuiteInfo; + +WOLFSSL_LOCAL const CipherSuiteInfo* GetCipherNames(void); +WOLFSSL_LOCAL int GetCipherNamesSize(void); +WOLFSSL_LOCAL const char* GetCipherNameInternal(const byte cipherSuite0, const byte cipherSuite); +WOLFSSL_LOCAL const char* GetCipherNameIana(const byte cipherSuite0, const byte cipherSuite); +WOLFSSL_LOCAL const char* wolfSSL_get_cipher_name_internal(WOLFSSL* ssl); +WOLFSSL_LOCAL const char* wolfSSL_get_cipher_name_iana(WOLFSSL* ssl); +WOLFSSL_LOCAL int GetCipherSuiteFromName(const char* name, byte* cipherSuite0, + byte* cipherSuite); + +enum encrypt_side { + ENCRYPT_SIDE_ONLY = 1, + DECRYPT_SIDE_ONLY, + ENCRYPT_AND_DECRYPT_SIDE +}; + +WOLFSSL_LOCAL int SetKeysSide(WOLFSSL*, enum encrypt_side); + + +#ifndef NO_DH + WOLFSSL_LOCAL int DhGenKeyPair(WOLFSSL* ssl, DhKey* dhKey, + byte* priv, word32* privSz, + byte* pub, word32* pubSz); + WOLFSSL_LOCAL int DhAgree(WOLFSSL* ssl, DhKey* dhKey, + const byte* priv, word32 privSz, + const byte* otherPub, word32 otherPubSz, + byte* agree, word32* agreeSz); +#endif /* !NO_DH */ + +#ifdef HAVE_ECC + WOLFSSL_LOCAL int EccMakeKey(WOLFSSL* ssl, ecc_key* key, ecc_key* peer); +#endif + +WOLFSSL_LOCAL int InitHandshakeHashes(WOLFSSL* ssl); +WOLFSSL_LOCAL void FreeHandshakeHashes(WOLFSSL* ssl); + +WOLFSSL_LOCAL int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, + const byte* input, int inSz, int type, int hashOutput, + int sizeOnly, int asyncOkay); + +#ifdef WOLFSSL_TLS13 +int BuildTls13Message(WOLFSSL* ssl, byte* output, int outSz, const byte* input, + int inSz, int type, int hashOutput, int sizeOnly, int asyncOkay); +#endif + +WOLFSSL_LOCAL int AllocKey(WOLFSSL* ssl, int type, void** pKey); +WOLFSSL_LOCAL void FreeKey(WOLFSSL* ssl, int type, void** pKey); + +#ifdef WOLFSSL_ASYNC_CRYPT + WOLFSSL_LOCAL int wolfSSL_AsyncInit(WOLFSSL* ssl, WC_ASYNC_DEV* asyncDev, word32 flags); + WOLFSSL_LOCAL int wolfSSL_AsyncPop(WOLFSSL* ssl, byte* state); + WOLFSSL_LOCAL int wolfSSL_AsyncPush(WOLFSSL* ssl, WC_ASYNC_DEV* asyncDev); +#endif + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* wolfSSL_INT_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/ocsp.h b/wolfssl_hlavickove_subory/wolfssl/ocsp.h new file mode 100644 index 0000000..1174a21 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/ocsp.h @@ -0,0 +1,133 @@ +/* ocsp.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +/* wolfSSL OCSP API */ + +#ifndef WOLFSSL_OCSP_H +#define WOLFSSL_OCSP_H + +#ifdef HAVE_OCSP + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct WOLFSSL_OCSP WOLFSSL_OCSP; + +#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(WOLFSSL_NGINX) ||\ + defined(WOLFSSL_HAPROXY) +typedef struct OcspResponse WOLFSSL_OCSP_BASICRESP; + +typedef struct OcspRequest WOLFSSL_OCSP_CERTID; + +typedef struct OcspRequest WOLFSSL_OCSP_ONEREQ; + +typedef struct OcspRequest WOLFSSL_OCSP_REQUEST; +#endif + +WOLFSSL_LOCAL int InitOCSP(WOLFSSL_OCSP*, WOLFSSL_CERT_MANAGER*); +WOLFSSL_LOCAL void FreeOCSP(WOLFSSL_OCSP*, int dynamic); + +WOLFSSL_LOCAL int CheckCertOCSP(WOLFSSL_OCSP*, DecodedCert*, + WOLFSSL_BUFFER_INFO* responseBuffer); +WOLFSSL_LOCAL int CheckCertOCSP_ex(WOLFSSL_OCSP*, DecodedCert*, + WOLFSSL_BUFFER_INFO* responseBuffer, WOLFSSL* ssl); +WOLFSSL_LOCAL int CheckOcspRequest(WOLFSSL_OCSP* ocsp, + OcspRequest* ocspRequest, WOLFSSL_BUFFER_INFO* responseBuffer); +WOLFSSL_LOCAL int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz, + WOLFSSL_BUFFER_INFO *responseBuffer, CertStatus *status, + OcspEntry *entry, OcspRequest *ocspRequest); + +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ + defined(WOLFSSL_APACHE_HTTPD) + + WOLFSSL_API int wolfSSL_OCSP_resp_find_status(WOLFSSL_OCSP_BASICRESP *bs, + WOLFSSL_OCSP_CERTID *id, int *status, int *reason, + WOLFSSL_ASN1_TIME **revtime, WOLFSSL_ASN1_TIME **thisupd, + WOLFSSL_ASN1_TIME **nextupd); +WOLFSSL_API const char *wolfSSL_OCSP_cert_status_str(long s); +WOLFSSL_API int wolfSSL_OCSP_check_validity(WOLFSSL_ASN1_TIME* thisupd, + WOLFSSL_ASN1_TIME* nextupd, long sec, long maxsec); + +WOLFSSL_API void wolfSSL_OCSP_CERTID_free(WOLFSSL_OCSP_CERTID* certId); +WOLFSSL_API WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id( + const WOLFSSL_EVP_MD *dgst, const WOLFSSL_X509 *subject, + const WOLFSSL_X509 *issuer); + +WOLFSSL_API void wolfSSL_OCSP_BASICRESP_free(WOLFSSL_OCSP_BASICRESP* basicResponse); +WOLFSSL_API int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP *bs, + WOLF_STACK_OF(WOLFSSL_X509) *certs, WOLFSSL_X509_STORE *st, unsigned long flags); + +WOLFSSL_API void wolfSSL_OCSP_RESPONSE_free(OcspResponse* response); +WOLFSSL_API OcspResponse* wolfSSL_d2i_OCSP_RESPONSE_bio(WOLFSSL_BIO* bio, + OcspResponse** response); +WOLFSSL_API OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response, + const unsigned char** data, int len); +WOLFSSL_API int wolfSSL_i2d_OCSP_RESPONSE(OcspResponse* response, + unsigned char** data); +WOLFSSL_API int wolfSSL_OCSP_response_status(OcspResponse *response); +WOLFSSL_API const char *wolfSSL_OCSP_response_status_str(long s); +WOLFSSL_API WOLFSSL_OCSP_BASICRESP* wolfSSL_OCSP_response_get1_basic( + OcspResponse* response); + +WOLFSSL_API OcspRequest* wolfSSL_OCSP_REQUEST_new(void); +WOLFSSL_API void wolfSSL_OCSP_REQUEST_free(OcspRequest* request); +WOLFSSL_API int wolfSSL_i2d_OCSP_REQUEST(OcspRequest* request, + unsigned char** data); +WOLFSSL_API WOLFSSL_OCSP_ONEREQ* wolfSSL_OCSP_request_add0_id(OcspRequest *req, + WOLFSSL_OCSP_CERTID *cid); +WOLFSSL_API WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_CERTID_dup(WOLFSSL_OCSP_CERTID*); +WOLFSSL_API int wolfSSL_i2d_OCSP_REQUEST_bio(WOLFSSL_BIO* out, + WOLFSSL_OCSP_REQUEST *req); + +#endif +#ifdef OPENSSL_EXTRA +WOLFSSL_API int wolfSSL_OCSP_REQUEST_add_ext(OcspRequest* req, + WOLFSSL_X509_EXTENSION* ext, int idx); +WOLFSSL_API OcspResponse* wolfSSL_OCSP_response_create(int status, + WOLFSSL_OCSP_BASICRESP* bs); +WOLFSSL_API const char* wolfSSL_OCSP_crl_reason_str(long s); + +WOLFSSL_API int wolfSSL_OCSP_id_get0_info(WOLFSSL_ASN1_STRING**, + WOLFSSL_ASN1_OBJECT**, WOLFSSL_ASN1_STRING**, + WOLFSSL_ASN1_INTEGER**, WOLFSSL_OCSP_CERTID*); + +WOLFSSL_API int wolfSSL_OCSP_request_add1_nonce(OcspRequest* req, + unsigned char* val, int sz); +WOLFSSL_API int wolfSSL_OCSP_check_nonce(OcspRequest* req, + WOLFSSL_OCSP_BASICRESP* bs); +#endif + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* HAVE_OCSP */ +#endif /* WOLFSSL_OCSP_H */ + + diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/aes.h b/wolfssl_hlavickove_subory/wolfssl/openssl/aes.h new file mode 100644 index 0000000..37d9d9b --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/aes.h @@ -0,0 +1,111 @@ +/* aes.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +/* aes.h defines mini des openssl compatibility layer + * + */ + + +#ifndef WOLFSSL_AES_H_ +#define WOLFSSL_AES_H_ + +#include + +#ifndef NO_AES +#include /* for size_t */ + +#ifdef __cplusplus + extern "C" { +#endif + +/* This structure wrapper is done because there is no aes_new function with + * OpenSSL compatibility layer. This makes code working with an AES structure + * to need the size of the structure. */ +typedef struct WOLFSSL_AES_KEY { + /* aligned and big enough for Aes from wolfssl/wolfcrypt/aes.h */ + ALIGN16 void* holder[(376 + WC_ASYNC_DEV_SIZE)/ sizeof(void*)]; + #ifdef GCM_TABLE + /* key-based fast multiplication table. */ + ALIGN16 void* M0[4096 / sizeof(void*)]; + #endif /* GCM_TABLE */ + #if defined(WOLFSSL_DEVCRYPTO) && \ + (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC)) + /* large enough for additional devcrypto information */ + void* devKey[288 / sizeof(void*)]; + #endif + #ifdef WOLFSSL_AFALG + void* afalg_holder[288 / sizeof(void*)]; + #endif + #ifdef HAVE_PKCS11 + void* pkcs11_holder[(AES_MAX_ID_LEN + sizeof(int)) / sizeof(void*)]; + #endif + #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) + void* async_holder[128 / sizeof(void*)]; + #endif +} WOLFSSL_AES_KEY; +typedef WOLFSSL_AES_KEY AES_KEY; + +WOLFSSL_API int wolfSSL_AES_set_encrypt_key + (const unsigned char *, const int bits, AES_KEY *); +WOLFSSL_API int wolfSSL_AES_set_decrypt_key + (const unsigned char *, const int bits, AES_KEY *); +WOLFSSL_API void wolfSSL_AES_cbc_encrypt + (const unsigned char *in, unsigned char* out, size_t len, + AES_KEY *key, unsigned char* iv, const int enc); +WOLFSSL_API void wolfSSL_AES_ecb_encrypt + (const unsigned char *in, unsigned char* out, + AES_KEY *key, const int enc); +WOLFSSL_API void wolfSSL_AES_cfb128_encrypt + (const unsigned char *in, unsigned char* out, size_t len, + AES_KEY *key, unsigned char* iv, int* num, const int enc); + +#define AES_cbc_encrypt wolfSSL_AES_cbc_encrypt +#define AES_ecb_encrypt wolfSSL_AES_ecb_encrypt +#define AES_cfb128_encrypt wolfSSL_AES_cfb128_encrypt +#define AES_set_encrypt_key wolfSSL_AES_set_encrypt_key +#define AES_set_decrypt_key wolfSSL_AES_set_decrypt_key + +#ifdef WOLFSSL_AES_DIRECT +WOLFSSL_API void wolfSSL_AES_encrypt + (const unsigned char* input, unsigned char* output, AES_KEY *); +WOLFSSL_API void wolfSSL_AES_decrypt + (const unsigned char* input, unsigned char* output, AES_KEY *); + +#define AES_encrypt wolfSSL_AES_encrypt +#define AES_decrypt wolfSSL_AES_decrypt +#endif /* HAVE_AES_DIRECT */ + +#ifndef AES_ENCRYPT +#define AES_ENCRYPT AES_ENCRYPTION +#endif +#ifndef AES_DECRYPT +#define AES_DECRYPT AES_DECRYPTION +#endif + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* NO_AES */ + +#endif /* WOLFSSL_AES_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/asn1.h b/wolfssl_hlavickove_subory/wolfssl/openssl/asn1.h new file mode 100644 index 0000000..fb83ae4 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/asn1.h @@ -0,0 +1,84 @@ +/* asn1.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* asn1.h for openssl */ + +#ifndef WOLFSSL_ASN1_H_ +#define WOLFSSL_ASN1_H_ + +#include + +#define ASN1_STRING_new wolfSSL_ASN1_STRING_new +#define ASN1_STRING_type_new wolfSSL_ASN1_STRING_type_new +#define ASN1_STRING_type wolfSSL_ASN1_STRING_type +#define ASN1_STRING_set wolfSSL_ASN1_STRING_set +#define ASN1_STRING_free wolfSSL_ASN1_STRING_free + +#define V_ASN1_INTEGER 0x02 +#define V_ASN1_OCTET_STRING 0x04 /* tag for ASN1_OCTET_STRING */ +#define V_ASN1_NEG 0x100 +#define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG) +#define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG) + +/* Type for ASN1_print_ex */ +# define ASN1_STRFLGS_ESC_2253 1 +# define ASN1_STRFLGS_ESC_CTRL 2 +# define ASN1_STRFLGS_ESC_MSB 4 +# define ASN1_STRFLGS_ESC_QUOTE 8 +# define ASN1_STRFLGS_UTF8_CONVERT 0x10 +# define ASN1_STRFLGS_IGNORE_TYPE 0x20 +# define ASN1_STRFLGS_SHOW_TYPE 0x40 +# define ASN1_STRFLGS_DUMP_ALL 0x80 +# define ASN1_STRFLGS_DUMP_UNKNOWN 0x100 +# define ASN1_STRFLGS_DUMP_DER 0x200 +# define ASN1_STRFLGS_RFC2253 (ASN1_STRFLGS_ESC_2253 | \ + ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + ASN1_STRFLGS_UTF8_CONVERT | \ + ASN1_STRFLGS_DUMP_UNKNOWN | \ + ASN1_STRFLGS_DUMP_DER) + +#define MBSTRING_UTF8 0x1000 +#define MBSTRING_ASC 0x1001 +#define MBSTRING_BMP 0x1002 +#define MBSTRING_UNIV 0x1004 + +#define ASN1_UTCTIME_print wolfSSL_ASN1_UTCTIME_print +#define ASN1_TIME_check wolfSSL_ASN1_TIME_check +#define ASN1_TIME_diff wolfSSL_ASN1_TIME_diff +#define ASN1_TIME_set wolfSSL_ASN1_TIME_set + +#define V_ASN1_UTCTIME 23 +#define V_ASN1_GENERALIZEDTIME 24 + +#define ASN1_STRING_FLAG_BITS_LEFT 0x008 +#define ASN1_STRING_FLAG_NDEF 0x010 +#define ASN1_STRING_FLAG_CONT 0x020 +#define ASN1_STRING_FLAG_MSTRING 0x040 +#define ASN1_STRING_FLAG_EMBED 0x080 + + +WOLFSSL_API WOLFSSL_ASN1_INTEGER *wolfSSL_BN_to_ASN1_INTEGER( + const WOLFSSL_BIGNUM*, WOLFSSL_ASN1_INTEGER*); +#define BN_to_ASN1_INTEGER wolfSSL_BN_to_ASN1_INTEGER + + +#endif /* WOLFSSL_ASN1_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/bio.h b/wolfssl_hlavickove_subory/wolfssl/openssl/bio.h new file mode 100644 index 0000000..e5fe8de --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/bio.h @@ -0,0 +1,159 @@ +/* bio.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* bio.h for openssl */ + + +#ifndef WOLFSSL_BIO_H_ +#define WOLFSSL_BIO_H_ + +#include + + +#ifdef __cplusplus + extern "C" { +#endif + + +#define BIO_FLAG_BASE64_NO_NL WOLFSSL_BIO_FLAG_BASE64_NO_NL +#define BIO_FLAG_READ WOLFSSL_BIO_FLAG_READ +#define BIO_FLAG_WRITE WOLFSSL_BIO_FLAG_WRITE +#define BIO_FLAG_IO_SPECIAL WOLFSSL_BIO_FLAG_IO_SPECIAL +#define BIO_FLAG_RETRY WOLFSSL_BIO_FLAG_RETRY + +#define BIO_new_fp wolfSSL_BIO_new_fp +#define BIO_new_file wolfSSL_BIO_new_file +#define BIO_new_fp wolfSSL_BIO_new_fp +#define BIO_ctrl wolfSSL_BIO_ctrl +#define BIO_ctrl_pending wolfSSL_BIO_ctrl_pending +#define BIO_wpending wolfSSL_BIO_wpending +#define BIO_get_mem_ptr wolfSSL_BIO_get_mem_ptr +#define BIO_int_ctrl wolfSSL_BIO_int_ctrl +#define BIO_reset wolfSSL_BIO_reset +#define BIO_s_file wolfSSL_BIO_s_file +#define BIO_s_bio wolfSSL_BIO_s_bio +#define BIO_s_socket wolfSSL_BIO_s_socket +#define BIO_set_fd wolfSSL_BIO_set_fd +#define BIO_ctrl_reset_read_request wolfSSL_BIO_ctrl_reset_read_request + +#define BIO_set_write_buf_size wolfSSL_BIO_set_write_buf_size +#define BIO_make_bio_pair wolfSSL_BIO_make_bio_pair + +#define BIO_set_fp wolfSSL_BIO_set_fp +#define BIO_get_fp wolfSSL_BIO_get_fp +#define BIO_seek wolfSSL_BIO_seek +#define BIO_write_filename wolfSSL_BIO_write_filename +#define BIO_set_mem_eof_return wolfSSL_BIO_set_mem_eof_return + +#define BIO_find_type wolfSSL_BIO_find_type +#define BIO_next wolfSSL_BIO_next +#define BIO_gets wolfSSL_BIO_gets +#define BIO_puts wolfSSL_BIO_puts + +#define BIO_should_retry(...) 1 + +#define BIO_TYPE_FILE WOLFSSL_BIO_FILE +#define BIO_TYPE_BIO WOLFSSL_BIO_BIO +#define BIO_TYPE_MEM WOLFSSL_BIO_MEMORY +#define BIO_TYPE_BASE64 WOLFSSL_BIO_BASE64 + +#define BIO_printf wolfSSL_BIO_printf +#define BIO_dump wolfSSL_BIO_dump + +/* BIO info callback */ +#define BIO_CB_FREE WOLFSSL_BIO_CB_FREE +#define BIO_CB_READ WOLFSSL_BIO_CB_READ +#define BIO_CB_WRITE WOLFSSL_BIO_CB_WRITE +#define BIO_CB_PUTS WOLFSSL_BIO_CB_PUTS +#define BIO_CB_GETS WOLFSSL_BIO_CB_GETS +#define BIO_CB_CTRL WOLFSSL_BIO_CB_CTRL +#define BIO_CB_RETURN WOLFSSL_BIO_CB_RETURN + +#define BIO_set_callback wolfSSL_BIO_set_callback +#define BIO_get_callback wolfSSL_BIO_get_callback +#define BIO_set_callback_arg wolfSSL_BIO_set_callback_arg +#define BIO_get_callback_arg wolfSSL_BIO_get_callback_arg + +/* BIO for 1.1.0 or later */ +#define BIO_set_init wolfSSL_BIO_set_init +#define BIO_get_data wolfSSL_BIO_get_data +#define BIO_set_data wolfSSL_BIO_set_data +#define BIO_get_shutdown wolfSSL_BIO_get_shutdown +#define BIO_set_shutdown wolfSSL_BIO_set_shutdown + +/* helper to set specific retry/read flags */ +#define BIO_set_retry_read(bio)\ + wolfSSL_BIO_set_flags((bio), WOLFSSL_BIO_FLAG_RETRY | WOLFSSL_BIO_FLAG_READ) +#define BIO_set_retry_write(bio)\ + wolfSSL_BIO_set_flags((bio), WOLFSSL_BIO_FLAG_RETRY | WOLFSSL_BIO_FLAG_WRITE) + +#define BIO_clear_retry_flags wolfSSL_BIO_clear_retry_flags + +#define BIO_meth_new wolfSSL_BIO_meth_new +#define BIO_meth_set_write wolfSSL_BIO_meth_set_write +#define BIO_meth_free wolfSSL_BIO_meth_free +#define BIO_meth_set_write wolfSSL_BIO_meth_set_write +#define BIO_meth_set_read wolfSSL_BIO_meth_set_read +#define BIO_meth_set_puts wolfSSL_BIO_meth_set_puts +#define BIO_meth_set_gets wolfSSL_BIO_meth_set_gets +#define BIO_meth_set_ctrl wolfSSL_BIO_meth_set_ctrl +#define BIO_meth_set_create wolfSSL_BIO_meth_set_create +#define BIO_meth_set_destroy wolfSSL_BIO_meth_set_destroy + + +/* BIO CTRL */ +#define BIO_CTRL_RESET 1 +#define BIO_CTRL_EOF 2 +#define BIO_CTRL_INFO 3 +#define BIO_CTRL_PUSH 6 +#define BIO_CTRL_POP 7 +#define BIO_CTRL_GET_CLOSE 8 +#define BIO_CTRL_SET_CLOSE 9 +#define BIO_CTRL_PENDING 10 +#define BIO_CTRL_FLUSH 11 +#define BIO_CTRL_DUP 12 +#define BIO_CTRL_WPENDING 13 + +#define BIO_C_SET_FILE_PTR 106 +#define BIO_C_GET_FILE_PTR 107 +#define BIO_C_SET_FILENAME 108 +#define BIO_C_SET_BUF_MEM 114 +#define BIO_C_GET_BUF_MEM_PTR 115 +#define BIO_C_FILE_SEEK 128 +#define BIO_C_SET_BUF_MEM_EOF_RETURN 130 +#define BIO_C_SET_WRITE_BUF_SIZE 136 +#define BIO_C_MAKE_BIO_PAIR 138 + +#define BIO_CTRL_DGRAM_QUERY_MTU 40 + +#define BIO_NOCLOSE 0x00 +#define BIO_CLOSE 0x01 + +#define BIO_FP_WRITE 0x04 + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* WOLFSSL_BIO_H_ */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/bn.h b/wolfssl_hlavickove_subory/wolfssl/openssl/bn.h new file mode 100644 index 0000000..9ca0b1e --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/bn.h @@ -0,0 +1,213 @@ +/* bn.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* bn.h for openssl */ + +/*! + \file wolfssl/openssl/bn.h + \brief bn.h for openssl +*/ + + +#ifndef WOLFSSL_BN_H_ +#define WOLFSSL_BN_H_ + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct WOLFSSL_BIGNUM { + int neg; /* openssh deference */ + void *internal; /* our big num */ +#ifdef WOLFSSL_SP_MATH + sp_int fp; +#elif defined(USE_FAST_MATH) && !defined(HAVE_WOLF_BIGINT) + fp_int fp; +#endif +} WOLFSSL_BIGNUM; + + +#define WOLFSSL_BN_ULONG mp_digit + +typedef struct WOLFSSL_BN_CTX WOLFSSL_BN_CTX; +typedef struct WOLFSSL_BN_GENCB WOLFSSL_BN_GENCB; + +WOLFSSL_API WOLFSSL_BN_CTX* wolfSSL_BN_CTX_new(void); +WOLFSSL_API void wolfSSL_BN_CTX_init(WOLFSSL_BN_CTX*); +WOLFSSL_API void wolfSSL_BN_CTX_free(WOLFSSL_BN_CTX*); + +WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_BN_new(void); +#if defined(USE_FAST_MATH) && !defined(HAVE_WOLF_BIGINT) +WOLFSSL_API void wolfSSL_BN_init(WOLFSSL_BIGNUM *); +#endif +WOLFSSL_API void wolfSSL_BN_free(WOLFSSL_BIGNUM*); +WOLFSSL_API void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM*); + + +WOLFSSL_API int wolfSSL_BN_sub(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, + const WOLFSSL_BIGNUM*); +WOLFSSL_API int wolfSSL_BN_mod(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, + const WOLFSSL_BIGNUM*, const WOLFSSL_BN_CTX*); +WOLFSSL_API int wolfSSL_BN_mod_exp(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a, + const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx); +WOLFSSL_API int wolfSSL_BN_mod_mul(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a, + const WOLFSSL_BIGNUM *b, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx); +WOLFSSL_API const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void); + + +WOLFSSL_API int wolfSSL_BN_num_bytes(const WOLFSSL_BIGNUM*); +WOLFSSL_API int wolfSSL_BN_num_bits(const WOLFSSL_BIGNUM*); + +WOLFSSL_API int wolfSSL_BN_is_zero(const WOLFSSL_BIGNUM*); +WOLFSSL_API int wolfSSL_BN_is_one(const WOLFSSL_BIGNUM*); +WOLFSSL_API int wolfSSL_BN_is_odd(const WOLFSSL_BIGNUM*); +WOLFSSL_API int wolfSSL_BN_is_negative(const WOLFSSL_BIGNUM*); + +WOLFSSL_API int wolfSSL_BN_cmp(const WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*); + +WOLFSSL_API int wolfSSL_BN_bn2bin(const WOLFSSL_BIGNUM*, unsigned char*); +WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char*, int len, + WOLFSSL_BIGNUM* ret); + +WOLFSSL_API int wolfSSL_mask_bits(WOLFSSL_BIGNUM*, int n); + +WOLFSSL_API int wolfSSL_BN_pseudo_rand(WOLFSSL_BIGNUM*, int bits, int top, + int bottom); +WOLFSSL_API int wolfSSL_BN_rand(WOLFSSL_BIGNUM*, int bits, int top, int bottom); +WOLFSSL_API int wolfSSL_BN_is_bit_set(const WOLFSSL_BIGNUM*, int n); +WOLFSSL_API int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM**, const char* str); + +WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_BN_dup(const WOLFSSL_BIGNUM*); +WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_BN_copy(WOLFSSL_BIGNUM*, + const WOLFSSL_BIGNUM*); + +WOLFSSL_API int wolfSSL_BN_dec2bn(WOLFSSL_BIGNUM**, const char* str); +WOLFSSL_API char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM*); + +WOLFSSL_API int wolfSSL_BN_lshift(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, int); +WOLFSSL_API int wolfSSL_BN_add_word(WOLFSSL_BIGNUM*, WOLFSSL_BN_ULONG); +WOLFSSL_API int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM*, int); +WOLFSSL_API int wolfSSL_BN_set_word(WOLFSSL_BIGNUM*, WOLFSSL_BN_ULONG); +WOLFSSL_API unsigned long wolfSSL_BN_get_word(const WOLFSSL_BIGNUM*); + +WOLFSSL_API int wolfSSL_BN_add(WOLFSSL_BIGNUM*, WOLFSSL_BIGNUM*, + WOLFSSL_BIGNUM*); +WOLFSSL_API char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM*); +WOLFSSL_API int wolfSSL_BN_is_prime_ex(const WOLFSSL_BIGNUM*, int, + WOLFSSL_BN_CTX*, WOLFSSL_BN_GENCB*); +WOLFSSL_API WOLFSSL_BN_ULONG wolfSSL_BN_mod_word(const WOLFSSL_BIGNUM*, + WOLFSSL_BN_ULONG); +#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) + WOLFSSL_API int wolfSSL_BN_print_fp(XFILE, const WOLFSSL_BIGNUM*); +#endif +WOLFSSL_API int wolfSSL_BN_rshift(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, int); +WOLFSSL_API WOLFSSL_BIGNUM *wolfSSL_BN_CTX_get(WOLFSSL_BN_CTX *ctx); +WOLFSSL_API void wolfSSL_BN_CTX_start(WOLFSSL_BN_CTX *ctx); +WOLFSSL_API WOLFSSL_BIGNUM *wolfSSL_BN_mod_inverse(WOLFSSL_BIGNUM*, WOLFSSL_BIGNUM*, + const WOLFSSL_BIGNUM*, WOLFSSL_BN_CTX *ctx); + +typedef WOLFSSL_BIGNUM BIGNUM; +typedef WOLFSSL_BN_CTX BN_CTX; +typedef WOLFSSL_BN_GENCB BN_GENCB; + +#define BN_CTX_new wolfSSL_BN_CTX_new +#define BN_CTX_init wolfSSL_BN_CTX_init +#define BN_CTX_free wolfSSL_BN_CTX_free + +#define BN_new wolfSSL_BN_new +#define BN_init wolfSSL_BN_init +#define BN_free wolfSSL_BN_free +#define BN_clear_free wolfSSL_BN_clear_free + +#define BN_num_bytes wolfSSL_BN_num_bytes +#define BN_num_bits wolfSSL_BN_num_bits + +#define BN_is_zero wolfSSL_BN_is_zero +#define BN_is_one wolfSSL_BN_is_one +#define BN_is_odd wolfSSL_BN_is_odd +#define BN_is_negative wolfSSL_BN_is_negative + +#define BN_cmp wolfSSL_BN_cmp + +#define BN_bn2bin wolfSSL_BN_bn2bin +#define BN_bin2bn wolfSSL_BN_bin2bn + +#define BN_mod wolfSSL_BN_mod +#define BN_mod_exp wolfSSL_BN_mod_exp +#define BN_mod_mul wolfSSL_BN_mod_mul +#define BN_sub wolfSSL_BN_sub +#define BN_value_one wolfSSL_BN_value_one + +#define BN_mask_bits wolfSSL_mask_bits + +#define BN_pseudo_rand wolfSSL_BN_pseudo_rand +#define BN_rand wolfSSL_BN_rand +#define BN_is_bit_set wolfSSL_BN_is_bit_set +#define BN_hex2bn wolfSSL_BN_hex2bn + +#define BN_dup wolfSSL_BN_dup +#define BN_copy wolfSSL_BN_copy + +#define BN_get_word wolfSSL_BN_get_word +#define BN_set_word wolfSSL_BN_set_word + +#define BN_dec2bn wolfSSL_BN_dec2bn +#define BN_bn2dec wolfSSL_BN_bn2dec +#define BN_bn2hex wolfSSL_BN_bn2hex + +#define BN_lshift wolfSSL_BN_lshift +#define BN_add_word wolfSSL_BN_add_word +#define BN_add wolfSSL_BN_add +#define BN_set_word wolfSSL_BN_set_word +#define BN_set_bit wolfSSL_BN_set_bit + + +#define BN_is_prime_ex wolfSSL_BN_is_prime_ex +#define BN_print_fp wolfSSL_BN_print_fp +#define BN_rshift wolfSSL_BN_rshift +#define BN_mod_word wolfSSL_BN_mod_word + +#define BN_CTX_get wolfSSL_BN_CTX_get +#define BN_CTX_start wolfSSL_BN_CTX_start + +#define BN_mod_inverse wolfSSL_BN_mod_inverse + +#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L +#define BN_get_rfc2409_prime_768 wolfSSL_DH_768_prime +#define BN_get_rfc2409_prime_1024 wolfSSL_DH_1024_prime +#define BN_get_rfc3526_prime_1536 wolfSSL_DH_1536_prime +#define BN_get_rfc3526_prime_2048 wolfSSL_DH_2048_prime +#define BN_get_rfc3526_prime_3072 wolfSSL_DH_3072_prime +#define BN_get_rfc3526_prime_4096 wolfSSL_DH_4096_prime +#define BN_get_rfc3526_prime_6144 wolfSSL_DH_6144_prime +#define BN_get_rfc3526_prime_8192 wolfSSL_DH_8192_prime +#endif + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* WOLFSSL__H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/buffer.h b/wolfssl_hlavickove_subory/wolfssl/openssl/buffer.h new file mode 100644 index 0000000..4efd315 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/buffer.h @@ -0,0 +1,47 @@ +/* buffer.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLFSSL_BUFFER_H_ +#define WOLFSSL_BUFFER_H_ + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + + +WOLFSSL_API WOLFSSL_BUF_MEM* wolfSSL_BUF_MEM_new(void); +WOLFSSL_API int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len); +WOLFSSL_API void wolfSSL_BUF_MEM_free(WOLFSSL_BUF_MEM* buf); + + +#define BUF_MEM_new wolfSSL_BUF_MEM_new +#define BUF_MEM_grow wolfSSL_BUF_MEM_grow +#define BUF_MEM_free wolfSSL_BUF_MEM_free + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_BUFFER_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/conf.h b/wolfssl_hlavickove_subory/wolfssl/openssl/conf.h new file mode 100644 index 0000000..12a20c8 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/conf.h @@ -0,0 +1,48 @@ +/* conf.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* conf.h for openSSL */ + +#ifndef WOLFSSL_conf_H_ +#define WOLFSSL_conf_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +struct WOLFSSL_CONF_VALUE { + char *section; + char *name; + char *value; +}; + +struct WOLFSSL_INIT_SETTINGS { + char* appname; +}; + +typedef struct WOLFSSL_CONF_VALUE CONF_VALUE; +typedef struct WOLFSSL_INIT_SETTINGS OPENSSL_INIT_SETTINGS; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* WOLFSSL_conf_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/crypto.h b/wolfssl_hlavickove_subory/wolfssl/openssl/crypto.h new file mode 100644 index 0000000..3eb90e4 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/crypto.h @@ -0,0 +1,79 @@ +/* crypto.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* crypto.h for openSSL */ + +#ifndef WOLFSSL_CRYPTO_H_ +#define WOLFSSL_CRYPTO_H_ + +#include + +#include + +#ifdef WOLFSSL_PREFIX +#include "prefix_crypto.h" +#endif + + +WOLFSSL_API const char* wolfSSLeay_version(int type); +WOLFSSL_API unsigned long wolfSSLeay(void); + +#ifdef OPENSSL_EXTRA +WOLFSSL_API void wolfSSL_OPENSSL_free(void*); +WOLFSSL_API void *wolfSSL_OPENSSL_malloc(size_t a); +#endif + +#define CRYPTO_THREADID void + +#define SSLeay_version wolfSSLeay_version +#define SSLeay wolfSSLeay + +#define SSLEAY_VERSION 0x0090600fL +#define SSLEAY_VERSION_NUMBER SSLEAY_VERSION +#define CRYPTO_lock wc_LockMutex_ex + +/* this function was used to set the default malloc, free, and realloc */ +#define CRYPTO_malloc_init() 0 /* CRYPTO_malloc_init is not needed */ + +#define OPENSSL_free wolfSSL_OPENSSL_free +#define OPENSSL_malloc wolfSSL_OPENSSL_malloc + +#if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \ + defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) +#define CRYPTO_set_mem_ex_functions wolfSSL_CRYPTO_set_mem_ex_functions +#define FIPS_mode wolfSSL_FIPS_mode +#define FIPS_mode_set wolfSSL_FIPS_mode_set +typedef struct CRYPTO_EX_DATA CRYPTO_EX_DATA; +typedef void (CRYPTO_free_func)(void*parent, void*ptr, CRYPTO_EX_DATA *ad, int idx, + long argl, void* argp); +#define CRYPTO_THREADID_set_callback wolfSSL_THREADID_set_callback +#define CRYPTO_THREADID_set_numeric wolfSSL_THREADID_set_numeric + +#define CRYPTO_r_lock wc_LockMutex_ex +#define CRYPTO_unlock wc_LockMutex_ex + +#define CRYPTO_THREAD_lock wc_LockMutex +#define CRYPTO_THREAD_r_lock wc_LockMutex +#define CRYPTO_THREAD_unlock wc_UnLockMutex + +#endif /* OPENSSL_ALL || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ + +#endif /* header */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/des.h b/wolfssl_hlavickove_subory/wolfssl/openssl/des.h new file mode 100644 index 0000000..8a356e5 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/des.h @@ -0,0 +1,115 @@ +/* des.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +/* des.h defines mini des openssl compatibility layer + * + */ + + +#ifndef WOLFSSL_DES_H_ +#define WOLFSSL_DES_H_ + +#include + +#ifndef NO_DES3 + +#ifdef WOLFSSL_PREFIX +#include "prefix_des.h" +#endif + + +#ifdef __cplusplus + extern "C" { +#endif + +typedef unsigned char WOLFSSL_DES_cblock[8]; +typedef /* const */ WOLFSSL_DES_cblock WOLFSSL_const_DES_cblock; +typedef WOLFSSL_DES_cblock WOLFSSL_DES_key_schedule; +typedef unsigned int WOLFSSL_DES_LONG; + + +enum { + DES_ENCRYPT = 1, + DES_DECRYPT = 0 +}; + + +WOLFSSL_API int wolfSSL_DES_is_weak_key(WOLFSSL_const_DES_cblock* key); +WOLFSSL_API WOLFSSL_DES_LONG wolfSSL_DES_cbc_cksum(const unsigned char* in, + WOLFSSL_DES_cblock* out, long length, WOLFSSL_DES_key_schedule* sc, + WOLFSSL_const_DES_cblock* iv); +WOLFSSL_API int wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* myDes, + WOLFSSL_DES_key_schedule* key); +WOLFSSL_API int wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes, + WOLFSSL_DES_key_schedule* key); +WOLFSSL_API void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock*, + WOLFSSL_DES_key_schedule*); +WOLFSSL_API int wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key, + WOLFSSL_DES_key_schedule* schedule); +WOLFSSL_API void wolfSSL_DES_cbc_encrypt(const unsigned char* input, + unsigned char* output, long length, + WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec, + int enc); +WOLFSSL_API void wolfSSL_DES_ede3_cbc_encrypt(const unsigned char* input, + unsigned char* output, long sz, + WOLFSSL_DES_key_schedule* ks1, + WOLFSSL_DES_key_schedule* ks2, + WOLFSSL_DES_key_schedule* ks3, + WOLFSSL_DES_cblock* ivec, int enc); +WOLFSSL_API void wolfSSL_DES_ncbc_encrypt(const unsigned char* input, + unsigned char* output, long length, + WOLFSSL_DES_key_schedule* schedule, + WOLFSSL_DES_cblock* ivec, int enc); + +WOLFSSL_API void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock*); +WOLFSSL_API void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock*, WOLFSSL_DES_cblock*, + WOLFSSL_DES_key_schedule*, int); +WOLFSSL_API int wolfSSL_DES_check_key_parity(WOLFSSL_DES_cblock*); + + +typedef WOLFSSL_DES_cblock DES_cblock; +typedef WOLFSSL_const_DES_cblock const_DES_cblock; +typedef WOLFSSL_DES_key_schedule DES_key_schedule; +typedef WOLFSSL_DES_LONG DES_LONG; + +#define DES_check_key(x) /* Define WOLFSSL_CHECK_DESKEY to check key */ +#define DES_is_weak_key wolfSSL_DES_is_weak_key +#define DES_set_key wolfSSL_DES_set_key +#define DES_set_key_checked wolfSSL_DES_set_key_checked +#define DES_set_key_unchecked wolfSSL_DES_set_key_unchecked +#define DES_key_sched wolfSSL_DES_key_sched +#define DES_cbc_encrypt wolfSSL_DES_cbc_encrypt +#define DES_ncbc_encrypt wolfSSL_DES_ncbc_encrypt +#define DES_set_odd_parity wolfSSL_DES_set_odd_parity +#define DES_ecb_encrypt wolfSSL_DES_ecb_encrypt +#define DES_ede3_cbc_encrypt wolfSSL_DES_ede3_cbc_encrypt +#define DES_cbc_cksum wolfSSL_DES_cbc_cksum +#define DES_check_key_parity wolfSSL_DES_check_key_parity + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* NO_DES3 */ + +#endif /* WOLFSSL_DES_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/dh.h b/wolfssl_hlavickove_subory/wolfssl/openssl/dh.h new file mode 100644 index 0000000..f31c76a --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/dh.h @@ -0,0 +1,93 @@ +/* dh.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* dh.h for openSSL */ + + +#ifndef WOLFSSL_DH_H_ +#define WOLFSSL_DH_H_ + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +struct WOLFSSL_DH { + WOLFSSL_BIGNUM* p; + WOLFSSL_BIGNUM* g; + WOLFSSL_BIGNUM* q; + WOLFSSL_BIGNUM* pub_key; /* openssh deference g^x */ + WOLFSSL_BIGNUM* priv_key; /* openssh deference x */ + void* internal; /* our DH */ + char inSet; /* internal set from external ? */ + char exSet; /* external set from internal ? */ + /*added for lighttpd openssl compatibility, go back and add a getter in + * lighttpd src code. + */ + int length; +}; + + +WOLFSSL_API WOLFSSL_DH* wolfSSL_DH_new(void); +WOLFSSL_API void wolfSSL_DH_free(WOLFSSL_DH*); + +WOLFSSL_API int wolfSSL_DH_size(WOLFSSL_DH*); +WOLFSSL_API int wolfSSL_DH_generate_key(WOLFSSL_DH*); +WOLFSSL_API int wolfSSL_DH_compute_key(unsigned char* key, WOLFSSL_BIGNUM* pub, + WOLFSSL_DH*); +WOLFSSL_API int wolfSSL_DH_set0_pqg(WOLFSSL_DH*, WOLFSSL_BIGNUM*, + WOLFSSL_BIGNUM*, WOLFSSL_BIGNUM*); + +typedef WOLFSSL_DH DH; + +#define DH_new wolfSSL_DH_new +#define DH_free wolfSSL_DH_free + +#define DH_size wolfSSL_DH_size +#define DH_generate_key wolfSSL_DH_generate_key +#define DH_compute_key wolfSSL_DH_compute_key +#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L +#define DH_set0_pqg wolfSSL_DH_set0_pqg +#endif +#define DH_bits(x) (BN_num_bits(x->p)) + +/* for pre 1.1.0 */ +#define get_rfc2409_prime_768 wolfSSL_DH_768_prime +#define get_rfc2409_prime_1024 wolfSSL_DH_1024_prime +#define get_rfc3526_prime_1536 wolfSSL_DH_1536_prime +#define get_rfc3526_prime_2048 wolfSSL_DH_2048_prime +#define get_rfc3526_prime_3072 wolfSSL_DH_3072_prime +#define get_rfc3526_prime_4096 wolfSSL_DH_4096_prime +#define get_rfc3526_prime_6144 wolfSSL_DH_6144_prime +#define get_rfc3526_prime_8192 wolfSSL_DH_8192_prime + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) +#define DH_generate_parameters wolfSSL_DH_generate_parameters +#define DH_generate_parameters_ex wolfSSL_DH_generate_parameters_ex +#endif /* OPENSSL_ALL || HAVE_STUNNEL */ + +#endif /* WOLFSSL_DH_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/dsa.h b/wolfssl_hlavickove_subory/wolfssl/openssl/dsa.h new file mode 100644 index 0000000..107bb05 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/dsa.h @@ -0,0 +1,87 @@ +/* dsa.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* dsa.h for openSSL */ + + +#ifndef WOLFSSL_DSA_H_ +#define WOLFSSL_DSA_H_ + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef WOLFSSL_DSA_TYPE_DEFINED /* guard on redeclaration */ +typedef struct WOLFSSL_DSA WOLFSSL_DSA; +#define WOLFSSL_DSA_TYPE_DEFINED +#endif + +typedef WOLFSSL_DSA DSA; + +struct WOLFSSL_DSA { + WOLFSSL_BIGNUM* p; + WOLFSSL_BIGNUM* q; + WOLFSSL_BIGNUM* g; + WOLFSSL_BIGNUM* pub_key; /* our y */ + WOLFSSL_BIGNUM* priv_key; /* our x */ + void* internal; /* our Dsa Key */ + char inSet; /* internal set from external ? */ + char exSet; /* external set from internal ? */ +}; + + +WOLFSSL_API WOLFSSL_DSA* wolfSSL_DSA_new(void); +WOLFSSL_API void wolfSSL_DSA_free(WOLFSSL_DSA*); + +WOLFSSL_API int wolfSSL_DSA_generate_key(WOLFSSL_DSA*); + +typedef void (*WOLFSSL_BN_CB)(int i, int j, void* exArg); +WOLFSSL_API WOLFSSL_DSA* wolfSSL_DSA_generate_parameters(int bits, + unsigned char* seed, int seedLen, int* counterRet, + unsigned long* hRet, WOLFSSL_BN_CB cb, void* CBArg); +WOLFSSL_API int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA*, int bits, + unsigned char* seed, int seedLen, int* counterRet, + unsigned long* hRet, void* cb); + +WOLFSSL_API int wolfSSL_DSA_LoadDer(WOLFSSL_DSA*, const unsigned char*, int sz); + +WOLFSSL_API int wolfSSL_DSA_do_sign(const unsigned char* d, + unsigned char* sigRet, WOLFSSL_DSA* dsa); + +WOLFSSL_API int wolfSSL_DSA_do_verify(const unsigned char* d, + unsigned char* sig, + WOLFSSL_DSA* dsa, int *dsacheck); + +#define DSA_new wolfSSL_DSA_new +#define DSA_free wolfSSL_DSA_free + +#define DSA_generate_key wolfSSL_DSA_generate_key +#define DSA_generate_parameters wolfSSL_DSA_generate_parameters +#define DSA_generate_parameters_ex wolfSSL_DSA_generate_parameters_ex + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* header */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/ec.h b/wolfssl_hlavickove_subory/wolfssl/openssl/ec.h new file mode 100644 index 0000000..18e3b4e --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/ec.h @@ -0,0 +1,253 @@ +/* ec.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* ec.h for openssl */ + +#ifndef WOLFSSL_EC_H_ +#define WOLFSSL_EC_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Map OpenSSL NID value */ +enum { + POINT_CONVERSION_COMPRESSED = 2, + POINT_CONVERSION_UNCOMPRESSED = 4, + +#ifdef HAVE_ECC + /* Use ecc_curve_type enum values for NID */ + NID_X9_62_prime192v1 = ECC_SECP192R1, + NID_X9_62_prime256v1 = ECC_SECP256R1, + NID_secp112r1 = ECC_SECP112R1, + NID_secp112r2 = ECC_SECP112R2, + NID_secp128r1 = ECC_SECP128R1, + NID_secp128r2 = ECC_SECP128R2, + NID_secp160r1 = ECC_SECP160R1, + NID_secp160r2 = ECC_SECP160R2, + NID_secp224r1 = ECC_SECP224R1, + NID_secp384r1 = ECC_SECP384R1, + NID_secp521r1 = ECC_SECP521R1, + NID_secp160k1 = ECC_SECP160K1, + NID_secp192k1 = ECC_SECP192K1, + NID_secp224k1 = ECC_SECP224K1, + NID_secp256k1 = ECC_SECP256K1, + NID_brainpoolP160r1 = ECC_BRAINPOOLP160R1, + NID_brainpoolP192r1 = ECC_BRAINPOOLP192R1, + NID_brainpoolP224r1 = ECC_BRAINPOOLP224R1, + NID_brainpoolP256r1 = ECC_BRAINPOOLP256R1, + NID_brainpoolP320r1 = ECC_BRAINPOOLP320R1, + NID_brainpoolP384r1 = ECC_BRAINPOOLP384R1, + NID_brainpoolP512r1 = ECC_BRAINPOOLP512R1, +#endif + + OPENSSL_EC_NAMED_CURVE = 0x001 +}; + +#ifndef WOLFSSL_EC_TYPE_DEFINED /* guard on redeclaration */ +typedef struct WOLFSSL_EC_KEY WOLFSSL_EC_KEY; +typedef struct WOLFSSL_EC_POINT WOLFSSL_EC_POINT; +typedef struct WOLFSSL_EC_GROUP WOLFSSL_EC_GROUP; +#define WOLFSSL_EC_TYPE_DEFINED +#endif + +typedef WOLFSSL_EC_KEY EC_KEY; +typedef WOLFSSL_EC_GROUP EC_GROUP; +typedef WOLFSSL_EC_POINT EC_POINT; + +struct WOLFSSL_EC_POINT { + WOLFSSL_BIGNUM *X; + WOLFSSL_BIGNUM *Y; + WOLFSSL_BIGNUM *Z; + + void* internal; /* our ECC point */ + char inSet; /* internal set from external ? */ + char exSet; /* external set from internal ? */ +}; + +struct WOLFSSL_EC_GROUP { + int curve_idx; /* index of curve, used by WolfSSL as reference */ + int curve_nid; /* NID of curve, used by OpenSSL/OpenSSH as reference */ + int curve_oid; /* OID of curve, used by OpenSSL/OpenSSH as reference */ +}; + +struct WOLFSSL_EC_KEY { + WOLFSSL_EC_GROUP *group; + WOLFSSL_EC_POINT *pub_key; + WOLFSSL_BIGNUM *priv_key; + + void* internal; /* our ECC Key */ + char inSet; /* internal set from external ? */ + char exSet; /* external set from internal ? */ +}; + +typedef struct WOLFSSL_EC_builtin_curve{ + int nid; + const char *comment; +} WOLFSSL_EC_builtin_curve; + +typedef WOLFSSL_EC_builtin_curve EC_builtin_curve; + +#define WOLFSSL_EC_KEY_LOAD_PRIVATE 1 +#define WOLFSSL_EC_KEY_LOAD_PUBLIC 2 + +WOLFSSL_API +int wolfSSL_ECPoint_i2d(const WOLFSSL_EC_GROUP *curve, + const WOLFSSL_EC_POINT *p, + unsigned char *out, unsigned int *len); +WOLFSSL_API +int wolfSSL_ECPoint_d2i(unsigned char *in, unsigned int len, + const WOLFSSL_EC_GROUP *curve, WOLFSSL_EC_POINT *p); +WOLFSSL_API +int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, + const unsigned char* der, int derSz); +WOLFSSL_API +int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, + const unsigned char* der, int derSz, int opt); +WOLFSSL_API +void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key); +WOLFSSL_API +WOLFSSL_EC_POINT *wolfSSL_EC_KEY_get0_public_key(const WOLFSSL_EC_KEY *key); +WOLFSSL_API +const WOLFSSL_EC_GROUP *wolfSSL_EC_KEY_get0_group(const WOLFSSL_EC_KEY *key); +WOLFSSL_API +int wolfSSL_EC_KEY_set_private_key(WOLFSSL_EC_KEY *key, + const WOLFSSL_BIGNUM *priv_key); +WOLFSSL_API +WOLFSSL_BIGNUM *wolfSSL_EC_KEY_get0_private_key(const WOLFSSL_EC_KEY *key); +WOLFSSL_API +WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid); +WOLFSSL_API const char* wolfSSL_EC_curve_nid2nist(int nid); +WOLFSSL_API +WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void); +WOLFSSL_API +int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group); +WOLFSSL_API +int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key); +WOLFSSL_API +void wolfSSL_EC_KEY_set_asn1_flag(WOLFSSL_EC_KEY *key, int asn1_flag); +WOLFSSL_API +int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key, + const WOLFSSL_EC_POINT *pub); +WOLFSSL_API +void wolfSSL_EC_GROUP_set_asn1_flag(WOLFSSL_EC_GROUP *group, int flag); +WOLFSSL_API +WOLFSSL_EC_GROUP *wolfSSL_EC_GROUP_new_by_curve_name(int nid); +WOLFSSL_API +int wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP *a, const WOLFSSL_EC_GROUP *b, + WOLFSSL_BN_CTX *ctx); +WOLFSSL_API +int wolfSSL_EC_GROUP_get_curve_name(const WOLFSSL_EC_GROUP *group); +WOLFSSL_API +int wolfSSL_EC_GROUP_get_degree(const WOLFSSL_EC_GROUP *group); +WOLFSSL_API +int wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP *group, + WOLFSSL_BIGNUM *order, WOLFSSL_BN_CTX *ctx); +WOLFSSL_API +int wolfSSL_EC_GROUP_order_bits(const WOLFSSL_EC_GROUP *group); +WOLFSSL_API +void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group); +WOLFSSL_API +WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group); +WOLFSSL_API +int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, + const WOLFSSL_EC_POINT *p, + WOLFSSL_BIGNUM *x, + WOLFSSL_BIGNUM *y, + WOLFSSL_BN_CTX *ctx); +WOLFSSL_API +int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, + const WOLFSSL_BIGNUM *n, + const WOLFSSL_EC_POINT *q, const WOLFSSL_BIGNUM *m, + WOLFSSL_BN_CTX *ctx); +WOLFSSL_API +void wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT *point); +WOLFSSL_API +int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group, + const WOLFSSL_EC_POINT *a, const WOLFSSL_EC_POINT *b, + WOLFSSL_BN_CTX *ctx); +WOLFSSL_API +void wolfSSL_EC_POINT_free(WOLFSSL_EC_POINT *point); +WOLFSSL_API +int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group, + const WOLFSSL_EC_POINT *a); + +WOLFSSL_API +size_t wolfSSL_EC_get_builtin_curves(WOLFSSL_EC_builtin_curve *r, size_t nitems); + +#ifndef HAVE_SELFTEST +WOLFSSL_API +char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, + const WOLFSSL_EC_POINT* point, int form, + WOLFSSL_BN_CTX* ctx); +#endif + +#ifndef HAVE_ECC +#define OPENSSL_NO_EC +#endif + +#define EC_KEY_new wolfSSL_EC_KEY_new +#define EC_KEY_free wolfSSL_EC_KEY_free +#define EC_KEY_get0_public_key wolfSSL_EC_KEY_get0_public_key +#define EC_KEY_get0_group wolfSSL_EC_KEY_get0_group +#define EC_KEY_set_private_key wolfSSL_EC_KEY_set_private_key +#define EC_KEY_get0_private_key wolfSSL_EC_KEY_get0_private_key +#define EC_KEY_new_by_curve_name wolfSSL_EC_KEY_new_by_curve_name +#define EC_KEY_set_group wolfSSL_EC_KEY_set_group +#define EC_KEY_generate_key wolfSSL_EC_KEY_generate_key +#define EC_KEY_set_asn1_flag wolfSSL_EC_KEY_set_asn1_flag +#define EC_KEY_set_public_key wolfSSL_EC_KEY_set_public_key + +#define EC_GROUP_free wolfSSL_EC_GROUP_free +#define EC_GROUP_set_asn1_flag wolfSSL_EC_GROUP_set_asn1_flag +#define EC_GROUP_new_by_curve_name wolfSSL_EC_GROUP_new_by_curve_name +#define EC_GROUP_cmp wolfSSL_EC_GROUP_cmp +#define EC_GROUP_get_curve_name wolfSSL_EC_GROUP_get_curve_name +#define EC_GROUP_get_degree wolfSSL_EC_GROUP_get_degree +#define EC_GROUP_get_order wolfSSL_EC_GROUP_get_order +#define EC_GROUP_order_bits wolfSSL_EC_GROUP_order_bits + +#define EC_POINT_new wolfSSL_EC_POINT_new +#define EC_POINT_free wolfSSL_EC_POINT_free +#define EC_POINT_get_affine_coordinates_GFp \ + wolfSSL_EC_POINT_get_affine_coordinates_GFp +#define EC_POINT_mul wolfSSL_EC_POINT_mul +#define EC_POINT_clear_free wolfSSL_EC_POINT_clear_free +#define EC_POINT_cmp wolfSSL_EC_POINT_cmp +#define EC_POINT_is_at_infinity wolfSSL_EC_POINT_is_at_infinity + +#ifndef HAVE_SELFTEST + #define EC_POINT_point2hex wolfSSL_EC_POINT_point2hex +#endif + +#define EC_POINT_dump wolfSSL_EC_POINT_dump +#define EC_get_builtin_curves wolfSSL_EC_get_builtin_curves + +#define EC_curve_nid2nist wolfSSL_EC_curve_nid2nist + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* header */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/ec25519.h b/wolfssl_hlavickove_subory/wolfssl/openssl/ec25519.h new file mode 100644 index 0000000..17231a5 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/ec25519.h @@ -0,0 +1,44 @@ +/* ec25519.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* ec25519.h */ + +#ifndef WOLFSSL_EC25519_H_ +#define WOLFSSL_EC25519_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +WOLFSSL_API +int wolfSSL_EC25519_generate_key(unsigned char *priv, unsigned int *privSz, + unsigned char *pub, unsigned int *pubSz); + +WOLFSSL_API +int wolfSSL_EC25519_shared_key(unsigned char *shared, unsigned int *sharedSz, + const unsigned char *priv, unsigned int privSz, + const unsigned char *pub, unsigned int pubSz); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* header */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/ecdh.h b/wolfssl_hlavickove_subory/wolfssl/openssl/ecdh.h new file mode 100644 index 0000000..dfa8054 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/ecdh.h @@ -0,0 +1,49 @@ +/* ecdh.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* ecdh.h for openssl */ + +#ifndef WOLFSSL_ECDH_H_ +#define WOLFSSL_ECDH_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +WOLFSSL_API int wolfSSL_ECDH_compute_key(void *out, size_t outlen, + const WOLFSSL_EC_POINT *pub_key, + WOLFSSL_EC_KEY *ecdh, + void *(*KDF) (const void *in, + size_t inlen, + void *out, + size_t *outlen)); + +#define ECDH_compute_key wolfSSL_ECDH_compute_key + +#ifdef __cplusplus +} /* extern C */ +#endif + +#endif /* header */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/ecdsa.h b/wolfssl_hlavickove_subory/wolfssl/openssl/ecdsa.h new file mode 100644 index 0000000..1bcf8f3 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/ecdsa.h @@ -0,0 +1,74 @@ +/* ecdsa.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* ecdsa.h for openssl */ + +#ifndef WOLFSSL_ECDSA_H_ +#define WOLFSSL_ECDSA_H_ + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef WOLFSSL_ECDSA_TYPE_DEFINED /* guard on redeclaration */ +typedef struct WOLFSSL_ECDSA_SIG WOLFSSL_ECDSA_SIG; +#define WOLFSSL_ECDSA_TYPE_DEFINED +#endif + +typedef WOLFSSL_ECDSA_SIG ECDSA_SIG; + +struct WOLFSSL_ECDSA_SIG { + WOLFSSL_BIGNUM *r; + WOLFSSL_BIGNUM *s; +}; + +WOLFSSL_API void wolfSSL_ECDSA_SIG_free(WOLFSSL_ECDSA_SIG *sig); +WOLFSSL_API WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_SIG_new(void); +WOLFSSL_API WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_do_sign(const unsigned char *dgst, + int dgst_len, + WOLFSSL_EC_KEY *eckey); +WOLFSSL_API int wolfSSL_ECDSA_do_verify(const unsigned char *dgst, + int dgst_len, + const WOLFSSL_ECDSA_SIG *sig, + WOLFSSL_EC_KEY *eckey); + +WOLFSSL_API WOLFSSL_ECDSA_SIG *wolfSSL_d2i_ECDSA_SIG(WOLFSSL_ECDSA_SIG **sig, + const unsigned char **pp, + long len); +WOLFSSL_API int wolfSSL_i2d_ECDSA_SIG(const WOLFSSL_ECDSA_SIG *sig, + unsigned char **pp); + +#define ECDSA_SIG_free wolfSSL_ECDSA_SIG_free +#define ECDSA_SIG_new wolfSSL_ECDSA_SIG_new +#define ECDSA_do_sign wolfSSL_ECDSA_do_sign +#define ECDSA_do_verify wolfSSL_ECDSA_do_verify +#define d2i_ECDSA_SIG wolfSSL_d2i_ECDSA_SIG +#define i2d_ECDSA_SIG wolfSSL_i2d_ECDSA_SIG + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* header */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/ed25519.h b/wolfssl_hlavickove_subory/wolfssl/openssl/ed25519.h new file mode 100644 index 0000000..ba435bd --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/ed25519.h @@ -0,0 +1,47 @@ +/* ed25519.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* ed25519.h */ + +#ifndef WOLFSSL_ED25519_H_ +#define WOLFSSL_ED25519_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +WOLFSSL_API +int wolfSSL_ED25519_generate_key(unsigned char *priv, unsigned int *privSz, + unsigned char *pub, unsigned int *pubSz); +WOLFSSL_API +int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz, + const unsigned char *priv, unsigned int privSz, + unsigned char *sig, unsigned int *sigSz); +WOLFSSL_API +int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz, + const unsigned char *pub, unsigned int pubSz, + const unsigned char *sig, unsigned int sigSz); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* header */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/engine.h b/wolfssl_hlavickove_subory/wolfssl/openssl/engine.h new file mode 100644 index 0000000..e4a1ff1 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/engine.h @@ -0,0 +1,8 @@ +/* engine.h for libcurl */ + +#include + +#undef HAVE_OPENSSL_ENGINE_H + +#define ENGINE_load_builtin_engines() /*ENGINE_load_builtin_engines not needed*/ + diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/err.h b/wolfssl_hlavickove_subory/wolfssl/openssl/err.h new file mode 100644 index 0000000..dcfdd15 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/err.h @@ -0,0 +1,51 @@ +/* err.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef WOLFSSL_OPENSSL_ERR_ +#define WOLFSSL_OPENSSL_ERR_ + +#include + +/* err.h for openssl */ +#define ERR_load_crypto_strings wolfSSL_ERR_load_crypto_strings +#define ERR_peek_last_error wolfSSL_ERR_peek_last_error + +/* fatal error */ +#define ERR_R_MALLOC_FAILURE MEMORY_E +#define ERR_R_PASSED_NULL_PARAMETER BAD_FUNC_ARG +#define ERR_R_DISABLED NOT_COMPILED_IN +#define ERR_R_PASSED_INVALID_ARGUMENT BAD_FUNC_ARG +#define RSA_R_UNKNOWN_PADDING_TYPE RSA_PAD_E + +/* SSL function codes */ +#define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT 1 +#define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE 2 +#define SSL_F_SSL_USE_PRIVATEKEY 3 + +/* reasons */ +#define ERR_R_SYS_LIB 1 +#define PKCS12_R_MAC_VERIFY_FAILURE 2 + +#define RSAerr(f,r) ERR_put_error(0,(f),(r),__FILE__,__LINE__) +#define SSLerr(f,r) ERR_put_error(0,(f),(r),__FILE__,__LINE__) + +#endif /* WOLFSSL_OPENSSL_ERR_ */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/evp.h b/wolfssl_hlavickove_subory/wolfssl/openssl/evp.h new file mode 100644 index 0000000..2918206 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/evp.h @@ -0,0 +1,745 @@ +/* evp.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +/*! + \file wolfssl/openssl/evp.h + \brief evp.h defines mini evp openssl compatibility layer + */ + + +#ifndef WOLFSSL_EVP_H_ +#define WOLFSSL_EVP_H_ + +#include + +#ifdef WOLFSSL_PREFIX +#include "prefix_evp.h" +#endif + +#ifndef NO_MD4 + #include +#endif +#ifndef NO_MD5 + #include +#endif +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#ifdef HAVE_IDEA + #include +#endif +#include + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef char WOLFSSL_EVP_CIPHER; +#ifndef WOLFSSL_EVP_TYPE_DEFINED /* guard on redeclaration */ +typedef char WOLFSSL_EVP_MD; +typedef struct WOLFSSL_EVP_PKEY WOLFSSL_EVP_PKEY; +#define WOLFSSL_EVP_TYPE_DEFINED +#endif + +typedef WOLFSSL_EVP_PKEY EVP_PKEY; +typedef WOLFSSL_EVP_PKEY PKCS8_PRIV_KEY_INFO; + +#ifndef NO_MD4 + WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_md4(void); +#endif +#ifndef NO_MD5 + WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void); +#endif +WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void); +WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha224(void); +WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha256(void); +WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void); +WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void); +WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_ripemd160(void); + +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ecb(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ecb(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ecb(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void); +#if !defined(NO_AES) && defined(HAVE_AES_CBC) +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void); +#endif +#if !defined(NO_AES) && defined(HAVE_AESGCM) +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_gcm(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_gcm(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_gcm(void); +#endif +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ecb(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_ecb(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_cbc(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_cbc(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc4(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_idea_cbc(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void); + + +typedef union { + #ifndef NO_MD4 + WOLFSSL_MD4_CTX md4; + #endif + #ifndef NO_MD5 + WOLFSSL_MD5_CTX md5; + #endif + WOLFSSL_SHA_CTX sha; + #ifdef WOLFSSL_SHA224 + WOLFSSL_SHA224_CTX sha224; + #endif + WOLFSSL_SHA256_CTX sha256; + #ifdef WOLFSSL_SHA384 + WOLFSSL_SHA384_CTX sha384; + #endif + #ifdef WOLFSSL_SHA512 + WOLFSSL_SHA512_CTX sha512; + #endif + #ifdef WOLFSSL_RIPEMD + WOLFSSL_RIPEMD_CTX ripemd; + #endif +} WOLFSSL_Hasher; + +typedef struct WOLFSSL_EVP_PKEY_CTX WOLFSSL_EVP_PKEY_CTX; + +typedef struct WOLFSSL_EVP_MD_CTX { + union { + WOLFSSL_Hasher digest; + Hmac hmac; + } hash; + unsigned char macType; + WOLFSSL_EVP_PKEY_CTX *pctx; +} WOLFSSL_EVP_MD_CTX; + + +typedef union { +#ifndef NO_AES + Aes aes; +#endif +#ifndef NO_DES3 + Des des; + Des3 des3; +#endif + Arc4 arc4; +#ifdef HAVE_IDEA + Idea idea; +#endif +} WOLFSSL_Cipher; + + +enum { + AES_128_CBC_TYPE = 1, + AES_192_CBC_TYPE = 2, + AES_256_CBC_TYPE = 3, + AES_128_CTR_TYPE = 4, + AES_192_CTR_TYPE = 5, + AES_256_CTR_TYPE = 6, + AES_128_ECB_TYPE = 7, + AES_192_ECB_TYPE = 8, + AES_256_ECB_TYPE = 9, + DES_CBC_TYPE = 10, + DES_ECB_TYPE = 11, + DES_EDE3_CBC_TYPE = 12, + DES_EDE3_ECB_TYPE = 13, + ARC4_TYPE = 14, + NULL_CIPHER_TYPE = 15, + EVP_PKEY_RSA = 16, + EVP_PKEY_DSA = 17, + EVP_PKEY_EC = 18, +#ifdef HAVE_IDEA + IDEA_CBC_TYPE = 19, +#endif + AES_128_GCM_TYPE = 21, + AES_192_GCM_TYPE = 22, + AES_256_GCM_TYPE = 23, + NID_sha1 = 64, + NID_sha224 = 65, + NID_md2 = 77, + NID_md5 = 4, + NID_hmac = 855, + NID_dhKeyAgreement= 28, + EVP_PKEY_DH = NID_dhKeyAgreement, + EVP_PKEY_HMAC = NID_hmac +}; + +enum { + NID_md5WithRSA = 104, + NID_md5WithRSAEncryption = 8, + NID_dsaWithSHA1 = 113, + NID_dsaWithSHA1_2 = 70, + NID_sha1WithRSA = 115, + NID_sha1WithRSAEncryption = 65, + NID_sha224WithRSAEncryption = 671, + NID_sha256WithRSAEncryption = 668, + NID_sha384WithRSAEncryption = 669, + NID_sha512WithRSAEncryption = 670, + NID_ecdsa_with_SHA1 = 416, + NID_ecdsa_with_SHA224 = 793, + NID_ecdsa_with_SHA256 = 794, + NID_ecdsa_with_SHA384 = 795, + NID_ecdsa_with_SHA512 = 796, + NID_dsa_with_SHA224 = 802, + NID_dsa_with_SHA256 = 803, +}; + +enum { + NID_aes_128_cbc = 419, + NID_aes_192_cbc = 423, + NID_aes_256_cbc = 427, + NID_aes_128_gcm = 895, + NID_aes_192_gcm = 898, + NID_aes_256_gcm = 901, + NID_aes_128_ctr = 904, + NID_aes_192_ctr = 905, + NID_aes_256_ctr = 906, + NID_aes_128_ecb = 418, + NID_aes_192_ecb = 422, + NID_aes_256_ecb = 426, + NID_des_cbc = 31, + NID_des_ecb = 29, + NID_des_ede3_cbc= 44, + NID_des_ede3_ecb= 33, + NID_idea_cbc = 34, +}; + +#define WOLFSSL_EVP_BUF_SIZE 16 +typedef struct WOLFSSL_EVP_CIPHER_CTX { + int keyLen; /* user may set for variable */ + int block_size; + unsigned long flags; + unsigned char enc; /* if encrypt side, then true */ + unsigned char cipherType; +#ifndef NO_AES + /* working iv pointer into cipher */ + ALIGN16 unsigned char iv[AES_BLOCK_SIZE]; +#elif !defined(NO_DES3) + /* working iv pointer into cipher */ + ALIGN16 unsigned char iv[DES_BLOCK_SIZE]; +#endif + WOLFSSL_Cipher cipher; + ALIGN16 byte buf[WOLFSSL_EVP_BUF_SIZE]; + int bufUsed; + ALIGN16 byte lastBlock[WOLFSSL_EVP_BUF_SIZE]; + int lastUsed; +#if defined(HAVE_AESGCM) + int ivSz; + ALIGN16 unsigned char authTag[AES_BLOCK_SIZE]; + int authTagSz; +#endif +} WOLFSSL_EVP_CIPHER_CTX; + +struct WOLFSSL_EVP_PKEY_CTX { + WOLFSSL_EVP_PKEY *pkey; + int op; /* operation */ + int padding; + int nbits; +}; + +typedef int WOLFSSL_ENGINE ; +typedef WOLFSSL_ENGINE ENGINE; +typedef WOLFSSL_EVP_PKEY_CTX EVP_PKEY_CTX; + +#define EVP_PKEY_OP_SIGN (1 << 3) +#define EVP_PKEY_OP_ENCRYPT (1 << 6) +#define EVP_PKEY_OP_DECRYPT (1 << 7) + +WOLFSSL_API void wolfSSL_EVP_init(void); +WOLFSSL_API int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* md); +WOLFSSL_API int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md); +WOLFSSL_API int wolfSSL_EVP_MD_block_size(const WOLFSSL_EVP_MD *md); + +WOLFSSL_API WOLFSSL_EVP_MD_CTX *wolfSSL_EVP_MD_CTX_new (void); +WOLFSSL_API void wolfSSL_EVP_MD_CTX_free(WOLFSSL_EVP_MD_CTX* ctx); +WOLFSSL_API void wolfSSL_EVP_MD_CTX_init(WOLFSSL_EVP_MD_CTX* ctx); +WOLFSSL_API int wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx); +WOLFSSL_API int wolfSSL_EVP_MD_CTX_copy(WOLFSSL_EVP_MD_CTX *out, const WOLFSSL_EVP_MD_CTX *in); +WOLFSSL_API int wolfSSL_EVP_MD_CTX_copy_ex(WOLFSSL_EVP_MD_CTX *out, const WOLFSSL_EVP_MD_CTX *in); +WOLFSSL_API int wolfSSL_EVP_MD_CTX_type(const WOLFSSL_EVP_MD_CTX *ctx); +WOLFSSL_API int wolfSSL_EVP_MD_CTX_size(const WOLFSSL_EVP_MD_CTX *ctx); +WOLFSSL_API int wolfSSL_EVP_MD_CTX_block_size(const WOLFSSL_EVP_MD_CTX *ctx); +WOLFSSL_API const WOLFSSL_EVP_MD *wolfSSL_EVP_MD_CTX_md(const WOLFSSL_EVP_MD_CTX *ctx); +WOLFSSL_API const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbyname(const char *name); +WOLFSSL_API const WOLFSSL_EVP_MD *wolfSSL_EVP_get_digestbyname(const char *name); +WOLFSSL_API int wolfSSL_EVP_CIPHER_nid(const WOLFSSL_EVP_CIPHER *cipher); + +WOLFSSL_API int wolfSSL_EVP_DigestInit(WOLFSSL_EVP_MD_CTX* ctx, + const WOLFSSL_EVP_MD* type); +WOLFSSL_API int wolfSSL_EVP_DigestInit_ex(WOLFSSL_EVP_MD_CTX* ctx, + const WOLFSSL_EVP_MD* type, + WOLFSSL_ENGINE *impl); +WOLFSSL_API int wolfSSL_EVP_DigestUpdate(WOLFSSL_EVP_MD_CTX* ctx, const void* data, + size_t sz); +WOLFSSL_API int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md, + unsigned int* s); +WOLFSSL_API int wolfSSL_EVP_DigestFinal_ex(WOLFSSL_EVP_MD_CTX* ctx, + unsigned char* md, unsigned int* s); + +WOLFSSL_API int wolfSSL_EVP_DigestSignInit(WOLFSSL_EVP_MD_CTX *ctx, + WOLFSSL_EVP_PKEY_CTX **pctx, + const WOLFSSL_EVP_MD *type, + WOLFSSL_ENGINE *e, + WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API int wolfSSL_EVP_DigestSignUpdate(WOLFSSL_EVP_MD_CTX *ctx, + const void *d, unsigned int cnt); +WOLFSSL_API int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, + unsigned char *sig, size_t *siglen); + +WOLFSSL_API int wolfSSL_EVP_DigestVerifyInit(WOLFSSL_EVP_MD_CTX *ctx, + WOLFSSL_EVP_PKEY_CTX **pctx, + const WOLFSSL_EVP_MD *type, + WOLFSSL_ENGINE *e, + WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API int wolfSSL_EVP_DigestVerifyUpdate(WOLFSSL_EVP_MD_CTX *ctx, + const void *d, size_t cnt); +WOLFSSL_API int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx, + const unsigned char *sig, + size_t siglen); +WOLFSSL_API int wolfSSL_EVP_Digest(const unsigned char* in, int inSz, unsigned char* out, + unsigned int* outSz, const WOLFSSL_EVP_MD* evp, + WOLFSSL_ENGINE* eng); + + +WOLFSSL_API int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER*, + const WOLFSSL_EVP_MD*, const unsigned char*, + const unsigned char*, int, int, unsigned char*, + unsigned char*); + +WOLFSSL_API void wolfSSL_EVP_CIPHER_CTX_init(WOLFSSL_EVP_CIPHER_CTX* ctx); +WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx); +WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_ctrl(WOLFSSL_EVP_CIPHER_CTX *ctx, \ + int type, int arg, void *ptr); +WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX*); +WOLFSSL_API int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER*); +WOLFSSL_API int wolfSSL_EVP_Cipher_key_length(const WOLFSSL_EVP_CIPHER* c); + + +WOLFSSL_API int wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + const unsigned char* key, + const unsigned char* iv, + int enc); +WOLFSSL_API int wolfSSL_EVP_CipherInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + WOLFSSL_ENGINE *impl, + const unsigned char* key, + const unsigned char* iv, + int enc); +WOLFSSL_API int wolfSSL_EVP_EncryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + const unsigned char* key, + const unsigned char* iv); +WOLFSSL_API int wolfSSL_EVP_EncryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + WOLFSSL_ENGINE *impl, + const unsigned char* key, + const unsigned char* iv); +WOLFSSL_API int wolfSSL_EVP_DecryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + const unsigned char* key, + const unsigned char* iv); +WOLFSSL_API int wolfSSL_EVP_DecryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + WOLFSSL_ENGINE *impl, + const unsigned char* key, + const unsigned char* iv); +WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl, + const unsigned char *in, int inl); +WOLFSSL_API int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl); +WOLFSSL_API int wolfSSL_EVP_CipherFinal_ex(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl, int enc); +WOLFSSL_API int wolfSSL_EVP_EncryptFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl); +WOLFSSL_API int wolfSSL_EVP_EncryptFinal_ex(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl); +WOLFSSL_API int wolfSSL_EVP_DecryptFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl); +WOLFSSL_API int wolfSSL_EVP_DecryptFinal_ex(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl); +WOLFSSL_API int wolfSSL_EVP_DecryptFinal_legacy(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl); + +WOLFSSL_API WOLFSSL_EVP_CIPHER_CTX *wolfSSL_EVP_CIPHER_CTX_new(void); +WOLFSSL_API void wolfSSL_EVP_CIPHER_CTX_free(WOLFSSL_EVP_CIPHER_CTX *ctx); +WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx); +WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_set_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx, + int keylen); +WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_set_iv_length(WOLFSSL_EVP_CIPHER_CTX* ctx, + int ivLen); +WOLFSSL_API int wolfSSL_EVP_Cipher(WOLFSSL_EVP_CIPHER_CTX* ctx, + unsigned char* dst, unsigned char* src, + unsigned int len); + +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_get_cipherbynid(int); +WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int); +WOLFSSL_API const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_CIPHER_CTX_cipher(const WOLFSSL_EVP_CIPHER_CTX *ctx); + +WOLFSSL_API int wolfSSL_EVP_PKEY_assign_RSA(WOLFSSL_EVP_PKEY* pkey, + WOLFSSL_RSA* key); +WOLFSSL_API int wolfSSL_EVP_PKEY_assign_EC_KEY(WOLFSSL_EVP_PKEY* pkey, + WOLFSSL_EC_KEY* key); +WOLFSSL_API WOLFSSL_RSA* wolfSSL_EVP_PKEY_get0_RSA(struct WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY*); +WOLFSSL_API WOLFSSL_DSA* wolfSSL_EVP_PKEY_get1_DSA(WOLFSSL_EVP_PKEY*); +WOLFSSL_API WOLFSSL_EC_KEY *wolfSSL_EVP_PKEY_get0_EC_KEY(WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API WOLFSSL_EC_KEY *wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API int wolfSSL_EVP_PKEY_set1_RSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_RSA *key); + +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_mac_key(int type, ENGINE* e, + const unsigned char* key, int keylen); +WOLFSSL_API const unsigned char* wolfSSL_EVP_PKEY_get0_hmac(const WOLFSSL_EVP_PKEY* pkey, + size_t* len); +WOLFSSL_API int wolfSSL_EVP_PKEY_sign_init(WOLFSSL_EVP_PKEY_CTX *ctx); +WOLFSSL_API int wolfSSL_EVP_PKEY_sign(WOLFSSL_EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen); +WOLFSSL_API int wolfSSL_EVP_PKEY_keygen_init(WOLFSSL_EVP_PKEY_CTX *ctx); +WOLFSSL_API int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx, + WOLFSSL_EVP_PKEY **ppkey); +WOLFSSL_API int wolfSSL_EVP_PKEY_bits(const WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_free(WOLFSSL_EVP_PKEY_CTX *ctx); +WOLFSSL_API WOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_ENGINE *e); +WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_set_rsa_padding(WOLFSSL_EVP_PKEY_CTX *ctx, int padding); +WOLFSSL_API WOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new_id(int id, WOLFSSL_ENGINE *e); +WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_set_rsa_keygen_bits(WOLFSSL_EVP_PKEY_CTX *ctx, int bits); + +WOLFSSL_API int wolfSSL_EVP_PKEY_decrypt(WOLFSSL_EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); +WOLFSSL_API int wolfSSL_EVP_PKEY_decrypt_init(WOLFSSL_EVP_PKEY_CTX *ctx); +WOLFSSL_API int wolfSSL_EVP_PKEY_encrypt(WOLFSSL_EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); +WOLFSSL_API int wolfSSL_EVP_PKEY_encrypt_init(WOLFSSL_EVP_PKEY_CTX *ctx); +WOLFSSL_API WOLFSSL_EVP_PKEY *wolfSSL_EVP_PKEY_new(void); +WOLFSSL_API void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY*); +WOLFSSL_API int wolfSSL_EVP_PKEY_size(WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API int wolfSSL_EVP_PKEY_missing_parameters(WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API int wolfSSL_EVP_PKEY_cmp(const WOLFSSL_EVP_PKEY *a, const WOLFSSL_EVP_PKEY *b); +WOLFSSL_API int wolfSSL_EVP_PKEY_type(int type); +WOLFSSL_API int wolfSSL_EVP_PKEY_id(const EVP_PKEY *pkey); +WOLFSSL_API int wolfSSL_EVP_PKEY_base_id(const EVP_PKEY *pkey); +WOLFSSL_API int wolfSSL_EVP_SignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API int wolfSSL_EVP_SignInit(WOLFSSL_EVP_MD_CTX *ctx, const WOLFSSL_EVP_MD *type); +WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx, + const WOLFSSL_EVP_MD* type, + WOLFSSL_ENGINE *impl); +WOLFSSL_API int wolfSSL_EVP_SignUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *data, size_t len); +WOLFSSL_API int wolfSSL_EVP_VerifyFinal(WOLFSSL_EVP_MD_CTX *ctx, + unsigned char* sig, unsigned int sig_len, WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API int wolfSSL_EVP_VerifyInit(WOLFSSL_EVP_MD_CTX *ctx, const WOLFSSL_EVP_MD *type); +WOLFSSL_API int wolfSSL_EVP_VerifyUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *data, size_t len); + + +/* these next ones don't need real OpenSSL type, for OpenSSH compat only */ +WOLFSSL_API void* wolfSSL_EVP_X_STATE(const WOLFSSL_EVP_CIPHER_CTX* ctx); +WOLFSSL_API int wolfSSL_EVP_X_STATE_LEN(const WOLFSSL_EVP_CIPHER_CTX* ctx); + +WOLFSSL_API void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset, + unsigned char* iv, int len); +WOLFSSL_API void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset, + unsigned char* iv, int len); + +WOLFSSL_API int wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx); +WOLFSSL_API int wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx); + +WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_block_size(const WOLFSSL_EVP_CIPHER_CTX *ctx); +WOLFSSL_API int wolfSSL_EVP_CIPHER_block_size(const WOLFSSL_EVP_CIPHER *cipher); +WOLFSSL_API unsigned long WOLFSSL_EVP_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher); +WOLFSSL_API unsigned long WOLFSSL_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher); +WOLFSSL_API unsigned long wolfSSL_EVP_CIPHER_flags(const WOLFSSL_EVP_CIPHER *cipher); +WOLFSSL_API void wolfSSL_EVP_CIPHER_CTX_set_flags(WOLFSSL_EVP_CIPHER_CTX *ctx, int flags); +WOLFSSL_API void wolfSSL_EVP_CIPHER_CTX_clear_flags(WOLFSSL_EVP_CIPHER_CTX *ctx, int flags); +WOLFSSL_API unsigned long wolfSSL_EVP_CIPHER_CTX_mode(const WOLFSSL_EVP_CIPHER_CTX *ctx); +WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_set_padding(WOLFSSL_EVP_CIPHER_CTX *c, int pad); +WOLFSSL_API int wolfSSL_EVP_add_digest(const WOLFSSL_EVP_MD *digest); +WOLFSSL_API int wolfSSL_EVP_add_cipher(const WOLFSSL_EVP_CIPHER *cipher); +WOLFSSL_API void wolfSSL_EVP_cleanup(void); +WOLFSSL_API int wolfSSL_add_all_algorithms(void); +WOLFSSL_API int wolfSSL_OpenSSL_add_all_algorithms_noconf(void); +WOLFSSL_API int wolfSSL_EVP_read_pw_string(char*, int, const char*, int); + +WOLFSSL_API int wolfSSL_PKCS5_PBKDF2_HMAC_SHA1(const char * pass, int passlen, + const unsigned char * salt, + int saltlen, int iter, + int keylen, unsigned char *out); + +WOLFSSL_API int wolfSSL_PKCS5_PBKDF2_HMAC(const char *pass, int passlen, + const unsigned char *salt, + int saltlen, int iter, + const WOLFSSL_EVP_MD *digest, + int keylen, unsigned char *out); +#define EVP_CIPH_STREAM_CIPHER WOLFSSL_EVP_CIPH_STREAM_CIPHER +#define EVP_CIPH_ECB_MODE WOLFSSL_EVP_CIPH_ECB_MODE +#define EVP_CIPH_CBC_MODE WOLFSSL_EVP_CIPH_CBC_MODE +#define EVP_CIPH_CFB_MODE WOLFSSL_EVP_CIPH_CFB_MODE +#define EVP_CIPH_OFB_MODE WOLFSSL_EVP_CIPH_OFB_MODE +#define EVP_CIPH_CTR_MODE WOLFSSL_EVP_CIPH_CTR_MODE +#define EVP_CIPH_GCM_MODE WOLFSSL_EVP_CIPH_GCM_MODE +#define EVP_CIPH_CCM_MODE WOLFSSL_EVP_CIPH_CCM_MODE + +#define WOLFSSL_EVP_CIPH_MODE 0x0007 +#define WOLFSSL_EVP_CIPH_STREAM_CIPHER 0x0 +#define WOLFSSL_EVP_CIPH_ECB_MODE 0x1 +#define WOLFSSL_EVP_CIPH_CBC_MODE 0x2 +#define WOLFSSL_EVP_CIPH_CFB_MODE 0x3 +#define WOLFSSL_EVP_CIPH_OFB_MODE 0x4 +#define WOLFSSL_EVP_CIPH_CTR_MODE 0x5 +#define WOLFSSL_EVP_CIPH_GCM_MODE 0x6 +#define WOLFSSL_EVP_CIPH_CCM_MODE 0x7 +#define WOLFSSL_EVP_CIPH_NO_PADDING 0x100 +#define EVP_CIPH_VARIABLE_LENGTH 0x200 +#define WOLFSSL_EVP_CIPH_TYPE_INIT 0xff + +/* end OpenSSH compat */ + +typedef WOLFSSL_EVP_MD EVP_MD; +typedef WOLFSSL_EVP_CIPHER EVP_CIPHER; +typedef WOLFSSL_EVP_MD_CTX EVP_MD_CTX; +typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; + +#ifndef NO_MD4 + #define EVP_md4 wolfSSL_EVP_md4 +#endif +#ifndef NO_MD5 + #define EVP_md5 wolfSSL_EVP_md5 +#endif +#define EVP_sha1 wolfSSL_EVP_sha1 +#define EVP_dds1 wolfSSL_EVP_sha1 +#define EVP_sha224 wolfSSL_EVP_sha224 +#define EVP_sha256 wolfSSL_EVP_sha256 +#define EVP_sha384 wolfSSL_EVP_sha384 +#define EVP_sha512 wolfSSL_EVP_sha512 +#define EVP_ripemd160 wolfSSL_EVP_ripemd160 + +#define EVP_aes_128_cbc wolfSSL_EVP_aes_128_cbc +#define EVP_aes_192_cbc wolfSSL_EVP_aes_192_cbc +#define EVP_aes_256_cbc wolfSSL_EVP_aes_256_cbc +#define EVP_aes_128_gcm wolfSSL_EVP_aes_128_gcm +#define EVP_aes_192_gcm wolfSSL_EVP_aes_192_gcm +#define EVP_aes_256_gcm wolfSSL_EVP_aes_256_gcm +#define EVP_aes_128_ecb wolfSSL_EVP_aes_128_ecb +#define EVP_aes_192_ecb wolfSSL_EVP_aes_192_ecb +#define EVP_aes_256_ecb wolfSSL_EVP_aes_256_ecb +#define EVP_aes_128_ctr wolfSSL_EVP_aes_128_ctr +#define EVP_aes_192_ctr wolfSSL_EVP_aes_192_ctr +#define EVP_aes_256_ctr wolfSSL_EVP_aes_256_ctr +#define EVP_des_cbc wolfSSL_EVP_des_cbc +#define EVP_des_ecb wolfSSL_EVP_des_ecb +#define EVP_des_ede3_cbc wolfSSL_EVP_des_ede3_cbc +#define EVP_des_ede3_ecb wolfSSL_EVP_des_ede3_ecb +#define EVP_rc4 wolfSSL_EVP_rc4 +#define EVP_idea_cbc wolfSSL_EVP_idea_cbc +#define EVP_enc_null wolfSSL_EVP_enc_null + +#define EVP_MD_size wolfSSL_EVP_MD_size +#define EVP_MD_CTX_new wolfSSL_EVP_MD_CTX_new +#define EVP_MD_CTX_create wolfSSL_EVP_MD_CTX_new +#define EVP_MD_CTX_free wolfSSL_EVP_MD_CTX_free +#define EVP_MD_CTX_destroy wolfSSL_EVP_MD_CTX_free +#define EVP_MD_CTX_init wolfSSL_EVP_MD_CTX_init +#define EVP_MD_CTX_cleanup wolfSSL_EVP_MD_CTX_cleanup +#define EVP_MD_CTX_md wolfSSL_EVP_MD_CTX_md +#define EVP_MD_CTX_type wolfSSL_EVP_MD_CTX_type +#define EVP_MD_CTX_size wolfSSL_EVP_MD_CTX_size +#define EVP_MD_CTX_block_size wolfSSL_EVP_MD_CTX_block_size +#define EVP_MD_type wolfSSL_EVP_MD_type + +#define EVP_Digest wolfSSL_EVP_Digest +#define EVP_DigestInit wolfSSL_EVP_DigestInit +#define EVP_DigestInit_ex wolfSSL_EVP_DigestInit_ex +#define EVP_DigestUpdate wolfSSL_EVP_DigestUpdate +#define EVP_DigestFinal wolfSSL_EVP_DigestFinal +#define EVP_DigestFinal_ex wolfSSL_EVP_DigestFinal_ex +#define EVP_DigestSignInit wolfSSL_EVP_DigestSignInit +#define EVP_DigestSignUpdate wolfSSL_EVP_DigestSignUpdate +#define EVP_DigestSignFinal wolfSSL_EVP_DigestSignFinal +#define EVP_DigestVerifyInit wolfSSL_EVP_DigestVerifyInit +#define EVP_DigestVerifyUpdate wolfSSL_EVP_DigestVerifyUpdate +#define EVP_DigestVerifyFinal wolfSSL_EVP_DigestVerifyFinal +#define EVP_BytesToKey wolfSSL_EVP_BytesToKey + +#define EVP_get_cipherbyname wolfSSL_EVP_get_cipherbyname +#define EVP_get_digestbyname wolfSSL_EVP_get_digestbyname + +#define EVP_CIPHER_CTX_init wolfSSL_EVP_CIPHER_CTX_init +#define EVP_CIPHER_CTX_cleanup wolfSSL_EVP_CIPHER_CTX_cleanup +#define EVP_CIPHER_CTX_iv_length wolfSSL_EVP_CIPHER_CTX_iv_length +#define EVP_CIPHER_CTX_key_length wolfSSL_EVP_CIPHER_CTX_key_length +#define EVP_CIPHER_CTX_set_key_length wolfSSL_EVP_CIPHER_CTX_set_key_length +#define EVP_CIPHER_CTX_mode wolfSSL_EVP_CIPHER_CTX_mode +#define EVP_CIPHER_CTX_cipher wolfSSL_EVP_CIPHER_CTX_cipher + +#define EVP_CIPHER_iv_length wolfSSL_EVP_CIPHER_iv_length +#define EVP_CIPHER_key_length wolfSSL_EVP_Cipher_key_length + +#define EVP_CipherInit wolfSSL_EVP_CipherInit +#define EVP_CipherInit_ex wolfSSL_EVP_CipherInit_ex +#define EVP_EncryptInit wolfSSL_EVP_EncryptInit +#define EVP_EncryptInit_ex wolfSSL_EVP_EncryptInit_ex +#define EVP_DecryptInit wolfSSL_EVP_DecryptInit +#define EVP_DecryptInit_ex wolfSSL_EVP_DecryptInit_ex + +#define EVP_Cipher wolfSSL_EVP_Cipher +#define EVP_CipherUpdate wolfSSL_EVP_CipherUpdate +#define EVP_EncryptUpdate wolfSSL_EVP_CipherUpdate +#define EVP_DecryptUpdate wolfSSL_EVP_CipherUpdate +#define EVP_CipherFinal wolfSSL_EVP_CipherFinal +#define EVP_CipherFinal_ex wolfSSL_EVP_CipherFinal +#define EVP_EncryptFinal wolfSSL_EVP_CipherFinal +#define EVP_EncryptFinal_ex wolfSSL_EVP_CipherFinal +#define EVP_DecryptFinal wolfSSL_EVP_CipherFinal +#define EVP_DecryptFinal_ex wolfSSL_EVP_CipherFinal + +#define EVP_CIPHER_CTX_free wolfSSL_EVP_CIPHER_CTX_free +#define EVP_CIPHER_CTX_new wolfSSL_EVP_CIPHER_CTX_new + +#define EVP_get_cipherbynid wolfSSL_EVP_get_cipherbynid +#define EVP_get_digestbynid wolfSSL_EVP_get_digestbynid +#define EVP_get_cipherbyname wolfSSL_EVP_get_cipherbyname +#define EVP_get_digestbyname wolfSSL_EVP_get_digestbyname + +#define EVP_PKEY_assign_RSA wolfSSL_EVP_PKEY_assign_RSA +#define EVP_PKEY_assign_EC_KEY wolfSSL_EVP_PKEY_assign_EC_KEY +#define EVP_PKEY_get1_DSA wolfSSL_EVP_PKEY_get1_DSA +#define EVP_PKEY_get1_RSA wolfSSL_EVP_PKEY_get1_RSA +#define EVP_PKEY_get1_DSA wolfSSL_EVP_PKEY_get1_DSA +#define EVP_PKEY_set1_RSA wolfSSL_EVP_PKEY_set1_RSA +#define EVP_PKEY_get0_EC_KEY wolfSSL_EVP_PKEY_get0_EC_KEY +#define EVP_PKEY_get1_EC_KEY wolfSSL_EVP_PKEY_get1_EC_KEY +#define EVP_PKEY_get0_hmac wolfSSL_EVP_PKEY_get0_hmac +#define EVP_PKEY_new_mac_key wolfSSL_EVP_PKEY_new_mac_key +#define EVP_MD_CTX_copy wolfSSL_EVP_MD_CTX_copy +#define EVP_MD_CTX_copy_ex wolfSSL_EVP_MD_CTX_copy_ex +#define EVP_PKEY_sign_init wolfSSL_EVP_PKEY_sign_init +#define EVP_PKEY_sign wolfSSL_EVP_PKEY_sign +#define EVP_PKEY_keygen wolfSSL_EVP_PKEY_keygen +#define EVP_PKEY_keygen_init wolfSSL_EVP_PKEY_keygen_init +#define EVP_PKEY_bits wolfSSL_EVP_PKEY_bits +#define EVP_PKEY_CTX_free wolfSSL_EVP_PKEY_CTX_free +#define EVP_PKEY_CTX_new wolfSSL_EVP_PKEY_CTX_new +#define EVP_PKEY_CTX_set_rsa_padding wolfSSL_EVP_PKEY_CTX_set_rsa_padding +#define EVP_PKEY_CTX_new_id wolfSSL_EVP_PKEY_CTX_new_id +#define EVP_PKEY_CTX_set_rsa_keygen_bits wolfSSL_EVP_PKEY_CTX_set_rsa_keygen_bits +#define EVP_PKEY_decrypt wolfSSL_EVP_PKEY_decrypt +#define EVP_PKEY_decrypt_init wolfSSL_EVP_PKEY_decrypt_init +#define EVP_PKEY_encrypt wolfSSL_EVP_PKEY_encrypt +#define EVP_PKEY_encrypt_init wolfSSL_EVP_PKEY_encrypt_init +#define EVP_PKEY_new wolfSSL_PKEY_new +#define EVP_PKEY_free wolfSSL_EVP_PKEY_free +#define EVP_PKEY_up_ref wolfSSL_EVP_PKEY_up_ref +#define EVP_PKEY_size wolfSSL_EVP_PKEY_size +#define EVP_PKEY_missing_parameters wolfSSL_EVP_PKEY_missing_parameters +#define EVP_PKEY_cmp wolfSSL_EVP_PKEY_cmp +#define EVP_PKEY_type wolfSSL_EVP_PKEY_type +#define EVP_PKEY_base_id wolfSSL_EVP_PKEY_base_id +#define EVP_PKEY_id wolfSSL_EVP_PKEY_id +#define EVP_SignFinal wolfSSL_EVP_SignFinal +#define EVP_SignInit wolfSSL_EVP_SignInit +#define EVP_SignInit_ex wolfSSL_EVP_SignInit_ex +#define EVP_SignUpdate wolfSSL_EVP_SignUpdate +#define EVP_VerifyFinal wolfSSL_EVP_VerifyFinal +#define EVP_VerifyInit wolfSSL_EVP_VerifyInit +#define EVP_VerifyUpdate wolfSSL_EVP_VerifyUpdate + +#define EVP_CIPHER_CTX_ctrl wolfSSL_EVP_CIPHER_CTX_ctrl +#define EVP_CIPHER_CTX_block_size wolfSSL_EVP_CIPHER_CTX_block_size +#define EVP_CIPHER_block_size wolfSSL_EVP_CIPHER_block_size +#define EVP_CIPHER_flags wolfSSL_EVP_CIPHER_flags +#define EVP_CIPHER_CTX_set_flags wolfSSL_EVP_CIPHER_CTX_set_flags +#define EVP_CIPHER_CTX_clear_flags wolfSSL_EVP_CIPHER_CTX_clear_flags +#define EVP_CIPHER_CTX_set_padding wolfSSL_EVP_CIPHER_CTX_set_padding +#define EVP_CIPHER_CTX_flags wolfSSL_EVP_CIPHER_CTX_flags +#define EVP_add_digest wolfSSL_EVP_add_digest +#define EVP_add_cipher wolfSSL_EVP_add_cipher +#define EVP_cleanup wolfSSL_EVP_cleanup +#define EVP_read_pw_string wolfSSL_EVP_read_pw_string + +#define OpenSSL_add_all_digests() wolfSSL_EVP_init() +#define OpenSSL_add_all_ciphers() wolfSSL_EVP_init() +#define OpenSSL_add_all_algorithms wolfSSL_add_all_algorithms +#define OpenSSL_add_all_algorithms_noconf wolfSSL_OpenSSL_add_all_algorithms_noconf +#define wolfSSL_OPENSSL_add_all_algorithms_noconf wolfSSL_OpenSSL_add_all_algorithms_noconf + +#define NO_PADDING_BLOCK_SIZE 1 + +#define PKCS5_PBKDF2_HMAC_SHA1 wolfSSL_PKCS5_PBKDF2_HMAC_SHA1 +#define PKCS5_PBKDF2_HMAC wolfSSL_PKCS5_PBKDF2_HMAC + +/* OpenSSL compat. ctrl values */ +#define EVP_CTRL_INIT 0x0 +#define EVP_CTRL_SET_KEY_LENGTH 0x1 +#define EVP_CTRL_SET_RC2_KEY_BITS 0x3 /* needed for qt compilation */ + +#define EVP_CTRL_AEAD_SET_IVLEN 0x9 +#define EVP_CTRL_AEAD_GET_TAG 0x10 +#define EVP_CTRL_AEAD_SET_TAG 0x11 +#define EVP_CTRL_AEAD_SET_IV_FIXED 0x12 +#define EVP_CTRL_GCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN +#define EVP_CTRL_GCM_GET_TAG EVP_CTRL_AEAD_GET_TAG +#define EVP_CTRL_GCM_SET_TAG EVP_CTRL_AEAD_SET_TAG + +#ifndef EVP_MAX_MD_SIZE + #define EVP_MAX_MD_SIZE 64 /* sha512 */ +#endif + +#ifndef EVP_MAX_KEY_LENGTH +#define EVP_MAX_KEY_LENGTH 64 +#endif + +#ifndef EVP_MAX_IV_LENGTH +#define EVP_MAX_IV_LENGTH 16 +#endif + +#ifndef EVP_MAX_BLOCK_LENGTH + #define EVP_MAX_BLOCK_LENGTH 32 /* 2 * blocklen(AES)? */ + /* They define this as 32. Using the same value here. */ +#endif + +#ifndef EVP_MAX_IV_LENGTH + #define EVP_MAX_IV_LENGTH 16 +#endif + +WOLFSSL_API void printPKEY(WOLFSSL_EVP_PKEY *k); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#include + +#endif /* WOLFSSL_EVP_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/hmac.h b/wolfssl_hlavickove_subory/wolfssl/openssl/hmac.h new file mode 100644 index 0000000..7a90617 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/hmac.h @@ -0,0 +1,100 @@ +/* hmac.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +/* hmac.h defines mini hamc openssl compatibility layer + * + */ + + +#ifndef WOLFSSL_HMAC_H_ +#define WOLFSSL_HMAC_H_ + +#include + +#ifdef WOLFSSL_PREFIX +#include "prefix_hmac.h" +#endif + +#include +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + + +WOLFSSL_API unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, + const void* key, int key_len, + const unsigned char* d, int n, unsigned char* md, + unsigned int* md_len); + + +typedef struct WOLFSSL_HMAC_CTX { + Hmac hmac; + int type; + word32 save_ipad[WC_HMAC_BLOCK_SIZE / sizeof(word32)]; /* same block size all*/ + word32 save_opad[WC_HMAC_BLOCK_SIZE / sizeof(word32)]; +} WOLFSSL_HMAC_CTX; + + +WOLFSSL_API WOLFSSL_HMAC_CTX* wolfSSL_HMAC_CTX_new(void); +WOLFSSL_API int wolfSSL_HMAC_CTX_Init(WOLFSSL_HMAC_CTX* ctx); +WOLFSSL_API int wolfSSL_HMAC_CTX_copy(WOLFSSL_HMAC_CTX* des, + WOLFSSL_HMAC_CTX* src); +WOLFSSL_LOCAL int wolfSSL_HmacCopy(Hmac* des, Hmac* src); +WOLFSSL_API int wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, + int keylen, const EVP_MD* type); +WOLFSSL_API int wolfSSL_HMAC_Init_ex(WOLFSSL_HMAC_CTX* ctx, const void* key, + int keylen, const EVP_MD* type, WOLFSSL_ENGINE* e); +WOLFSSL_API int wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, + const unsigned char* data, int len); +WOLFSSL_API int wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash, + unsigned int* len); +WOLFSSL_API int wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx); +WOLFSSL_API void wolfSSL_HMAC_CTX_free(WOLFSSL_HMAC_CTX* ctx); +WOLFSSL_API size_t wolfSSL_HMAC_size(const WOLFSSL_HMAC_CTX *ctx); + +typedef struct WOLFSSL_HMAC_CTX HMAC_CTX; + +#define HMAC(a,b,c,d,e,f,g) wolfSSL_HMAC((a),(b),(c),(d),(e),(f),(g)) + +#define HMAC_CTX_new wolfSSL_HMAC_CTX_new +#define HMAC_CTX_init wolfSSL_HMAC_CTX_Init +#define HMAC_CTX_copy wolfSSL_HMAC_CTX_copy +#define HMAC_CTX_free wolfSSL_HMAC_CTX_free +#define HMAC_CTX_reset wolfSSL_HMAC_cleanup +#define HMAC_Init_ex wolfSSL_HMAC_Init_ex +#define HMAC_Init wolfSSL_HMAC_Init +#define HMAC_Update wolfSSL_HMAC_Update +#define HMAC_Final wolfSSL_HMAC_Final +#define HMAC_cleanup wolfSSL_HMAC_cleanup +#define HMAC_size wolfSSL_HMAC_size + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* WOLFSSL_HMAC_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/include.am b/wolfssl_hlavickove_subory/wolfssl/openssl/include.am new file mode 100644 index 0000000..f7ce8b7 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/include.am @@ -0,0 +1,47 @@ +# vim:ft=automake +# All paths should be given relative to the root + +nobase_include_HEADERS+= \ + wolfssl/openssl/asn1.h \ + wolfssl/openssl/aes.h\ + wolfssl/openssl/bio.h \ + wolfssl/openssl/bn.h \ + wolfssl/openssl/buffer.h \ + wolfssl/openssl/conf.h \ + wolfssl/openssl/crypto.h \ + wolfssl/openssl/des.h \ + wolfssl/openssl/dh.h \ + wolfssl/openssl/dsa.h \ + wolfssl/openssl/ecdsa.h \ + wolfssl/openssl/ecdh.h \ + wolfssl/openssl/ec.h \ + wolfssl/openssl/ec25519.h \ + wolfssl/openssl/ed25519.h \ + wolfssl/openssl/engine.h \ + wolfssl/openssl/err.h \ + wolfssl/openssl/evp.h \ + wolfssl/openssl/hmac.h \ + wolfssl/openssl/lhash.h \ + wolfssl/openssl/md4.h \ + wolfssl/openssl/md5.h \ + wolfssl/openssl/ripemd.h \ + wolfssl/openssl/objects.h \ + wolfssl/openssl/ocsp.h \ + wolfssl/openssl/opensslconf.h \ + wolfssl/openssl/opensslv.h \ + wolfssl/openssl/ossl_typ.h \ + wolfssl/openssl/pem.h \ + wolfssl/openssl/pkcs12.h \ + wolfssl/openssl/pkcs7.h \ + wolfssl/openssl/rand.h \ + wolfssl/openssl/rsa.h \ + wolfssl/openssl/sha.h \ + wolfssl/openssl/ssl23.h \ + wolfssl/openssl/ssl.h \ + wolfssl/openssl/stack.h \ + wolfssl/openssl/tls1.h \ + wolfssl/openssl/ui.h \ + wolfssl/openssl/x509.h \ + wolfssl/openssl/x509_vfy.h \ + wolfssl/openssl/x509v3.h \ + wolfssl/openssl/rc4.h diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/lhash.h b/wolfssl_hlavickove_subory/wolfssl/openssl/lhash.h new file mode 100644 index 0000000..01f8535 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/lhash.h @@ -0,0 +1,2 @@ +/* lhash.h for openSSL */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/md4.h b/wolfssl_hlavickove_subory/wolfssl/openssl/md4.h new file mode 100644 index 0000000..7310a00 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/md4.h @@ -0,0 +1,62 @@ +/* md4.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLFSSL_MD4_H_ +#define WOLFSSL_MD4_H_ + +#include + +#ifndef NO_MD4 + +#ifdef WOLFSSL_PREFIX +#include "prefix_md4.h" +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef struct WOLFSSL_MD4_CTX { + int buffer[32]; /* big enough to hold, check size in Init */ +} WOLFSSL_MD4_CTX; + + +WOLFSSL_API void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX*); +WOLFSSL_API void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX*, const void*, unsigned long); +WOLFSSL_API void wolfSSL_MD4_Final(unsigned char*, WOLFSSL_MD4_CTX*); + + +typedef WOLFSSL_MD4_CTX MD4_CTX; + +#define MD4_Init wolfSSL_MD4_Init +#define MD4_Update wolfSSL_MD4_Update +#define MD4_Final wolfSSL_MD4_Final + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* NO_MD4 */ + +#endif /* WOLFSSL_MD4_H_ */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/md5.h b/wolfssl_hlavickove_subory/wolfssl/openssl/md5.h new file mode 100644 index 0000000..cf77bc9 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/md5.h @@ -0,0 +1,81 @@ +/* md5.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* md5.h for openssl */ + + +#ifndef WOLFSSL_MD5_H_ +#define WOLFSSL_MD5_H_ + +#include + +#ifndef NO_MD5 + +#include + +#ifdef WOLFSSL_PREFIX +#include "prefix_md5.h" +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef struct WOLFSSL_MD5_CTX { + /* big enough to hold wolfcrypt md5, but check on init */ +#ifdef STM32_HASH + void* holder[(112 + WC_ASYNC_DEV_SIZE + sizeof(STM32_HASH_Context)) / sizeof(void*)]; +#else + void* holder[(112 + WC_ASYNC_DEV_SIZE) / sizeof(void*)]; +#endif +} WOLFSSL_MD5_CTX; + +WOLFSSL_API int wolfSSL_MD5_Init(WOLFSSL_MD5_CTX*); +WOLFSSL_API int wolfSSL_MD5_Update(WOLFSSL_MD5_CTX*, const void*, unsigned long); +WOLFSSL_API int wolfSSL_MD5_Final(unsigned char*, WOLFSSL_MD5_CTX*); + + +typedef WOLFSSL_MD5_CTX MD5_CTX; + +#define MD5_Init wolfSSL_MD5_Init +#define MD5_Update wolfSSL_MD5_Update +#define MD5_Final wolfSSL_MD5_Final + +#ifdef OPENSSL_EXTRA_BSD + #define MD5Init wolfSSL_MD5_Init + #define MD5Update wolfSSL_MD5_Update + #define MD5Final wolfSSL_MD5_Final +#endif + +#ifndef MD5 +#define MD5(d, n, md) wc_Md5Hash((d), (n), (md)) +#endif + +#define MD5_DIGEST_LENGTH MD5_DIGEST_SIZE + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* NO_MD5 */ + +#endif /* WOLFSSL_MD5_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/objects.h b/wolfssl_hlavickove_subory/wolfssl/openssl/objects.h new file mode 100644 index 0000000..01b1067 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/objects.h @@ -0,0 +1,62 @@ +/* objects.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLFSSL_OBJECTS_H_ +#define WOLFSSL_OBJECTS_H_ + +#include +//#include +#ifndef OPENSSL_EXTRA_SSL_GUARD +#define OPENSSL_EXTRA_SSL_GUARD +#include +#endif /* OPENSSL_EXTRA_SSL_GUARD */ + +#ifdef __cplusplus + extern "C" { +#endif + +#define OBJ_nid2sn wolfSSL_OBJ_nid2sn +#define OBJ_obj2nid wolfSSL_OBJ_obj2nid +#define OBJ_sn2nid wolfSSL_OBJ_sn2nid +#define OBJ_nid2ln wolfSSL_OBJ_nid2ln +#define OBJ_txt2nid wolfSSL_OBJ_txt2nid +#define OBJ_txt2obj wolfSSL_OBJ_txt2obj +#define OBJ_nid2obj wolfSSL_OBJ_nid2obj +#define OBJ_obj2txt wolfSSL_OBJ_obj2txt +#define OBJ_cleanup wolfSSL_OBJ_cleanup +#define OBJ_cmp wolfSSL_OBJ_cmp +#define OBJ_create wolfSSL_OBJ_create +#define ASN1_OBJECT_free wolfSSL_ASN1_OBJECT_free + +/* not required for wolfSSL */ +#define OPENSSL_load_builtin_modules() + + +#define NID_ad_OCSP 178 +#define NID_ad_ca_issuers 179 + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_OBJECTS_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/ocsp.h b/wolfssl_hlavickove_subory/wolfssl/openssl/ocsp.h new file mode 100644 index 0000000..0a0f27d --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/ocsp.h @@ -0,0 +1,82 @@ +/* ocsp.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* ocsp.h for libcurl */ + +#ifndef WOLFSSL_OCSP_H_ +#define WOLFSSL_OCSP_H_ + +#ifdef HAVE_OCSP +#include + +#define OCSP_REQUEST OcspRequest +#define OCSP_RESPONSE OcspResponse +#define OCSP_BASICRESP WOLFSSL_OCSP_BASICRESP +#define OCSP_CERTID WOLFSSL_OCSP_CERTID +#define OCSP_ONEREQ WOLFSSL_OCSP_ONEREQ + +#define OCSP_REVOKED_STATUS_NOSTATUS -1 + + +#define OCSP_RESPONSE_STATUS_SUCCESSFUL 0 +#define OCSP_RESPONSE_STATUS_TRYLATER 3 + +#define V_OCSP_CERTSTATUS_GOOD 0 +#define V_OCSP_CERTSTATUS_REVOKED 1 +#define V_OCSP_CERTSTATUS_UNKNOWN 2 + +#define OCSP_resp_find_status wolfSSL_OCSP_resp_find_status +#define OCSP_cert_status_str wolfSSL_OCSP_cert_status_str +#define OCSP_check_validity wolfSSL_OCSP_check_validity + +#define OCSP_CERTID_free wolfSSL_OCSP_CERTID_free +#define OCSP_cert_to_id wolfSSL_OCSP_cert_to_id + +#define OCSP_BASICRESP_free wolfSSL_OCSP_BASICRESP_free +#define OCSP_basic_verify wolfSSL_OCSP_basic_verify + +#define OCSP_RESPONSE_free wolfSSL_OCSP_RESPONSE_free +#define d2i_OCSP_RESPONSE_bio wolfSSL_d2i_OCSP_RESPONSE_bio +#define d2i_OCSP_RESPONSE wolfSSL_d2i_OCSP_RESPONSE +#define i2d_OCSP_RESPONSE wolfSSL_i2d_OCSP_RESPONSE +#define OCSP_response_status wolfSSL_OCSP_response_status +#define OCSP_response_status_str wolfSSL_OCSP_response_status_str +#define OCSP_response_get1_basic wolfSSL_OCSP_response_get1_basic +#define OCSP_response_create wolfSSL_OCSP_response_create + +#define OCSP_REQUEST_new wolfSSL_OCSP_REQUEST_new +#define OCSP_REQUEST_free wolfSSL_OCSP_REQUEST_free +#define i2d_OCSP_REQUEST wolfSSL_i2d_OCSP_REQUEST +#define OCSP_request_add0_id wolfSSL_OCSP_request_add0_id +#define OCSP_request_add1_nonce wolfSSL_OCSP_request_add1_nonce +#define OCSP_check_nonce wolfSSL_OCSP_check_nonce +#define OCSP_id_get0_info wolfSSL_OCSP_id_get0_info +#define OCSP_crl_reason_str wolfSSL_OCSP_crl_reason_str +#define OCSP_REQUEST_add_ext wolfSSL_OCSP_REQUEST_add_ext + +#define OCSP_CERTID_dup wolfSSL_OCSP_CERTID_dup + +#define i2d_OCSP_REQUEST_bio wolfSSL_i2d_OCSP_REQUEST_bio + +#endif /* HAVE_OCSP */ + +#endif /* WOLFSSL_OCSP_H_ */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/opensslconf.h b/wolfssl_hlavickove_subory/wolfssl/openssl/opensslconf.h new file mode 100644 index 0000000..ac6b55b --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/opensslconf.h @@ -0,0 +1,8 @@ +/* opensslconf.h for openSSL */ + + +#ifndef OPENSSL_THREADS + #define OPENSSL_THREADS +#endif + + diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/opensslv.h b/wolfssl_hlavickove_subory/wolfssl/openssl/opensslv.h new file mode 100644 index 0000000..4bc495e --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/opensslv.h @@ -0,0 +1,44 @@ +/* opensslv.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* opensslv.h compatibility */ + +#ifndef WOLFSSL_OPENSSLV_H_ +#define WOLFSSL_OPENSSLV_H_ + + +/* api version compatibility */ +#if defined(WOLFSSL_APACHE_HTTPD) + /* For Apache httpd, Use 1.1.0 compatibility */ + #define OPENSSL_VERSION_NUMBER 0x10100000L +#elif defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(HAVE_LIGHTY) || \ + defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) + /* version number can be increased for Lighty after compatibility for ECDH + is added */ + #define OPENSSL_VERSION_NUMBER 0x10001000L +#else + #define OPENSSL_VERSION_NUMBER 0x0090810fL +#endif + +#define OPENSSL_VERSION_TEXT LIBWOLFSSL_VERSION_STRING +#define OPENSSL_VERSION 0 + +#endif /* header */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/ossl_typ.h b/wolfssl_hlavickove_subory/wolfssl/openssl/ossl_typ.h new file mode 100644 index 0000000..9966b89 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/ossl_typ.h @@ -0,0 +1,32 @@ +/* ossl_typ.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/openssl/ossl_typ.h +*/ + + +#ifndef WOLFSSL_OSSL_TYP_H_ +#define WOLFSSL_OSSL_TYP_H_ + +#include + +#endif /* !WOLFSSL_OSSL_TYP_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/pem.h b/wolfssl_hlavickove_subory/wolfssl/openssl/pem.h new file mode 100644 index 0000000..c8f57b4 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/pem.h @@ -0,0 +1,224 @@ +/* pem.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* pem.h for openssl */ + +/*! + \file wolfssl/openssl/pem.h +*/ + + +#ifndef WOLFSSL_PEM_H_ +#define WOLFSSL_PEM_H_ + +#include +#include +#include +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/* RSA */ +WOLFSSL_API +int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, + const EVP_CIPHER* cipher, + unsigned char* passwd, int len, + pem_password_cb* cb, void* arg); +WOLFSSL_API +WOLFSSL_RSA* wolfSSL_PEM_read_bio_RSAPrivateKey(WOLFSSL_BIO* bio, + WOLFSSL_RSA**, + pem_password_cb* cb, + void* arg); + +WOLFSSL_API +int wolfSSL_PEM_write_bio_RSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa); + +WOLFSSL_API +WOLFSSL_RSA *wolfSSL_PEM_read_bio_RSA_PUBKEY(WOLFSSL_BIO* bio, + WOLFSSL_RSA** rsa, + pem_password_cb* cb, void *u); + +WOLFSSL_API +WOLFSSL_EC_GROUP* wolfSSL_PEM_read_bio_ECPKParameters(WOLFSSL_BIO* bio, + WOLFSSL_EC_GROUP** group, + pem_password_cb* cb, + void* pass); +WOLFSSL_API +int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, + unsigned char* passwd, int len, + unsigned char **pem, int *plen); +#if !defined(NO_FILESYSTEM) +WOLFSSL_API +int wolfSSL_PEM_write_RSAPrivateKey(XFILE fp, WOLFSSL_RSA *rsa, + const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); +WOLFSSL_API +WOLFSSL_RSA *wolfSSL_PEM_read_RSAPublicKey(XFILE fp, WOLFSSL_RSA **x, + pem_password_cb *cb, void *u); +WOLFSSL_API +int wolfSSL_PEM_write_RSAPublicKey(XFILE fp, WOLFSSL_RSA *x); + +WOLFSSL_API +int wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA *x); +#endif /* NO_FILESYSTEM */ + +/* DSA */ +WOLFSSL_API +int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, + WOLFSSL_DSA* dsa, + const EVP_CIPHER* cipher, + unsigned char* passwd, int len, + pem_password_cb* cb, void* arg); +WOLFSSL_API +int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, + const EVP_CIPHER* cipher, + unsigned char* passwd, int len, + unsigned char **pem, int *plen); +#if !defined(NO_FILESYSTEM) +WOLFSSL_API +int wolfSSL_PEM_write_DSAPrivateKey(XFILE fp, WOLFSSL_DSA *dsa, + const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); +WOLFSSL_API +int wolfSSL_PEM_write_DSA_PUBKEY(XFILE fp, WOLFSSL_DSA *x); +#endif /* NO_FILESYSTEM */ + +/* ECC */ +WOLFSSL_API +int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec, + const EVP_CIPHER* cipher, + unsigned char* passwd, int len, + pem_password_cb* cb, void* arg); +WOLFSSL_API +int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* key, + const EVP_CIPHER* cipher, + unsigned char* passwd, int len, + unsigned char **pem, int *plen); +#if !defined(NO_FILESYSTEM) +WOLFSSL_API +int wolfSSL_PEM_write_ECPrivateKey(XFILE fp, WOLFSSL_EC_KEY *key, + const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); +WOLFSSL_API +int wolfSSL_PEM_write_EC_PUBKEY(XFILE fp, WOLFSSL_EC_KEY *key); +#endif /* NO_FILESYSTEM */ + +/* EVP_KEY */ +WOLFSSL_API +WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio, + WOLFSSL_EVP_PKEY**, + pem_password_cb* cb, + void* arg); +WOLFSSL_API +WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_bio_PUBKEY(WOLFSSL_BIO* bio, + WOLFSSL_EVP_PKEY **key, + pem_password_cb *cb, void *pass); +WOLFSSL_API +int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key, + const WOLFSSL_EVP_CIPHER* cipher, + unsigned char* passwd, int len, + pem_password_cb* cb, void* arg); +WOLFSSL_API +int wolfSSL_PEM_write_bio_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key); + + +WOLFSSL_API +int wolfSSL_PEM_read_bio(WOLFSSL_BIO* bio, char **name, char **header, + unsigned char **data, long *len); +WOLFSSL_API +int wolfSSL_PEM_write_bio(WOLFSSL_BIO *bio, const char *name, + const char *header, const unsigned char *data, + long len); +#if !defined(NO_FILESYSTEM) +WOLFSSL_API +int wolfSSL_PEM_read(XFILE fp, char **name, char **header, unsigned char **data, + long *len); +WOLFSSL_API +int wolfSSL_PEM_write(XFILE fp, const char *name, const char *header, + const unsigned char *data, long len); +#endif + +#if !defined(NO_FILESYSTEM) +WOLFSSL_API +WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, EVP_PKEY **x, + pem_password_cb *cb, void *u); +WOLFSSL_API +WOLFSSL_X509 *wolfSSL_PEM_read_X509(XFILE fp, WOLFSSL_X509 **x, + pem_password_cb *cb, void *u); +WOLFSSL_API +WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PrivateKey(XFILE fp, WOLFSSL_EVP_PKEY **x, + pem_password_cb *cb, void *u); + +WOLFSSL_API +int wolfSSL_PEM_write_X509(XFILE fp, WOLFSSL_X509 *x); +WOLFSSL_API +int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh); +#endif /* NO_FILESYSTEM */ + +#define PEM_read wolfSSL_PEM_read +#define PEM_read_bio wolfSSL_PEM_read_bio +#define PEM_write wolfSSL_PEM_write +#define PEM_write_bio wolfSSL_PEM_write_bio + +#define PEM_read_X509 wolfSSL_PEM_read_X509 +#define PEM_read_PrivateKey wolfSSL_PEM_read_PrivateKey +#define PEM_write_X509 wolfSSL_PEM_write_X509 +#define PEM_write_bio_PrivateKey wolfSSL_PEM_write_bio_PrivateKey +#define PEM_write_bio_PKCS8PrivateKey wolfSSL_PEM_write_bio_PKCS8PrivateKey + +/* DH */ +#define PEM_write_DHparams wolfSSL_PEM_write_DHparams +/* RSA */ +#define PEM_write_bio_RSAPrivateKey wolfSSL_PEM_write_bio_RSAPrivateKey +#define PEM_read_bio_RSAPrivateKey wolfSSL_PEM_read_bio_RSAPrivateKey +#define PEM_write_bio_RSA_PUBKEY wolfSSL_PEM_write_bio_RSA_PUBKEY +#define PEM_read_bio_RSA_PUBKEY wolfSSL_PEM_read_bio_RSA_PUBKEY +#define PEM_read_bio_ECPKParameters wolfSSL_PEM_read_bio_ECPKParameters +#define PEM_write_RSAPrivateKey wolfSSL_PEM_write_RSAPrivateKey +#define PEM_write_RSA_PUBKEY wolfSSL_PEM_write_RSA_PUBKEY +#define PEM_write_RSAPublicKey wolfSSL_PEM_write_RSAPublicKey +#define PEM_read_RSAPublicKey wolfSSL_PEM_read_RSAPublicKey +/* DSA */ +#define PEM_write_bio_DSAPrivateKey wolfSSL_PEM_write_bio_DSAPrivateKey +#define PEM_write_DSAPrivateKey wolfSSL_PEM_write_DSAPrivateKey +#define PEM_write_DSA_PUBKEY wolfSSL_PEM_write_DSA_PUBKEY +/* ECC */ +#define PEM_write_bio_ECPrivateKey wolfSSL_PEM_write_bio_ECPrivateKey +#define PEM_write_EC_PUBKEY wolfSSL_PEM_write_EC_PUBKEY +#define PEM_write_ECPrivateKey wolfSSL_PEM_write_ECPrivateKey +/* EVP_KEY */ +#define PEM_read_bio_PrivateKey wolfSSL_PEM_read_bio_PrivateKey +#define PEM_read_PUBKEY wolfSSL_PEM_read_PUBKEY +#define PEM_read_bio_PUBKEY wolfSSL_PEM_read_bio_PUBKEY +#define PEM_write_bio_PUBKEY wolfSSL_PEM_write_bio_PUBKEY + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_PEM_H_ */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/pkcs12.h b/wolfssl_hlavickove_subory/wolfssl/openssl/pkcs12.h new file mode 100644 index 0000000..7a751e7 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/pkcs12.h @@ -0,0 +1,49 @@ +/* pkcs12.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* pkcs12.h for openssl */ + + +#include +#include + +#ifndef WOLFSSL_PKCS12_COMPAT_H_ +#define WOLFSSL_PKCS12_COMPAT_H_ + +#define NID_pbe_WithSHA1AndDES_CBC 2 +#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 3 +#define NID_pbe_WithSHA1And128BitRC4 1 + +#define PKCS12_DEFAULT_ITER WC_PKCS12_ITT_DEFAULT + +/* wolfCrypt level does not make use of ssl.h */ +#define PKCS12 WC_PKCS12 +#define PKCS12_new wc_PKCS12_new +#define PKCS12_free wc_PKCS12_free + +/* wolfSSL level using structs from ssl.h and calls down to wolfCrypt */ +#define d2i_PKCS12_bio wolfSSL_d2i_PKCS12_bio +#define PKCS12_parse wolfSSL_PKCS12_parse +#define PKCS12_create wolfSSL_PKCS12_create +#define PKCS12_PBE_add wolfSSL_PKCS12_PBE_add + +#endif /* WOLFSSL_PKCS12_COMPAT_H_ */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/pkcs7.h b/wolfssl_hlavickove_subory/wolfssl/openssl/pkcs7.h new file mode 100644 index 0000000..401ce4e --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/pkcs7.h @@ -0,0 +1,79 @@ +/* pkcs7.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* pkcs7.h for openSSL */ + + +#ifndef WOLFSSL_PKCS7_H_ +#define WOLFSSL_PKCS7_H_ + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(OPENSSL_ALL) && defined(HAVE_PKCS7) + +#define PKCS7_NOINTERN 0x0010 +#define PKCS7_NOVERIFY 0x0020 + + +typedef struct WOLFSSL_PKCS7 +{ + PKCS7 pkcs7; + unsigned char* data; + int len; +} WOLFSSL_PKCS7; + + +WOLFSSL_API PKCS7* wolfSSL_PKCS7_new(void); +WOLFSSL_API PKCS7_SIGNED* wolfSSL_PKCS7_SIGNED_new(void); +WOLFSSL_API void wolfSSL_PKCS7_free(PKCS7* p7); +WOLFSSL_API void wolfSSL_PKCS7_SIGNED_free(PKCS7_SIGNED* p7); +WOLFSSL_API PKCS7* wolfSSL_d2i_PKCS7(PKCS7** p7, const unsigned char** in, + int len); +WOLFSSL_API PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7); +WOLFSSL_API int wolfSSL_PKCS7_verify(PKCS7* p7, WOLFSSL_STACK* certs, + WOLFSSL_X509_STORE* store, WOLFSSL_BIO* in, WOLFSSL_BIO* out, int flags); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_PKCS7_get0_signers(PKCS7* p7, + WOLFSSL_STACK* certs, int flags); +WOLFSSL_API int wolfSSL_PEM_write_bio_PKCS7(WOLFSSL_BIO* bio, PKCS7* p7); + +#define PKCS7_new wolfSSL_PKCS7_new +#define PKCS7_SIGNED_new wolfSSL_PKCS7_SIGNED_new +#define PKCS7_free wolfSSL_PKCS7_free +#define PKCS7_SIGNED_free wolfSSL_PKCS7_SIGNED_free +#define d2i_PKCS7 wolfSSL_d2i_PKCS7 +#define d2i_PKCS7_bio wolfSSL_d2i_PKCS7_bio +#define PKCS7_verify wolfSSL_PKCS7_verify +#define PKCS7_get0_signers wolfSSL_PKCS7_get0_signers +#define PEM_write_bio_PKCS7 wolfSSL_PEM_write_bio_PKCS7 + +#endif /* OPENSSL_ALL && HAVE_PKCS7 */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_PKCS7_H_ */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/rand.h b/wolfssl_hlavickove_subory/wolfssl/openssl/rand.h new file mode 100644 index 0000000..3827504 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/rand.h @@ -0,0 +1,27 @@ +/* rand.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* rand.h for openSSL */ + +#include +#include + +#define RAND_set_rand_method wolfSSL_RAND_set_rand_method diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/rc4.h b/wolfssl_hlavickove_subory/wolfssl/openssl/rc4.h new file mode 100644 index 0000000..7c6c7d6 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/rc4.h @@ -0,0 +1,59 @@ +/* rc4.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +/* rc4.h defines mini des openssl compatibility layer + * + */ + +#ifndef WOLFSSL_RC4_COMPAT_H_ +#define WOLFSSL_RC4_COMPAT_H_ + +#include +#include /* included for size_t */ + +#ifdef __cplusplus + extern "C" { +#endif + +/* applications including wolfssl/openssl/rc4.h are expecting to have access to + * the size of RC4_KEY structures. */ +typedef struct WOLFSSL_RC4_KEY { + /* big enough for Arc4 from wolfssl/wolfcrypt/arc4.h */ + void* holder[(272 + WC_ASYNC_DEV_SIZE) / sizeof(void*)]; +} WOLFSSL_RC4_KEY; +typedef WOLFSSL_RC4_KEY RC4_KEY; + +WOLFSSL_API void wolfSSL_RC4_set_key(WOLFSSL_RC4_KEY* key, int len, + const unsigned char* data); +WOLFSSL_API void wolfSSL_RC4(WOLFSSL_RC4_KEY* key, size_t len, + const unsigned char* in, unsigned char* out); + +#define RC4 wolfSSL_RC4 +#define RC4_set_key wolfSSL_RC4_set_key + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_RC4_COMPAT_H_ */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/ripemd.h b/wolfssl_hlavickove_subory/wolfssl/openssl/ripemd.h new file mode 100644 index 0000000..db83e75 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/ripemd.h @@ -0,0 +1,58 @@ +/* ripemd.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* ripemd.h for openssl */ + + +#ifndef WOLFSSL_RIPEMD_H_ +#define WOLFSSL_RIPEMD_H_ + +#include + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef struct WOLFSSL_RIPEMD_CTX { + int holder[32]; /* big enough to hold wolfcrypt, but check on init */ +} WOLFSSL_RIPEMD_CTX; + +WOLFSSL_API void wolfSSL_RIPEMD_Init(WOLFSSL_RIPEMD_CTX*); +WOLFSSL_API void wolfSSL_RIPEMD_Update(WOLFSSL_RIPEMD_CTX*, const void*, + unsigned long); +WOLFSSL_API void wolfSSL_RIPEMD_Final(unsigned char*, WOLFSSL_RIPEMD_CTX*); + + +typedef WOLFSSL_RIPEMD_CTX RIPEMD_CTX; + +#define RIPEMD_Init wolfSSL_RIPEMD_Init +#define RIPEMD_Update wolfSSL_RIPEMD_Update +#define RIPEMD_Final wolfSSL_RIPEMD_Final + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* WOLFSSL_MD5_H_ */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/rsa.h b/wolfssl_hlavickove_subory/wolfssl/openssl/rsa.h new file mode 100644 index 0000000..6d956f4 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/rsa.h @@ -0,0 +1,172 @@ +/* rsa.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* rsa.h for openSSL */ + + +#ifndef WOLFSSL_RSA_H_ +#define WOLFSSL_RSA_H_ + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/* Padding types */ +#define RSA_PKCS1_PADDING 0 +#define RSA_PKCS1_OAEP_PADDING 1 +#define RSA_PKCS1_PSS_PADDING 2 +#define RSA_NO_PADDING 3 + +/* Emulate OpenSSL flags */ +#define RSA_METHOD_FLAG_NO_CHECK (1 << 1) +#define RSA_FLAG_CACHE_PUBLIC (1 << 2) +#define RSA_FLAG_CACHE_PRIVATE (1 << 3) +#define RSA_FLAG_BLINDING (1 << 4) +#define RSA_FLAG_THREAD_SAFE (1 << 5) +#define RSA_FLAG_EXT_PKEY (1 << 6) +#define RSA_FLAG_NO_BLINDING (1 << 7) +#define RSA_FLAG_NO_CONSTTIME (1 << 8) + +#ifndef WOLFSSL_RSA_TYPE_DEFINED /* guard on redeclaration */ +typedef struct WOLFSSL_RSA WOLFSSL_RSA; +#define WOLFSSL_RSA_TYPE_DEFINED +#endif + +typedef WOLFSSL_RSA RSA; + +typedef struct WOLFSSL_RSA_METHOD { + int flags; + char *name; +} WOLFSSL_RSA_METHOD; + +typedef WOLFSSL_RSA_METHOD RSA_METHOD; + +struct WOLFSSL_RSA { +#ifdef WC_RSA_BLINDING + WC_RNG* rng; /* for PrivateDecrypt blinding */ +#endif + WOLFSSL_BIGNUM* n; + WOLFSSL_BIGNUM* e; + WOLFSSL_BIGNUM* d; + WOLFSSL_BIGNUM* p; + WOLFSSL_BIGNUM* q; + WOLFSSL_BIGNUM* dmp1; /* dP */ + WOLFSSL_BIGNUM* dmq1; /* dQ */ + WOLFSSL_BIGNUM* iqmp; /* u */ + void* heap; + void* internal; /* our RSA */ + char inSet; /* internal set from external ? */ + char exSet; /* external set from internal ? */ + char ownRng; /* flag for if the rng should be free'd */ +#if defined(OPENSSL_EXTRA) + WOLFSSL_RSA_METHOD* meth; +#endif +}; + +WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSA_new(void); +WOLFSSL_API void wolfSSL_RSA_free(WOLFSSL_RSA*); + +WOLFSSL_API int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA*, int bits, WOLFSSL_BIGNUM*, + void* cb); + +WOLFSSL_API int wolfSSL_RSA_blinding_on(WOLFSSL_RSA*, WOLFSSL_BN_CTX*); +WOLFSSL_API int wolfSSL_RSA_public_encrypt(int len, const unsigned char* fr, + unsigned char* to, WOLFSSL_RSA*, int padding); +WOLFSSL_API int wolfSSL_RSA_private_decrypt(int len, const unsigned char* fr, + unsigned char* to, WOLFSSL_RSA*, int padding); +WOLFSSL_API int wolfSSL_RSA_private_encrypt(int len, unsigned char* in, + unsigned char* out, WOLFSSL_RSA* rsa, int padding); + +WOLFSSL_API int wolfSSL_RSA_size(const WOLFSSL_RSA*); +WOLFSSL_API int wolfSSL_RSA_sign(int type, const unsigned char* m, + unsigned int mLen, unsigned char* sigRet, + unsigned int* sigLen, WOLFSSL_RSA*); +WOLFSSL_API int wolfSSL_RSA_sign_ex(int type, const unsigned char* m, + unsigned int mLen, unsigned char* sigRet, + unsigned int* sigLen, WOLFSSL_RSA*, int); +WOLFSSL_API int wolfSSL_RSA_verify(int type, const unsigned char* m, + unsigned int mLen, const unsigned char* sig, + unsigned int sigLen, WOLFSSL_RSA*); +WOLFSSL_API int wolfSSL_RSA_public_decrypt(int flen, const unsigned char* from, + unsigned char* to, WOLFSSL_RSA*, int padding); +WOLFSSL_API int wolfSSL_RSA_GenAdd(WOLFSSL_RSA*); +WOLFSSL_API int wolfSSL_RSA_LoadDer(WOLFSSL_RSA*, const unsigned char*, int sz); +WOLFSSL_API int wolfSSL_RSA_LoadDer_ex(WOLFSSL_RSA*, const unsigned char*, int sz, int opt); + +WOLFSSL_API WOLFSSL_RSA_METHOD *wolfSSL_RSA_meth_new(const char *name, int flags); +WOLFSSL_API void wolfSSL_RSA_meth_free(WOLFSSL_RSA_METHOD *meth); +WOLFSSL_API int wolfSSL_RSA_meth_set(WOLFSSL_RSA_METHOD *rsa, void* p); +WOLFSSL_API int wolfSSL_RSA_set_method(WOLFSSL_RSA *rsa, WOLFSSL_RSA_METHOD *meth); +WOLFSSL_API const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_method(const WOLFSSL_RSA *rsa); +WOLFSSL_API void wolfSSL_RSA_get0_key(const WOLFSSL_RSA *r, const WOLFSSL_BIGNUM **n, + const WOLFSSL_BIGNUM **e, const WOLFSSL_BIGNUM **d); +WOLFSSL_API int wolfSSL_RSA_set0_key(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *n, WOLFSSL_BIGNUM *e, + WOLFSSL_BIGNUM *d); +WOLFSSL_API int wolfSSL_RSA_flags(const WOLFSSL_RSA *r); +WOLFSSL_API void wolfSSL_RSA_set_flags(WOLFSSL_RSA *r, int flags); + +#define WOLFSSL_RSA_LOAD_PRIVATE 1 +#define WOLFSSL_RSA_LOAD_PUBLIC 2 +#define WOLFSSL_RSA_F4 0x10001L + +#define RSA_new wolfSSL_RSA_new +#define RSA_free wolfSSL_RSA_free + +#define RSA_generate_key_ex wolfSSL_RSA_generate_key_ex + +#define RSA_blinding_on wolfSSL_RSA_blinding_on +#define RSA_public_encrypt wolfSSL_RSA_public_encrypt +#define RSA_private_decrypt wolfSSL_RSA_private_decrypt +#define RSA_private_encrypt wolfSSL_RSA_private_encrypt + +#define RSA_size wolfSSL_RSA_size +#define RSA_sign wolfSSL_RSA_sign +#define RSA_verify wolfSSL_RSA_verify +#define RSA_public_decrypt wolfSSL_RSA_public_decrypt +#define EVP_PKEY_get0_RSA wolfSSL_EVP_PKEY_get0_RSA + +#define RSA_meth_new wolfSSL_RSA_meth_new +#define RSA_meth_free wolfSSL_RSA_meth_free +#define RSA_meth_set_pub_enc wolfSSL_RSA_meth_set +#define RSA_meth_set_pub_dec wolfSSL_RSA_meth_set +#define RSA_meth_set_priv_enc wolfSSL_RSA_meth_set +#define RSA_meth_set_priv_dec wolfSSL_RSA_meth_set +#define RSA_meth_set_init wolfSSL_RSA_meth_set +#define RSA_meth_set_finish wolfSSL_RSA_meth_set +#define RSA_meth_set0_app_data wolfSSL_RSA_meth_set +#define RSA_get_method wolfSSL_RSA_get_method +#define RSA_set_method wolfSSL_RSA_set_method +#define RSA_get0_key wolfSSL_RSA_get0_key +#define RSA_set0_key wolfSSL_RSA_set0_key +#define RSA_flags wolfSSL_RSA_flags +#define RSA_set_flags wolfSSL_RSA_set_flags + +#define RSA_get0_key wolfSSL_RSA_get0_key + +#define RSA_F4 WOLFSSL_RSA_F4 + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* header */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/sha.h b/wolfssl_hlavickove_subory/wolfssl/openssl/sha.h new file mode 100644 index 0000000..485cf96 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/sha.h @@ -0,0 +1,203 @@ +/* sha.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* sha.h for openssl */ + + +#ifndef WOLFSSL_SHA_H_ +#define WOLFSSL_SHA_H_ + +#include +#include + +#ifdef WOLFSSL_PREFIX +#include "prefix_sha.h" +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef struct WOLFSSL_SHA_CTX { + /* big enough to hold wolfcrypt Sha, but check on init */ +#if defined(STM32_HASH) + void* holder[(112 + WC_ASYNC_DEV_SIZE + sizeof(STM32_HASH_Context)) / sizeof(void*)]; +#else + void* holder[(112 + WC_ASYNC_DEV_SIZE) / sizeof(void*)]; +#endif + #ifdef WOLF_CRYPTO_CB + void* cryptocb_holder[(sizeof(int) + sizeof(void*) + 4) / sizeof(void*)]; + #endif +} WOLFSSL_SHA_CTX; + +WOLFSSL_API int wolfSSL_SHA_Init(WOLFSSL_SHA_CTX*); +WOLFSSL_API int wolfSSL_SHA_Update(WOLFSSL_SHA_CTX*, const void*, unsigned long); +WOLFSSL_API int wolfSSL_SHA_Final(unsigned char*, WOLFSSL_SHA_CTX*); + +/* SHA1 points to above, shouldn't use SHA0 ever */ +WOLFSSL_API int wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX*); +WOLFSSL_API int wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX*, const void*, unsigned long); +WOLFSSL_API int wolfSSL_SHA1_Final(unsigned char*, WOLFSSL_SHA_CTX*); + +enum { + SHA_DIGEST_LENGTH = 20 +}; + + +typedef WOLFSSL_SHA_CTX SHA_CTX; + +#define SHA_Init wolfSSL_SHA_Init +#define SHA_Update wolfSSL_SHA_Update +#define SHA_Final wolfSSL_SHA_Final + +#define SHA1_Init wolfSSL_SHA1_Init +#define SHA1_Update wolfSSL_SHA1_Update +#define SHA1_Final wolfSSL_SHA1_Final + + +#ifdef WOLFSSL_SHA224 + +/* Using ALIGN16 because when AES-NI is enabled digest and buffer in Sha256 + * struct are 16 byte aligned. Any derefrence to those elements after casting to + * Sha224, is expected to also be 16 byte aligned addresses. */ +typedef struct WOLFSSL_SHA224_CTX { + /* big enough to hold wolfcrypt Sha224, but check on init */ + ALIGN16 void* holder[(272 + WC_ASYNC_DEV_SIZE) / sizeof(void*)]; +} WOLFSSL_SHA224_CTX; + +WOLFSSL_API int wolfSSL_SHA224_Init(WOLFSSL_SHA224_CTX*); +WOLFSSL_API int wolfSSL_SHA224_Update(WOLFSSL_SHA224_CTX*, const void*, + unsigned long); +WOLFSSL_API int wolfSSL_SHA224_Final(unsigned char*, WOLFSSL_SHA224_CTX*); + +enum { + SHA224_DIGEST_LENGTH = 28 +}; + + +typedef WOLFSSL_SHA224_CTX SHA224_CTX; + +#define SHA224_Init wolfSSL_SHA224_Init +#define SHA224_Update wolfSSL_SHA224_Update +#define SHA224_Final wolfSSL_SHA224_Final + +#endif /* WOLFSSL_SHA224 */ + + +/* Using ALIGN16 because when AES-NI is enabled digest and buffer in Sha256 + * struct are 16 byte aligned. Any derefrence to those elements after casting to + * Sha256, is expected to also be 16 byte aligned addresses. */ +typedef struct WOLFSSL_SHA256_CTX { + /* big enough to hold wolfcrypt Sha256, but check on init */ + ALIGN16 void* holder[(272 + WC_ASYNC_DEV_SIZE) / sizeof(void*)]; +} WOLFSSL_SHA256_CTX; + +WOLFSSL_API int wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX*); +WOLFSSL_API int wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX*, const void*, + unsigned long); +WOLFSSL_API int wolfSSL_SHA256_Final(unsigned char*, WOLFSSL_SHA256_CTX*); + +enum { + SHA256_DIGEST_LENGTH = 32 +}; + + +typedef WOLFSSL_SHA256_CTX SHA256_CTX; + +#define SHA256_Init wolfSSL_SHA256_Init +#define SHA256_Update wolfSSL_SHA256_Update +#define SHA256_Final wolfSSL_SHA256_Final +#if defined(NO_OLD_SHA_NAMES) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + /* SHA256 is only available in non-fips mode because of SHA256 enum in FIPS + * build. */ + #define SHA256 wolfSSL_SHA256 +#endif + + +#ifdef WOLFSSL_SHA384 + +typedef struct WOLFSSL_SHA384_CTX { + /* big enough to hold wolfCrypt Sha384, but check on init */ + void* holder[(256 + WC_ASYNC_DEV_SIZE) / sizeof(void*)]; +} WOLFSSL_SHA384_CTX; + +WOLFSSL_API int wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX*); +WOLFSSL_API int wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX*, const void*, + unsigned long); +WOLFSSL_API int wolfSSL_SHA384_Final(unsigned char*, WOLFSSL_SHA384_CTX*); + +enum { + SHA384_DIGEST_LENGTH = 48 +}; + + +typedef WOLFSSL_SHA384_CTX SHA384_CTX; + +#define SHA384_Init wolfSSL_SHA384_Init +#define SHA384_Update wolfSSL_SHA384_Update +#define SHA384_Final wolfSSL_SHA384_Final +#if defined(NO_OLD_SHA_NAMES) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + /* SHA384 is only available in non-fips mode because of SHA384 enum in FIPS + * build. */ + #define SHA384 wolfSSL_SHA384 +#endif +#endif /* WOLFSSL_SHA384 */ + +#ifdef WOLFSSL_SHA512 + +typedef struct WOLFSSL_SHA512_CTX { + /* big enough to hold wolfCrypt Sha384, but check on init */ + void* holder[(288 + WC_ASYNC_DEV_SIZE) / sizeof(void*)]; +} WOLFSSL_SHA512_CTX; + +WOLFSSL_API int wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX*); +WOLFSSL_API int wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX*, const void*, + unsigned long); +WOLFSSL_API int wolfSSL_SHA512_Final(unsigned char*, WOLFSSL_SHA512_CTX*); + +enum { + SHA512_DIGEST_LENGTH = 64 +}; + + +typedef WOLFSSL_SHA512_CTX SHA512_CTX; + +#define SHA512_Init wolfSSL_SHA512_Init +#define SHA512_Update wolfSSL_SHA512_Update +#define SHA512_Final wolfSSL_SHA512_Final +#if defined(NO_OLD_SHA_NAMES) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + /* SHA512 is only available in non-fips mode because of SHA512 enum in FIPS + * build. */ + #define SHA512 wolfSSL_SHA512 +#endif +#endif /* WOLFSSL_SHA512 */ + + + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* WOLFSSL_SHA_H_ */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/ssl.h b/wolfssl_hlavickove_subory/wolfssl/openssl/ssl.h new file mode 100644 index 0000000..d7dbfcf --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/ssl.h @@ -0,0 +1,1176 @@ +/* ssl.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +/* ssl.h defines wolfssl_openssl compatibility layer + * + */ + + +#ifndef WOLFSSL_OPENSSL_H_ +#define WOLFSSL_OPENSSL_H_ + +/* wolfssl_openssl compatibility layer */ +#ifndef OPENSSL_EXTRA_SSL_GUARD +#define OPENSSL_EXTRA_SSL_GUARD +#include +#endif /* OPENSSL_EXTRA_SSL_GUARD */ + +#include +#include +#include +#ifdef OPENSSL_EXTRA +#include +#endif + +/* all NID_* values are in asn.h */ +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef _WIN32 + /* wincrypt.h clashes */ + #undef X509_NAME +#endif + +#ifdef WOLFSSL_UTASKER + /* tcpip.h clashes */ + #undef ASN1_INTEGER +#endif + + +typedef WOLFSSL SSL; +typedef WOLFSSL_SESSION SSL_SESSION; +typedef WOLFSSL_METHOD SSL_METHOD; +typedef WOLFSSL_CTX SSL_CTX; + +typedef WOLFSSL_X509 X509; +typedef WOLFSSL_X509 X509_REQ; +typedef WOLFSSL_X509_NAME X509_NAME; +typedef WOLFSSL_X509_INFO X509_INFO; +typedef WOLFSSL_X509_CHAIN X509_CHAIN; + +typedef WOLFSSL_STACK EXTENDED_KEY_USAGE; + + +/* redeclare guard */ +#define WOLFSSL_TYPES_DEFINED + +typedef WOLFSSL_BIO BIO; +typedef WOLFSSL_BIO_METHOD BIO_METHOD; +typedef WOLFSSL_CIPHER SSL_CIPHER; +typedef WOLFSSL_X509_LOOKUP X509_LOOKUP; +typedef WOLFSSL_X509_LOOKUP_METHOD X509_LOOKUP_METHOD; +typedef WOLFSSL_X509_CRL X509_CRL; +typedef WOLFSSL_X509_EXTENSION X509_EXTENSION; +typedef WOLFSSL_X509_PUBKEY X509_PUBKEY; +typedef WOLFSSL_X509_ALGOR X509_ALGOR; +typedef WOLFSSL_ASN1_TIME ASN1_TIME; +typedef WOLFSSL_ASN1_INTEGER ASN1_INTEGER; +typedef WOLFSSL_ASN1_OBJECT ASN1_OBJECT; +typedef WOLFSSL_ASN1_STRING ASN1_STRING; +typedef WOLFSSL_ASN1_TYPE ASN1_TYPE; +typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING; +typedef WOLFSSL_dynlock_value CRYPTO_dynlock_value; +typedef WOLFSSL_BUF_MEM BUF_MEM; +typedef WOLFSSL_GENERAL_NAMES GENERAL_NAMES; +typedef WOLFSSL_GENERAL_NAME GENERAL_NAME; + +#define ASN1_UTCTIME WOLFSSL_ASN1_TIME +#define ASN1_GENERALIZEDTIME WOLFSSL_ASN1_TIME + +typedef WOLFSSL_COMP_METHOD COMP_METHOD; +typedef WOLFSSL_COMP SSL_COMP; +typedef WOLFSSL_X509_REVOKED X509_REVOKED; +typedef WOLFSSL_X509_OBJECT X509_OBJECT; +typedef WOLFSSL_X509_STORE X509_STORE; +typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; +typedef WOLFSSL_X509_VERIFY_PARAM X509_VERIFY_PARAM; + +#define EVP_CIPHER_INFO EncryptedInfo + +#define STACK_OF(x) WOLFSSL_STACK + +#define CRYPTO_free XFREE +#define CRYPTO_malloc XMALLOC +#define CRYPTO_EX_new WOLFSSL_CRYPTO_EX_new +#define CRYPTO_EX_dup WOLFSSL_CRYPTO_EX_dup +#define CRYPTO_EX_free WOLFSSL_CRYPTO_EX_free + +/* depreciated */ +#define CRYPTO_thread_id wolfSSL_thread_id +#define CRYPTO_set_id_callback wolfSSL_set_id_callback + +#define CRYPTO_LOCK 0x01 +#define CRYPTO_UNLOCK 0x02 +#define CRYPTO_READ 0x04 +#define CRYPTO_WRITE 0x08 + +#define CRYPTO_set_locking_callback wolfSSL_set_locking_callback +#define CRYPTO_set_dynlock_create_callback wolfSSL_set_dynlock_create_callback +#define CRYPTO_set_dynlock_lock_callback wolfSSL_set_dynlock_lock_callback +#define CRYPTO_set_dynlock_destroy_callback wolfSSL_set_dynlock_destroy_callback +#define CRYPTO_num_locks wolfSSL_num_locks +#define CRYPTO_dynlock_value WOLFSSL_dynlock_value + +#define CRYPTO_cleanup_all_ex_data wolfSSL_cleanup_all_ex_data + +/* this function was used to set the default malloc, free, and realloc */ +#define CRYPTO_malloc_init() 0 /* CRYPTO_malloc_init is not needed */ +#define OPENSSL_malloc_init() 0 /* OPENSSL_malloc_init is not needed */ + +#define SSL_get_client_random(ssl,out,outSz) \ + wolfSSL_get_client_random((ssl),(out),(outSz)) +#define SSL_get_cipher_list(ctx,i) wolfSSL_get_cipher_list_ex((ctx),(i)) +#define SSL_get_cipher_name(ctx) wolfSSL_get_cipher((ctx)) +#define SSL_get_shared_ciphers(ctx,buf,len) \ + wolfSSL_get_shared_ciphers((ctx),(buf),(len)) + +/* at the moment only returns ok */ +#define SSL_get_verify_result wolfSSL_get_verify_result +#define SSL_get_verify_mode wolfSSL_SSL_get_mode +#define SSL_get_verify_depth wolfSSL_get_verify_depth +#define SSL_CTX_get_verify_mode wolfSSL_CTX_get_verify_mode +#define SSL_CTX_get_verify_depth wolfSSL_CTX_get_verify_depth +#define SSL_get_certificate wolfSSL_get_certificate +#define SSL_use_certificate wolfSSL_use_certificate +#define SSL_use_certificate_ASN1 wolfSSL_use_certificate_ASN1 +#define d2i_PKCS8_PRIV_KEY_INFO_bio wolfSSL_d2i_PKCS8_PKEY_bio +#define d2i_PKCS8PrivateKey_bio wolfSSL_d2i_PKCS8PrivateKey_bio +#define PKCS8_PRIV_KEY_INFO_free wolfSSL_EVP_PKEY_free +#define d2i_PKCS12_fp wolfSSL_d2i_PKCS12_fp + +#define d2i_PUBKEY wolfSSL_d2i_PUBKEY +#define d2i_PUBKEY_bio wolfSSL_d2i_PUBKEY_bio +#define d2i_PrivateKey wolfSSL_d2i_PrivateKey +#define d2i_AutoPrivateKey wolfSSL_d2i_AutoPrivateKey +#define i2d_PrivateKey wolfSSL_i2d_PrivateKey +#define SSL_use_PrivateKey wolfSSL_use_PrivateKey +#define SSL_use_PrivateKey_ASN1 wolfSSL_use_PrivateKey_ASN1 +#define SSL_use_RSAPrivateKey_ASN1 wolfSSL_use_RSAPrivateKey_ASN1 +#define SSL_get_privatekey wolfSSL_get_privatekey +#define SSL_CTX_use_PrivateKey_ASN1 wolfSSL_CTX_use_PrivateKey_ASN1 + +#define SSLv23_method wolfSSLv23_method +#define SSLv23_client_method wolfSSLv23_client_method +#define SSLv2_client_method wolfSSLv2_client_method +#define SSLv2_server_method wolfSSLv2_server_method +#define SSLv3_server_method wolfSSLv3_server_method +#define SSLv3_client_method wolfSSLv3_client_method +#define TLS_client_method wolfTLS_client_method +#define TLS_server_method wolfTLS_server_method +#define TLSv1_method wolfTLSv1_method +#define TLSv1_server_method wolfTLSv1_server_method +#define TLSv1_client_method wolfTLSv1_client_method +#define TLSv1_1_method wolfTLSv1_1_method +#define TLSv1_1_server_method wolfTLSv1_1_server_method +#define TLSv1_1_client_method wolfTLSv1_1_client_method +#define TLSv1_2_method wolfTLSv1_2_method +#define TLSv1_2_server_method wolfTLSv1_2_server_method +#define TLSv1_2_client_method wolfTLSv1_2_client_method +#define TLSv1_3_method wolfTLSv1_3_method +#define TLSv1_3_server_method wolfTLSv1_3_server_method +#define TLSv1_3_client_method wolfTLSv1_3_client_method +#define TLS_method wolfSSLv23_method + +#define X509_FILETYPE_ASN1 SSL_FILETYPE_ASN1 + +#define X509_F_X509_CHECK_PRIVATE_KEY 128 + +#ifdef WOLFSSL_DTLS + #define DTLSv1_client_method wolfDTLSv1_client_method + #define DTLSv1_server_method wolfDTLSv1_server_method + #define DTLSv1_2_client_method wolfDTLSv1_2_client_method + #define DTLSv1_2_server_method wolfDTLSv1_2_server_method + #define DTLS_method wolfDTLS_method +#endif + + +#ifndef NO_FILESYSTEM + #define SSL_CTX_use_certificate_file wolfSSL_CTX_use_certificate_file + #define SSL_CTX_use_PrivateKey_file wolfSSL_CTX_use_PrivateKey_file + #define SSL_CTX_load_verify_locations wolfSSL_CTX_load_verify_locations + #define SSL_CTX_use_certificate_chain_file wolfSSL_CTX_use_certificate_chain_file + #define SSL_CTX_use_RSAPrivateKey_file wolfSSL_CTX_use_RSAPrivateKey_file + + #define SSL_use_certificate_file wolfSSL_use_certificate_file + #define SSL_use_PrivateKey_file wolfSSL_use_PrivateKey_file + #define SSL_use_certificate_chain_file wolfSSL_use_certificate_chain_file + #define SSL_use_RSAPrivateKey_file wolfSSL_use_RSAPrivateKey_file +#endif + +#define SSL_CTX_new(method) wolfSSL_CTX_new((WOLFSSL_METHOD*)(method)) +#ifdef OPENSSL_EXTRA +#define SSL_CTX_up_ref wolfSSL_CTX_up_ref +#endif +#define SSL_new wolfSSL_new +#define SSL_set_fd wolfSSL_set_fd +#define SSL_get_fd wolfSSL_get_fd +#define SSL_connect wolfSSL_connect +#define SSL_clear wolfSSL_clear +#define SSL_state wolfSSL_state + +#define SSL_write wolfSSL_write +#define SSL_read wolfSSL_read +#define SSL_peek wolfSSL_peek +#define SSL_accept wolfSSL_accept +#define SSL_CTX_free wolfSSL_CTX_free +#define SSL_free wolfSSL_free +#define SSL_shutdown wolfSSL_shutdown +#define SSL_set_timeout wolfSSL_set_timeout + +#define SSL_CTX_set_quiet_shutdown wolfSSL_CTX_set_quiet_shutdown +#define SSL_set_quiet_shutdown wolfSSL_set_quiet_shutdown +#define SSL_get_error wolfSSL_get_error +#define SSL_set_session wolfSSL_set_session +#define SSL_get_session wolfSSL_get_session +#define SSL_flush_sessions wolfSSL_flush_sessions +/* assume unlimited temporarily */ +#define SSL_CTX_get_session_cache_mode(ctx) 0 + +#define SSL_CTX_set_verify wolfSSL_CTX_set_verify +#define SSL_CTX_set_cert_verify_callback wolfSSL_CTX_set_cert_verify_callback +#define SSL_set_verify wolfSSL_set_verify +#define SSL_set_verify_result wolfSSL_set_verify_result +#define SSL_pending wolfSSL_pending +#define SSL_load_error_strings wolfSSL_load_error_strings +#define SSL_library_init wolfSSL_library_init +#define SSL_CTX_set_session_cache_mode wolfSSL_CTX_set_session_cache_mode +#define SSL_CTX_set_cipher_list wolfSSL_CTX_set_cipher_list +#define SSL_CTX_set_ciphersuites wolfSSL_CTX_set_cipher_list +#define SSL_set_cipher_list wolfSSL_set_cipher_list +/* wolfSSL does not support security levels */ +#define SSL_CTX_set_security_level(...) +/* wolfSSL does not support expoting keying material */ +#define SSL_export_keying_material(...) 0 + +#define SSL_set_ex_data wolfSSL_set_ex_data +#define SSL_get_shutdown wolfSSL_get_shutdown +#define SSL_set_rfd wolfSSL_set_rfd +#define SSL_set_wfd wolfSSL_set_wfd +#define SSL_set_shutdown wolfSSL_set_shutdown +#define SSL_set_session_id_context wolfSSL_set_session_id_context +#define SSL_set_connect_state wolfSSL_set_connect_state +#define SSL_set_accept_state wolfSSL_set_accept_state +#define SSL_session_reused wolfSSL_session_reused +#define SSL_SESSION_dup wolfSSL_SESSION_dup +#define SSL_SESSION_free wolfSSL_SESSION_free +#define SSL_is_init_finished wolfSSL_is_init_finished + +#define SSL_get_version wolfSSL_get_version +#define SSL_get_current_cipher wolfSSL_get_current_cipher + +/* use wolfSSL_get_cipher_name for its return format */ +#define SSL_get_cipher wolfSSL_get_cipher_name +#define SSL_CIPHER_description wolfSSL_CIPHER_description +#define SSL_CIPHER_get_name wolfSSL_CIPHER_get_name +#define SSL_CIPHER_get_version wolfSSL_CIPHER_get_version +#define SSL_CIPHER_get_id wolfSSL_CIPHER_get_id +#define SSL_CIPHER_get_rfc_name wolfSSL_CIPHER_get_name +#define SSL_CIPHER_standard_name wolfSSL_CIPHER_get_name +#define SSL_get_cipher_by_value wolfSSL_get_cipher_by_value + +#define SSL_get1_session wolfSSL_get1_session + +#define SSL_get_keyblock_size wolfSSL_get_keyblock_size +#define SSL_get_keys wolfSSL_get_keys +#define SSL_SESSION_get_master_key wolfSSL_SESSION_get_master_key +#define SSL_SESSION_get_master_key_length wolfSSL_SESSION_get_master_key_length + +#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) + #define ASN1_BOOLEAN WOLFSSL_ASN1_BOOLEAN + #define X509_get_ext wolfSSL_X509_get_ext + #define X509_cmp wolfSSL_X509_cmp + #define X509_EXTENSION_get_object wolfSSL_X509_EXTENSION_get_object + #define X509_EXTENSION_get_critical wolfSSL_X509_EXTENSION_get_critical + #define X509_EXTENSION_get_data wolfSSL_X509_EXTENSION_get_data + #define X509_EXTENSION_new wolfSSL_X509_EXTENSION_new + #define X509_EXTENSION_free wolfSSL_X509_EXTENSION_free +#endif + +#define DSA_dup_DH wolfSSL_DSA_dup_DH +/* wolfSSL does not support DSA as the cert public key */ +#define EVP_PKEY_get0_DSA(...) NULL +#define DSA_bits(...) 0 + +#define i2d_X509_bio wolfSSL_i2d_X509_bio +#define d2i_X509_bio wolfSSL_d2i_X509_bio +#define d2i_X509_fp wolfSSL_d2i_X509_fp +#define i2d_X509 wolfSSL_i2d_X509 +#define d2i_X509 wolfSSL_d2i_X509 +#define PEM_read_bio_X509 wolfSSL_PEM_read_bio_X509 +#define PEM_read_bio_X509_CRL wolfSSL_PEM_read_bio_X509_CRL +#define PEM_read_bio_X509_AUX wolfSSL_PEM_read_bio_X509_AUX +#define PEM_read_X509 wolfSSL_PEM_read_X509 +#define PEM_X509_INFO_read_bio wolfSSL_PEM_X509_INFO_read_bio +#define PEM_write_bio_X509 wolfSSL_PEM_write_bio_X509 +#define PEM_write_bio_X509_AUX wolfSSL_PEM_write_bio_X509_AUX +#define PEM_X509_INFO_read_bio wolfSSL_PEM_X509_INFO_read_bio +#define i2d_PrivateKey wolfSSL_i2d_PrivateKey + +#define i2d_X509_REQ wolfSSL_i2d_X509_REQ +#define X509_REQ_new wolfSSL_X509_REQ_new +#define X509_REQ_free wolfSSL_X509_REQ_free +#define X509_REQ_sign wolfSSL_X509_REQ_sign +#define X509_REQ_add_extensions wolfSSL_X509_REQ_add_extensions +#define X509_REQ_set_subject_name wolfSSL_X509_REQ_set_subject_name +#define X509_REQ_set_pubkey wolfSSL_X509_REQ_set_pubkey +#define PEM_write_bio_X509_REQ wolfSSL_PEM_write_bio_X509_REQ + +#define X509_new wolfSSL_X509_new +#define X509_up_ref wolfSSL_X509_up_ref +#define X509_free wolfSSL_X509_free +#define X509_load_certificate_file wolfSSL_X509_load_certificate_file +#define X509_digest wolfSSL_X509_digest +#define X509_get_ext_count wolfSSL_X509_get_ext_count +#define X509_get_ext_d2i wolfSSL_X509_get_ext_d2i +#define X509_get_ext wolfSSL_X509_get_ext +#define X509_get_ext_by_NID wolfSSL_X509_get_ext_by_NID +#define X509_get_issuer_name wolfSSL_X509_get_issuer_name +#define X509_get_subject_name wolfSSL_X509_get_subject_name +#define X509_get_pubkey wolfSSL_X509_get_pubkey +#define X509_get0_pubkey wolfSSL_X509_get_pubkey +#define X509_get_notBefore wolfSSL_X509_get_notBefore +#define X509_get_notAfter wolfSSL_X509_get_notAfter +#define X509_get_serialNumber wolfSSL_X509_get_serialNumber +#define X509_get0_pubkey_bitstr wolfSSL_X509_get0_pubkey_bitstr +#define X509_get_ex_new_index wolfSSL_X509_get_ex_new_index +#define X509_get_ex_data wolfSSL_X509_get_ex_data +#define X509_set_ex_data wolfSSL_X509_set_ex_data +#define X509_get1_ocsp wolfSSL_X509_get1_ocsp +#ifndef WOLFSSL_HAPROXY +#define X509_get_version wolfSSL_X509_get_version +#endif +#define X509_get_signature_nid wolfSSL_X509_get_signature_nid +#define X509_set_subject_name wolfSSL_X509_set_subject_name +#define X509_set_issuer_name wolfSSL_X509_set_issuer_name +#define X509_set_pubkey wolfSSL_X509_set_pubkey +#define X509_set_notAfter wolfSSL_X509_set_notAfter +#define X509_set_notBefore wolfSSL_X509_set_notBefore +#define X509_set_serialNumber wolfSSL_X509_set_serialNumber +#define X509_set_version wolfSSL_X509_set_version +#define X509_sign wolfSSL_X509_sign +#define X509_print wolfSSL_X509_print +#define X509_print_ex wolfSSL_X509_print_ex +#define X509_verify_cert_error_string wolfSSL_X509_verify_cert_error_string +#define X509_verify_cert wolfSSL_X509_verify_cert +#define X509_check_private_key wolfSSL_X509_check_private_key +#define X509_check_ca wolfSSL_X509_check_ca +#define X509_check_host wolfSSL_X509_check_host +#define X509_email_free wolfSSL_X509_email_free +#define X509_check_issued wolfSSL_X509_check_issued +#define X509_dup wolfSSL_X509_dup + +#define X509_EXTENSION_get_object wolfSSL_X509_EXTENSION_get_object +#define X509_EXTENSION_get_data wolfSSL_X509_EXTENSION_get_data + +#define sk_X509_new wolfSSL_sk_X509_new +#define sk_X509_new_null wolfSSL_sk_X509_new +#define sk_X509_num wolfSSL_sk_X509_num +#define sk_X509_value wolfSSL_sk_X509_value +#define sk_X509_shift wolfSSL_sk_X509_shift +#define sk_X509_push wolfSSL_sk_X509_push +#define sk_X509_pop wolfSSL_sk_X509_pop +#define sk_X509_pop_free wolfSSL_sk_X509_pop_free +#define sk_X509_dup wolfSSL_sk_X509_dup +#define sk_X509_free wolfSSL_sk_X509_free + +#define sk_X509_EXTENSION_num wolfSSL_sk_X509_EXTENSION_num +#define sk_X509_EXTENSION_value wolfSSL_sk_X509_EXTENSION_value +#define sk_X509_EXTENSION_new_null wolfSSL_sk_X509_EXTENSION_new_null +#define sk_X509_EXTENSION_pop_free wolfSSL_sk_X509_EXTENSION_pop_free +#define sk_X509_EXTENSION_push wolfSSL_sk_X509_EXTENSION_push +#define X509_EXTENSION_free wolfSSL_X509_EXTENSION_free + +#define X509_INFO_new wolfSSL_X509_INFO_new +#define X509_INFO_free wolfSSL_X509_INFO_free + +#define sk_X509_INFO_new_null wolfSSL_sk_X509_INFO_new_null +#define sk_X509_INFO_num wolfSSL_sk_X509_INFO_num +#define sk_X509_INFO_value wolfSSL_sk_X509_INFO_value +#define sk_X509_INFO_push wolfSSL_sk_X509_INFO_push +#define sk_X509_INFO_pop wolfSSL_sk_X509_INFO_pop +#define sk_X509_INFO_pop_free wolfSSL_sk_X509_INFO_pop_free +#define sk_X509_INFO_free wolfSSL_sk_X509_INFO_free + +#define i2d_X509_NAME wolfSSL_i2d_X509_NAME +#define X509_NAME_new wolfSSL_X509_NAME_new +#define X509_NAME_free wolfSSL_X509_NAME_free +#define X509_NAME_dup wolfSSL_X509_NAME_dup +#define X509_NAME_get_text_by_NID wolfSSL_X509_NAME_get_text_by_NID +#define X509_NAME_get_index_by_OBJ wolfSSL_X509_NAME_get_index_by_OBJ +#define X509_NAME_cmp wolfSSL_X509_NAME_cmp +#define X509_NAME_ENTRY_free wolfSSL_X509_NAME_ENTRY_free +#define X509_NAME_ENTRY_create_by_NID wolfSSL_X509_NAME_ENTRY_create_by_NID +#define X509_NAME_add_entry wolfSSL_X509_NAME_add_entry +#define X509_NAME_add_entry_by_txt wolfSSL_X509_NAME_add_entry_by_txt +#define X509_NAME_add_entry_by_NID wolfSSL_X509_NAME_add_entry_by_NID +#define X509_NAME_oneline wolfSSL_X509_NAME_oneline +#define X509_NAME_get_index_by_NID wolfSSL_X509_NAME_get_index_by_NID +#define X509_NAME_print_ex wolfSSL_X509_NAME_print_ex +#define X509_NAME_digest wolfSSL_X509_NAME_digest +#define X509_cmp_current_time wolfSSL_X509_cmp_current_time +#define X509_cmp_time wolfSSL_X509_cmp_time +#define X509_time_adj wolfSSL_X509_time_adj +#define X509_time_adj_ex wolfSSL_X509_time_adj_ex + +#define sk_ACCESS_DESCRIPTION_num wolfSSL_sk_ACCESS_DESCRIPTION_num +#define sk_ACCESS_DESCRIPTION_value wolfSSL_sk_ACCESS_DESCRIPTION_value + +#define sk_X509_NAME_new wolfSSL_sk_X509_NAME_new +#define sk_X509_NAME_push wolfSSL_sk_X509_NAME_push +#define sk_X509_NAME_find wolfSSL_sk_X509_NAME_find +#define sk_X509_NAME_set_cmp_func wolfSSL_sk_X509_NAME_set_cmp_func +#define sk_X509_NAME_num wolfSSL_sk_X509_NAME_num +#define sk_X509_NAME_value wolfSSL_sk_X509_NAME_value +#define sk_X509_NAME_pop wolfSSL_sk_X509_NAME_pop +#define sk_X509_NAME_pop_free wolfSSL_sk_X509_NAME_pop_free +#define sk_X509_NAME_free wolfSSL_sk_X509_NAME_free + +typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY; + +#define X509_NAME_entry_count wolfSSL_X509_NAME_entry_count +#define X509_NAME_ENTRY_get_object wolfSSL_X509_NAME_ENTRY_get_object +#define X509_NAME_get_entry wolfSSL_X509_NAME_get_entry +#define X509_NAME_ENTRY_get_data wolfSSL_X509_NAME_ENTRY_get_data +#define X509_NAME_ENTRY_get_object wolfSSL_X509_NAME_ENTRY_get_object + +#define X509_V_FLAG_CRL_CHECK WOLFSSL_CRL_CHECK +#define X509_V_FLAG_CRL_CHECK_ALL WOLFSSL_CRL_CHECKALL + +#define X509_V_FLAG_USE_CHECK_TIME WOLFSSL_USE_CHECK_TIME +#define X509_V_FLAG_NO_CHECK_TIME WOLFSSL_NO_CHECK_TIME +#define X509_CHECK_FLAG_NO_WILDCARDS WOLFSSL_NO_WILDCARDS + +#define X509_STORE_CTX_get_current_cert wolfSSL_X509_STORE_CTX_get_current_cert +#define X509_STORE_CTX_set_verify_cb wolfSSL_X509_STORE_CTX_set_verify_cb +#define X509_STORE_CTX_new wolfSSL_X509_STORE_CTX_new +#define X509_STORE_CTX_free wolfSSL_X509_STORE_CTX_free +#define X509_STORE_CTX_get_chain wolfSSL_X509_STORE_CTX_get_chain +#define X509_STORE_CTX_get1_chain wolfSSL_X509_STORE_CTX_get1_chain +#define X509_STORE_CTX_get_error wolfSSL_X509_STORE_CTX_get_error +#define X509_STORE_CTX_get_error_depth wolfSSL_X509_STORE_CTX_get_error_depth +#define X509_STORE_CTX_init wolfSSL_X509_STORE_CTX_init +#define X509_STORE_CTX_cleanup wolfSSL_X509_STORE_CTX_cleanup +#define X509_STORE_CTX_set_error wolfSSL_X509_STORE_CTX_set_error +#define X509_STORE_CTX_get_ex_data wolfSSL_X509_STORE_CTX_get_ex_data +#define X509_STORE_CTX_set_ex_data wolfSSL_X509_STORE_CTX_set_ex_data +#define X509_STORE_CTX_set_depth wolfSSL_X509_STORE_CTX_set_depth +#define X509_STORE_CTX_get0_current_issuer \ + wolfSSL_X509_STORE_CTX_get0_current_issuer +#define X509_STORE_CTX_get0_store wolfSSL_X509_STORE_CTX_get0_store +#define X509_STORE_CTX_get0_cert wolfSSL_X509_STORE_CTX_get0_cert + +#define X509_STORE_new wolfSSL_X509_STORE_new +#define X509_STORE_free wolfSSL_X509_STORE_free +#define X509_STORE_add_lookup wolfSSL_X509_STORE_add_lookup +#define X509_STORE_add_cert wolfSSL_X509_STORE_add_cert +#define X509_STORE_add_crl wolfSSL_X509_STORE_add_crl +#define X509_STORE_set_flags wolfSSL_X509_STORE_set_flags +#define X509_STORE_get1_certs wolfSSL_X509_STORE_get1_certs +#define X509_STORE_get_by_subject wolfSSL_X509_STORE_get_by_subject +#define X509_STORE_CTX_get1_issuer wolfSSL_X509_STORE_CTX_get1_issuer +#define X509_STORE_CTX_set_time wolfSSL_X509_STORE_CTX_set_time +#define X509_VERIFY_PARAM_set_hostflags wolfSSL_X509_VERIFY_PARAM_set_hostflags +#define X509_VERIFY_PARAM_set1_host wolfSSL_X509_VERIFY_PARAM_set1_host +#define X509_VERIFY_PARAM_set1_ip_asc wolfSSL_X509_VERIFY_PARAM_set1_ip_asc +#define X509_STORE_load_locations wolfSSL_X509_STORE_load_locations + +#define X509_LOOKUP_add_dir wolfSSL_X509_LOOKUP_add_dir +#define X509_LOOKUP_load_file wolfSSL_X509_LOOKUP_load_file +#define X509_LOOKUP_hash_dir wolfSSL_X509_LOOKUP_hash_dir +#define X509_LOOKUP_file wolfSSL_X509_LOOKUP_file + +#define d2i_X509_CRL wolfSSL_d2i_X509_CRL +#define d2i_X509_CRL_fp wolfSSL_d2i_X509_CRL_fp +#define PEM_read_X509_CRL wolfSSL_PEM_read_X509_CRL + +#define X509_CRL_free wolfSSL_X509_CRL_free +#define X509_CRL_get_lastUpdate wolfSSL_X509_CRL_get_lastUpdate +#define X509_CRL_get_nextUpdate wolfSSL_X509_CRL_get_nextUpdate +#define X509_CRL_verify wolfSSL_X509_CRL_verify +#define X509_CRL_get_REVOKED wolfSSL_X509_CRL_get_REVOKED + +#define X509_get_X509_PUBKEY wolfSSL_X509_get_X509_PUBKEY +#define X509_get0_tbs_sigalg wolfSSL_X509_get0_tbs_sigalg +#define X509_PUBKEY_get0_param wolfSSL_X509_PUBKEY_get0_param +#define X509_ALGOR_get0 wolfSSL_X509_ALGOR_get0 + +#define sk_X509_REVOKED_num wolfSSL_sk_X509_REVOKED_num +#define sk_X509_REVOKED_value wolfSSL_sk_X509_REVOKED_value + +#define X509_OBJECT_free_contents wolfSSL_X509_OBJECT_free_contents +#define X509_subject_name_hash wolfSSL_X509_subject_name_hash + +#define X509_check_purpose(...) 0 + +#define OCSP_parse_url wolfSSL_OCSP_parse_url + +#define MD4_Init wolfSSL_MD4_Init +#define MD4_Update wolfSSL_MD4_Update +#define MD4_Final wolfSSL_MD4_Final + +#define BIO_new wolfSSL_BIO_new +#define BIO_free wolfSSL_BIO_free +#define BIO_vfree wolfSSL_BIO_vfree +#define BIO_free_all wolfSSL_BIO_free_all +#define BIO_nread0 wolfSSL_BIO_nread0 +#define BIO_nread wolfSSL_BIO_nread +#define BIO_read wolfSSL_BIO_read +#define BIO_nwrite0 wolfSSL_BIO_nwrite0 +#define BIO_nwrite wolfSSL_BIO_nwrite +#define BIO_write wolfSSL_BIO_write +#define BIO_push wolfSSL_BIO_push +#define BIO_pop wolfSSL_BIO_pop +#define BIO_flush wolfSSL_BIO_flush +#define BIO_pending wolfSSL_BIO_pending + +#define BIO_get_mem_data wolfSSL_BIO_get_mem_data +#define BIO_new_mem_buf wolfSSL_BIO_new_mem_buf + +#define BIO_f_buffer wolfSSL_BIO_f_buffer +#define BIO_set_write_buffer_size wolfSSL_BIO_set_write_buffer_size +#define BIO_f_ssl wolfSSL_BIO_f_ssl +#define BIO_new_socket wolfSSL_BIO_new_socket +#define SSL_set_bio wolfSSL_set_bio +#define BIO_set_ssl wolfSSL_BIO_set_ssl +#define BIO_eof wolfSSL_BIO_eof +#define BIO_set_ss wolfSSL_BIO_set_ss + +#define BIO_s_mem wolfSSL_BIO_s_mem +#define BIO_f_base64 wolfSSL_BIO_f_base64 +#define BIO_set_flags wolfSSL_BIO_set_flags +#define BIO_set_nbio wolfSSL_BIO_set_nbio + +#define SSLeay_add_ssl_algorithms wolfSSL_add_all_algorithms +#define SSLeay_add_all_algorithms wolfSSL_add_all_algorithms + +#define RAND_screen wolfSSL_RAND_screen +#define RAND_file_name wolfSSL_RAND_file_name +#define RAND_write_file wolfSSL_RAND_write_file +#define RAND_load_file wolfSSL_RAND_load_file +#define RAND_egd wolfSSL_RAND_egd +#define RAND_seed wolfSSL_RAND_seed +#define RAND_cleanup wolfSSL_RAND_Cleanup +#define RAND_add wolfSSL_RAND_add +#define RAND_poll wolfSSL_RAND_poll +#define RAND_status wolfSSL_RAND_status +#define RAND_bytes wolfSSL_RAND_bytes +#define RAND_pseudo_bytes wolfSSL_RAND_pseudo_bytes + +#define COMP_zlib wolfSSL_COMP_zlib +#define COMP_rle wolfSSL_COMP_rle +#define SSL_COMP_add_compression_method wolfSSL_COMP_add_compression_method + +#define SSL_get_ex_new_index wolfSSL_get_ex_new_index + +#define ASN1_BIT_STRING_new wolfSSL_ASN1_BIT_STRING_new +#define ASN1_BIT_STRING_free wolfSSL_ASN1_BIT_STRING_free +#define ASN1_BIT_STRING_get_bit wolfSSL_ASN1_BIT_STRING_get_bit +#define ASN1_BIT_STRING_set_bit wolfSSL_ASN1_BIT_STRING_set_bit + +#define sk_ASN1_OBJECT_free wolfSSL_sk_ASN1_OBJECT_free + +#define ASN1_TIME_adj wolfSSL_ASN1_TIME_adj +#define ASN1_TIME_print wolfSSL_ASN1_TIME_print +#define ASN1_TIME_to_generalizedtime wolfSSL_ASN1_TIME_to_generalizedtime +#define ASN1_GENERALIZEDTIME_print wolfSSL_ASN1_GENERALIZEDTIME_print +#define ASN1_GENERALIZEDTIME_free wolfSSL_ASN1_GENERALIZEDTIME_free + +#define ASN1_tag2str wolfSSL_ASN1_tag2str + +#define i2a_ASN1_INTEGER wolfSSL_i2a_ASN1_INTEGER +#define i2c_ASN1_INTEGER wolfSSL_i2c_ASN1_INTEGER +#define ASN1_INTEGER_new wolfSSL_ASN1_INTEGER_new +#define ASN1_INTEGER_free wolfSSL_ASN1_INTEGER_free +#define ASN1_INTEGER_cmp wolfSSL_ASN1_INTEGER_cmp +#define ASN1_INTEGER_get wolfSSL_ASN1_INTEGER_get +#define ASN1_INTEGER_set wolfSSL_ASN1_INTEGER_set +#define ASN1_INTEGER_to_BN wolfSSL_ASN1_INTEGER_to_BN + +#define i2a_ASN1_OBJECT wolfSSL_i2a_ASN1_OBJECT + +#define ASN1_STRING_data wolfSSL_ASN1_STRING_data +#define ASN1_STRING_get0_data wolfSSL_ASN1_STRING_data +#define ASN1_STRING_length wolfSSL_ASN1_STRING_length +#define ASN1_STRING_to_UTF8 wolfSSL_ASN1_STRING_to_UTF8 +#define ASN1_STRING_print_ex wolfSSL_ASN1_STRING_print_ex +#define ASN1_STRING_print(x, y) wolfSSL_ASN1_STRING_print ((WOLFSSL_BIO*)(x), (WOLFSSL_ASN1_STRING*)(y)) +#define d2i_DISPLAYTEXT wolfSSL_d2i_DISPLAYTEXT + +#define ASN1_UTCTIME_pr wolfSSL_ASN1_UTCTIME_pr + +#define ASN1_IA5STRING WOLFSSL_ASN1_STRING + +#define ASN1_OCTET_STRING WOLFSSL_ASN1_STRING +#define ASN1_BOOLEAN WOLFSSL_ASN1_BOOLEAN + +#define SSL_load_client_CA_file wolfSSL_load_client_CA_file + +#define SSL_CTX_get_client_CA_list wolfSSL_CTX_get_client_CA_list +#define SSL_CTX_set_client_CA_list wolfSSL_CTX_set_client_CA_list +#define SSL_CTX_set_client_cert_cb wolfSSL_CTX_set_client_cert_cb +#define SSL_CTX_set_cert_store wolfSSL_CTX_set_cert_store +#define SSL_CTX_get_cert_store(x) wolfSSL_CTX_get_cert_store ((WOLFSSL_CTX*) (x)) +#define SSL_get_client_CA_list wolfSSL_get_client_CA_list +#define SSL_get_ex_data_X509_STORE_CTX_idx wolfSSL_get_ex_data_X509_STORE_CTX_idx +#define SSL_get_ex_data wolfSSL_get_ex_data + +#define SSL_CTX_set_default_passwd_cb_userdata wolfSSL_CTX_set_default_passwd_cb_userdata +#define SSL_CTX_set_default_passwd_cb wolfSSL_CTX_set_default_passwd_cb + +#define SSL_CTX_set_timeout(ctx, to) \ + wolfSSL_CTX_set_timeout(ctx, (unsigned int) to) +#define SSL_CTX_set_info_callback wolfSSL_CTX_set_info_callback +#define SSL_CTX_set_alpn_protos wolfSSL_CTX_set_alpn_protos + +#define SSL_alert_type_string wolfSSL_alert_type_string +#define SSL_alert_desc_string wolfSSL_alert_desc_string +#define SSL_state_string wolfSSL_state_string + +#define RSA_free wolfSSL_RSA_free +#define RSA_generate_key wolfSSL_RSA_generate_key +#define SSL_CTX_set_tmp_rsa_callback wolfSSL_CTX_set_tmp_rsa_callback +#define RSA_print wolfSSL_RSA_print +#define RSA_bits wolfSSL_RSA_size + +#define PEM_def_callback wolfSSL_PEM_def_callback + +#define SSL_CTX_sess_accept wolfSSL_CTX_sess_accept +#define SSL_CTX_sess_connect wolfSSL_CTX_sess_connect +#define SSL_CTX_sess_accept_good wolfSSL_CTX_sess_accept_good +#define SSL_CTX_sess_connect_good wolfSSL_CTX_sess_connect_good +#define SSL_CTX_sess_accept_renegotiate wolfSSL_CTX_sess_accept_renegotiate +#define SSL_CTX_sess_connect_renegotiate wolfSSL_CTX_sess_connect_renegotiate +#define SSL_CTX_sess_hits wolfSSL_CTX_sess_hits +#define SSL_CTX_sess_cb_hits wolfSSL_CTX_sess_cb_hits +#define SSL_CTX_sess_cache_full wolfSSL_CTX_sess_cache_full +#define SSL_CTX_sess_misses wolfSSL_CTX_sess_misses +#define SSL_CTX_sess_timeouts wolfSSL_CTX_sess_timeouts +#define SSL_CTX_sess_number wolfSSL_CTX_sess_number +#define SSL_CTX_sess_get_cache_size wolfSSL_CTX_sess_get_cache_size + + +#define SSL_DEFAULT_CIPHER_LIST WOLFSSL_DEFAULT_CIPHER_LIST + +#define SSL_CTX_set_psk_client_callback wolfSSL_CTX_set_psk_client_callback +#define SSL_set_psk_client_callback wolfSSL_set_psk_client_callback + +#define SSL_get_psk_identity_hint wolfSSL_get_psk_identity_hint +#define SSL_get_psk_identity wolfSSL_get_psk_identity + +#define SSL_CTX_use_psk_identity_hint wolfSSL_CTX_use_psk_identity_hint +#define SSL_use_psk_identity_hint wolfSSL_use_psk_identity_hint + +#define SSL_CTX_set_psk_server_callback wolfSSL_CTX_set_psk_server_callback +#define SSL_set_psk_server_callback wolfSSL_set_psk_server_callback + +/* system file ints for ERR_put_error */ +#define SYS_F_ACCEPT WOLFSSL_SYS_ACCEPT +#define SYS_F_BIND WOLFSSL_SYS_BIND +#define SYS_F_CONNECT WOLFSSL_SYS_CONNECT +#define SYS_F_FOPEN WOLFSSL_SYS_FOPEN +#define SYS_F_FREAD WOLFSSL_SYS_FREAD +#define SYS_F_GETADDRINFO WOLFSSL_SYS_GETADDRINFO +#define SYS_F_GETSOCKOPT WOLFSSL_SYS_GETSOCKOPT +#define SYS_F_GETSOCKNAME WOLFSSL_SYS_GETSOCKNAME +#define SYS_F_OPENDIR WOLFSSL_SYS_OPENDIR +#define SYS_F_SETSOCKOPT WOLFSSL_SYS_SETSOCKOPT +#define SYS_F_SOCKET WOLFSSL_SYS_SOCKET +#define SYS_F_GETHOSTBYNAME WOLFSSL_SYS_GETHOSTBYNAME +#define SYS_F_GETNAMEINFO WOLFSSL_SYS_GETNAMEINFO +#define SYS_F_GETSERVBYNAME WOLFSSL_SYS_GETSERVBYNAME +#define SYS_F_IOCTLSOCKET WOLFSSL_SYS_IOCTLSOCKET +#define SYS_F_LISTEN WOLFSSL_SYS_LISTEN + +#define ERR_GET_REASON wolfSSL_ERR_GET_REASON + +#define ERR_put_error wolfSSL_ERR_put_error +#define ERR_peek_error wolfSSL_ERR_peek_error +#define ERR_peek_errors_fp wolfSSL_ERR_peek_errors_fp +#define ERR_peek_error_line_data wolfSSL_ERR_peek_error_line_data +#define ERR_peek_last_error wolfSSL_ERR_peek_last_error +#define ERR_peek_last_error_line wolfSSL_ERR_peek_last_error_line +#define ERR_get_error_line wolfSSL_ERR_get_error_line +#define ERR_get_error_line_data wolfSSL_ERR_get_error_line_data +#define ERR_get_error wolfSSL_ERR_get_error +#define ERR_print_errors_fp(file) wolfSSL_ERR_dump_errors_fp((file)) +#define ERR_print_errors wolfSSL_ERR_print_errors +#define ERR_clear_error wolfSSL_ERR_clear_error +#define ERR_free_strings wolfSSL_ERR_free_strings +#define ERR_remove_state wolfSSL_ERR_remove_state +#define ERR_remove_thread_state wolfSSL_ERR_remove_thread_state +#define ERR_error_string wolfSSL_ERR_error_string +#define ERR_error_string_n wolfSSL_ERR_error_string_n +#define ERR_reason_error_string wolfSSL_ERR_reason_error_string +#define ERR_load_BIO_strings wolfSSL_ERR_load_BIO_strings + +#define PEMerr(func, reason) wolfSSL_ERR_put_error(ERR_LIB_PEM,\ + (func), (reason), __FILE__, __LINE__) + +#define SSLv23_server_method wolfSSLv23_server_method +#define SSL_CTX_set_options wolfSSL_CTX_set_options +#define SSL_CTX_get_options wolfSSL_CTX_get_options +#define SSL_CTX_clear_options wolfSSL_CTX_clear_options + +#define SSL_CTX_check_private_key wolfSSL_CTX_check_private_key +#define SSL_check_private_key wolfSSL_check_private_key + +#define SSL_CTX_set_mode wolfSSL_CTX_set_mode +#define SSL_CTX_get_mode wolfSSL_CTX_get_mode +#define SSL_CTX_set_default_read_ahead wolfSSL_CTX_set_default_read_ahead + +#define SSL_CTX_sess_set_cache_size wolfSSL_CTX_sess_set_cache_size +#define SSL_CTX_set_default_verify_paths wolfSSL_CTX_set_default_verify_paths + +#define SSL_CTX_set_session_id_context wolfSSL_CTX_set_session_id_context +#define SSL_get_peer_certificate wolfSSL_get_peer_certificate +#define SSL_get_peer_cert_chain wolfSSL_get_peer_cert_chain + +#define SSL_want wolfSSL_want +#define SSL_want_read wolfSSL_want_read +#define SSL_want_write wolfSSL_want_write + +#define BIO_prf wolfSSL_BIO_prf + +#define sk_num wolfSSL_sk_num +#define sk_ASN1_OBJECT_num wolfSSL_sk_num +#define sk_value wolfSSL_sk_value +#define sk_ASN1_OBJECT_value wolfSSL_sk_value + +#define d2i_PKCS12_bio wolfSSL_d2i_PKCS12_bio +#define d2i_PKCS12_fp wolfSSL_d2i_PKCS12_fp +#define i2d_PKCS12_bio wolfSSL_i2d_PKCS12_bio + +#define d2i_RSAPublicKey wolfSSL_d2i_RSAPublicKey +#define d2i_RSAPrivateKey wolfSSL_d2i_RSAPrivateKey +#define i2d_RSAPrivateKey wolfSSL_i2d_RSAPrivateKey +#define i2d_RSAPublicKey wolfSSL_i2d_RSAPublicKey + +#define SSL_CTX_get_ex_data wolfSSL_CTX_get_ex_data +#define SSL_CTX_set_ex_data wolfSSL_CTX_set_ex_data +#define SSL_CTX_sess_set_get_cb wolfSSL_CTX_sess_set_get_cb +#define SSL_CTX_sess_set_new_cb wolfSSL_CTX_sess_set_new_cb +#define SSL_CTX_sess_set_remove_cb wolfSSL_CTX_sess_set_remove_cb + +#define i2d_SSL_SESSION wolfSSL_i2d_SSL_SESSION +#define d2i_SSL_SESSION wolfSSL_d2i_SSL_SESSION +#define SSL_SESSION_set_timeout wolfSSL_SSL_SESSION_set_timeout +#define SSL_SESSION_get_timeout wolfSSL_SESSION_get_timeout +#define SSL_SESSION_get_time wolfSSL_SESSION_get_time + +#define SSL_CTX_get_ex_new_index wolfSSL_CTX_get_ex_new_index +#define PEM_read wolfSSL_PEM_read +#define PEM_write wolfSSL_PEM_write +#define PEM_get_EVP_CIPHER_INFO wolfSSL_PEM_get_EVP_CIPHER_INFO +#define PEM_do_header wolfSSL_PEM_do_header + +/*#if OPENSSL_API_COMPAT < 0x10100000L*/ +#define CONF_modules_free() +#define ENGINE_cleanup() +#define HMAC_CTX_cleanup wolfSSL_HMAC_cleanup +#define SSL_CTX_need_tmp_RSA(ctx) 0 +#define SSL_CTX_set_tmp_rsa(ctx,rsa) 1 +#define SSL_need_tmp_RSA(ssl) 0 +#define SSL_set_tmp_rsa(ssl,rsa) 1 +/*#endif*/ + +#define CONF_modules_unload(a) + +#define SSL_get_hit wolfSSL_session_reused + +/* yassl had set the default to be 500 */ +#define SSL_get_default_timeout(ctx) 500 + +#define DTLSv1_get_timeout(ssl, timeleft) wolfSSL_DTLSv1_get_timeout((ssl), (Timeval*)(timeleft)) +#define DTLSv1_handle_timeout wolfSSL_DTLSv1_handle_timeout +#define DTLSv1_set_initial_timeout_duration wolfSSL_DTLSv1_set_initial_timeout_duration + +#ifndef NO_WOLFSSL_STUB +#define SSL_CTX_set_current_time_cb(ssl, cb) ({ (void)ssl; (void)cb; }) +#endif + +#define SSL_CTX_use_certificate wolfSSL_CTX_use_certificate +#define SSL_CTX_add1_chain_cert wolfSSL_CTX_add1_chain_cert +#define SSL_CTX_use_PrivateKey wolfSSL_CTX_use_PrivateKey +#define BIO_read_filename wolfSSL_BIO_read_filename +#define SSL_CTX_set_verify_depth wolfSSL_CTX_set_verify_depth +#define SSL_set_verify_depth wolfSSL_set_verify_depth +#define SSL_get_app_data wolfSSL_get_app_data +#define SSL_set_app_data wolfSSL_set_app_data +#define SHA1 wolfSSL_SHA1 + +#define SSL_dup_CA_list wolfSSL_dup_CA_list + +#define sk_X509_NAME_find wolfSSL_sk_X509_NAME_find + +enum { + GEN_DNS = 0x02, /* ASN_DNS_TYPE */ + GEN_EMAIL = 0x01, /* ASN_RFC822_TYPE */ + GEN_URI = 0x06, /* ASN_URI_TYPE */ + GEN_RID = 0x08, /* Registered ID, not supported */ +}; + +#define PEM_read_bio_DHparams wolfSSL_PEM_read_bio_DHparams +#define PEM_read_bio_DSAparams wolfSSL_PEM_read_bio_DSAparams + +#if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY) +#define SSL_get_rbio wolfSSL_SSL_get_rbio +#define SSL_get_wbio wolfSSL_SSL_get_wbio +#define SSL_do_handshake wolfSSL_SSL_do_handshake +#define SSL_get_ciphers(x) wolfSSL_get_ciphers_compat(x) +#define SSL_SESSION_get_id wolfSSL_SESSION_get_id +#define SSL_get_cipher_bits(s,np) \ + wolfSSL_CIPHER_get_bits(SSL_get_current_cipher(s),np) +#define sk_SSL_CIPHER_num wolfSSL_sk_SSL_CIPHER_num +#define sk_SSL_COMP_zero wolfSSL_sk_SSL_COMP_zero +#define sk_SSL_CIPHER_value wolfSSL_sk_SSL_CIPHER_value +#endif /* OPENSSL_ALL || WOLFSSL_HAPROXY */ +#define sk_SSL_CIPHER_dup wolfSSL_sk_SSL_CIPHER_dup +#define sk_SSL_CIPHER_free wolfSSL_sk_SSL_CIPHER_free +#define sk_SSL_CIPHER_find wolfSSL_sk_SSL_CIPHER_find + +#if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \ + || defined(WOLFSSL_NGINX) +#include + +#define SSL_CTRL_CHAIN 88 +#define GEN_IPADD 7 +#define ERR_LIB_SSL 20 +#define SSL_R_SHORT_READ 10 +#define ERR_R_PEM_LIB 9 +#define V_ASN1_IA5STRING 22 +#define V_ASN1_UTF8STRING 12 +#define SSL_CTRL_MODE 33 + +#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 + +#define SSL_CTX_clear_chain_certs(ctx) SSL_CTX_set0_chain(ctx,NULL) +#define d2i_RSAPrivateKey_bio wolfSSL_d2i_RSAPrivateKey_bio +#define SSL_CTX_use_RSAPrivateKey wolfSSL_CTX_use_RSAPrivateKey +#define d2i_PrivateKey_bio wolfSSL_d2i_PrivateKey_bio +#define BIO_new_bio_pair wolfSSL_BIO_new_bio_pair +#define SSL_get_verify_callback wolfSSL_get_verify_callback + +#define SSL_set_mode(ssl,op) wolfSSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL) + +#define SSL_CTX_use_certificate_ASN1 wolfSSL_CTX_use_certificate_ASN1 +#define SSL_CTX_set0_chain(ctx,sk) \ + wolfSSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)(sk)) +#define SSL_CTX_get_app_data(ctx) wolfSSL_CTX_get_ex_data(ctx,0) +#define SSL_CTX_set_app_data(ctx,arg) wolfSSL_CTX_set_ex_data(ctx,0, \ + (char *)(arg)) +#endif /* OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY */ + +#define SSL_CTX_set_tmp_dh wolfSSL_CTX_set_tmp_dh + +#define TLSEXT_STATUSTYPE_ocsp 1 + +#define SSL_set_options wolfSSL_set_options +#define SSL_get_options wolfSSL_get_options +#define SSL_clear_options wolfSSL_clear_options +#define SSL_set_tmp_dh wolfSSL_set_tmp_dh +#define SSL_clear_num_renegotiations wolfSSL_clear_num_renegotiations +#define SSL_total_renegotiations wolfSSL_total_renegotiations +#define SSL_num_renegotiations wolfSSL_num_renegotiations +#define SSL_renegotiate wolfSSL_Rehandshake +#define SSL_get_secure_renegotiation_support wolfSSL_SSL_get_secure_renegotiation_support +#define SSL_set_tlsext_debug_arg wolfSSL_set_tlsext_debug_arg +#define SSL_set_tlsext_status_type wolfSSL_set_tlsext_status_type +#define SSL_set_tlsext_status_exts wolfSSL_set_tlsext_status_exts +#define SSL_get_tlsext_status_ids wolfSSL_get_tlsext_status_ids +#define SSL_set_tlsext_status_ids wolfSSL_set_tlsext_status_ids +#define SSL_get_tlsext_status_ocsp_res wolfSSL_get_tlsext_status_ocsp_resp +#define SSL_set_tlsext_status_ocsp_res wolfSSL_set_tlsext_status_ocsp_resp +#define SSL_set_tlsext_status_ocsp_resp wolfSSL_set_tlsext_status_ocsp_resp +#define SSL_get_tlsext_status_ocsp_resp wolfSSL_get_tlsext_status_ocsp_resp + +#define SSL_CTX_add_extra_chain_cert wolfSSL_CTX_add_extra_chain_cert +#define SSL_CTX_get_read_ahead wolfSSL_CTX_get_read_ahead +#define SSL_CTX_set_read_ahead wolfSSL_CTX_set_read_ahead +#define SSL_CTX_set_tlsext_status_arg wolfSSL_CTX_set_tlsext_status_arg +#define SSL_CTX_set_tlsext_opaque_prf_input_callback_arg \ + wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg +#define SSL_get_server_random wolfSSL_get_server_random +#define SSL_get_server_tmp_key wolfSSL_get_server_tmp_key + +#define SSL_CTX_set_min_proto_version wolfSSL_CTX_set_min_proto_version +#define SSL_CTX_set_max_proto_version wolfSSL_CTX_set_max_proto_version + +#define SSL_get_tlsext_status_exts wolfSSL_get_tlsext_status_exts + +#define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 11 +#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 12 +#define SSL_CTRL_SET_TMP_DH 3 +#define SSL_CTRL_SET_TLSEXT_DEBUG_ARG 57 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE 65 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS 66 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS 67 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS 68 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS 69 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP 70 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71 + +#define SSL_CTRL_SET_TMP_DH 3 +#define SSL_CTRL_EXTRA_CHAIN_CERT 14 + +#define SSL_CTRL_SET_SESS_CACHE_SIZE 42 +#define SSL_CTRL_GET_READ_AHEAD 40 +#define SSL_CTRL_SET_READ_AHEAD 41 + +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB 63 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG 64 + +#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82 + +#define SSL_ctrl wolfSSL_ctrl +#define SSL_CTX_ctrl wolfSSL_CTX_ctrl + +#define SSL3_RANDOM_SIZE 32 /* same as RAN_LEN in internal.h */ + +#define SSL2_VERSION 0x0002 +#define SSL3_VERSION 0x0300 +#define TLS1_VERSION 0x0301 +#define TLS1_1_VERSION 0x0302 +#define TLS1_2_VERSION 0x0303 +#define TLS1_3_VERSION 0x0304 +#define DTLS1_VERSION 0xFEFF +#define DTLS1_2_VERSION 0xFEFD + +#if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(OPENSSL_EXTRA) \ + || defined(OPENSSL_ALL) +#include + +#define SSL23_ST_SR_CLNT_HELLO_A (0x210|0x2000) +#define SSL3_ST_SR_CLNT_HELLO_A (0x110|0x2000) + +#define SSL3_AD_BAD_CERTIFICATE bad_certificate +#define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE + +#define ASN1_STRFLGS_ESC_MSB 4 + +#define SSL_MAX_MASTER_KEY_LENGTH WOLFSSL_MAX_MASTER_KEY_LENGTH + +#define SSL_alert_desc_string_long wolfSSL_alert_desc_string_long +#define SSL_alert_type_string_long wolfSSL_alert_type_string_long +#define SSL_CIPHER_get_bits wolfSSL_CIPHER_get_bits +#define sk_GENERAL_NAME_num wolfSSL_sk_GENERAL_NAME_num +#define SSL_CTX_get_options wolfSSL_CTX_get_options + +#define SSL_CTX_flush_sessions wolfSSL_flush_sessions +#define SSL_CTX_add_session wolfSSL_CTX_add_session +#define SSL_version wolfSSL_version +#define SSL_get_state wolfSSL_get_state +#define SSL_state_string_long wolfSSL_state_string_long + +#define GENERAL_NAME_new wolfSSL_GENERAL_NAME_new +#define GENERAL_NAME_free wolfSSL_GENERAL_NAME_free +#define sk_GENERAL_NAME_push wolfSSL_sk_GENERAL_NAME_push +#define sk_GENERAL_NAME_value wolfSSL_sk_GENERAL_NAME_value +#define SSL_SESSION_get_ex_data wolfSSL_SESSION_get_ex_data +#define SSL_SESSION_set_ex_data wolfSSL_SESSION_set_ex_data +#define SSL_SESSION_get_ex_new_index wolfSSL_SESSION_get_ex_new_index +#define SSL_SESSION_get_id wolfSSL_SESSION_get_id +#define SSL_SESSION_print wolfSSL_SESSION_print +#define sk_GENERAL_NAME_pop_free wolfSSL_sk_GENERAL_NAME_pop_free +#define sk_GENERAL_NAME_free wolfSSL_sk_GENERAL_NAME_free +#define sk_ASN1_OBJECT_pop_free wolfSSL_sk_ASN1_OBJECT_pop_free +#define GENERAL_NAME_free wolfSSL_GENERAL_NAME_free +#define GENERAL_NAMES_free wolfSSL_GENERAL_NAMES_free + +#define AUTHORITY_INFO_ACCESS_free wolfSSL_AUTHORITY_INFO_ACCESS_free +#define sk_ACCESS_DESCRIPTION_pop_free wolfSSL_sk_ACCESS_DESCRIPTION_pop_free +#define sk_ACCESS_DESCRIPTION_free wolfSSL_sk_ACCESS_DESCRIPTION_free +#define ACCESS_DESCRIPTION_free NULL + +#define SSL3_AL_FATAL 2 +#define SSL_TLSEXT_ERR_OK 0 +#define SSL_TLSEXT_ERR_ALERT_FATAL alert_fatal +#define SSL_TLSEXT_ERR_NOACK alert_warning +#define TLSEXT_NAMETYPE_host_name WOLFSSL_SNI_HOST_NAME + +#define SSL_set_tlsext_host_name wolfSSL_set_tlsext_host_name +#define SSL_get_servername wolfSSL_get_servername +#define SSL_set_SSL_CTX wolfSSL_set_SSL_CTX +#define SSL_CTX_get_verify_callback wolfSSL_CTX_get_verify_callback +#define SSL_CTX_set_tlsext_servername_callback wolfSSL_CTX_set_tlsext_servername_callback +#define SSL_CTX_set_tlsext_servername_arg wolfSSL_CTX_set_servername_arg + +#define PSK_MAX_PSK_LEN 256 +#define PSK_MAX_IDENTITY_LEN 128 +#define SSL_CTX_clear_options wolfSSL_CTX_clear_options + + +#endif /* HAVE_STUNNEL || WOLFSSL_NGINX */ +#define SSL_CTX_get_default_passwd_cb wolfSSL_CTX_get_default_passwd_cb +#define SSL_CTX_get_default_passwd_cb_userdata wolfSSL_CTX_get_default_passwd_cb_userdata + +#define SSL_CTX_set_msg_callback wolfSSL_CTX_set_msg_callback +#define SSL_set_msg_callback wolfSSL_set_msg_callback +#define SSL_CTX_set_msg_callback_arg wolfSSL_CTX_set_msg_callback_arg +#define SSL_set_msg_callback_arg wolfSSL_set_msg_callback_arg + +#define SSL_CTX_clear_extra_chain_certs wolfSSL_CTX_clear_extra_chain_certs + + +/* Nginx uses this to determine if reached end of certs in file. + * PEM_read_bio_X509 is called and the return error is lost. + * The error that needs to be detected is: SSL_NO_PEM_HEADER. + */ +#define ERR_GET_LIB(l) (int)((((unsigned long)l) >> 24L) & 0xffL) +#define ERR_GET_FUNC(l) (int)((((unsigned long)l) >> 12L) & 0xfffL) + +#define PEM_F_PEM_DEF_CALLBACK 100 + +#define PEM_R_NO_START_LINE 108 +#define PEM_R_PROBLEMS_GETTING_PASSWORD 109 +#define ERR_LIB_PEM 9 +#define ERR_LIB_X509 10 + +#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ + defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_ALL) || \ + defined(HAVE_LIGHTY) + +#include + +#define OPENSSL_STRING WOLFSSL_STRING + +#define TLSEXT_TYPE_application_layer_protocol_negotiation 16 + +#define OPENSSL_NPN_UNSUPPORTED 0 +#define OPENSSL_NPN_NEGOTIATED 1 +#define OPENSSL_NPN_NO_OVERLAP 2 + +/* Nginx checks these to see if the error was a handshake error. */ +#define SSL_R_BAD_CHANGE_CIPHER_SPEC LENGTH_ERROR +#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG BUFFER_E +#define SSL_R_DIGEST_CHECK_FAILED VERIFY_MAC_ERROR +#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST SUITES_ERROR +#define SSL_R_EXCESSIVE_MESSAGE_SIZE BUFFER_ERROR +#define SSL_R_LENGTH_MISMATCH LENGTH_ERROR +#define SSL_R_NO_CIPHERS_SPECIFIED SUITES_ERROR +#define SSL_R_NO_COMPRESSION_SPECIFIED COMPRESSION_ERROR +#define SSL_R_NO_SHARED_CIPHER MATCH_SUITE_ERROR +#define SSL_R_RECORD_LENGTH_MISMATCH HANDSHAKE_SIZE_ERROR +#define SSL_R_UNEXPECTED_MESSAGE OUT_OF_ORDER_E +#define SSL_R_UNEXPECTED_RECORD SANITY_MSG_E +#define SSL_R_UNKNOWN_ALERT_TYPE BUFFER_ERROR +#define SSL_R_UNKNOWN_PROTOCOL VERSION_ERROR +#define SSL_R_WRONG_VERSION_NUMBER VERSION_ERROR +#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC ENCRYPT_ERROR +#define SSL_R_HTTPS_PROXY_REQUEST PARSE_ERROR +#define SSL_R_HTTP_REQUEST PARSE_ERROR +#define SSL_R_UNSUPPORTED_PROTOCOL VERSION_ERROR + + +#ifdef HAVE_SESSION_TICKET +#define SSL_OP_NO_TICKET SSL_OP_NO_TICKET +#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72 +#endif + +#define OPENSSL_config wolfSSL_OPENSSL_config +#define OPENSSL_memdup wolfSSL_OPENSSL_memdup +#define SSL_CTX_get_timeout wolfSSL_SSL_CTX_get_timeout +#define SSL_CTX_set_tmp_ecdh wolfSSL_SSL_CTX_set_tmp_ecdh +#define SSL_CTX_remove_session wolfSSL_SSL_CTX_remove_session +#define SSL_get_rbio wolfSSL_SSL_get_rbio +#define SSL_get_wbio wolfSSL_SSL_get_wbio +#define SSL_do_handshake wolfSSL_SSL_do_handshake +#define SSL_in_init wolfSSL_SSL_in_init +#define SSL_in_connect_init wolfSSL_SSL_in_connect_init +#define SSL_get0_session wolfSSL_SSL_get0_session +#define SSL_CTX_set_tlsext_ticket_key_cb wolfSSL_CTX_set_tlsext_ticket_key_cb +#define SSL_CTX_set_tlsext_status_cb wolfSSL_CTX_set_tlsext_status_cb +#define SSL_CTX_get_extra_chain_certs wolfSSL_CTX_get_extra_chain_certs +#define sk_OPENSSL_STRING_value wolfSSL_sk_WOLFSSL_STRING_value +#define SSL_get0_alpn_selected wolfSSL_get0_alpn_selected +#define SSL_select_next_proto wolfSSL_select_next_proto +#define SSL_CTX_set_alpn_select_cb wolfSSL_CTX_set_alpn_select_cb +#define SSL_CTX_set_next_protos_advertised_cb wolfSSL_CTX_set_next_protos_advertised_cb +#define SSL_CTX_set_next_proto_select_cb wolfSSL_CTX_set_next_proto_select_cb +#define SSL_set_alpn_protos wolfSSL_set_alpn_protos +#define SSL_get0_next_proto_negotiated wolfSSL_get0_next_proto_negotiated +#define SSL_is_server wolfSSL_is_server + +#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || WOLFSSL_MYSQL_COMPATIBLE || + OPENSSL_ALL || HAVE_LIGHTY */ + +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) +#define SSL_CTX_set1_curves_list wolfSSL_CTX_set1_curves_list +#define SSL_set1_curves_list wolfSSL_set1_curves_list +#endif + +#ifdef OPENSSL_EXTRA +#define SSL_CTX_add_client_CA wolfSSL_CTX_add_client_CA +#define SSL_CTX_set_srp_password wolfSSL_CTX_set_srp_password +#define SSL_CTX_set_srp_username wolfSSL_CTX_set_srp_username +#define SSL_get_SSL_CTX wolfSSL_get_SSL_CTX +#define SSL_get0_param wolfSSL_get0_param + +#define ERR_NUM_ERRORS 16 +#define EVP_PKEY_NONE NID_undef +#define EVP_PKEY_RSA 6 +#define EVP_PKEY_RSA2 19 +#define EVP_PKEY_DH 28 +#define SN_pkcs9_emailAddress "Email" +#define LN_pkcs9_emailAddress "emailAddress" +#define NID_pkcs9_emailAddress 48 +#define OBJ_pkcs9_emailAddress 1L,2L,840L,113539L,1L,9L,1L + +#define SSL_get_rbio wolfSSL_SSL_get_rbio +#define SSL_get_wbio wolfSSL_SSL_get_wbio +#define SSL_do_handshake wolfSSL_SSL_do_handshake +#endif /* OPENSSL_EXTRA */ + +/* cipher suites for compatibility */ +#define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013) +#define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) +#define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) +#define TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8) +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009) +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a) +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b) +#define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9) + +#define EVP_CIPHER_mode WOLFSSL_CIPHER_mode +/* WOLFSSL_EVP_CIPHER is just the string name of the cipher */ +#define EVP_CIPHER_name(x) x +#define EVP_MD_CTX_reset wolfSSL_EVP_MD_CTX_cleanup +/* WOLFSSL_EVP_MD is just the string name of the digest */ +#define EVP_MD_name(x) x +#define X509_STORE_get0_objects wolfSSL_X509_STORE_get0_objects +#define sk_X509_OBJECT_num wolfSSL_sk_X509_OBJECT_num +#define sk_X509_OBJECT_value wolfSSL_sk_X509_OBJECT_value +#define sk_X509_OBJECT_delete wolfSSL_sk_X509_OBJECT_delete +#define X509_OBJECT_free wolfSSL_X509_OBJECT_free +#define X509_OBJECT_get_type(x) 0 +#define EVP_CIPHER_nid wolfSSL_EVP_CIPHER_nid + +#define OpenSSL_version(x) wolfSSL_lib_version() + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* wolfSSL_openssl_h__ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/ssl23.h b/wolfssl_hlavickove_subory/wolfssl/openssl/ssl23.h new file mode 100644 index 0000000..fc3ddfb --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/ssl23.h @@ -0,0 +1 @@ +/* ssl23.h for openssl */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/stack.h b/wolfssl_hlavickove_subory/wolfssl/openssl/stack.h new file mode 100644 index 0000000..84bcbae --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/stack.h @@ -0,0 +1,59 @@ +/* stack.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* stack.h for openSSL */ + +#ifndef WOLFSSL_STACK_H_ +#define WOLFSSL_STACK_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +typedef void (*wolfSSL_sk_freefunc)(void *); + +WOLFSSL_API void wolfSSL_sk_GENERIC_pop_free(WOLFSSL_STACK* sk, wolfSSL_sk_freefunc); +WOLFSSL_API void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK *); +WOLFSSL_API int wolfSSL_sk_GENERIC_push(WOLFSSL_STACK *sk, void *data); +WOLFSSL_API void wolfSSL_sk_pop_free(WOLFSSL_STACK *st, void (*func) (void *)); +WOLFSSL_API void wolfSSL_sk_CONF_VALUE_free(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk); +WOLFSSL_API WOLFSSL_STACK *wolfSSL_sk_new_null(void); + +WOLFSSL_API int wolfSSL_sk_CIPHER_push(WOLFSSL_STACK *st,WOLFSSL_CIPHER *cipher); +WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_sk_CIPHER_pop(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_new_cipher(void); + +#define OPENSSL_sk_free wolfSSL_sk_free +#define OPENSSL_sk_pop_free wolfSSL_sk_pop_free +#define OPENSSL_sk_new_null wolfSSL_sk_new_null +#define OPENSSL_sk_push wolfSSL_sk_push + +/* provides older OpenSSL API compatibility */ +#define sk_free OPENSSL_sk_free +#define sk_pop_free OPENSSL_sk_pop_free +#define sk_new_null OPENSSL_sk_new_null +#define sk_push OPENSSL_sk_push + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/tls1.h b/wolfssl_hlavickove_subory/wolfssl/openssl/tls1.h new file mode 100644 index 0000000..074c854 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/tls1.h @@ -0,0 +1,46 @@ +/* tls1.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLFSSL_OPENSSL_TLS1_H_ +#define WOLFSSL_OPENSSL_TLS1_H_ + +#ifndef TLS1_VERSION +#define TLS1_VERSION 0x0301 +#endif + +#ifndef TLS1_1_VERSION +#define TLS1_1_VERSION 0x0302 +#endif + +#ifndef TLS1_2_VERSION +#define TLS1_2_VERSION 0x0303 +#endif + +#ifndef TLS1_3_VERSION +#define TLS1_3_VERSION 0x0304 +#endif + +#ifndef TLS_MAX_VERSION +#define TLS_MAX_VERSION TLS1_3_VERSION +#endif + +#endif /* WOLFSSL_OPENSSL_TLS1_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/ui.h b/wolfssl_hlavickove_subory/wolfssl/openssl/ui.h new file mode 100644 index 0000000..a253930 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/ui.h @@ -0,0 +1,2 @@ +/* ui.h for openssl */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/x509.h b/wolfssl_hlavickove_subory/wolfssl/openssl/x509.h new file mode 100644 index 0000000..55fe71b --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/x509.h @@ -0,0 +1,23 @@ +/* x509.h for openssl */ + +#include +#include + +/* wolfSSL_X509_print_ex flags */ +#define X509_FLAG_COMPAT (0UL) +#define X509_FLAG_NO_HEADER (1UL << 0) +#define X509_FLAG_NO_VERSION (1UL << 1) +#define X509_FLAG_NO_SERIAL (1UL << 2) +#define X509_FLAG_NO_SIGNAME (1UL << 3) +#define X509_FLAG_NO_ISSUER (1UL << 4) +#define X509_FLAG_NO_VALIDITY (1UL << 5) +#define X509_FLAG_NO_SUBJECT (1UL << 6) +#define X509_FLAG_NO_PUBKEY (1UL << 7) +#define X509_FLAG_NO_EXTENSIONS (1UL << 8) +#define X509_FLAG_NO_SIGDUMP (1UL << 9) +#define X509_FLAG_NO_AUX (1UL << 10) +#define X509_FLAG_NO_ATTRIBUTES (1UL << 11) +#define X509_FLAG_NO_IDS (1UL << 12) + +#define XN_FLAG_FN_SN 0 +#define XN_FLAG_SEP_CPLUS_SPC 2 diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/x509_vfy.h b/wolfssl_hlavickove_subory/wolfssl/openssl/x509_vfy.h new file mode 100644 index 0000000..54afb67 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/x509_vfy.h @@ -0,0 +1 @@ +/* x509_vfy.h for openssl */ diff --git a/wolfssl_hlavickove_subory/wolfssl/openssl/x509v3.h b/wolfssl_hlavickove_subory/wolfssl/openssl/x509v3.h new file mode 100644 index 0000000..e287834 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/openssl/x509v3.h @@ -0,0 +1,116 @@ +/* x509v3.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* x509v3.h for openSSL */ + +#ifndef WOLFSSL_x509v3_H +#define WOLFSSL_x509v3_H + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#define X509_PURPOSE_SSL_CLIENT 0 +#define X509_PURPOSE_SSL_SERVER 1 + +#define NS_SSL_CLIENT 0 +#define NS_SSL_SERVER 1 + +/* Forward reference */ + +typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long); +typedef STACK_OF(CONF_VALUE) *(*X509V3_EXT_I2V) ( + struct WOLFSSL_v3_ext_method *method, + void *ext, STACK_OF(CONF_VALUE) *extlist); +typedef char *(*X509V3_EXT_I2S)(struct WOLFSSL_v3_ext_method *method, void *ext); +typedef int (*X509V3_EXT_I2R) (struct WOLFSSL_v3_ext_method *method, + void *ext, BIO *out, int indent); +typedef struct WOLFSSL_v3_ext_method X509V3_EXT_METHOD; + +struct WOLFSSL_v3_ext_method { + int ext_nid; + int ext_flags; + void *usr_data; + X509V3_EXT_D2I d2i; + X509V3_EXT_I2V i2v; + X509V3_EXT_I2S i2s; + X509V3_EXT_I2R i2r; +}; + +struct WOLFSSL_X509_EXTENSION { + WOLFSSL_ASN1_OBJECT *obj; + WOLFSSL_ASN1_BOOLEAN crit; + WOLFSSL_ASN1_STRING value; + WOLFSSL_v3_ext_method ext_method; + WOLFSSL_STACK* ext_sk; /* For extension specific data */ +}; + +#define WOLFSSL_ASN1_BOOLEAN int +#define GEN_OTHERNAME 0 +#define GEN_EMAIL 1 +#define GEN_DNS 2 +#define GEN_X400 3 +#define GEN_DIRNAME 4 +#define GEN_EDIPARTY 5 +#define GEN_URI 6 +#define GEN_IPADD 7 +#define GEN_RID 8 + +#define GENERAL_NAME WOLFSSL_GENERAL_NAME + +#define X509V3_CTX WOLFSSL_X509V3_CTX + +typedef struct WOLFSSL_AUTHORITY_KEYID AUTHORITY_KEYID; +typedef struct WOLFSSL_BASIC_CONSTRAINTS BASIC_CONSTRAINTS; +typedef struct WOLFSSL_ACCESS_DESCRIPTION ACCESS_DESCRIPTION; +typedef WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION) WOLFSSL_AUTHORITY_INFO_ACCESS; + +WOLFSSL_API void wolfSSL_BASIC_CONSTRAINTS_free(WOLFSSL_BASIC_CONSTRAINTS *bc); +WOLFSSL_API void wolfSSL_AUTHORITY_KEYID_free(WOLFSSL_AUTHORITY_KEYID *id); +WOLFSSL_API const WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get( + WOLFSSL_X509_EXTENSION* ex); +WOLFSSL_API void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ex); +WOLFSSL_API char* wolfSSL_i2s_ASN1_STRING(WOLFSSL_v3_ext_method *method, + const WOLFSSL_ASN1_STRING *s); +WOLFSSL_API int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, + WOLFSSL_X509_EXTENSION *ext, unsigned long flag, int indent); + +#define BASIC_CONSTRAINTS_free wolfSSL_BASIC_CONSTRAINTS_free +#define AUTHORITY_KEYID_free wolfSSL_AUTHORITY_KEYID_free +#define SSL_CTX_get_cert_store(x) wolfSSL_CTX_get_cert_store ((WOLFSSL_CTX*) (x)) +#define ASN1_INTEGER WOLFSSL_ASN1_INTEGER +#define ASN1_OCTET_STRING WOLFSSL_ASN1_STRING +#define X509V3_EXT_get wolfSSL_X509V3_EXT_get +#define X509V3_EXT_d2i wolfSSL_X509V3_EXT_d2i +#define i2s_ASN1_OCTET_STRING wolfSSL_i2s_ASN1_STRING +#define X509V3_EXT_print wolfSSL_X509V3_EXT_print +#define X509V3_EXT_conf_nid wolfSSL_X509V3_EXT_conf_nid +#define X509V3_set_ctx wolfSSL_X509V3_set_ctx +#define X509V3_set_ctx_nodb wolfSSL_X509V3_set_ctx_nodb + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/wolfssl_hlavickove_subory/wolfssl/options.h b/wolfssl_hlavickove_subory/wolfssl/options.h new file mode 100644 index 0000000..fd1bea0 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/options.h @@ -0,0 +1,290 @@ +/* options.h.in + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +/* default blank options for autoconf */ + +#ifndef WOLFSSL_OPTIONS_H +#define WOLFSSL_OPTIONS_H + +#undef HAVE_FFDHE_2048 +#define HAVE_FFDHE_2048 + +#undef WOLFSSL_VERIFY_CB_ALL_CERTS +#define WOLFSSL_VERIFY_CB_ALL_CERTS + +#undef WOLFSSL_EXTRA_ALERTS +#define WOLFSSL_EXTRA_ALERTS + +#undef OPENSSL_EXTRA +#define OPENSSL_EXTRA + +#undef WOLFSSL_ALWAYS_VERIFY_CB +#define WOLFSSL_ALWAYS_VERIFY_CB + +#ifndef WOLFSSL_OPTIONS_IGNORE_SYS +#undef _POSIX_THREADS +#define _POSIX_THREADS +#endif + +#undef HAVE_THREAD_LS +#define HAVE_THREAD_LS + +#undef TFM_TIMING_RESISTANT +#define TFM_TIMING_RESISTANT + +#undef ECC_TIMING_RESISTANT +#define ECC_TIMING_RESISTANT + +#undef WC_RSA_BLINDING +#define WC_RSA_BLINDING + +#undef HAVE_AESGCM +#define HAVE_AESGCM + +#undef WOLFSSL_SHA512 +#define WOLFSSL_SHA512 + +#undef WOLFSSL_SHA384 +#define WOLFSSL_SHA384 + +#undef WOLFSSL_KEY_GEN +#define WOLFSSL_KEY_GEN + +#undef WOLFSSL_CERT_GEN +#define WOLFSSL_CERT_GEN + +#undef WOLFSSL_CERT_REQ +#define WOLFSSL_CERT_REQ + +#undef NO_DSA +#define NO_DSA + +#undef TFM_ECC256 +#define TFM_ECC256 + +#undef ECC_SHAMIR +#define ECC_SHAMIR + +#undef WOLFSSL_BASE64_ENCODE +#define WOLFSSL_BASE64_ENCODE + +#undef NO_RC4 +#define NO_RC4 + +#undef NO_HC128 +#define NO_HC128 + +#undef NO_RABBIT +#define NO_RABBIT + +#undef WOLFSSL_SHA224 +#define WOLFSSL_SHA224 + +#undef WOLFSSL_SHA3 +#define WOLFSSL_SHA3 + +#undef HAVE_POLY1305 +#define HAVE_POLY1305 + +#undef HAVE_ONE_TIME_AUTH +#define HAVE_ONE_TIME_AUTH + +#undef HAVE_CHACHA +#define HAVE_CHACHA + +#undef HAVE_HASHDRBG +#define HAVE_HASHDRBG + +#undef HAVE_TLS_EXTENSIONS +#define HAVE_TLS_EXTENSIONS + +#undef HAVE_SUPPORTED_CURVES +#define HAVE_SUPPORTED_CURVES + +#undef HAVE_EXTENDED_MASTER +#define HAVE_EXTENDED_MASTER + +#undef HAVE_ENCRYPT_THEN_MAC +#define HAVE_ENCRYPT_THEN_MAC + +#undef NO_PSK +#define NO_PSK + +#undef NO_MD4 +#define NO_MD4 + +#undef WOLFSSL_ENCRYPTED_KEYS +#define WOLFSSL_ENCRYPTED_KEYS + +#undef USE_FAST_MATH +#define USE_FAST_MATH + +#undef WOLFSSL_X86_64_BUILD +#define WOLFSSL_X86_64_BUILD + +#undef WC_NO_ASYNC_THREADING +#define WC_NO_ASYNC_THREADING + +#undef NO_DES3 +#define NO_DES3 + +#undef HAVE___UINT128_T +#define HAVE___UINT128_T 1#undef HAVE_FFDHE_2048 +#define HAVE_FFDHE_2048 + +#undef WOLFSSL_VERIFY_CB_ALL_CERTS +#define WOLFSSL_VERIFY_CB_ALL_CERTS + +#undef WOLFSSL_EXTRA_ALERTS +#define WOLFSSL_EXTRA_ALERTS + +#undef OPENSSL_EXTRA +#define OPENSSL_EXTRA + +#undef WOLFSSL_ALWAYS_VERIFY_CB +#define WOLFSSL_ALWAYS_VERIFY_CB + +#ifndef WOLFSSL_OPTIONS_IGNORE_SYS +#undef _POSIX_THREADS +#define _POSIX_THREADS +#endif + +#undef HAVE_THREAD_LS +#define HAVE_THREAD_LS + +#undef TFM_TIMING_RESISTANT +#define TFM_TIMING_RESISTANT + +#undef ECC_TIMING_RESISTANT +#define ECC_TIMING_RESISTANT + +#undef WC_RSA_BLINDING +#define WC_RSA_BLINDING + +#undef HAVE_AESGCM +#define HAVE_AESGCM + +#undef WOLFSSL_SHA512 +#define WOLFSSL_SHA512 + +#undef WOLFSSL_SHA384 +#define WOLFSSL_SHA384 + +#undef WOLFSSL_KEY_GEN +#define WOLFSSL_KEY_GEN + +#undef WOLFSSL_CERT_GEN +#define WOLFSSL_CERT_GEN + +#undef WOLFSSL_CERT_REQ +#define WOLFSSL_CERT_REQ + +#undef NO_DSA +#define NO_DSA + +#undef HAVE_ECC +#define HAVE_ECC + +#undef TFM_ECC256 +#define TFM_ECC256 + +#undef ECC_SHAMIR +#define ECC_SHAMIR + +#undef WOLFSSL_BASE64_ENCODE +#define WOLFSSL_BASE64_ENCODE + +#undef NO_RC4 +#define NO_RC4 + +#undef NO_HC128 +#define NO_HC128 + +#undef NO_RABBIT +#define NO_RABBIT + +#undef WOLFSSL_SHA224 +#define WOLFSSL_SHA224 + +#undef WOLFSSL_SHA3 +#define WOLFSSL_SHA3 + +#undef HAVE_POLY1305 +#define HAVE_POLY1305 + +#undef HAVE_ONE_TIME_AUTH +#define HAVE_ONE_TIME_AUTH + +#undef HAVE_CHACHA +#define HAVE_CHACHA + +#undef HAVE_HASHDRBG +#define HAVE_HASHDRBG + +#undef HAVE_TLS_EXTENSIONS +#define HAVE_TLS_EXTENSIONS + +#undef HAVE_SUPPORTED_CURVES +#define HAVE_SUPPORTED_CURVES + +#undef HAVE_EXTENDED_MASTER +#define HAVE_EXTENDED_MASTER + +#undef HAVE_ENCRYPT_THEN_MAC +#define HAVE_ENCRYPT_THEN_MAC + +#undef NO_PSK +#define NO_PSK + +#undef NO_MD4 +#define NO_MD4 + +#undef WOLFSSL_ENCRYPTED_KEYS +#define WOLFSSL_ENCRYPTED_KEYS + +#undef USE_FAST_MATH +#define USE_FAST_MATH + +#undef WOLFSSL_X86_64_BUILD +#define WOLFSSL_X86_64_BUILD + +#undef WC_NO_ASYNC_THREADING +#define WC_NO_ASYNC_THREADING + +#undef NO_DES3 +#define NO_DES3 + +#undef HAVE___UINT128_T +#define HAVE___UINT128_T + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + + +#endif /* WOLFSSL_OPTIONS_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/sniffer.h b/wolfssl_hlavickove_subory/wolfssl/sniffer.h new file mode 100644 index 0000000..6d6e155 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/sniffer.h @@ -0,0 +1,228 @@ +/* sniffer.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +#ifndef WOLFSSL_SNIFFER_H +#define WOLFSSL_SNIFFER_H + +#include + +#ifdef _WIN32 + #ifdef SSL_SNIFFER_EXPORTS + #define SSL_SNIFFER_API __declspec(dllexport) + #else + #define SSL_SNIFFER_API __declspec(dllimport) + #endif +#else + #define SSL_SNIFFER_API +#endif /* _WIN32 */ + + +#ifdef __cplusplus + extern "C" { +#endif + +/* @param typeK: (formerly keyType) was shadowing a global declaration in + * wolfssl/wolfcrypt/asn.h line 175 + */ +WOLFSSL_API +SSL_SNIFFER_API int ssl_SetPrivateKey(const char* address, int port, + const char* keyFile, int typeK, + const char* password, char* error); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_SetNamedPrivateKey(const char* name, + const char* address, int port, + const char* keyFile, int typeK, + const char* password, char* error); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_DecodePacket(const unsigned char* packet, int length, + unsigned char** data, char* error); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_FreeDecodeBuffer(unsigned char** data, char* error); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_FreeZeroDecodeBuffer(unsigned char** data, int sz, + char* error); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_Trace(const char* traceFile, char* error); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_EnableRecovery(int onOff, int maxMemory, char* error); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_GetSessionStats(unsigned int* active, + unsigned int* total, + unsigned int* peak, + unsigned int* maxSessions, + unsigned int* missedData, + unsigned int* reassemblyMemory, + char* error); + +WOLFSSL_API void ssl_InitSniffer(void); + +WOLFSSL_API void ssl_FreeSniffer(void); + + +/* ssl_SetPrivateKey typeKs */ +enum { + FILETYPE_PEM = 1, + FILETYPE_DER = 2, +}; + + +/* + * New Sniffer API that provides read-only access to the TLS and cipher + * information associated with the SSL session. + */ + +#if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) + #define WOLFSSL_PACK __attribute__ ((packed)) +#else + #define WOLFSSL_PACK +#endif + + +typedef struct SSLInfo +{ + unsigned char isValid; + /* indicates if the info in this struct is valid: 0 = no, 1 = yes */ + unsigned char protocolVersionMajor; /* SSL Version: major */ + unsigned char protocolVersionMinor; /* SSL Version: minor */ + unsigned char serverCipherSuite0; /* first byte, normally 0 */ + unsigned char serverCipherSuite; /* second byte, actual suite */ + unsigned char serverCipherSuiteName[256]; + /* cipher name, e.g., "TLS_RSA_..." */ + unsigned char serverNameIndication[128]; + unsigned int keySize; +} WOLFSSL_PACK SSLInfo; + + +WOLFSSL_API +SSL_SNIFFER_API int ssl_DecodePacketWithSessionInfo( + const unsigned char* packet, int length, + unsigned char** data, SSLInfo* sslInfo, char* error); + +typedef void (*SSLConnCb)(const void* session, SSLInfo* info, void* ctx); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_SetConnectionCb(SSLConnCb cb); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_SetConnectionCtx(void* ctx); + + +typedef struct SSLStats +{ + unsigned long int sslStandardConns; + unsigned long int sslClientAuthConns; + unsigned long int sslResumedConns; + unsigned long int sslEphemeralMisses; + unsigned long int sslResumeMisses; + unsigned long int sslCiphersUnsupported; + unsigned long int sslKeysUnmatched; + unsigned long int sslKeyFails; + unsigned long int sslDecodeFails; + unsigned long int sslAlerts; + unsigned long int sslDecryptedBytes; + unsigned long int sslEncryptedBytes; + unsigned long int sslEncryptedPackets; + unsigned long int sslDecryptedPackets; + unsigned long int sslKeyMatches; + unsigned long int sslEncryptedConns; + + unsigned long int sslResumptionValid; + unsigned long int sslResumptionInserts; +} SSLStats; + + +WOLFSSL_API +SSL_SNIFFER_API int ssl_ResetStatistics(void); + + +WOLFSSL_API +SSL_SNIFFER_API int ssl_ReadStatistics(SSLStats* stats); + + +WOLFSSL_API +SSL_SNIFFER_API int ssl_ReadResetStatistics(SSLStats* stats); + + +typedef int (*SSLWatchCb)(void* vSniffer, + const unsigned char* certHash, + unsigned int certHashSz, + const unsigned char* certChain, + unsigned int certChainSz, + void* ctx, char* error); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_SetWatchKeyCallback(SSLWatchCb cb, char* error); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_SetWatchKeyCallback_ex(SSLWatchCb cb, int devId, + char* error); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_SetWatchKeyCtx(void* ctx, char* error); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_SetWatchKey_buffer(void* vSniffer, + const unsigned char* key, unsigned int keySz, + int keyType, char* error); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_SetWatchKey_file(void* vSniffer, + const char* keyFile, int keyType, + const char* password, char* error); + + +typedef int (*SSLStoreDataCb)(const unsigned char* decryptBuf, + unsigned int decryptBufSz, unsigned int decryptBufOffset, void* ctx); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_SetStoreDataCallback(SSLStoreDataCb cb); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_DecodePacketWithSessionInfoStoreData( + const unsigned char* packet, int length, void* ctx, + SSLInfo* sslInfo, char* error); + + +WOLFSSL_API +SSL_SNIFFER_API int ssl_DecodePacketWithChain(void* vChain, + unsigned int chainSz, unsigned char** data, char* error); + + +WOLFSSL_API +SSL_SNIFFER_API int ssl_DecodePacketWithChainSessionInfoStoreData( + void* vChain, unsigned int chainSz, void* ctx, SSLInfo* sslInfo, + char* error); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* wolfSSL_SNIFFER_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/sniffer_error.h b/wolfssl_hlavickove_subory/wolfssl/sniffer_error.h new file mode 100644 index 0000000..a63e1d0 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/sniffer_error.h @@ -0,0 +1,137 @@ +/* sniffer_error.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +#ifndef WOLFSSL_SNIFFER_ERROR_H +#define WOLFSSL_SNIFFER_ERROR_H + +/* need to have errors as #defines since .rc files can't handle enums */ +/* need to start at 1 and go in order for same reason */ + +#define MEMORY_STR 1 +#define NEW_SERVER_STR 2 +#define IP_CHECK_STR 3 +#define SERVER_NOT_REG_STR 4 +#define TCP_CHECK_STR 5 +#define SERVER_PORT_NOT_REG_STR 6 +#define RSA_DECRYPT_STR 7 +#define RSA_DECODE_STR 8 +#define BAD_CIPHER_SPEC_STR 9 +#define SERVER_HELLO_INPUT_STR 10 + +#define BAD_SESSION_RESUME_STR 11 +#define SERVER_DID_RESUMPTION_STR 12 +#define CLIENT_HELLO_INPUT_STR 13 +#define CLIENT_RESUME_TRY_STR 14 +#define HANDSHAKE_INPUT_STR 15 +#define GOT_HELLO_VERIFY_STR 16 +#define GOT_SERVER_HELLO_STR 17 +#define GOT_CERT_REQ_STR 18 +#define GOT_SERVER_KEY_EX_STR 19 +#define GOT_CERT_STR 20 + +#define GOT_SERVER_HELLO_DONE_STR 21 +#define GOT_FINISHED_STR 22 +#define GOT_CLIENT_HELLO_STR 23 +#define GOT_CLIENT_KEY_EX_STR 24 +#define GOT_CERT_VER_STR 25 +#define GOT_UNKNOWN_HANDSHAKE_STR 26 +#define NEW_SESSION_STR 27 +#define BAD_NEW_SSL_STR 28 +#define GOT_PACKET_STR 29 +#define NO_DATA_STR 30 + +#define BAD_SESSION_STR 31 +#define GOT_OLD_CLIENT_HELLO_STR 32 +#define OLD_CLIENT_INPUT_STR 33 +#define OLD_CLIENT_OK_STR 34 +#define BAD_OLD_CLIENT_STR 35 +#define BAD_RECORD_HDR_STR 36 +#define RECORD_INPUT_STR 37 +#define GOT_HANDSHAKE_STR 38 +#define BAD_HANDSHAKE_STR 39 +#define GOT_CHANGE_CIPHER_STR 40 + +#define GOT_APP_DATA_STR 41 +#define BAD_APP_DATA_STR 42 +#define GOT_ALERT_STR 43 +#define ANOTHER_MSG_STR 44 +#define REMOVE_SESSION_STR 45 +#define KEY_FILE_STR 46 +#define BAD_IPVER_STR 47 +#define BAD_PROTO_STR 48 +#define PACKET_HDR_SHORT_STR 49 +#define GOT_UNKNOWN_RECORD_STR 50 + +#define BAD_TRACE_FILE_STR 51 +#define FATAL_ERROR_STR 52 +#define PARTIAL_INPUT_STR 53 +#define BUFFER_ERROR_STR 54 +#define PARTIAL_ADD_STR 55 +#define DUPLICATE_STR 56 +#define OUT_OF_ORDER_STR 57 +#define OVERLAP_DUPLICATE_STR 58 +#define OVERLAP_REASSEMBLY_BEGIN_STR 59 +#define OVERLAP_REASSEMBLY_END_STR 60 + +#define MISSED_CLIENT_HELLO_STR 61 +#define GOT_HELLO_REQUEST_STR 62 +#define GOT_SESSION_TICKET_STR 63 +#define BAD_INPUT_STR 64 +#define BAD_DECRYPT_TYPE 65 +#define BAD_FINISHED_MSG 66 +#define BAD_COMPRESSION_STR 67 +#define BAD_DERIVE_STR 68 +#define ACK_MISSED_STR 69 +#define BAD_DECRYPT 70 + +#define DECRYPT_KEYS_NOT_SETUP 71 +#define CLIENT_HELLO_LATE_KEY_STR 72 +#define GOT_CERT_STATUS_STR 73 +#define RSA_KEY_MISSING_STR 74 +#define NO_SECURE_RENEGOTIATION 75 + +#define BAD_SESSION_STATS 76 +#define REASSEMBLY_MAX_STR 77 +#define DROPPING_LOST_FRAG_STR 78 +#define DROPPING_PARTIAL_RECORD 79 +#define CLEAR_ACK_FAULT 80 + +#define BAD_DECRYPT_SIZE 81 +#define EXTENDED_MASTER_HASH_STR 82 +#define SPLIT_HANDSHAKE_MSG_STR 83 +#define ECC_DECODE_STR 84 +#define ECC_PUB_DECODE_STR 85 +#define WATCH_CB_MISSING_STR 86 +#define WATCH_HASH_STR 87 +#define WATCH_FAIL_STR 88 +#define BAD_CERT_MSG_STR 89 +#define STORE_DATA_CB_MISSING_STR 90 + +#define NO_DATA_DEST_STR 91 +#define STORE_DATA_FAIL_STR 92 +#define CHAIN_INPUT_STR 93 +/* !!!! also add to msgTable in sniffer.c and .rc file !!!! */ + + +#endif /* wolfSSL_SNIFFER_ERROR_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/sniffer_error.rc b/wolfssl_hlavickove_subory/wolfssl/sniffer_error.rc new file mode 100644 index 0000000..72fe36e --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/sniffer_error.rc @@ -0,0 +1,116 @@ + +STRINGTABLE +{ + 1, "Out of Memory" + 2, "New SSL Sniffer Server Registered" + 3, "Checking IP Header" + 4, "SSL Sniffer Server Not Registered" + 5, "Checking TCP Header" + + 6, "SSL Sniffer Server Port Not Registered" + 7, "RSA Private Decrypt Error" + 8, "RSA Private Decode Error" + 9, "Set Cipher Spec Error" + 10, "Server Hello Input Malformed" + + 11, "Couldn't Resume Session Error" + 12, "Server Did Resumption" + 13, "Client Hello Input Malformed" + 14, "Client Trying to Resume" + 15, "Handshake Input Malformed" + + 16, "Got Hello Verify msg" + 17, "Got Server Hello msg" + 18, "Got Cert Request msg" + 19, "Got Server Key Exchange msg" + 20, "Got Cert msg" + + 21, "Got Server Hello Done msg" + 22, "Got Finished msg" + 23, "Got Client Hello msg" + 24, "Got Client Key Exchange msg" + 25, "Got Cert Verify msg" + + 26, "Got Unknown Handshake msg" + 27, "New SSL Sniffer Session created" + 28, "Couldn't create new SSL" + 29, "Got a Packet to decode" + 30, "No data present" + + 31, "Session Not Found" + 32, "Got an Old Client Hello msg" + 33, "Old Client Hello Input Malformed" + 34, "Old Client Hello OK" + 35, "Bad Old Client Hello" + + 36, "Bad Record Header" + 37, "Record Header Input Malformed" + 38, "Got a HandShake msg" + 39, "Bad HandShake msg" + 40, "Got a Change Cipher Spec msg" + + 41, "Got Application Data msg" + 42, "Bad Application Data" + 43, "Got an Alert msg" + 44, "Another msg to Process" + 45, "Removing Session From Table" + + 46, "Bad Key File" + 47, "Wrong IP Version" + 48, "Wrong Protocol type" + 49, "Packet Short for header processing" + 50, "Got Unknown Record Type" + + 51, "Can't Open Trace File" + 52, "Session in Fatal Error State" + 53, "Partial SSL record received" + 54, "Buffer Error, malformed input" + 55, "Added to Partial Input" + + 56, "Received a Duplicate Packet" + 57, "Received an Out of Order Packet" + 58, "Received an Overlap Duplicate Packet" + 59, "Received an Overlap Reassembly Begin Duplicate Packet" + 60, "Received an Overlap Reassembly End Duplicate Packet" + + 61, "Missed the Client Hello Entirely" + 62, "Got Hello Request msg" + 63, "Got Session Ticket msg" + 64, "Bad Input" + 65, "Bad Decrypt Type" + + 66, "Bad Finished Message Processing" + 67, "Bad Compression Type" + 68, "Bad DeriveKeys Error" + 69, "Saw ACK for Missing Packet Error" + 70, "Bad Decrypt Operation" + + 71, "Decrypt Keys Not Set Up" + 72, "Late Key Load Error" + 73, "Got Certificate Status msg" + 74, "RSA Key Missing Error" + 75, "Secure Renegotiation Not Supported" + + 76, "Get Session Stats Failure" + 77, "Reassembly Buffer Size Exceeded" + 78, "Dropping Lost Fragment" + 79, "Dropping Partial Record" + 80, "Clear ACK Fault" + + 81, "Bad Decrypt Size" + 82, "Extended Master Secret Hash Error" + 83, "Handshake Message Split Across TLS Records" + 84, "ECC Private Decode Error" + 85, "ECC Public Decode Error" + + 86, "Watch callback not set" + 87, "Watch hash failed" + 88, "Watch callback failed" + 89, "Bad Certificate Message" + 90, "Store data callback not set" + + 91, "No data destination Error" + 92, "Store Data callback failed" + 93, "Loading chain input" +} + diff --git a/wolfssl_hlavickove_subory/wolfssl/ssl.h b/wolfssl_hlavickove_subory/wolfssl/ssl.h new file mode 100644 index 0000000..f923276 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/ssl.h @@ -0,0 +1,3692 @@ +/* ssl.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ +/*! + \file ../wolfssl/ssl.h + \brief Header file containing key wolfSSL API +*/ + +/* wolfSSL API */ + +#ifndef WOLFSSL_SSL_H +#define WOLFSSL_SSL_H + + +/* for users not using preprocessor flags*/ +#include +#include +#include +#include + +#ifdef HAVE_WOLF_EVENT + #include +#endif + +/* used internally by wolfSSL while OpenSSL types aren't */ +#include + +#ifdef WOLFSSL_PREFIX + #include "prefix_ssl.h" +#endif + +#ifdef LIBWOLFSSL_VERSION_STRING + #define WOLFSSL_VERSION LIBWOLFSSL_VERSION_STRING +#endif + +#ifdef _WIN32 + /* wincrypt.h clashes */ + #undef OCSP_REQUEST + #undef OCSP_RESPONSE +#endif + +#ifdef OPENSSL_COEXIST + /* mode to allow wolfSSL and OpenSSL to exist together */ + #ifdef TEST_OPENSSL_COEXIST + /* + ./configure --enable-opensslcoexist \ + CFLAGS="-I/usr/local/opt/openssl/include -DTEST_OPENSSL_COEXIST" \ + LDFLAGS="-L/usr/local/opt/openssl/lib -lcrypto" + */ + #include + #include + #include + #include + #include + #include + #endif + + /* make sure old names are disabled */ + #ifndef NO_OLD_SSL_NAMES + #define NO_OLD_SSL_NAMES + #endif + #ifndef NO_OLD_WC_NAMES + #define NO_OLD_WC_NAMES + #endif + +#elif (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) + #include + #include + + /* We need the old SSL names */ + #ifdef NO_OLD_SSL_NAMES + #undef NO_OLD_SSL_NAMES + #endif + #ifdef NO_OLD_WC_NAMES + #undef NO_OLD_WC_NAMES + #endif +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef WOLFSSL_WOLFSSL_TYPE_DEFINED +#define WOLFSSL_WOLFSSL_TYPE_DEFINED +typedef struct WOLFSSL WOLFSSL; +#endif +typedef struct WOLFSSL_SESSION WOLFSSL_SESSION; +typedef struct WOLFSSL_METHOD WOLFSSL_METHOD; +#ifndef WOLFSSL_WOLFSSL_CTX_TYPE_DEFINED +#define WOLFSSL_WOLFSSL_CTX_TYPE_DEFINED +typedef struct WOLFSSL_CTX WOLFSSL_CTX; +#endif + +typedef struct WOLFSSL_STACK WOLFSSL_STACK; +typedef struct WOLFSSL_X509 WOLFSSL_X509; +typedef struct WOLFSSL_X509_NAME WOLFSSL_X509_NAME; +typedef struct WOLFSSL_X509_NAME_ENTRY WOLFSSL_X509_NAME_ENTRY; +typedef struct WOLFSSL_X509_PUBKEY WOLFSSL_X509_PUBKEY; +typedef struct WOLFSSL_X509_ALGOR WOLFSSL_X509_ALGOR; +typedef struct WOLFSSL_X509_CHAIN WOLFSSL_X509_CHAIN; +typedef struct WC_PKCS12 WOLFSSL_X509_PKCS12; +typedef struct WOLFSSL_X509_INFO WOLFSSL_X509_INFO; + +typedef struct WOLFSSL_CERT_MANAGER WOLFSSL_CERT_MANAGER; +typedef struct WOLFSSL_SOCKADDR WOLFSSL_SOCKADDR; +typedef struct WOLFSSL_CRL WOLFSSL_CRL; + +typedef void *WOLFSSL_X509_STORE_CTX_verify_cb; /* verify callback */ + +/* redeclare guard */ +#define WOLFSSL_TYPES_DEFINED + +#include + + +#ifndef WOLFSSL_RSA_TYPE_DEFINED /* guard on redeclaration */ +typedef struct WOLFSSL_RSA WOLFSSL_RSA; +#define WOLFSSL_RSA_TYPE_DEFINED +#endif + +#ifndef WC_RNG_TYPE_DEFINED /* guard on redeclaration */ + typedef struct WC_RNG WC_RNG; + #define WC_RNG_TYPE_DEFINED +#endif + +#ifndef WOLFSSL_DSA_TYPE_DEFINED /* guard on redeclaration */ +typedef struct WOLFSSL_DSA WOLFSSL_DSA; +#define WOLFSSL_DSA_TYPE_DEFINED +#endif + +#ifndef WOLFSSL_EC_TYPE_DEFINED /* guard on redeclaration */ +typedef struct WOLFSSL_EC_KEY WOLFSSL_EC_KEY; +typedef struct WOLFSSL_EC_POINT WOLFSSL_EC_POINT; +typedef struct WOLFSSL_EC_GROUP WOLFSSL_EC_GROUP; +#define WOLFSSL_EC_TYPE_DEFINED +#endif + +#ifndef WOLFSSL_ECDSA_TYPE_DEFINED /* guard on redeclaration */ +typedef struct WOLFSSL_ECDSA_SIG WOLFSSL_ECDSA_SIG; +#define WOLFSSL_ECDSA_TYPE_DEFINED +#endif + +typedef struct WOLFSSL_CIPHER WOLFSSL_CIPHER; +typedef struct WOLFSSL_X509_LOOKUP WOLFSSL_X509_LOOKUP; +typedef struct WOLFSSL_X509_LOOKUP_METHOD WOLFSSL_X509_LOOKUP_METHOD; +typedef struct WOLFSSL_CRL WOLFSSL_X509_CRL; +typedef struct WOLFSSL_X509_STORE WOLFSSL_X509_STORE; +typedef struct WOLFSSL_X509_VERIFY_PARAM WOLFSSL_X509_VERIFY_PARAM; +typedef struct WOLFSSL_BIO WOLFSSL_BIO; +typedef struct WOLFSSL_BIO_METHOD WOLFSSL_BIO_METHOD; +typedef struct WOLFSSL_X509_EXTENSION WOLFSSL_X509_EXTENSION; +typedef struct WOLFSSL_CONF_VALUE WOLFSSL_CONF_VALUE; +typedef struct WOLFSSL_ASN1_OBJECT WOLFSSL_ASN1_OBJECT; +typedef struct WOLFSSL_ASN1_OTHERNAME WOLFSSL_ASN1_OTHERNAME; +typedef struct WOLFSSL_X509V3_CTX WOLFSSL_X509V3_CTX; +typedef struct WOLFSSL_v3_ext_method WOLFSSL_v3_ext_method; + +typedef struct WOLFSSL_ASN1_STRING WOLFSSL_ASN1_STRING; +typedef struct WOLFSSL_dynlock_value WOLFSSL_dynlock_value; +typedef struct WOLFSSL_DH WOLFSSL_DH; +typedef struct WOLFSSL_ASN1_BIT_STRING WOLFSSL_ASN1_BIT_STRING; +typedef struct WOLFSSL_ASN1_TYPE WOLFSSL_ASN1_TYPE; + +typedef struct WOLFSSL_GENERAL_NAME WOLFSSL_GENERAL_NAME; +typedef struct WOLFSSL_AUTHORITY_KEYID WOLFSSL_AUTHORITY_KEYID; +typedef struct WOLFSSL_BASIC_CONSTRAINTS WOLFSSL_BASIC_CONSTRAINTS; +typedef struct WOLFSSL_ACCESS_DESCRIPTION WOLFSSL_ACCESS_DESCRIPTION; + +#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) + +struct WOLFSSL_AUTHORITY_KEYID { + WOLFSSL_ASN1_STRING *keyid; + WOLFSSL_ASN1_OBJECT *issuer; + WOLFSSL_ASN1_INTEGER *serial; +}; + +struct WOLFSSL_BASIC_CONSTRAINTS { + int ca; + WOLFSSL_ASN1_INTEGER *pathlen; +}; + +#endif /* OPENSSL_ALL || OPENSSL_EXTRA*/ + +#define WOLFSSL_ASN1_UTCTIME WOLFSSL_ASN1_TIME +#define WOLFSSL_ASN1_GENERALIZEDTIME WOLFSSL_ASN1_TIME + +struct WOLFSSL_ASN1_STRING { + char strData[CTC_NAME_SIZE]; + int length; + int type; /* type of string i.e. CTC_UTF8 */ + char* data; + long flags; + unsigned int isDynamic:1; /* flag for if data pointer dynamic (1 is yes 0 is no) */ +}; + +#define WOLFSSL_MAX_SNAME 40 + +#if defined(HAVE_EX_DATA) || defined(FORTRESS) + #define MAX_EX_DATA 5 /* allow for five items of ex_data */ +#endif + + +#define WOLFSSL_ASN1_DYNAMIC 0x1 +#define WOLFSSL_ASN1_DYNAMIC_DATA 0x2 + +struct WOLFSSL_ASN1_OTHERNAME { + WOLFSSL_ASN1_OBJECT* type_id; + WOLFSSL_ASN1_TYPE* value; +}; + +struct WOLFSSL_GENERAL_NAME { + int type; + union { + char* ptr; + WOLFSSL_ASN1_OTHERNAME* otherName; + WOLFSSL_ASN1_STRING* rfc822Name; + WOLFSSL_ASN1_STRING* dNSName; + WOLFSSL_ASN1_TYPE* x400Address; + WOLFSSL_X509_NAME* directoryName; + WOLFSSL_ASN1_STRING* uniformResourceIdentifier; + WOLFSSL_ASN1_STRING* iPAddress; + WOLFSSL_ASN1_OBJECT* registeredID; + + WOLFSSL_ASN1_STRING* ip; + WOLFSSL_X509_NAME* dirn; + WOLFSSL_ASN1_STRING* ia5; + WOLFSSL_ASN1_OBJECT* rid; + WOLFSSL_ASN1_TYPE* other; + } d; /* dereference */ +}; + +struct WOLFSSL_ACCESS_DESCRIPTION { + WOLFSSL_ASN1_OBJECT* method; + WOLFSSL_GENERAL_NAME* location; +}; + +struct WOLFSSL_X509V3_CTX { + WOLFSSL_X509* x509; +}; + + + +struct WOLFSSL_ASN1_OBJECT { + void* heap; + const unsigned char* obj; + /* sName is short name i.e sha256 rather than oid (null terminated) */ + char sName[WOLFSSL_MAX_SNAME]; + int type; /* oid */ + int grp; /* type of OID, i.e. oidCertPolicyType */ + int nid; + unsigned int objSz; +#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || defined(WOLFSSL_APACHE_HTTPD) + int ca; + WOLFSSL_ASN1_INTEGER *pathlen; +#endif + unsigned char dynamic; /* if 1 then obj was dynamically created, 0 otherwise */ + +#if defined(WOLFSSL_APACHE_HTTPD) + WOLFSSL_GENERAL_NAME* gn; +#endif + + struct d { /* derefrenced */ + WOLFSSL_ASN1_STRING* dNSName; + WOLFSSL_ASN1_STRING ia5_internal; + WOLFSSL_ASN1_STRING* ia5; /* points to ia5_internal */ +#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) + WOLFSSL_ASN1_STRING* uniformResourceIdentifier; + WOLFSSL_ASN1_STRING iPAddress_internal; + WOLFSSL_ASN1_OTHERNAME* otherName; /* added for Apache httpd */ +#endif + WOLFSSL_ASN1_STRING* iPAddress; /* points to iPAddress_internal */ + } d; +}; + +/* wrap ASN1 types */ +struct WOLFSSL_ASN1_TYPE { + int type; + union { + char *ptr; + WOLFSSL_ASN1_STRING* asn1_string; + WOLFSSL_ASN1_OBJECT* object; + WOLFSSL_ASN1_INTEGER* integer; + WOLFSSL_ASN1_BIT_STRING* bit_string; + WOLFSSL_ASN1_STRING* octet_string; + WOLFSSL_ASN1_STRING* printablestring; + WOLFSSL_ASN1_STRING* ia5string; + WOLFSSL_ASN1_UTCTIME* utctime; + WOLFSSL_ASN1_GENERALIZEDTIME* generalizedtime; + WOLFSSL_ASN1_STRING* utf8string; + WOLFSSL_ASN1_STRING* set; + WOLFSSL_ASN1_STRING* sequence; + } value; +}; + +struct WOLFSSL_EVP_PKEY { + void* heap; + int type; /* openssh dereference */ + int save_type; /* openssh dereference */ + int pkey_sz; + int references; /*number of times free should be called for complete free*/ + wolfSSL_Mutex refMutex; /* ref count mutex */ + + union { + char* ptr; /* der format of key / or raw for NTRU */ + } pkey; + #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) + #ifndef NO_RSA + WOLFSSL_RSA* rsa; + byte ownRsa; /* if struct owns RSA and should free it */ + #endif + #ifdef HAVE_ECC + WOLFSSL_EC_KEY* ecc; + byte ownEcc; /* if struct owns ECC and should free it */ + #endif + WC_RNG rng; + #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ + #ifdef HAVE_ECC + int pkey_curve; + #endif +}; +typedef struct WOLFSSL_EVP_PKEY WOLFSSL_PKCS8_PRIV_KEY_INFO; + +#ifndef WOLFSSL_EVP_TYPE_DEFINED /* guard on redeclaration */ +typedef struct WOLFSSL_EVP_PKEY WOLFSSL_EVP_PKEY; +typedef char WOLFSSL_EVP_MD; +#define WOLFSSL_EVP_TYPE_DEFINED +#endif + +struct WOLFSSL_X509_PKEY { + WOLFSSL_EVP_PKEY* dec_pkey; /* dereferenced by Apache */ + void* heap; +}; +typedef struct WOLFSSL_X509_PKEY WOLFSSL_X509_PKEY; + +struct WOLFSSL_X509_INFO { + WOLFSSL_X509 *x509; + WOLFSSL_X509_CRL *crl; + WOLFSSL_X509_PKEY *x_pkey; /* dereferenced by Apache */ + EncryptedInfo enc_cipher; + int enc_len; + char *enc_data; + int num; +}; + +#define WOLFSSL_EVP_PKEY_DEFAULT EVP_PKEY_RSA /* default key type */ + +struct WOLFSSL_X509_ALGOR { + WOLFSSL_ASN1_OBJECT* algorithm; +}; + +struct WOLFSSL_X509_PUBKEY { + WOLFSSL_X509_ALGOR* algor; + int pubKeyOID; +}; + + +enum BIO_TYPE { + WOLFSSL_BIO_BUFFER = 1, + WOLFSSL_BIO_SOCKET = 2, + WOLFSSL_BIO_SSL = 3, + WOLFSSL_BIO_MEMORY = 4, + WOLFSSL_BIO_BIO = 5, + WOLFSSL_BIO_FILE = 6, + WOLFSSL_BIO_BASE64 = 7 +}; + +enum BIO_FLAGS { + WOLFSSL_BIO_FLAG_BASE64_NO_NL = 0x01, + WOLFSSL_BIO_FLAG_READ = 0x02, + WOLFSSL_BIO_FLAG_WRITE = 0x04, + WOLFSSL_BIO_FLAG_IO_SPECIAL = 0x08, + WOLFSSL_BIO_FLAG_RETRY = 0x10 +}; + +enum BIO_CB_OPS { + WOLFSSL_BIO_CB_FREE = 0x01, + WOLFSSL_BIO_CB_READ = 0x02, + WOLFSSL_BIO_CB_WRITE = 0x03, + WOLFSSL_BIO_CB_PUTS = 0x04, + WOLFSSL_BIO_CB_GETS = 0x05, + WOLFSSL_BIO_CB_CTRL = 0x06, + WOLFSSL_BIO_CB_RETURN = 0x80 +}; + +typedef struct WOLFSSL_BUF_MEM { + char* data; /* dereferenced */ + size_t length; /* current length */ + size_t max; /* maximum length */ +} WOLFSSL_BUF_MEM; + +/* custom method with user set callbacks */ +typedef int (*wolfSSL_BIO_meth_write_cb)(WOLFSSL_BIO*, const char*, int); +typedef int (*wolfSSL_BIO_meth_read_cb)(WOLFSSL_BIO *, char *, int); +typedef int (*wolfSSL_BIO_meth_puts_cb)(WOLFSSL_BIO*, const char*); +typedef int (*wolfSSL_BIO_meth_gets_cb)(WOLFSSL_BIO*, char*, int); +typedef long (*wolfSSL_BIO_meth_ctrl_get_cb)(WOLFSSL_BIO*, int, long, void*); +typedef int (*wolfSSL_BIO_meth_create_cb)(WOLFSSL_BIO*); +typedef int (*wolfSSL_BIO_meth_destroy_cb)(WOLFSSL_BIO*); + +typedef int wolfSSL_BIO_info_cb(WOLFSSL_BIO *, int, int); +typedef long (*wolfssl_BIO_meth_ctrl_info_cb)(WOLFSSL_BIO*, int, wolfSSL_BIO_info_cb*); + +/* wolfSSL BIO_METHOD type */ +#ifndef MAX_BIO_METHOD_NAME +#define MAX_BIO_METHOD_NAME 256 +#endif +struct WOLFSSL_BIO_METHOD { + byte type; /* method type */ + char name[MAX_BIO_METHOD_NAME]; + wolfSSL_BIO_meth_write_cb writeCb; + wolfSSL_BIO_meth_read_cb readCb; + wolfSSL_BIO_meth_puts_cb putsCb; + wolfSSL_BIO_meth_gets_cb getsCb; + wolfSSL_BIO_meth_ctrl_get_cb ctrlCb; + wolfSSL_BIO_meth_create_cb createCb; + wolfSSL_BIO_meth_destroy_cb freeCb; + wolfssl_BIO_meth_ctrl_info_cb ctrlInfoCb; +}; + +/* wolfSSL BIO type */ +typedef long (*wolf_bio_info_cb)(WOLFSSL_BIO *bio, int event, const char *parg, + int iarg, long larg, long return_value); + +struct WOLFSSL_BIO { + WOLFSSL_BUF_MEM* mem_buf; + WOLFSSL_BIO_METHOD* method; + WOLFSSL_BIO* prev; /* previous in chain */ + WOLFSSL_BIO* next; /* next in chain */ + WOLFSSL_BIO* pair; /* BIO paired with */ + void* heap; /* user heap hint */ + void* ptr; /* WOLFSSL, file descriptor or memory buffer */ + void* usrCtx; /* user set pointer */ + char* infoArg; /* BIO callback argument */ + wolf_bio_info_cb infoCb; /* BIO callback */ + int wrSz; /* write buffer size (mem) */ + int wrIdx; /* current index for write buffer */ + int rdIdx; /* current read index */ + int readRq; /* read request */ + int num; /* socket num or length */ + int eof; /* eof flag */ + int flags; + byte type; /* method type */ + byte init:1; /* bio has been initialized */ + byte shutdown:1; /* close flag */ +}; + + +typedef struct WOLFSSL_COMP_METHOD { + int type; /* stunnel dereference */ +} WOLFSSL_COMP_METHOD; + +typedef struct WOLFSSL_COMP { + int id; + const char *name; + WOLFSSL_COMP_METHOD *method; +} WOLFSSL_COMP; + +struct WOLFSSL_X509_LOOKUP_METHOD { + int type; +}; + +struct WOLFSSL_X509_LOOKUP { + WOLFSSL_X509_STORE *store; +}; + +struct WOLFSSL_X509_STORE { + int cache; /* stunnel dereference */ + WOLFSSL_CERT_MANAGER* cm; + WOLFSSL_X509_LOOKUP lookup; +#ifdef OPENSSL_EXTRA + int isDynamic; + WOLFSSL_X509_VERIFY_PARAM* param; /* certificate validation parameter */ +#endif +#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL) + WOLFSSL_X509_CRL *crl; +#endif +}; + +#ifdef OPENSSL_EXTRA +#define WOLFSSL_USE_CHECK_TIME 0x2 +#define WOLFSSL_NO_CHECK_TIME 0x200000 +#define WOLFSSL_NO_WILDCARDS 0x4 +#define WOLFSSL_HOST_NAME_MAX 256 +#define WOLFSSL_MAX_IPSTR 46 /* max ip size IPv4 mapped IPv6 */ +struct WOLFSSL_X509_VERIFY_PARAM { + time_t check_time; + unsigned long flags; + char hostName[WOLFSSL_HOST_NAME_MAX]; + unsigned int hostFlags; + char ipasc[WOLFSSL_MAX_IPSTR]; +}; +#endif + +typedef struct WOLFSSL_ALERT { + int code; + int level; +} WOLFSSL_ALERT; + +typedef struct WOLFSSL_ALERT_HISTORY { + WOLFSSL_ALERT last_rx; + WOLFSSL_ALERT last_tx; +} WOLFSSL_ALERT_HISTORY; + +typedef struct WOLFSSL_X509_REVOKED { + WOLFSSL_ASN1_INTEGER* serialNumber; /* stunnel dereference */ +} WOLFSSL_X509_REVOKED; + + +typedef struct WOLFSSL_X509_OBJECT { + union { + char* ptr; + WOLFSSL_X509 *x509; + WOLFSSL_X509_CRL* crl; /* stunnel dereference */ + } data; +} WOLFSSL_X509_OBJECT; + +#define WOLFSSL_ASN1_BOOLEAN int + +typedef struct WOLFSSL_BUFFER_INFO { + unsigned char* buffer; + unsigned int length; +} WOLFSSL_BUFFER_INFO; + +typedef struct WOLFSSL_X509_STORE_CTX { + WOLFSSL_X509_STORE* store; /* Store full of a CA cert chain */ + WOLFSSL_X509* current_cert; /* current X509 (OPENSSL_EXTRA) */ +#ifdef WOLFSSL_ASIO + WOLFSSL_X509* current_issuer; /* asio dereference */ +#endif + WOLFSSL_X509_CHAIN* sesChain; /* pointer to WOLFSSL_SESSION peer chain */ + WOLFSSL_STACK* chain; +#ifdef OPENSSL_EXTRA + WOLFSSL_X509_VERIFY_PARAM* param; /* certificate validation parameter */ +#endif + char* domain; /* subject CN domain name */ +#if defined(HAVE_EX_DATA) || defined(FORTRESS) + void* ex_data[MAX_EX_DATA]; /* external data */ +#endif +#if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_EXTRA) + int depth; /* used in X509_STORE_CTX_*_depth */ +#endif + void* userCtx; /* user ctx */ + int error; /* current error */ + int error_depth; /* index of cert depth for this error */ + int discardSessionCerts; /* so verify callback can flag for discard */ + int totalCerts; /* number of peer cert buffers */ + WOLFSSL_BUFFER_INFO* certs; /* peer certs */ + WOLFSSL_X509_STORE_CTX_verify_cb verify_cb; /* verify callback */ +} WOLFSSL_X509_STORE_CTX; + +typedef char* WOLFSSL_STRING; + +/* Valid Alert types from page 16/17 + * Add alert string to the function wolfSSL_alert_type_string_long in src/ssl.c + */ +enum AlertDescription { + close_notify = 0, + unexpected_message = 10, + bad_record_mac = 20, + record_overflow = 22, + decompression_failure = 30, + handshake_failure = 40, + no_certificate = 41, + bad_certificate = 42, + unsupported_certificate = 43, + certificate_revoked = 44, + certificate_expired = 45, + certificate_unknown = 46, + illegal_parameter = 47, + unknown_ca = 48, + decode_error = 50, + decrypt_error = 51, + #ifdef WOLFSSL_MYSQL_COMPATIBLE + /* catch name conflict for enum protocol with MYSQL build */ + wc_protocol_version = 70, + #else + protocol_version = 70, + #endif + inappropriate_fallback = 86, + no_renegotiation = 100, + missing_extension = 109, + unsupported_extension = 110, /**< RFC 5246, section 7.2.2 */ + unrecognized_name = 112, /**< RFC 6066, section 3 */ + bad_certificate_status_response = 113, /**< RFC 6066, section 8 */ + unknown_psk_identity = 115, /**< RFC 4279, section 2 */ + no_application_protocol = 120 +}; + + +enum AlertLevel { + alert_warning = 1, + alert_fatal = 2 +}; + +/* Maximum master key length (SECRET_LEN) */ +#define WOLFSSL_MAX_MASTER_KEY_LENGTH 48 +/* Maximum number of groups that can be set */ +#define WOLFSSL_MAX_GROUP_COUNT 10 + +typedef WOLFSSL_METHOD* (*wolfSSL_method_func)(void* heap); + +/* CTX Method EX Constructor Functions */ +WOLFSSL_API WOLFSSL_METHOD *wolfTLS_client_method_ex(void* heap); +WOLFSSL_API WOLFSSL_METHOD *wolfTLS_server_method_ex(void* heap); +WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_server_method_ex(void* heap); +WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_client_method_ex(void* heap); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_method_ex(void* heap); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_server_method_ex(void* heap); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_client_method_ex(void* heap); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_1_method_ex(void* heap); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_1_server_method_ex(void* heap); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_1_client_method_ex(void* heap); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_2_method_ex(void* heap); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_2_server_method_ex(void* heap); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_2_client_method_ex(void* heap); +#ifdef WOLFSSL_TLS13 + WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_3_method_ex(void* heap); + WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_3_server_method_ex(void* heap); + WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_3_client_method_ex(void* heap); +#endif + +WOLFSSL_API WOLFSSL_METHOD *wolfSSLv23_method_ex(void* heap); +WOLFSSL_API WOLFSSL_METHOD *wolfSSLv23_server_method_ex(void* heap); +WOLFSSL_API WOLFSSL_METHOD *wolfSSLv23_client_method_ex(void* heap); + +#ifdef WOLFSSL_DTLS + WOLFSSL_API WOLFSSL_METHOD *wolfDTLS_method_ex(void* heap); + WOLFSSL_API WOLFSSL_METHOD *wolfDTLS_client_method_ex(void* heap); + WOLFSSL_API WOLFSSL_METHOD *wolfDTLS_server_method_ex(void* heap); + WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_method_ex(void* heap); + WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_client_method_ex(void* heap); + WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_server_method_ex(void* heap); + WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_method_ex(void* heap); + WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_client_method_ex(void* heap); + WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_server_method_ex(void* heap); +#endif + +/* CTX Method Constructor Functions */ +WOLFSSL_API WOLFSSL_METHOD *wolfTLS_client_method(void); +WOLFSSL_API WOLFSSL_METHOD *wolfTLS_server_method(void); +WOLFSSL_API WOLFSSL_METHOD *wolfSSLv23_method(void); +WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_server_method(void); +WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_client_method(void); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_method(void); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_server_method(void); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_client_method(void); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_1_method(void); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_1_server_method(void); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_1_client_method(void); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_2_method(void); +WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_2_server_method(void); +WOLFSSL_ABI WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_2_client_method(void); +#ifdef WOLFSSL_TLS13 + WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_3_method(void); + WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_3_server_method(void); + WOLFSSL_ABI WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_3_client_method(void); +#endif + +#ifdef WOLFSSL_DTLS + WOLFSSL_API WOLFSSL_METHOD *wolfDTLS_method(void); + WOLFSSL_API WOLFSSL_METHOD *wolfDTLS_server_method(void); + WOLFSSL_API WOLFSSL_METHOD *wolfDTLS_client_method(void); + WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_method(void); + WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_client_method(void); + WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_server_method(void); + WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_method(void); + WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_client_method(void); + WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_server_method(void); +#endif + +#ifdef HAVE_POLY1305 + WOLFSSL_API int wolfSSL_use_old_poly(WOLFSSL*, int); +#endif + +#ifdef WOLFSSL_SESSION_EXPORT +#ifdef WOLFSSL_DTLS + +#ifndef WOLFSSL_DTLS_EXPORT_TYPES +typedef int (*wc_dtls_export)(WOLFSSL* ssl, + unsigned char* exportBuffer, unsigned int sz, void* userCtx); +#define WOLFSSL_DTLS_EXPORT_TYPES +#endif /* WOLFSSL_DTLS_EXPORT_TYPES */ + +WOLFSSL_API int wolfSSL_dtls_import(WOLFSSL* ssl, unsigned char* buf, + unsigned int sz); +WOLFSSL_API int wolfSSL_CTX_dtls_set_export(WOLFSSL_CTX* ctx, + wc_dtls_export func); +WOLFSSL_API int wolfSSL_dtls_set_export(WOLFSSL* ssl, wc_dtls_export func); +WOLFSSL_API int wolfSSL_dtls_export(WOLFSSL* ssl, unsigned char* buf, + unsigned int* sz); +WOLFSSL_API int wolfSSL_dtls_export_state_only(WOLFSSL* ssl, unsigned char* buf, + unsigned int* sz); +#endif /* WOLFSSL_DTLS */ +#endif /* WOLFSSL_SESSION_EXPORT */ + +#ifdef WOLFSSL_STATIC_MEMORY +#ifndef WOLFSSL_MEM_GUARD +#define WOLFSSL_MEM_GUARD + typedef struct WOLFSSL_MEM_STATS WOLFSSL_MEM_STATS; + typedef struct WOLFSSL_MEM_CONN_STATS WOLFSSL_MEM_CONN_STATS; +#endif +WOLFSSL_API int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx, + wolfSSL_method_func method, + unsigned char* buf, unsigned int sz, + int flag, int max); +WOLFSSL_API int wolfSSL_CTX_is_static_memory(WOLFSSL_CTX* ctx, + WOLFSSL_MEM_STATS* mem_stats); +WOLFSSL_API int wolfSSL_is_static_memory(WOLFSSL* ssl, + WOLFSSL_MEM_CONN_STATS* mem_stats); +#endif + +#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) + +WOLFSSL_ABI WOLFSSL_API int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX*, + const char*, int); +WOLFSSL_ABI WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX*, + const char*, int); + +#endif + +#ifndef NO_CERTS +#define WOLFSSL_LOAD_FLAG_NONE 0x00000000 +#define WOLFSSL_LOAD_FLAG_IGNORE_ERR 0x00000001 +#define WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY 0x00000002 +#define WOLFSSL_LOAD_FLAG_PEM_CA_ONLY 0x00000004 + +#ifndef WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS +#define WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS WOLFSSL_LOAD_FLAG_NONE +#endif +#endif /* !NO_CERTS */ + +#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) + +WOLFSSL_API int wolfSSL_CTX_load_verify_locations_ex(WOLFSSL_CTX*, const char*, + const char*, unsigned int); +WOLFSSL_ABI WOLFSSL_API int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX*, + const char*, const char*); +#ifdef WOLFSSL_TRUST_PEER_CERT +WOLFSSL_API int wolfSSL_CTX_trust_peer_cert(WOLFSSL_CTX*, const char*, int); +#endif +WOLFSSL_ABI WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_file( + WOLFSSL_CTX*, const char*); +WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_file_format(WOLFSSL_CTX *, + const char *file, int format); +WOLFSSL_API int wolfSSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX*, const char*, int); + +WOLFSSL_API long wolfSSL_get_verify_depth(WOLFSSL* ssl); +WOLFSSL_API long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx); +WOLFSSL_API void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx,int depth); +WOLFSSL_ABI WOLFSSL_API int wolfSSL_use_certificate_file(WOLFSSL*, const char*, + int); +WOLFSSL_ABI WOLFSSL_API int wolfSSL_use_PrivateKey_file(WOLFSSL*, const char*, + int); +WOLFSSL_ABI WOLFSSL_API int wolfSSL_use_certificate_chain_file(WOLFSSL*, + const char*); +WOLFSSL_API int wolfSSL_use_certificate_chain_file_format(WOLFSSL*, + const char *file, int format); +WOLFSSL_API int wolfSSL_use_RSAPrivateKey_file(WOLFSSL*, const char*, int); + +#ifdef WOLFSSL_DER_LOAD + WOLFSSL_API int wolfSSL_CTX_der_load_verify_locations(WOLFSSL_CTX*, + const char*, int); +#endif + +#ifdef HAVE_NTRU + WOLFSSL_API int wolfSSL_CTX_use_NTRUPrivateKey_file(WOLFSSL_CTX*, const char*); + /* load NTRU private key blob */ +#endif + +#endif /* !NO_FILESYSTEM && !NO_CERTS */ + +WOLFSSL_API WOLFSSL_CTX* wolfSSL_CTX_new_ex(WOLFSSL_METHOD* method, void* heap); +WOLFSSL_ABI WOLFSSL_API WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD*); +#ifdef OPENSSL_EXTRA +WOLFSSL_API int wolfSSL_CTX_up_ref(WOLFSSL_CTX*); +#endif +WOLFSSL_ABI WOLFSSL_API WOLFSSL* wolfSSL_new(WOLFSSL_CTX*); +WOLFSSL_API WOLFSSL_CTX* wolfSSL_get_SSL_CTX(WOLFSSL* ssl); +WOLFSSL_API WOLFSSL_X509_VERIFY_PARAM* wolfSSL_get0_param(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_is_server(WOLFSSL*); +WOLFSSL_API WOLFSSL* wolfSSL_write_dup(WOLFSSL*); +WOLFSSL_ABI WOLFSSL_API int wolfSSL_set_fd (WOLFSSL*, int); +WOLFSSL_API int wolfSSL_set_write_fd (WOLFSSL*, int); +WOLFSSL_API int wolfSSL_set_read_fd (WOLFSSL*, int); +WOLFSSL_API char* wolfSSL_get_cipher_list(int priority); +WOLFSSL_API char* wolfSSL_get_cipher_list_ex(WOLFSSL* ssl, int priority); +WOLFSSL_API int wolfSSL_get_ciphers(char*, int); +WOLFSSL_API int wolfSSL_get_ciphers_iana(char*, int); +WOLFSSL_API const char* wolfSSL_get_cipher_name(WOLFSSL* ssl); +WOLFSSL_API const char* wolfSSL_get_cipher_name_from_suite(const unsigned char, + const unsigned char); +WOLFSSL_API const char* wolfSSL_get_cipher_name_iana_from_suite( + const unsigned char, const unsigned char); +WOLFSSL_API const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf, + int len); +WOLFSSL_API const char* wolfSSL_get_curve_name(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_get_fd(const WOLFSSL*); +/* please see note at top of README if you get an error from connect */ +WOLFSSL_ABI WOLFSSL_API int wolfSSL_connect(WOLFSSL*); +WOLFSSL_ABI WOLFSSL_API int wolfSSL_write(WOLFSSL*, const void*, int); +WOLFSSL_ABI WOLFSSL_API int wolfSSL_read(WOLFSSL*, void*, int); +WOLFSSL_API int wolfSSL_peek(WOLFSSL*, void*, int); +WOLFSSL_API int wolfSSL_accept(WOLFSSL*); +#ifdef WOLFSSL_TLS13 +WOLFSSL_API int wolfSSL_send_hrr_cookie(WOLFSSL* ssl, + const unsigned char* secret, unsigned int secretSz); +WOLFSSL_API int wolfSSL_CTX_no_ticket_TLSv13(WOLFSSL_CTX* ctx); +WOLFSSL_API int wolfSSL_no_ticket_TLSv13(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_CTX_no_dhe_psk(WOLFSSL_CTX* ctx); +WOLFSSL_API int wolfSSL_no_dhe_psk(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_update_keys(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_CTX_allow_post_handshake_auth(WOLFSSL_CTX* ctx); +WOLFSSL_API int wolfSSL_allow_post_handshake_auth(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_request_certificate(WOLFSSL* ssl); + +WOLFSSL_API int wolfSSL_preferred_group(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_CTX_set_groups(WOLFSSL_CTX* ctx, int* groups, + int count); +WOLFSSL_API int wolfSSL_set_groups(WOLFSSL* ssl, int* groups, int count); + +WOLFSSL_API int wolfSSL_connect_TLSv13(WOLFSSL*); +WOLFSSL_API int wolfSSL_accept_TLSv13(WOLFSSL*); + +#ifdef WOLFSSL_EARLY_DATA +WOLFSSL_API int wolfSSL_CTX_set_max_early_data(WOLFSSL_CTX* ctx, + unsigned int sz); +WOLFSSL_API int wolfSSL_set_max_early_data(WOLFSSL* ssl, unsigned int sz); +WOLFSSL_API int wolfSSL_write_early_data(WOLFSSL*, const void*, int, int*); +WOLFSSL_API int wolfSSL_read_early_data(WOLFSSL*, void*, int, int*); +#endif +#endif +WOLFSSL_ABI WOLFSSL_API void wolfSSL_CTX_free(WOLFSSL_CTX*); +WOLFSSL_ABI WOLFSSL_API void wolfSSL_free(WOLFSSL*); +WOLFSSL_ABI WOLFSSL_API int wolfSSL_shutdown(WOLFSSL*); +WOLFSSL_API int wolfSSL_send(WOLFSSL*, const void*, int sz, int flags); +WOLFSSL_API int wolfSSL_recv(WOLFSSL*, void*, int sz, int flags); + +WOLFSSL_API void wolfSSL_CTX_set_quiet_shutdown(WOLFSSL_CTX*, int); +WOLFSSL_API void wolfSSL_set_quiet_shutdown(WOLFSSL*, int); + +WOLFSSL_ABI WOLFSSL_API int wolfSSL_get_error(WOLFSSL*, int); +WOLFSSL_API int wolfSSL_get_alert_history(WOLFSSL*, WOLFSSL_ALERT_HISTORY *); + +WOLFSSL_ABI WOLFSSL_API int wolfSSL_set_session(WOLFSSL*, WOLFSSL_SESSION*); +WOLFSSL_API long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION*, long); +WOLFSSL_ABI WOLFSSL_API WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL*); +WOLFSSL_ABI WOLFSSL_API void wolfSSL_flush_sessions(WOLFSSL_CTX*, long); +WOLFSSL_API int wolfSSL_SetServerID(WOLFSSL*, const unsigned char*, int, int); + +#if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \ + || defined(WOLFSSL_NGINX) +WOLFSSL_API int wolfSSL_BIO_new_bio_pair(WOLFSSL_BIO**, size_t, + WOLFSSL_BIO**, size_t); + +WOLFSSL_API WOLFSSL_RSA* wolfSSL_d2i_RSAPrivateKey_bio(WOLFSSL_BIO*, WOLFSSL_RSA**); +WOLFSSL_API int wolfSSL_CTX_use_certificate_ASN1(WOLFSSL_CTX*, + int, const unsigned char*); +WOLFSSL_API int wolfSSL_CTX_use_RSAPrivateKey(WOLFSSL_CTX*, WOLFSSL_RSA*); +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_bio(WOLFSSL_BIO*, WOLFSSL_EVP_PKEY**); +#endif /* OPENSSL_ALL || WOLFSSL_ASIO */ + +#ifdef SESSION_INDEX +WOLFSSL_API int wolfSSL_GetSessionIndex(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_GetSessionAtIndex(int index, WOLFSSL_SESSION* session); +#endif /* SESSION_INDEX */ + +#if defined(SESSION_INDEX) && defined(SESSION_CERTS) +WOLFSSL_API + WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session); +#endif /* SESSION_INDEX && SESSION_CERTS */ + +typedef int (*VerifyCallback)(int, WOLFSSL_X509_STORE_CTX*); +#ifdef OPENSSL_EXTRA +typedef void (CallbackInfoState)(const WOLFSSL*, int, int); + +typedef struct WOLFSSL_CRYPTO_EX_DATA { + WOLFSSL_STACK* data; +} WOLFSSL_CRYPTO_EX_DATA; + +typedef int (WOLFSSL_CRYPTO_EX_new)(void* p, void* ptr, + WOLFSSL_CRYPTO_EX_DATA* a, int idx, long argValue, void* arg); +typedef int (WOLFSSL_CRYPTO_EX_dup)(WOLFSSL_CRYPTO_EX_DATA* out, + WOLFSSL_CRYPTO_EX_DATA* in, void* inPtr, int idx, long argV, void* arg); +typedef void (WOLFSSL_CRYPTO_EX_free)(void* p, void* ptr, + WOLFSSL_CRYPTO_EX_DATA* a, int idx, long argValue, void* arg); + +WOLFSSL_API int wolfSSL_get_ex_new_index(long argValue, void* arg, + WOLFSSL_CRYPTO_EX_new* a, WOLFSSL_CRYPTO_EX_dup* b, + WOLFSSL_CRYPTO_EX_free* c); +#endif + +WOLFSSL_API void wolfSSL_CTX_set_verify(WOLFSSL_CTX*, int, + VerifyCallback verify_callback); + +#ifdef OPENSSL_ALL +typedef int (*CertVerifyCallback)(WOLFSSL_X509_STORE_CTX* store, void* arg); +WOLFSSL_API void wolfSSL_CTX_set_cert_verify_callback(WOLFSSL_CTX* ctx, + CertVerifyCallback cb, void* arg); +#endif + +WOLFSSL_API void wolfSSL_set_verify(WOLFSSL*, int, VerifyCallback verify_callback); +WOLFSSL_API void wolfSSL_set_verify_result(WOLFSSL*, long); +WOLFSSL_API void wolfSSL_SetCertCbCtx(WOLFSSL*, void*); + +WOLFSSL_ABI WOLFSSL_API int wolfSSL_pending(WOLFSSL*); + +WOLFSSL_API void wolfSSL_load_error_strings(void); +WOLFSSL_API int wolfSSL_library_init(void); +WOLFSSL_ABI WOLFSSL_API long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX*, + long); + +#ifdef HAVE_SECRET_CALLBACK +typedef int (*SessionSecretCb)(WOLFSSL* ssl, + void* secret, int* secretSz, void* ctx); +WOLFSSL_API int wolfSSL_set_session_secret_cb(WOLFSSL*, SessionSecretCb, void*); +#endif /* HAVE_SECRET_CALLBACK */ + +/* session cache persistence */ +WOLFSSL_API int wolfSSL_save_session_cache(const char*); +WOLFSSL_API int wolfSSL_restore_session_cache(const char*); +WOLFSSL_API int wolfSSL_memsave_session_cache(void*, int); +WOLFSSL_API int wolfSSL_memrestore_session_cache(const void*, int); +WOLFSSL_API int wolfSSL_get_session_cache_memsize(void); + +/* certificate cache persistence, uses ctx since certs are per ctx */ +WOLFSSL_API int wolfSSL_CTX_save_cert_cache(WOLFSSL_CTX*, const char*); +WOLFSSL_API int wolfSSL_CTX_restore_cert_cache(WOLFSSL_CTX*, const char*); +WOLFSSL_API int wolfSSL_CTX_memsave_cert_cache(WOLFSSL_CTX*, void*, int, int*); +WOLFSSL_API int wolfSSL_CTX_memrestore_cert_cache(WOLFSSL_CTX*, const void*, int); +WOLFSSL_API int wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX*); + +/* only supports full name from cipher_name[] delimited by : */ +WOLFSSL_API int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX*, const char*); +WOLFSSL_API int wolfSSL_set_cipher_list(WOLFSSL*, const char*); + +/* Nonblocking DTLS helper functions */ +WOLFSSL_API void wolfSSL_dtls_set_using_nonblock(WOLFSSL*, int); +WOLFSSL_API int wolfSSL_dtls_get_using_nonblock(WOLFSSL*); +#define wolfSSL_set_using_nonblock wolfSSL_dtls_set_using_nonblock +#define wolfSSL_get_using_nonblock wolfSSL_dtls_get_using_nonblock + /* The old names are deprecated. */ +WOLFSSL_API int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_DTLSv1_get_timeout(WOLFSSL* ssl, Timeval* timeleft); +WOLFSSL_API void wolfSSL_DTLSv1_set_initial_timeout_duration(WOLFSSL* ssl, + word32 duration_ms); +WOLFSSL_API int wolfSSL_DTLSv1_handle_timeout(WOLFSSL* ssl); + +WOLFSSL_API int wolfSSL_dtls_set_timeout_init(WOLFSSL* ssl, int); +WOLFSSL_API int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int); +WOLFSSL_API int wolfSSL_dtls_got_timeout(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_dtls_retransmit(WOLFSSL*); +WOLFSSL_API int wolfSSL_dtls(WOLFSSL* ssl); + +WOLFSSL_API int wolfSSL_dtls_set_peer(WOLFSSL*, void*, unsigned int); +WOLFSSL_API int wolfSSL_dtls_get_peer(WOLFSSL*, void*, unsigned int*); + +WOLFSSL_API int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX*); +WOLFSSL_API int wolfSSL_dtls_set_sctp(WOLFSSL*); +WOLFSSL_API int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX*, unsigned short); +WOLFSSL_API int wolfSSL_dtls_set_mtu(WOLFSSL*, unsigned short); + +WOLFSSL_API int wolfSSL_dtls_get_drop_stats(WOLFSSL*, + unsigned int*, unsigned int*); +WOLFSSL_API int wolfSSL_CTX_mcast_set_member_id(WOLFSSL_CTX*, unsigned short); +WOLFSSL_API int wolfSSL_set_secret(WOLFSSL*, unsigned short, + const unsigned char*, unsigned int, + const unsigned char*, const unsigned char*, + const unsigned char*); +WOLFSSL_API int wolfSSL_mcast_read(WOLFSSL*, unsigned short*, void*, int); +WOLFSSL_API int wolfSSL_mcast_peer_add(WOLFSSL*, unsigned short, int); +WOLFSSL_API int wolfSSL_mcast_peer_known(WOLFSSL*, unsigned short); +WOLFSSL_API int wolfSSL_mcast_get_max_peers(void); +typedef int (*CallbackMcastHighwater)(unsigned short peerId, + unsigned int maxSeq, + unsigned int curSeq, void* ctx); +WOLFSSL_API int wolfSSL_CTX_mcast_set_highwater_cb(WOLFSSL_CTX*, + unsigned int, + unsigned int, + unsigned int, + CallbackMcastHighwater); +WOLFSSL_API int wolfSSL_mcast_set_highwater_ctx(WOLFSSL*, void*); + +WOLFSSL_API int wolfSSL_ERR_GET_REASON(unsigned long err); +WOLFSSL_API char* wolfSSL_ERR_error_string(unsigned long,char*); +WOLFSSL_API void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, + unsigned long sz); +WOLFSSL_API const char* wolfSSL_ERR_reason_error_string(unsigned long); + +/* extras */ + + +/* for now LHASH is not implemented */ +typedef int WOLFSSL_LHASH; +#ifndef WOLF_LHASH_OF + #define WOLF_LHASH_OF(x) WOLFSSL_LHASH +#endif + +#ifndef WOLF_STACK_OF + #define WOLF_STACK_OF(x) WOLFSSL_STACK +#endif +#ifndef DECLARE_STACK_OF + #define DECLARE_STACK_OF(x) WOLF_STACK_OF(x); +#endif + +WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_new_node(void* heap); +WOLFSSL_API void wolfSSL_sk_free(WOLFSSL_STACK* sk); +WOLFSSL_API void wolfSSL_sk_free_node(WOLFSSL_STACK* in); +WOLFSSL_API int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx); +WOLFSSL_API int wolfSSL_sk_push(WOLFSSL_STACK *st, const void *data); + +#if defined(HAVE_OCSP) +#include "wolfssl/ocsp.h" +#include "wolfssl/wolfcrypt/asn.h" +#endif + +#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) +WOLFSSL_API int wolfSSL_sk_ACCESS_DESCRIPTION_push( + WOLF_STACK_OF(ACCESS_DESCRIPTION)* sk, + WOLFSSL_ACCESS_DESCRIPTION* access); +#endif /* defined(OPENSSL_ALL) || defined(WOLFSSL_QT) */ + +typedef WOLF_STACK_OF(WOLFSSL_GENERAL_NAME) WOLFSSL_GENERAL_NAMES; + +WOLFSSL_API int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, + WOLFSSL_X509* x509); +WOLFSSL_API WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_X509_dup(WOLFSSL_STACK* sk); +WOLFSSL_API void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk); +WOLFSSL_API WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_new(void); +WOLFSSL_API void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* gn); +WOLFSSL_API int wolfSSL_sk_GENERAL_NAME_push(WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)* sk, + WOLFSSL_GENERAL_NAME* gn); +WOLFSSL_API WOLFSSL_GENERAL_NAME* wolfSSL_sk_GENERAL_NAME_value( + WOLFSSL_STACK* sk, int i); +WOLFSSL_API int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk); +WOLFSSL_API void wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK* sk, + void (*f) (WOLFSSL_GENERAL_NAME*)); +WOLFSSL_API void wolfSSL_sk_GENERAL_NAME_free(WOLFSSL_STACK* sk); +WOLFSSL_API void wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES* name); +WOLFSSL_API int wolfSSL_sk_ACCESS_DESCRIPTION_num(WOLFSSL_STACK* sk); +WOLFSSL_API void wolfSSL_AUTHORITY_INFO_ACCESS_free( + WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk); +WOLFSSL_API WOLFSSL_ACCESS_DESCRIPTION* wolfSSL_sk_ACCESS_DESCRIPTION_value( + WOLFSSL_STACK* sk, int idx); +WOLFSSL_API void wolfSSL_sk_ACCESS_DESCRIPTION_free(WOLFSSL_STACK* sk); +WOLFSSL_API void wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(WOLFSSL_STACK* sk, + void (*f) (WOLFSSL_ACCESS_DESCRIPTION*)); +WOLFSSL_API void wolfSSL_sk_X509_EXTENSION_pop_free( + WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, + void f (WOLFSSL_X509_EXTENSION*)); +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* wolfSSL_sk_X509_EXTENSION_new_null(void); +WOLFSSL_API WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_new(void); +WOLFSSL_API void wolfSSL_ASN1_OBJECT_free(WOLFSSL_ASN1_OBJECT* obj); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_new_asn1_obj(void); +WOLFSSL_API int wolfSSL_sk_ASN1_OBJECT_push(WOLF_STACK_OF(WOLFSSL_ASN1_OBJEXT)* sk, + WOLFSSL_ASN1_OBJECT* obj); +WOLFSSL_API WOLFSSL_ASN1_OBJECT* wolfSSL_sk_ASN1_OBJECT_pop( + WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk); +WOLFSSL_API void wolfSSL_sk_ASN1_OBJECT_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk); +WOLFSSL_API void wolfSSL_sk_ASN1_OBJECT_pop_free( + WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, + void (*f)(WOLFSSL_ASN1_OBJECT*)); +WOLFSSL_API int wolfSSL_ASN1_STRING_to_UTF8(unsigned char **out, WOLFSSL_ASN1_STRING *in); +WOLFSSL_API int wolfSSL_sk_X509_EXTENSION_num(WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk); +WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_sk_X509_EXTENSION_value( + WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int idx); +WOLFSSL_API int wolfSSL_set_ex_data(WOLFSSL*, int, void*); +WOLFSSL_API int wolfSSL_get_shutdown(const WOLFSSL*); +WOLFSSL_API int wolfSSL_set_rfd(WOLFSSL*, int); +WOLFSSL_API int wolfSSL_set_wfd(WOLFSSL*, int); +WOLFSSL_API void wolfSSL_set_shutdown(WOLFSSL*, int); +WOLFSSL_API int wolfSSL_set_session_id_context(WOLFSSL*, const unsigned char*, + unsigned int); +WOLFSSL_API void wolfSSL_set_connect_state(WOLFSSL*); +WOLFSSL_API void wolfSSL_set_accept_state(WOLFSSL*); +WOLFSSL_API int wolfSSL_session_reused(WOLFSSL*); +WOLFSSL_API WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session); +WOLFSSL_API void wolfSSL_SESSION_free(WOLFSSL_SESSION* session); +WOLFSSL_API int wolfSSL_is_init_finished(WOLFSSL*); + +WOLFSSL_API const char* wolfSSL_get_version(WOLFSSL*); +WOLFSSL_API int wolfSSL_get_current_cipher_suite(WOLFSSL* ssl); +WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL*); +WOLFSSL_API char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER*, char*, int); +WOLFSSL_API const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher); +WOLFSSL_API const char* wolfSSL_CIPHER_get_version(const WOLFSSL_CIPHER* cipher); +WOLFSSL_API word32 wolfSSL_CIPHER_get_id(const WOLFSSL_CIPHER* cipher); +WOLFSSL_API const WOLFSSL_CIPHER* wolfSSL_get_cipher_by_value(word16 value); +WOLFSSL_API const char* wolfSSL_SESSION_CIPHER_get_name(WOLFSSL_SESSION* session); +WOLFSSL_API const char* wolfSSL_get_cipher(WOLFSSL*); +WOLFSSL_API void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk); +WOLFSSL_API WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl); + /* what's ref count */ + +WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_new(void); +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) +WOLFSSL_API int wolfSSL_X509_up_ref(WOLFSSL_X509* x509); +WOLFSSL_API int wolfSSL_EVP_PKEY_up_ref(WOLFSSL_EVP_PKEY* pkey); +#endif + +WOLFSSL_API int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, + char** path, int* ssl); + +WOLFSSL_API WOLFSSL_METHOD* wolfSSLv23_client_method(void); +WOLFSSL_API WOLFSSL_METHOD* wolfSSLv2_client_method(void); +WOLFSSL_API WOLFSSL_METHOD* wolfSSLv2_server_method(void); + +WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new(WOLFSSL_BIO_METHOD*); +WOLFSSL_API int wolfSSL_BIO_free(WOLFSSL_BIO*); +WOLFSSL_API void wolfSSL_BIO_vfree(WOLFSSL_BIO*); +WOLFSSL_API int wolfSSL_BIO_free_all(WOLFSSL_BIO*); +WOLFSSL_API int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz); +WOLFSSL_API int wolfSSL_BIO_puts(WOLFSSL_BIO* bio, const char* buf); +WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_next(WOLFSSL_BIO* bio); +WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_find_type(WOLFSSL_BIO* bio, int type); +WOLFSSL_API int wolfSSL_BIO_read(WOLFSSL_BIO*, void*, int); +WOLFSSL_API int wolfSSL_BIO_write(WOLFSSL_BIO*, const void*, int); +WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_push(WOLFSSL_BIO*, WOLFSSL_BIO* append); +WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_pop(WOLFSSL_BIO*); +WOLFSSL_API int wolfSSL_BIO_flush(WOLFSSL_BIO*); +WOLFSSL_API int wolfSSL_BIO_pending(WOLFSSL_BIO*); +WOLFSSL_API void wolfSSL_BIO_set_callback(WOLFSSL_BIO *bio, + wolf_bio_info_cb callback_func); +WOLFSSL_API wolf_bio_info_cb wolfSSL_BIO_get_callback(WOLFSSL_BIO *bio); +WOLFSSL_API void wolfSSL_BIO_set_callback_arg(WOLFSSL_BIO *bio, char *arg); +WOLFSSL_API char* wolfSSL_BIO_get_callback_arg(const WOLFSSL_BIO *bio); + +WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_buffer(void); +WOLFSSL_API long wolfSSL_BIO_set_write_buffer_size(WOLFSSL_BIO*, long size); +WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_ssl(void); +WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_socket(int sfd, int flag); +WOLFSSL_API int wolfSSL_BIO_eof(WOLFSSL_BIO*); + +WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_mem(void); +WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_base64(void); +WOLFSSL_API void wolfSSL_BIO_set_flags(WOLFSSL_BIO*, int); +WOLFSSL_API long wolfSSL_BIO_set_nbio(WOLFSSL_BIO*, long); + +WOLFSSL_API int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio,void* p); + +WOLFSSL_API void wolfSSL_BIO_set_init(WOLFSSL_BIO*, int); +WOLFSSL_API void wolfSSL_BIO_set_data(WOLFSSL_BIO*, void*); +WOLFSSL_API void* wolfSSL_BIO_get_data(WOLFSSL_BIO*); +WOLFSSL_API void wolfSSL_BIO_set_shutdown(WOLFSSL_BIO*, int); +WOLFSSL_API int wolfSSL_BIO_get_shutdown(WOLFSSL_BIO*); +WOLFSSL_API void wolfSSL_BIO_clear_retry_flags(WOLFSSL_BIO*); + +WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_meth_new(int, const char*); +WOLFSSL_API void wolfSSL_BIO_meth_free(WOLFSSL_BIO_METHOD*); +WOLFSSL_API int wolfSSL_BIO_meth_set_write(WOLFSSL_BIO_METHOD*, wolfSSL_BIO_meth_write_cb); +WOLFSSL_API int wolfSSL_BIO_meth_set_read(WOLFSSL_BIO_METHOD*, wolfSSL_BIO_meth_read_cb); +WOLFSSL_API int wolfSSL_BIO_meth_set_puts(WOLFSSL_BIO_METHOD*, wolfSSL_BIO_meth_puts_cb); +WOLFSSL_API int wolfSSL_BIO_meth_set_gets(WOLFSSL_BIO_METHOD*, wolfSSL_BIO_meth_gets_cb); +WOLFSSL_API int wolfSSL_BIO_meth_set_ctrl(WOLFSSL_BIO_METHOD*, wolfSSL_BIO_meth_ctrl_get_cb); +WOLFSSL_API int wolfSSL_BIO_meth_set_create(WOLFSSL_BIO_METHOD*, wolfSSL_BIO_meth_create_cb); +WOLFSSL_API int wolfSSL_BIO_meth_set_destroy(WOLFSSL_BIO_METHOD*, wolfSSL_BIO_meth_destroy_cb); +WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_mem_buf(const void* buf, int len); + +WOLFSSL_API long wolfSSL_BIO_set_ssl(WOLFSSL_BIO*, WOLFSSL*, int flag); +#ifndef NO_FILESYSTEM +WOLFSSL_API long wolfSSL_BIO_set_fd(WOLFSSL_BIO* b, int fd, int flag); +#endif +WOLFSSL_API void wolfSSL_set_bio(WOLFSSL*, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr); + +#ifndef NO_FILESYSTEM +WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_file(void); +#endif + +WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_bio(void); +WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_socket(void); + +WOLFSSL_API long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, void *parg); +WOLFSSL_API long wolfSSL_BIO_int_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, int iarg); + +WOLFSSL_API int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *b, long size); +WOLFSSL_API int wolfSSL_BIO_make_bio_pair(WOLFSSL_BIO *b1, WOLFSSL_BIO *b2); +WOLFSSL_API int wolfSSL_BIO_ctrl_reset_read_request(WOLFSSL_BIO *b); +WOLFSSL_API int wolfSSL_BIO_nread0(WOLFSSL_BIO *bio, char **buf); +WOLFSSL_API int wolfSSL_BIO_nread(WOLFSSL_BIO *bio, char **buf, int num); +WOLFSSL_API int wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num); +WOLFSSL_API int wolfSSL_BIO_reset(WOLFSSL_BIO *bio); + +WOLFSSL_API int wolfSSL_BIO_seek(WOLFSSL_BIO *bio, int ofs); +WOLFSSL_API int wolfSSL_BIO_write_filename(WOLFSSL_BIO *bio, char *name); +WOLFSSL_API long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v); +WOLFSSL_API long wolfSSL_BIO_get_mem_ptr(WOLFSSL_BIO *bio, WOLFSSL_BUF_MEM **m); +WOLFSSL_API int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio); + +WOLFSSL_API void wolfSSL_RAND_screen(void); +WOLFSSL_API const char* wolfSSL_RAND_file_name(char*, unsigned long); +WOLFSSL_API int wolfSSL_RAND_write_file(const char*); +WOLFSSL_API int wolfSSL_RAND_load_file(const char*, long); +WOLFSSL_API int wolfSSL_RAND_egd(const char*); +WOLFSSL_API int wolfSSL_RAND_seed(const void*, int); +WOLFSSL_API void wolfSSL_RAND_Cleanup(void); +WOLFSSL_API void wolfSSL_RAND_add(const void*, int, double); +WOLFSSL_API int wolfSSL_RAND_poll(void); + +WOLFSSL_API WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void); +WOLFSSL_API WOLFSSL_COMP_METHOD* wolfSSL_COMP_rle(void); +WOLFSSL_API int wolfSSL_COMP_add_compression_method(int, void*); + +WOLFSSL_API unsigned long wolfSSL_thread_id(void); +WOLFSSL_API void wolfSSL_set_id_callback(unsigned long (*f)(void)); +WOLFSSL_API void wolfSSL_set_locking_callback(void (*f)(int, int, const char*, + int)); +WOLFSSL_API void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f) + (const char*, int)); +WOLFSSL_API void wolfSSL_set_dynlock_lock_callback(void (*f)(int, + WOLFSSL_dynlock_value*, const char*, int)); +WOLFSSL_API void wolfSSL_set_dynlock_destroy_callback(void (*f) + (WOLFSSL_dynlock_value*, const char*, int)); +WOLFSSL_API int wolfSSL_num_locks(void); + +WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get_current_cert( + WOLFSSL_X509_STORE_CTX*); +WOLFSSL_API int wolfSSL_X509_STORE_CTX_get_error(WOLFSSL_X509_STORE_CTX*); +WOLFSSL_API int wolfSSL_X509_STORE_CTX_get_error_depth(WOLFSSL_X509_STORE_CTX*); + +WOLFSSL_API void wolfSSL_X509_STORE_CTX_set_verify_cb(WOLFSSL_X509_STORE_CTX *ctx, + WOLFSSL_X509_STORE_CTX_verify_cb verify_cb); +WOLFSSL_API int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* n, + unsigned char** out); +#ifndef NO_RSA +WOLFSSL_API int wolfSSL_RSA_print(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, int offset); +#endif +WOLFSSL_API int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, + unsigned long nmflags, unsigned long cflag); +WOLFSSL_API int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509); +WOLFSSL_ABI WOLFSSL_API char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME*, + char*, int); +WOLFSSL_ABI WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name( + WOLFSSL_X509*); +WOLFSSL_ABI WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name( + WOLFSSL_X509*); +WOLFSSL_API int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509*, int); +WOLFSSL_API int wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509*, int); +WOLFSSL_API int wolfSSL_X509_get_isCA(WOLFSSL_X509*); +WOLFSSL_API int wolfSSL_X509_get_isSet_pathLength(WOLFSSL_X509*); +WOLFSSL_API unsigned int wolfSSL_X509_get_pathLength(WOLFSSL_X509*); +WOLFSSL_API unsigned int wolfSSL_X509_get_keyUsage(WOLFSSL_X509*); +WOLFSSL_API unsigned char* wolfSSL_X509_get_authorityKeyID( + WOLFSSL_X509*, unsigned char*, int*); +WOLFSSL_API unsigned char* wolfSSL_X509_get_subjectKeyID( + WOLFSSL_X509*, unsigned char*, int*); + +WOLFSSL_API int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey); +WOLFSSL_API int wolfSSL_X509_set_subject_name(WOLFSSL_X509*, + WOLFSSL_X509_NAME*); +WOLFSSL_API int wolfSSL_X509_set_issuer_name(WOLFSSL_X509*, + WOLFSSL_X509_NAME*); +WOLFSSL_API int wolfSSL_X509_set_pubkey(WOLFSSL_X509*, WOLFSSL_EVP_PKEY*); +WOLFSSL_API int wolfSSL_X509_set_notAfter(WOLFSSL_X509* x509, + const WOLFSSL_ASN1_TIME* t); +WOLFSSL_API int wolfSSL_X509_set_notBefore(WOLFSSL_X509* x509, + const WOLFSSL_ASN1_TIME* t); +WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notBefore(const WOLFSSL_X509* x509); +WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notAfter(const WOLFSSL_X509* x509); +WOLFSSL_API int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, + WOLFSSL_ASN1_INTEGER* s); +WOLFSSL_API int wolfSSL_X509_set_version(WOLFSSL_X509* x509, long v); +WOLFSSL_API int wolfSSL_X509_sign(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey, + const WOLFSSL_EVP_MD* md); + + +WOLFSSL_API int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME*); +WOLFSSL_API int wolfSSL_X509_NAME_get_text_by_NID( + WOLFSSL_X509_NAME*, int, char*, int); +WOLFSSL_API int wolfSSL_X509_NAME_get_index_by_NID( + WOLFSSL_X509_NAME*, int, int); +WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_X509_NAME_ENTRY_get_data(WOLFSSL_X509_NAME_ENTRY*); + +WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_new(void); +WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_type_new(int type); +WOLFSSL_API int wolfSSL_ASN1_STRING_type(const WOLFSSL_ASN1_STRING* asn1); +WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_d2i_DISPLAYTEXT(WOLFSSL_ASN1_STRING **asn, const unsigned char **in, long len); +WOLFSSL_API void wolfSSL_ASN1_STRING_free(WOLFSSL_ASN1_STRING* asn1); +WOLFSSL_API int wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING* asn1, + const void* data, int dataSz); +WOLFSSL_API unsigned char* wolfSSL_ASN1_STRING_data(WOLFSSL_ASN1_STRING*); +WOLFSSL_API int wolfSSL_ASN1_STRING_length(WOLFSSL_ASN1_STRING*); +WOLFSSL_API int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX*); +WOLFSSL_API const char* wolfSSL_X509_verify_cert_error_string(long); +WOLFSSL_API int wolfSSL_X509_get_signature_type(WOLFSSL_X509*); +WOLFSSL_API int wolfSSL_X509_get_signature(WOLFSSL_X509*, unsigned char*, int*); +WOLFSSL_API int wolfSSL_X509_get_pubkey_buffer(WOLFSSL_X509*, unsigned char*, + int*); +WOLFSSL_API int wolfSSL_X509_get_pubkey_type(WOLFSSL_X509* x509); + +WOLFSSL_API int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP*,const char*,long); +WOLFSSL_API int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP*, const char*, + long); +WOLFSSL_API WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void); +WOLFSSL_API WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void); + +WOLFSSL_API WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE*, + WOLFSSL_X509_LOOKUP_METHOD*); +WOLFSSL_API WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void); +WOLFSSL_API void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE*); +WOLFSSL_API int wolfSSL_X509_STORE_add_cert( + WOLFSSL_X509_STORE*, WOLFSSL_X509*); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain( + WOLFSSL_X509_STORE_CTX* ctx); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get1_chain( + WOLFSSL_X509_STORE_CTX* ctx); +WOLFSSL_API int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, + unsigned long flag); +WOLFSSL_API int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE*); +WOLFSSL_API int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX*, + int, WOLFSSL_X509_NAME*, WOLFSSL_X509_OBJECT*); +WOLFSSL_API WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new(void); +WOLFSSL_API int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX*, + WOLFSSL_X509_STORE*, WOLFSSL_X509*, WOLF_STACK_OF(WOLFSSL_X509)*); +WOLFSSL_API void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX*); +WOLFSSL_API void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX*); + +WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL*); +WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL*); + +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509*); +WOLFSSL_API int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL*, WOLFSSL_EVP_PKEY*); +WOLFSSL_API void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT*); +WOLFSSL_API WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY_bio( + WOLFSSL_BIO* bio, WOLFSSL_PKCS8_PRIV_KEY_INFO** pkey); +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY_bio(WOLFSSL_BIO* bio, + WOLFSSL_EVP_PKEY** out); +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY** key, + unsigned char** in, long inSz); +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, + WOLFSSL_EVP_PKEY** out, const unsigned char **in, long inSz); +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_EVP(WOLFSSL_EVP_PKEY** key, + unsigned char** in, long inSz); +WOLFSSL_API int wolfSSL_i2d_PrivateKey(WOLFSSL_EVP_PKEY* key, + unsigned char** der); +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_PKEY_new_ex(void* heap); +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_PKEY_new(void); +WOLFSSL_API int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME*); +#ifdef OPENSSL_EXTRA +WOLFSSL_API int wolfSSL_X509_cmp_time(const WOLFSSL_ASN1_TIME* asnTime, + time_t *cmpTime); +WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj_ex(WOLFSSL_ASN1_TIME *asnTime, + int offset_day, long offset_sec, time_t *in_tm); +WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj(WOLFSSL_ASN1_TIME *asnTime, + long offset_sec, time_t *in_tm); +WOLFSSL_API int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED*); +WOLFSSL_API void wolfSSL_X509_STORE_CTX_set_time(WOLFSSL_X509_STORE_CTX*, + unsigned long flags, + time_t t); +WOLFSSL_API void wolfSSL_X509_VERIFY_PARAM_set_hostflags( + WOLFSSL_X509_VERIFY_PARAM* param, unsigned int flags); +WOLFSSL_API int wolfSSL_X509_VERIFY_PARAM_set1_host(WOLFSSL_X509_VERIFY_PARAM* pParam, + const char* name, + unsigned int nameSz); +WOLFSSL_API int wolfSSL_X509_VERIFY_PARAM_set1_ip_asc( + WOLFSSL_X509_VERIFY_PARAM *param, const char *ipasc); +#endif +WOLFSSL_API WOLFSSL_X509_REVOKED* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL*); +WOLFSSL_API WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value( + WOLFSSL_X509_REVOKED*,int); +WOLFSSL_API WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509*); +WOLFSSL_API void wolfSSL_ASN1_INTEGER_free(WOLFSSL_ASN1_INTEGER*); +WOLFSSL_API WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_new(void); +WOLFSSL_API WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_dup( + const WOLFSSL_ASN1_INTEGER* src); +WOLFSSL_API int wolfSSL_ASN1_INTEGER_set(WOLFSSL_ASN1_INTEGER *a, long v); + +WOLFSSL_API int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO*, const WOLFSSL_ASN1_TIME*); + +WOLFSSL_API char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* t, + char* buf, int len); +WOLFSSL_API int wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER*, + const WOLFSSL_ASN1_INTEGER*); +WOLFSSL_API long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER*); + +#ifdef OPENSSL_EXTRA +WOLFSSL_API WOLFSSL_BIGNUM *wolfSSL_ASN1_INTEGER_to_BN(const WOLFSSL_ASN1_INTEGER *ai, + WOLFSSL_BIGNUM *bn); +WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_adj(WOLFSSL_ASN1_TIME*, time_t, + int, long); +#endif + +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char*); +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_CTX_get_client_CA_list( + const WOLFSSL_CTX *s); +/* depricated function name */ +#define wolfSSL_SSL_CTX_get_client_CA_list wolfSSL_CTX_get_client_CA_list + +WOLFSSL_API void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX*, + WOLF_STACK_OF(WOLFSSL_X509_NAME)*); +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_get_client_CA_list( + const WOLFSSL* ssl); + +typedef int (*client_cert_cb)(WOLFSSL *ssl, WOLFSSL_X509 **x509, + WOLFSSL_EVP_PKEY **pkey); +WOLFSSL_API void wolfSSL_CTX_set_client_cert_cb(WOLFSSL_CTX *ctx, client_cert_cb); + +WOLFSSL_API void* wolfSSL_X509_STORE_CTX_get_ex_data( + WOLFSSL_X509_STORE_CTX* ctx, int idx); +WOLFSSL_API int wolfSSL_X509_STORE_CTX_set_ex_data(WOLFSSL_X509_STORE_CTX* ctx, + int idx, void *data); +WOLFSSL_API void wolfSSL_X509_STORE_CTX_set_depth(WOLFSSL_X509_STORE_CTX* ctx, + int depth); +WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get0_current_issuer( + WOLFSSL_X509_STORE_CTX* ctx); +WOLFSSL_API WOLFSSL_X509_STORE* wolfSSL_X509_STORE_CTX_get0_store( + WOLFSSL_X509_STORE_CTX* ctx); +WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get0_cert( + WOLFSSL_X509_STORE_CTX*); +WOLFSSL_API int wolfSSL_get_ex_data_X509_STORE_CTX_idx(void); +WOLFSSL_API void wolfSSL_X509_STORE_CTX_set_error( + WOLFSSL_X509_STORE_CTX* ctx, int er); +WOLFSSL_API void* wolfSSL_get_ex_data(const WOLFSSL*, int); + +WOLFSSL_API void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX*, + void* userdata); +WOLFSSL_API void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX*, + pem_password_cb*); +WOLFSSL_API pem_password_cb* wolfSSL_CTX_get_default_passwd_cb(WOLFSSL_CTX *ctx); +WOLFSSL_API void *wolfSSL_CTX_get_default_passwd_cb_userdata(WOLFSSL_CTX *ctx); + +WOLFSSL_API void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX*, + void (*)(const WOLFSSL* ssl, int type, int val)); + +WOLFSSL_API unsigned long wolfSSL_ERR_peek_error(void); +WOLFSSL_API int wolfSSL_GET_REASON(int); + +WOLFSSL_API const char* wolfSSL_alert_type_string_long(int); +WOLFSSL_API const char* wolfSSL_alert_desc_string_long(int); +WOLFSSL_API const char* wolfSSL_state_string_long(const WOLFSSL*); + +WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSA_generate_key(int, unsigned long, + void(*)(int, int, void*), void*); +WOLFSSL_API WOLFSSL_RSA *wolfSSL_d2i_RSAPublicKey(WOLFSSL_RSA **r, + const unsigned char **pp, long len); +WOLFSSL_API WOLFSSL_RSA *wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA**, + const unsigned char**, long); +WOLFSSL_API int wolfSSL_i2d_RSAPublicKey(WOLFSSL_RSA *r, const unsigned char **pp); +WOLFSSL_API int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *r, unsigned char **pp); +WOLFSSL_API void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX *, + WOLFSSL_RSA *(*)(WOLFSSL *, int, int)); + +WOLFSSL_API int wolfSSL_PEM_def_callback(char*, int num, int w, void* key); + +WOLFSSL_API long wolfSSL_CTX_sess_accept(WOLFSSL_CTX*); +WOLFSSL_API long wolfSSL_CTX_sess_connect(WOLFSSL_CTX*); +WOLFSSL_API long wolfSSL_CTX_sess_accept_good(WOLFSSL_CTX*); +WOLFSSL_API long wolfSSL_CTX_sess_connect_good(WOLFSSL_CTX*); +WOLFSSL_API long wolfSSL_CTX_sess_accept_renegotiate(WOLFSSL_CTX*); +WOLFSSL_API long wolfSSL_CTX_sess_connect_renegotiate(WOLFSSL_CTX*); +WOLFSSL_API long wolfSSL_CTX_sess_hits(WOLFSSL_CTX*); +WOLFSSL_API long wolfSSL_CTX_sess_cb_hits(WOLFSSL_CTX*); +WOLFSSL_API long wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX*); +WOLFSSL_API long wolfSSL_CTX_sess_misses(WOLFSSL_CTX*); +WOLFSSL_API long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX*); +WOLFSSL_API long wolfSSL_CTX_sess_number(WOLFSSL_CTX*); + +WOLFSSL_API long wolfSSL_CTX_add_extra_chain_cert(WOLFSSL_CTX*, WOLFSSL_X509*); +WOLFSSL_API long wolfSSL_CTX_sess_set_cache_size(WOLFSSL_CTX*, long); +WOLFSSL_API long wolfSSL_CTX_sess_get_cache_size(WOLFSSL_CTX*); + +WOLFSSL_API long wolfSSL_CTX_get_session_cache_mode(WOLFSSL_CTX*); +WOLFSSL_API int wolfSSL_CTX_get_read_ahead(WOLFSSL_CTX*); +WOLFSSL_API int wolfSSL_CTX_set_read_ahead(WOLFSSL_CTX*, int v); +WOLFSSL_API long wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX*, void* arg); +WOLFSSL_API long wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg( + WOLFSSL_CTX*, void* arg); +WOLFSSL_API int wolfSSL_CTX_add_client_CA(WOLFSSL_CTX*, WOLFSSL_X509*); +WOLFSSL_API int wolfSSL_CTX_set_srp_password(WOLFSSL_CTX*, char*); +WOLFSSL_API int wolfSSL_CTX_set_srp_username(WOLFSSL_CTX*, char*); + +WOLFSSL_API long wolfSSL_set_options(WOLFSSL *s, long op); +WOLFSSL_API long wolfSSL_get_options(const WOLFSSL *s); +WOLFSSL_API long wolfSSL_clear_options(WOLFSSL *s, long op); +WOLFSSL_API long wolfSSL_clear_num_renegotiations(WOLFSSL *s); +WOLFSSL_API long wolfSSL_total_renegotiations(WOLFSSL *s); +WOLFSSL_API long wolfSSL_num_renegotiations(WOLFSSL* s); +WOLFSSL_API long wolfSSL_set_tmp_dh(WOLFSSL *s, WOLFSSL_DH *dh); +WOLFSSL_API long wolfSSL_set_tlsext_debug_arg(WOLFSSL *s, void *arg); +WOLFSSL_API long wolfSSL_set_tlsext_status_type(WOLFSSL *s, int type); +WOLFSSL_API long wolfSSL_set_tlsext_status_exts(WOLFSSL *s, void *arg); +WOLFSSL_API long wolfSSL_get_tlsext_status_ids(WOLFSSL *s, void *arg); +WOLFSSL_API long wolfSSL_set_tlsext_status_ids(WOLFSSL *s, void *arg); +WOLFSSL_API long wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char **resp); +WOLFSSL_API long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char *resp, int len); + +WOLFSSL_API void wolfSSL_CONF_modules_unload(int all); +WOLFSSL_API long wolfSSL_get_tlsext_status_exts(WOLFSSL *s, void *arg); +WOLFSSL_API long wolfSSL_get_verify_result(const WOLFSSL *ssl); + +#define WOLFSSL_DEFAULT_CIPHER_LIST "" /* default all */ + +enum { + WOLFSSL_OCSP_URL_OVERRIDE = 1, + WOLFSSL_OCSP_NO_NONCE = 2, + WOLFSSL_OCSP_CHECKALL = 4, + + WOLFSSL_CRL_CHECKALL = 1, + WOLFSSL_CRL_CHECK = 27, +}; + +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \ + defined(HAVE_WEBSERVER) +/* seperated out from other enums because of size */ +enum { + SSL_OP_MICROSOFT_SESS_ID_BUG = 0x00000001, + SSL_OP_NETSCAPE_CHALLENGE_BUG = 0x00000002, + SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = 0x00000004, + SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG = 0x00000008, + SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER = 0x00000010, + SSL_OP_MSIE_SSLV2_RSA_PADDING = 0x00000020, + SSL_OP_SSLEAY_080_CLIENT_DH_BUG = 0x00000040, + SSL_OP_TLS_D5_BUG = 0x00000080, + SSL_OP_TLS_BLOCK_PADDING_BUG = 0x00000100, + SSL_OP_TLS_ROLLBACK_BUG = 0x00000200, + SSL_OP_ALL = 0x00000400, + SSL_OP_EPHEMERAL_RSA = 0x00000800, + WOLFSSL_OP_NO_SSLv3 = 0x00001000, + WOLFSSL_OP_NO_TLSv1 = 0x00002000, + SSL_OP_PKCS1_CHECK_1 = 0x00004000, + SSL_OP_PKCS1_CHECK_2 = 0x00008000, + SSL_OP_NETSCAPE_CA_DN_BUG = 0x00010000, + SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = 0x00020000, + SSL_OP_SINGLE_DH_USE = 0x00040000, + SSL_OP_NO_TICKET = 0x00080000, + SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = 0x00100000, + SSL_OP_NO_QUERY_MTU = 0x00200000, + SSL_OP_COOKIE_EXCHANGE = 0x00400000, + SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = 0x00800000, + SSL_OP_SINGLE_ECDH_USE = 0x01000000, + SSL_OP_CIPHER_SERVER_PREFERENCE = 0x02000000, + WOLFSSL_OP_NO_TLSv1_1 = 0x04000000, + WOLFSSL_OP_NO_TLSv1_2 = 0x08000000, + SSL_OP_NO_COMPRESSION = 0x10000000, + WOLFSSL_OP_NO_TLSv1_3 = 0x20000000, + WOLFSSL_OP_NO_SSLv2 = 0x40000000, +}; + +/* for compatibility these must be macros */ +#define SSL_OP_NO_SSLv2 WOLFSSL_OP_NO_SSLv2 +#define SSL_OP_NO_SSLv3 WOLFSSL_OP_NO_SSLv3 +#define SSL_OP_NO_TLSv1 WOLFSSL_OP_NO_TLSv1 +#define SSL_OP_NO_TLSv1_1 WOLFSSL_OP_NO_TLSv1_1 +#define SSL_OP_NO_TLSv1_2 WOLFSSL_OP_NO_TLSv1_2 +#if !(!defined(WOLFSSL_TLS13) && defined(WOLFSSL_APACHE_HTTPD)) /* apache uses this to determine if TLS 1.3 is enabled */ +#define SSL_OP_NO_TLSv1_3 WOLFSSL_OP_NO_TLSv1_3 +#endif + +#define SSL_OP_NO_SSL_MASK (SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | \ + SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_3) + +#define SSL_NOTHING 1 +#define SSL_WRITING 2 +#define SSL_READING 3 + +enum { +#ifdef HAVE_OCSP + /* OCSP Flags */ + OCSP_NOCERTS = 1, + OCSP_NOINTERN = 2, + OCSP_NOSIGS = 4, + OCSP_NOCHAIN = 8, + OCSP_NOVERIFY = 16, + OCSP_NOEXPLICIT = 32, + OCSP_NOCASIGN = 64, + OCSP_NODELEGATED = 128, + OCSP_NOCHECKS = 256, + OCSP_TRUSTOTHER = 512, + OCSP_RESPID_KEY = 1024, + OCSP_NOTIME = 2048, + + /* OCSP Types */ + OCSP_CERTID = 2, + OCSP_REQUEST = 4, + OCSP_RESPONSE = 8, + OCSP_BASICRESP = 16, +#endif + + ASN1_GENERALIZEDTIME = 4, + SSL_MAX_SSL_SESSION_ID_LENGTH = 32, + + EVP_R_BAD_DECRYPT = 2, + + SSL_ST_CONNECT = 0x1000, + SSL_ST_ACCEPT = 0x2000, + SSL_ST_MASK = 0x0FFF, + + SSL_CB_LOOP = 0x01, + SSL_CB_EXIT = 0x02, + SSL_CB_READ = 0x04, + SSL_CB_WRITE = 0x08, + SSL_CB_HANDSHAKE_START = 0x10, + SSL_CB_HANDSHAKE_DONE = 0x20, + SSL_CB_ALERT = 0x4000, + SSL_CB_READ_ALERT = (SSL_CB_ALERT | SSL_CB_READ), + SSL_CB_WRITE_ALERT = (SSL_CB_ALERT | SSL_CB_WRITE), + SSL_CB_ACCEPT_LOOP = (SSL_ST_ACCEPT | SSL_CB_LOOP), + SSL_CB_ACCEPT_EXIT = (SSL_ST_ACCEPT | SSL_CB_EXIT), + SSL_CB_CONNECT_LOOP = (SSL_ST_CONNECT | SSL_CB_LOOP), + SSL_CB_CONNECT_EXIT = (SSL_ST_CONNECT | SSL_CB_EXIT), + SSL_CB_MODE_READ = 1, + SSL_CB_MODE_WRITE = 2, + + SSL_MODE_ENABLE_PARTIAL_WRITE = 2, + SSL_MODE_RELEASE_BUFFERS = -1, /* For libwebsockets build. No current use. */ + + BIO_FLAGS_BASE64_NO_NL = 1, + BIO_CLOSE = 1, + BIO_NOCLOSE = 0, + + X509_FILETYPE_PEM = 8, + X509_LU_X509 = 9, + X509_LU_CRL = 12, + + X509_V_OK = 0, + X509_V_ERR_CRL_SIGNATURE_FAILURE = 13, + X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD = 14, + X509_V_ERR_CRL_HAS_EXPIRED = 15, + X509_V_ERR_CERT_REVOKED = 16, + X509_V_ERR_CERT_CHAIN_TOO_LONG = 17, + X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT = 18, + X509_V_ERR_CERT_NOT_YET_VALID = 19, + X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD = 20, + X509_V_ERR_CERT_HAS_EXPIRED = 21, + X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD = 22, + X509_V_ERR_CERT_REJECTED = 23, + /* Required for Nginx */ + X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT = 24, + X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN = 25, + X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY = 26, + X509_V_ERR_CERT_UNTRUSTED = 27, + X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE = 28, + X509_V_ERR_SUBJECT_ISSUER_MISMATCH = 29, + /* additional X509_V_ERR_* enums not used in wolfSSL */ + X509_V_ERR_UNABLE_TO_GET_CRL, + X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE, + X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE, + X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY, + X509_V_ERR_CERT_SIGNATURE_FAILURE, + X509_V_ERR_CRL_NOT_YET_VALID, + X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD, + X509_V_ERR_OUT_OF_MEM, + X509_V_ERR_INVALID_CA, + X509_V_ERR_PATH_LENGTH_EXCEEDED, + X509_V_ERR_INVALID_PURPOSE, + X509_V_ERR_AKID_SKID_MISMATCH, + X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH, + X509_V_ERR_KEYUSAGE_NO_CERTSIGN, + X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER, + X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION, + X509_V_ERR_KEYUSAGE_NO_CRL_SIGN, + X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION, + X509_V_ERR_INVALID_NON_CA, + X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED, + X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE, + X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED, + X509_V_ERR_INVALID_EXTENSION, + X509_V_ERR_INVALID_POLICY_EXTENSION, + X509_V_ERR_NO_EXPLICIT_POLICY, + X509_V_ERR_UNNESTED_RESOURCE, + X509_V_ERR_APPLICATION_VERIFICATION, + + X509_R_CERT_ALREADY_IN_HASH_TABLE, + + XN_FLAG_SPC_EQ = (1 << 23), + XN_FLAG_SEP_CPLUS_SPC = (2 << 16), + XN_FLAG_ONELINE = 0, + XN_FLAG_RFC2253 = 1, + XN_FLAG_DN_REV = (1 << 20), + + CRYPTO_LOCK = 1, + CRYPTO_NUM_LOCKS = 10, + + ASN1_STRFLGS_ESC_MSB = 4 +}; +#endif + +/* extras end */ + +#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) +/* wolfSSL extension, provide last error from SSL_get_error + since not using thread storage error queue */ +#include +WOLFSSL_API void wolfSSL_ERR_print_errors_fp(XFILE, int err); +#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) +WOLFSSL_API void wolfSSL_ERR_dump_errors_fp(XFILE fp); +#endif +#endif +WOLFSSL_API void wolfSSL_ERR_print_errors(WOLFSSL_BIO *bio); + + +#ifndef NO_OLD_SSL_NAMES + #define SSL_ERROR_NONE WOLFSSL_ERROR_NONE + #define SSL_FAILURE WOLFSSL_FAILURE + #define SSL_SUCCESS WOLFSSL_SUCCESS + #define SSL_SHUTDOWN_NOT_DONE WOLFSSL_SHUTDOWN_NOT_DONE + + #define SSL_ALPN_NOT_FOUND WOLFSSL_ALPN_NOT_FOUND + #define SSL_BAD_CERTTYPE WOLFSSL_BAD_CERTTYPE + #define SSL_BAD_STAT WOLFSSL_BAD_STAT + #define SSL_BAD_PATH WOLFSSL_BAD_PATH + #define SSL_BAD_FILETYPE WOLFSSL_BAD_FILETYPE + #define SSL_BAD_FILE WOLFSSL_BAD_FILE + #define SSL_NOT_IMPLEMENTED WOLFSSL_NOT_IMPLEMENTED + #define SSL_UNKNOWN WOLFSSL_UNKNOWN + #define SSL_FATAL_ERROR WOLFSSL_FATAL_ERROR + + #define SSL_FILETYPE_ASN1 WOLFSSL_FILETYPE_ASN1 + #define SSL_FILETYPE_PEM WOLFSSL_FILETYPE_PEM + #define SSL_FILETYPE_DEFAULT WOLFSSL_FILETYPE_DEFAULT + #define SSL_FILETYPE_RAW WOLFSSL_FILETYPE_RAW + + #define SSL_VERIFY_NONE WOLFSSL_VERIFY_NONE + #define SSL_VERIFY_PEER WOLFSSL_VERIFY_PEER + #define SSL_VERIFY_FAIL_IF_NO_PEER_CERT WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT + #define SSL_VERIFY_CLIENT_ONCE WOLFSSL_VERIFY_CLIENT_ONCE + #define SSL_VERIFY_FAIL_EXCEPT_PSK WOLFSSL_VERIFY_FAIL_EXCEPT_PSK + + #define SSL_SESS_CACHE_OFF WOLFSSL_SESS_CACHE_OFF + #define SSL_SESS_CACHE_CLIENT WOLFSSL_SESS_CACHE_CLIENT + #define SSL_SESS_CACHE_SERVER WOLFSSL_SESS_CACHE_SERVER + #define SSL_SESS_CACHE_BOTH WOLFSSL_SESS_CACHE_BOTH + #define SSL_SESS_CACHE_NO_AUTO_CLEAR WOLFSSL_SESS_CACHE_NO_AUTO_CLEAR + #define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP WOLFSSL_SESS_CACHE_NO_INTERNAL_LOOKUP + #define SSL_SESS_CACHE_NO_INTERNAL_STORE WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE + #define SSL_SESS_CACHE_NO_INTERNAL WOLFSSL_SESS_CACHE_NO_INTERNAL + + #define SSL_ERROR_WANT_READ WOLFSSL_ERROR_WANT_READ + #define SSL_ERROR_WANT_WRITE WOLFSSL_ERROR_WANT_WRITE + #define SSL_ERROR_WANT_CONNECT WOLFSSL_ERROR_WANT_CONNECT + #define SSL_ERROR_WANT_ACCEPT WOLFSSL_ERROR_WANT_ACCEPT + #define SSL_ERROR_SYSCALL WOLFSSL_ERROR_SYSCALL + #define SSL_ERROR_WANT_X509_LOOKUP WOLFSSL_ERROR_WANT_X509_LOOKUP + #define SSL_ERROR_ZERO_RETURN WOLFSSL_ERROR_ZERO_RETURN + #define SSL_ERROR_SSL WOLFSSL_ERROR_SSL + + #define SSL_SENT_SHUTDOWN WOLFSSL_SENT_SHUTDOWN + #define SSL_RECEIVED_SHUTDOWN WOLFSSL_RECEIVED_SHUTDOWN + #define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER + + #define SSL_R_SSL_HANDSHAKE_FAILURE WOLFSSL_R_SSL_HANDSHAKE_FAILURE + #define SSL_R_TLSV1_ALERT_UNKNOWN_CA WOLFSSL_R_TLSV1_ALERT_UNKNOWN_CA + #define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN WOLFSSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN + #define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE WOLFSSL_R_SSLV3_ALERT_BAD_CERTIFICATE + + #define PEM_BUFSIZE WOLF_PEM_BUFSIZE +#endif + +enum { /* ssl Constants */ + WOLFSSL_ERROR_NONE = 0, /* for most functions */ + WOLFSSL_FAILURE = 0, /* for some functions */ + WOLFSSL_SUCCESS = 1, + WOLFSSL_SHUTDOWN_NOT_DONE = 2, /* call wolfSSL_shutdown again to complete */ + + WOLFSSL_ALPN_NOT_FOUND = -9, + WOLFSSL_BAD_CERTTYPE = -8, + WOLFSSL_BAD_STAT = -7, + WOLFSSL_BAD_PATH = -6, + WOLFSSL_BAD_FILETYPE = -5, + WOLFSSL_BAD_FILE = -4, + WOLFSSL_NOT_IMPLEMENTED = -3, + WOLFSSL_UNKNOWN = -2, + WOLFSSL_FATAL_ERROR = -1, + + WOLFSSL_FILETYPE_ASN1 = 2, + WOLFSSL_FILETYPE_PEM = 1, + WOLFSSL_FILETYPE_DEFAULT = 2, /* ASN1 */ + WOLFSSL_FILETYPE_RAW = 3, /* NTRU raw key blob */ + + WOLFSSL_VERIFY_NONE = 0, + WOLFSSL_VERIFY_PEER = 1, + WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT = 2, + WOLFSSL_VERIFY_CLIENT_ONCE = 4, + WOLFSSL_VERIFY_FAIL_EXCEPT_PSK = 8, + + WOLFSSL_SESS_CACHE_OFF = 0x0000, + WOLFSSL_SESS_CACHE_CLIENT = 0x0001, + WOLFSSL_SESS_CACHE_SERVER = 0x0002, + WOLFSSL_SESS_CACHE_BOTH = 0x0003, + WOLFSSL_SESS_CACHE_NO_AUTO_CLEAR = 0x0008, + WOLFSSL_SESS_CACHE_NO_INTERNAL_LOOKUP = 0x0100, + WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE = 0x0200, + WOLFSSL_SESS_CACHE_NO_INTERNAL = 0x0300, + + WOLFSSL_ERROR_WANT_READ = 2, + WOLFSSL_ERROR_WANT_WRITE = 3, + WOLFSSL_ERROR_WANT_CONNECT = 7, + WOLFSSL_ERROR_WANT_ACCEPT = 8, + WOLFSSL_ERROR_SYSCALL = 5, + WOLFSSL_ERROR_WANT_X509_LOOKUP = 83, + WOLFSSL_ERROR_ZERO_RETURN = 6, + WOLFSSL_ERROR_SSL = 85, + + WOLFSSL_SENT_SHUTDOWN = 1, + WOLFSSL_RECEIVED_SHUTDOWN = 2, + WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER = 4, + + WOLFSSL_R_SSL_HANDSHAKE_FAILURE = 101, + WOLFSSL_R_TLSV1_ALERT_UNKNOWN_CA = 102, + WOLFSSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN = 103, + WOLFSSL_R_SSLV3_ALERT_BAD_CERTIFICATE = 104, + + WOLF_PEM_BUFSIZE = 1024 +}; + +#ifndef NO_PSK + typedef unsigned int (*wc_psk_client_callback)(WOLFSSL*, const char*, char*, + unsigned int, unsigned char*, unsigned int); + WOLFSSL_API void wolfSSL_CTX_set_psk_client_callback(WOLFSSL_CTX*, + wc_psk_client_callback); + WOLFSSL_API void wolfSSL_set_psk_client_callback(WOLFSSL*, + wc_psk_client_callback); +#ifdef WOLFSSL_TLS13 + typedef unsigned int (*wc_psk_client_tls13_callback)(WOLFSSL*, const char*, + char*, unsigned int, unsigned char*, unsigned int, const char**); + WOLFSSL_API void wolfSSL_CTX_set_psk_client_tls13_callback(WOLFSSL_CTX*, + wc_psk_client_tls13_callback); + WOLFSSL_API void wolfSSL_set_psk_client_tls13_callback(WOLFSSL*, + wc_psk_client_tls13_callback); +#endif + + WOLFSSL_API const char* wolfSSL_get_psk_identity_hint(const WOLFSSL*); + WOLFSSL_API const char* wolfSSL_get_psk_identity(const WOLFSSL*); + + WOLFSSL_API int wolfSSL_CTX_use_psk_identity_hint(WOLFSSL_CTX*, const char*); + WOLFSSL_API int wolfSSL_use_psk_identity_hint(WOLFSSL*, const char*); + + typedef unsigned int (*wc_psk_server_callback)(WOLFSSL*, const char*, + unsigned char*, unsigned int); + WOLFSSL_API void wolfSSL_CTX_set_psk_server_callback(WOLFSSL_CTX*, + wc_psk_server_callback); + WOLFSSL_API void wolfSSL_set_psk_server_callback(WOLFSSL*, + wc_psk_server_callback); +#ifdef WOLFSSL_TLS13 + typedef unsigned int (*wc_psk_server_tls13_callback)(WOLFSSL*, const char*, + unsigned char*, unsigned int, const char**); + WOLFSSL_API void wolfSSL_CTX_set_psk_server_tls13_callback(WOLFSSL_CTX*, + wc_psk_server_tls13_callback); + WOLFSSL_API void wolfSSL_set_psk_server_tls13_callback(WOLFSSL*, + wc_psk_server_tls13_callback); +#endif + + #define PSK_TYPES_DEFINED +#endif /* NO_PSK */ + + +#ifdef HAVE_ANON + WOLFSSL_API int wolfSSL_CTX_allow_anon_cipher(WOLFSSL_CTX*); +#endif /* HAVE_ANON */ + + +/* extra begins */ +#ifdef OPENSSL_EXTRA +enum { /* ERR Constants */ + ERR_TXT_STRING = 1 +}; + +/* bio misc */ +enum { + WOLFSSL_BIO_ERROR = -1, + WOLFSSL_BIO_UNSET = -2, + WOLFSSL_BIO_SIZE = 17000 /* default BIO write size if not set */ +}; +#endif + +WOLFSSL_API void wolfSSL_ERR_put_error(int lib, int fun, int err, + const char* file, int line); +WOLFSSL_API unsigned long wolfSSL_ERR_get_error_line(const char**, int*); +WOLFSSL_API unsigned long wolfSSL_ERR_get_error_line_data(const char**, int*, + const char**, int *); + +WOLFSSL_API unsigned long wolfSSL_ERR_get_error(void); +WOLFSSL_API void wolfSSL_ERR_clear_error(void); + + +WOLFSSL_API int wolfSSL_RAND_status(void); +WOLFSSL_API int wolfSSL_RAND_pseudo_bytes(unsigned char* buf, int num); +WOLFSSL_API int wolfSSL_RAND_bytes(unsigned char* buf, int num); +WOLFSSL_API WOLFSSL_METHOD *wolfSSLv23_server_method(void); +WOLFSSL_API long wolfSSL_CTX_set_options(WOLFSSL_CTX*, long); +WOLFSSL_API long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx); +WOLFSSL_API long wolfSSL_CTX_clear_options(WOLFSSL_CTX*, long); + +#ifndef NO_CERTS + WOLFSSL_API int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX*); +#endif /* !NO_CERTS */ + +WOLFSSL_API void wolfSSL_ERR_free_strings(void); +WOLFSSL_API void wolfSSL_ERR_remove_state(unsigned long); +WOLFSSL_API int wolfSSL_clear(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_state(WOLFSSL* ssl); + +WOLFSSL_API void wolfSSL_cleanup_all_ex_data(void); +WOLFSSL_API long wolfSSL_CTX_set_mode(WOLFSSL_CTX* ctx, long mode); +WOLFSSL_API long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx); +WOLFSSL_API void wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX* ctx, int m); +WOLFSSL_API long wolfSSL_SSL_get_mode(WOLFSSL* ssl); + + +WOLFSSL_API int wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX*); +WOLFSSL_API int wolfSSL_CTX_set_session_id_context(WOLFSSL_CTX*, + const unsigned char*, unsigned int); +WOLFSSL_ABI WOLFSSL_API WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL*); +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL*); + +#ifdef OPENSSL_EXTRA +WOLFSSL_API int wolfSSL_want(WOLFSSL*); +#endif +WOLFSSL_API int wolfSSL_want_read(WOLFSSL*); +WOLFSSL_API int wolfSSL_want_write(WOLFSSL*); + +WOLFSSL_API int wolfSSL_BIO_printf(WOLFSSL_BIO*, const char*, ...); +WOLFSSL_API int wolfSSL_BIO_dump(WOLFSSL_BIO *bio, const char*, int); +WOLFSSL_API int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO*, + const WOLFSSL_ASN1_UTCTIME*); +WOLFSSL_API int wolfSSL_ASN1_GENERALIZEDTIME_print(WOLFSSL_BIO*, + const WOLFSSL_ASN1_GENERALIZEDTIME*); +WOLFSSL_API void wolfSSL_ASN1_GENERALIZEDTIME_free(WOLFSSL_ASN1_GENERALIZEDTIME*); +WOLFSSL_API int wolfSSL_ASN1_TIME_check(const WOLFSSL_ASN1_TIME*); +WOLFSSL_API int wolfSSL_ASN1_TIME_diff(int *pday, int *psec, + const WOLFSSL_ASN1_TIME *from, const WOLFSSL_ASN1_TIME *to); +#ifdef OPENSSL_EXTRA +WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_set(WOLFSSL_ASN1_TIME *s, time_t t); +#endif + +WOLFSSL_API int wolfSSL_sk_num(WOLFSSL_STACK* sk); +WOLFSSL_API void* wolfSSL_sk_value(WOLFSSL_STACK* sk, int i); + +/* stunnel 4.28 needs */ +WOLFSSL_API void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX*, int); +WOLFSSL_API int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX*, int, void*); +WOLFSSL_API void wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX*, + WOLFSSL_SESSION*(*f)(WOLFSSL*, unsigned char*, int, int*)); +WOLFSSL_API void wolfSSL_CTX_sess_set_new_cb(WOLFSSL_CTX*, + int (*f)(WOLFSSL*, WOLFSSL_SESSION*)); +WOLFSSL_API void wolfSSL_CTX_sess_set_remove_cb(WOLFSSL_CTX*, + void (*f)(WOLFSSL_CTX*, WOLFSSL_SESSION*)); + +WOLFSSL_API int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION*,unsigned char**); +WOLFSSL_API WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION**, + const unsigned char**, long); + +WOLFSSL_API long wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION*); +WOLFSSL_API long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION*); +WOLFSSL_API int wolfSSL_CTX_get_ex_new_index(long, void*, void*, void*, void*); + +/* extra ends */ + + +/* wolfSSL extensions */ + +/* call before SSL_connect, if verifying will add name check to + date check and signature check */ +WOLFSSL_ABI WOLFSSL_API int wolfSSL_check_domain_name(WOLFSSL*, const char*); + +/* need to call once to load library (session cache) */ +WOLFSSL_ABI WOLFSSL_API int wolfSSL_Init(void); +/* call when done to cleanup/free session cache mutex / resources */ +WOLFSSL_ABI WOLFSSL_API int wolfSSL_Cleanup(void); + +/* which library version do we have */ +WOLFSSL_API const char* wolfSSL_lib_version(void); +/* which library version do we have in hex */ +WOLFSSL_API word32 wolfSSL_lib_version_hex(void); + +/* do accept or connect depedning on side */ +WOLFSSL_API int wolfSSL_negotiate(WOLFSSL* ssl); +/* turn on wolfSSL data compression */ +WOLFSSL_API int wolfSSL_set_compression(WOLFSSL* ssl); + +WOLFSSL_ABI WOLFSSL_API int wolfSSL_set_timeout(WOLFSSL*, unsigned int); +WOLFSSL_ABI WOLFSSL_API int wolfSSL_CTX_set_timeout(WOLFSSL_CTX*, unsigned int); +WOLFSSL_API void wolfSSL_CTX_set_current_time_cb(WOLFSSL_CTX* ctx, + void (*cb)(const WOLFSSL* ssl, Timeval* out_clock)); + +/* get wolfSSL peer X509_CHAIN */ +WOLFSSL_API WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl); +#ifdef WOLFSSL_ALT_CERT_CHAINS +WOLFSSL_API int wolfSSL_is_peer_alt_cert_chain(const WOLFSSL* ssl); +/* get wolfSSL alternate peer X509_CHAIN */ +WOLFSSL_API WOLFSSL_X509_CHAIN* wolfSSL_get_peer_alt_chain(WOLFSSL* ssl); +#endif +/* peer chain count */ +WOLFSSL_API int wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain); +/* index cert length */ +WOLFSSL_API int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN*, int idx); +/* index cert */ +WOLFSSL_API unsigned char* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN*, int idx); +/* index cert in X509 */ +WOLFSSL_API WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN*, int idx); +/* free X509 */ +#define wolfSSL_FreeX509(x509) wolfSSL_X509_free((x509)) +WOLFSSL_ABI WOLFSSL_API void wolfSSL_X509_free(WOLFSSL_X509*); +/* get index cert in PEM */ +WOLFSSL_API int wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN*, int idx, + unsigned char* buf, int inLen, int* outLen); +WOLFSSL_ABI WOLFSSL_API const unsigned char* wolfSSL_get_sessionID( + const WOLFSSL_SESSION* s); +WOLFSSL_API int wolfSSL_X509_get_serial_number(WOLFSSL_X509*,unsigned char*,int*); +WOLFSSL_API char* wolfSSL_X509_get_subjectCN(WOLFSSL_X509*); +WOLFSSL_API const unsigned char* wolfSSL_X509_get_der(WOLFSSL_X509*, int*); +WOLFSSL_API const unsigned char* wolfSSL_X509_get_tbs(WOLFSSL_X509*, int*); +WOLFSSL_ABI WOLFSSL_API const byte* wolfSSL_X509_notBefore(WOLFSSL_X509*); +WOLFSSL_ABI WOLFSSL_API const byte* wolfSSL_X509_notAfter(WOLFSSL_X509*); +WOLFSSL_API int wolfSSL_X509_version(WOLFSSL_X509*); + +WOLFSSL_API int wolfSSL_cmp_peer_cert_to_file(WOLFSSL*, const char*); + +WOLFSSL_ABI WOLFSSL_API char* wolfSSL_X509_get_next_altname(WOLFSSL_X509*); + +WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509, + const unsigned char** in, int len); +WOLFSSL_API WOLFSSL_X509* + wolfSSL_X509_d2i(WOLFSSL_X509** x509, const unsigned char* in, int len); +WOLFSSL_API int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out); +WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL **crl, + const unsigned char *in, int len); +#ifndef NO_FILESYSTEM +WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_fp(XFILE file, WOLFSSL_X509_CRL **crl); +#endif +WOLFSSL_API void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl); + +#ifndef NO_FILESYSTEM + #ifndef NO_STDIO_FILESYSTEM + WOLFSSL_API WOLFSSL_X509* + wolfSSL_X509_d2i_fp(WOLFSSL_X509** x509, XFILE file); + #endif +WOLFSSL_ABI WOLFSSL_API WOLFSSL_X509* + wolfSSL_X509_load_certificate_file(const char* fname, int format); +#endif +WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer( + const unsigned char* buf, int sz, int format); + +#ifdef WOLFSSL_SEP + WOLFSSL_API unsigned char* + wolfSSL_X509_get_device_type(WOLFSSL_X509*, unsigned char*, int*); + WOLFSSL_API unsigned char* + wolfSSL_X509_get_hw_type(WOLFSSL_X509*, unsigned char*, int*); + WOLFSSL_API unsigned char* + wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509*, unsigned char*, int*); +#endif + +/* connect enough to get peer cert */ +WOLFSSL_API int wolfSSL_connect_cert(WOLFSSL* ssl); + + + +/* PKCS12 compatibility */ +typedef struct WC_PKCS12 WC_PKCS12; +WOLFSSL_API WC_PKCS12* wolfSSL_d2i_PKCS12_bio(WOLFSSL_BIO* bio, + WC_PKCS12** pkcs12); +WOLFSSL_API int wolfSSL_i2d_PKCS12_bio(WOLFSSL_BIO *bio, WC_PKCS12 *pkcs12); +#ifndef NO_FILESYSTEM +WOLFSSL_API WOLFSSL_X509_PKCS12* wolfSSL_d2i_PKCS12_fp(XFILE fp, + WOLFSSL_X509_PKCS12** pkcs12); +#endif +WOLFSSL_API int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, + WOLFSSL_EVP_PKEY** pkey, WOLFSSL_X509** cert, + WOLF_STACK_OF(WOLFSSL_X509)** ca); +WOLFSSL_API WC_PKCS12* wolfSSL_PKCS12_create(char* pass, char* name, + WOLFSSL_EVP_PKEY* pkey, WOLFSSL_X509* cert, + WOLF_STACK_OF(WOLFSSL_X509)* ca, + int keyNID, int certNID, int itt, int macItt, int keytype); +WOLFSSL_API void wolfSSL_PKCS12_PBE_add(void); + + + +#ifndef NO_DH +/* server Diffie-Hellman parameters */ +WOLFSSL_API int wolfSSL_SetTmpDH(WOLFSSL*, const unsigned char* p, int pSz, + const unsigned char* g, int gSz); +WOLFSSL_API int wolfSSL_SetTmpDH_buffer(WOLFSSL*, const unsigned char* b, long sz, + int format); +WOLFSSL_API int wolfSSL_SetEnableDhKeyTest(WOLFSSL*, int); +#ifndef NO_FILESYSTEM + WOLFSSL_API int wolfSSL_SetTmpDH_file(WOLFSSL*, const char* f, int format); +#endif + +/* server ctx Diffie-Hellman parameters */ +WOLFSSL_API int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX*, const unsigned char* p, + int pSz, const unsigned char* g, int gSz); +WOLFSSL_API int wolfSSL_CTX_SetTmpDH_buffer(WOLFSSL_CTX*, const unsigned char* b, + long sz, int format); + +#ifndef NO_FILESYSTEM + WOLFSSL_API int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX*, const char* f, + int format); +#endif + +WOLFSSL_API int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX*, word16); +WOLFSSL_API int wolfSSL_SetMinDhKey_Sz(WOLFSSL*, word16); +WOLFSSL_API int wolfSSL_CTX_SetMaxDhKey_Sz(WOLFSSL_CTX*, word16); +WOLFSSL_API int wolfSSL_SetMaxDhKey_Sz(WOLFSSL*, word16); +WOLFSSL_API int wolfSSL_GetDhKey_Sz(WOLFSSL*); +#endif /* NO_DH */ + +#ifndef NO_RSA +WOLFSSL_API int wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX*, short); +WOLFSSL_API int wolfSSL_SetMinRsaKey_Sz(WOLFSSL*, short); +#endif /* NO_RSA */ + +#ifdef HAVE_ECC +WOLFSSL_API int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX*, short); +WOLFSSL_API int wolfSSL_SetMinEccKey_Sz(WOLFSSL*, short); +#endif /* NO_RSA */ + +WOLFSSL_API int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL*, word16); +WOLFSSL_API int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX*, word16); + +/* keyblock size in bytes or -1 */ +/* need to call wolfSSL_KeepArrays before handshake to save keys */ +WOLFSSL_API int wolfSSL_get_keyblock_size(WOLFSSL*); +WOLFSSL_API int wolfSSL_get_keys(WOLFSSL*,unsigned char** ms, unsigned int* msLen, + unsigned char** sr, unsigned int* srLen, + unsigned char** cr, unsigned int* crLen); + +/* Computes EAP-TLS and EAP-TTLS keying material from the master_secret. */ +WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL*, void* key, unsigned int len, + const char* label); + + +#ifndef _WIN32 + #ifndef NO_WRITEV + #ifdef __PPU + #include + #include + #elif !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_IAR_ARM) && \ + !defined(WOLFSSL_PICOTCP) && !defined(WOLFSSL_ROWLEY_ARM) && \ + !defined(WOLFSSL_EMBOS) && !defined(WOLFSSL_FROSTED) && \ + !defined(WOLFSSL_CHIBIOS) && !defined(WOLFSSL_CONTIKI) && \ + !defined(WOLFSSL_ZEPHYR) + #include + #endif + /* allow writev style writing */ + WOLFSSL_API int wolfSSL_writev(WOLFSSL* ssl, const struct iovec* iov, + int iovcnt); + #endif +#endif + + +#ifndef NO_CERTS + /* SSL_CTX versions */ + WOLFSSL_API int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX*); +#ifdef WOLFSSL_TRUST_PEER_CERT + WOLFSSL_API int wolfSSL_CTX_Unload_trust_peers(WOLFSSL_CTX*); + WOLFSSL_API int wolfSSL_CTX_trust_peer_buffer(WOLFSSL_CTX*, + const unsigned char*, long, int); +#endif + WOLFSSL_API int wolfSSL_CTX_load_verify_buffer_ex(WOLFSSL_CTX*, + const unsigned char*, long, int, + int, word32); + WOLFSSL_API int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX*, + const unsigned char*, long, int); + WOLFSSL_API int wolfSSL_CTX_load_verify_chain_buffer_format(WOLFSSL_CTX*, + const unsigned char*, long, int); + WOLFSSL_API int wolfSSL_CTX_use_certificate_buffer(WOLFSSL_CTX*, + const unsigned char*, long, int); + WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX*, + const unsigned char*, long, int); + WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_id(WOLFSSL_CTX*, + const unsigned char*, long, int, long); + WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer_format(WOLFSSL_CTX*, + const unsigned char*, long, int); + WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX*, + const unsigned char*, long); + + /* SSL versions */ + WOLFSSL_API int wolfSSL_use_certificate_buffer(WOLFSSL*, const unsigned char*, + long, int); + WOLFSSL_API int wolfSSL_use_certificate_ASN1(WOLFSSL* ssl, unsigned char* der, + int derSz); + WOLFSSL_API int wolfSSL_use_PrivateKey_buffer(WOLFSSL*, const unsigned char*, + long, int); + WOLFSSL_API int wolfSSL_use_PrivateKey_id(WOLFSSL*, const unsigned char*, + long, int, long); + WOLFSSL_API int wolfSSL_use_certificate_chain_buffer_format(WOLFSSL*, + const unsigned char*, long, int); + WOLFSSL_API int wolfSSL_use_certificate_chain_buffer(WOLFSSL*, + const unsigned char*, long); + WOLFSSL_API int wolfSSL_UnloadCertsKeys(WOLFSSL*); + + #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ + defined(KEEP_OUR_CERT) + WOLFSSL_API WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl); + #endif +#endif + +WOLFSSL_API int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX*); +WOLFSSL_API int wolfSSL_set_group_messages(WOLFSSL*); + + +#ifdef HAVE_FUZZER +enum fuzzer_type { + FUZZ_HMAC = 0, + FUZZ_ENCRYPT = 1, + FUZZ_SIGNATURE = 2, + FUZZ_HASH = 3, + FUZZ_HEAD = 4 +}; + +typedef int (*CallbackFuzzer)(WOLFSSL* ssl, const unsigned char* buf, int sz, + int type, void* fuzzCtx); + +WOLFSSL_API void wolfSSL_SetFuzzerCb(WOLFSSL* ssl, CallbackFuzzer cbf, void* fCtx); +#endif + + +WOLFSSL_API int wolfSSL_DTLS_SetCookieSecret(WOLFSSL*, const byte*, word32); + + +/* I/O Callback default errors */ +enum IOerrors { + WOLFSSL_CBIO_ERR_GENERAL = -1, /* general unexpected err */ + WOLFSSL_CBIO_ERR_WANT_READ = -2, /* need to call read again */ + WOLFSSL_CBIO_ERR_WANT_WRITE = -2, /* need to call write again */ + WOLFSSL_CBIO_ERR_CONN_RST = -3, /* connection reset */ + WOLFSSL_CBIO_ERR_ISR = -4, /* interrupt */ + WOLFSSL_CBIO_ERR_CONN_CLOSE = -5, /* connection closed or epipe */ + WOLFSSL_CBIO_ERR_TIMEOUT = -6 /* socket timeout */ +}; + + +/* CA cache callbacks */ +enum { + WOLFSSL_SSLV3 = 0, + WOLFSSL_TLSV1 = 1, + WOLFSSL_TLSV1_1 = 2, + WOLFSSL_TLSV1_2 = 3, + WOLFSSL_TLSV1_3 = 4, + WOLFSSL_USER_CA = 1, /* user added as trusted */ + WOLFSSL_CHAIN_CA = 2 /* added to cache from trusted chain */ +}; + +WOLFSSL_API WC_RNG* wolfSSL_GetRNG(WOLFSSL*); + +WOLFSSL_ABI WOLFSSL_API int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX*, int); +WOLFSSL_API int wolfSSL_SetMinVersion(WOLFSSL*, int); +WOLFSSL_API int wolfSSL_GetObjectSize(void); /* object size based on build */ +WOLFSSL_API int wolfSSL_CTX_GetObjectSize(void); +WOLFSSL_API int wolfSSL_METHOD_GetObjectSize(void); +WOLFSSL_API int wolfSSL_GetOutputSize(WOLFSSL*, int); +WOLFSSL_API int wolfSSL_GetMaxOutputSize(WOLFSSL*); +WOLFSSL_API int wolfSSL_GetVersion(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_SetVersion(WOLFSSL* ssl, int version); + +/* moved to asn.c, old names kept for backwards compatability */ +#define wolfSSL_KeyPemToDer wc_KeyPemToDer +#define wolfSSL_CertPemToDer wc_CertPemToDer +#define wolfSSL_PemPubKeyToDer wc_PemPubKeyToDer +#define wolfSSL_PubKeyPemToDer wc_PubKeyPemToDer +#define wolfSSL_PemCertToDer wc_PemCertToDer + + +typedef void (*CallbackCACache)(unsigned char* der, int sz, int type); +typedef void (*CbMissingCRL)(const char* url); +typedef int (*CbOCSPIO)(void*, const char*, int, + unsigned char*, int, unsigned char**); +typedef void (*CbOCSPRespFree)(void*,unsigned char*); + +#ifdef HAVE_CRL_IO +typedef int (*CbCrlIO)(WOLFSSL_CRL* crl, const char* url, int urlSz); +#endif + +/* User Atomic Record Layer CallBacks */ +typedef int (*CallbackMacEncrypt)(WOLFSSL* ssl, unsigned char* macOut, + const unsigned char* macIn, unsigned int macInSz, int macContent, + int macVerify, unsigned char* encOut, const unsigned char* encIn, + unsigned int encSz, void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX*, CallbackMacEncrypt); +WOLFSSL_API void wolfSSL_SetMacEncryptCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetMacEncryptCtx(WOLFSSL* ssl); + +typedef int (*CallbackDecryptVerify)(WOLFSSL* ssl, + unsigned char* decOut, const unsigned char* decIn, + unsigned int decSz, int content, int verify, unsigned int* padSz, + void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX*, + CallbackDecryptVerify); +WOLFSSL_API void wolfSSL_SetDecryptVerifyCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetDecryptVerifyCtx(WOLFSSL* ssl); + +typedef int (*CallbackEncryptMac)(WOLFSSL* ssl, unsigned char* macOut, + int content, int macVerify, unsigned char* encOut, + const unsigned char* encIn, unsigned int encSz, void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetEncryptMacCb(WOLFSSL_CTX*, CallbackEncryptMac); +WOLFSSL_API void wolfSSL_SetEncryptMacCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetEncryptMacCtx(WOLFSSL* ssl); + +typedef int (*CallbackVerifyDecrypt)(WOLFSSL* ssl, + unsigned char* decOut, const unsigned char* decIn, + unsigned int decSz, int content, int verify, unsigned int* padSz, + void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetVerifyDecryptCb(WOLFSSL_CTX*, + CallbackVerifyDecrypt); +WOLFSSL_API void wolfSSL_SetVerifyDecryptCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetVerifyDecryptCtx(WOLFSSL* ssl); + +WOLFSSL_API const unsigned char* wolfSSL_GetMacSecret(WOLFSSL*, int); +WOLFSSL_API const unsigned char* wolfSSL_GetClientWriteKey(WOLFSSL*); +WOLFSSL_API const unsigned char* wolfSSL_GetClientWriteIV(WOLFSSL*); +WOLFSSL_API const unsigned char* wolfSSL_GetServerWriteKey(WOLFSSL*); +WOLFSSL_API const unsigned char* wolfSSL_GetServerWriteIV(WOLFSSL*); +WOLFSSL_API int wolfSSL_GetKeySize(WOLFSSL*); +WOLFSSL_API int wolfSSL_GetIVSize(WOLFSSL*); +WOLFSSL_API int wolfSSL_GetSide(WOLFSSL*); +WOLFSSL_API int wolfSSL_IsTLSv1_1(WOLFSSL*); +WOLFSSL_API int wolfSSL_GetBulkCipher(WOLFSSL*); +WOLFSSL_API int wolfSSL_GetCipherBlockSize(WOLFSSL*); +WOLFSSL_API int wolfSSL_GetAeadMacSize(WOLFSSL*); +WOLFSSL_API int wolfSSL_GetHmacSize(WOLFSSL*); +WOLFSSL_API int wolfSSL_GetHmacType(WOLFSSL*); +WOLFSSL_API int wolfSSL_GetCipherType(WOLFSSL*); +WOLFSSL_API int wolfSSL_SetTlsHmacInner(WOLFSSL*, unsigned char*, + word32, int, int); + +/* Atomic User Needs */ +enum { + WOLFSSL_SERVER_END = 0, + WOLFSSL_CLIENT_END = 1, + WOLFSSL_NEITHER_END = 3, + WOLFSSL_BLOCK_TYPE = 2, + WOLFSSL_STREAM_TYPE = 3, + WOLFSSL_AEAD_TYPE = 4, + WOLFSSL_TLS_HMAC_INNER_SZ = 13 /* SEQ_SZ + ENUM + VERSION_SZ + LEN_SZ */ +}; + +/* for GetBulkCipher and internal use */ +enum BulkCipherAlgorithm { + wolfssl_cipher_null, + wolfssl_rc4, + wolfssl_rc2, + wolfssl_des, + wolfssl_triple_des, /* leading 3 (3des) not valid identifier */ + wolfssl_des40, +#ifdef HAVE_IDEA + wolfssl_idea, +#endif + wolfssl_aes, + wolfssl_aes_gcm, + wolfssl_aes_ccm, + wolfssl_chacha, + wolfssl_camellia, + wolfssl_hc128, /* wolfSSL extensions */ + wolfssl_rabbit +}; + + +/* for KDF TLS 1.2 mac types */ +enum KDF_MacAlgorithm { + wolfssl_sha256 = 4, /* needs to match hash.h wc_MACAlgorithm */ + wolfssl_sha384, + wolfssl_sha512 +}; + + +/* Public Key Callback support */ +#ifdef HAVE_PK_CALLBACKS +#ifdef HAVE_ECC + +struct ecc_key; + +typedef int (*CallbackEccKeyGen)(WOLFSSL* ssl, struct ecc_key* key, + unsigned int keySz, int ecc_curve, void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetEccKeyGenCb(WOLFSSL_CTX*, CallbackEccKeyGen); +WOLFSSL_API void wolfSSL_SetEccKeyGenCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetEccKeyGenCtx(WOLFSSL* ssl); + +typedef int (*CallbackEccSign)(WOLFSSL* ssl, + const unsigned char* in, unsigned int inSz, + unsigned char* out, word32* outSz, + const unsigned char* keyDer, unsigned int keySz, + void* ctx); +WOLFSSL_ABI WOLFSSL_API void wolfSSL_CTX_SetEccSignCb(WOLFSSL_CTX*, + CallbackEccSign); +WOLFSSL_API void wolfSSL_SetEccSignCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetEccSignCtx(WOLFSSL* ssl); + +typedef int (*CallbackEccVerify)(WOLFSSL* ssl, + const unsigned char* sig, unsigned int sigSz, + const unsigned char* hash, unsigned int hashSz, + const unsigned char* keyDer, unsigned int keySz, + int* result, void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX*, CallbackEccVerify); +WOLFSSL_API void wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl); + +typedef int (*CallbackEccSharedSecret)(WOLFSSL* ssl, struct ecc_key* otherKey, + unsigned char* pubKeyDer, word32* pubKeySz, + unsigned char* out, word32* outlen, + int side, void* ctx); /* side is WOLFSSL_CLIENT_END or WOLFSSL_SERVER_END */ +WOLFSSL_API void wolfSSL_CTX_SetEccSharedSecretCb(WOLFSSL_CTX*, CallbackEccSharedSecret); +WOLFSSL_API void wolfSSL_SetEccSharedSecretCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetEccSharedSecretCtx(WOLFSSL* ssl); +#endif + +#ifndef NO_DH +/* Public DH Key Callback support */ +struct DhKey; +typedef int (*CallbackDhAgree)(WOLFSSL* ssl, struct DhKey* key, + const unsigned char* priv, unsigned int privSz, + const unsigned char* otherPubKeyDer, unsigned int otherPubKeySz, + unsigned char* out, unsigned int* outlen, + void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetDhAgreeCb(WOLFSSL_CTX*, CallbackDhAgree); +WOLFSSL_API void wolfSSL_SetDhAgreeCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl); +#endif /* !NO_DH */ + +#ifdef HAVE_ED25519 +struct ed25519_key; +typedef int (*CallbackEd25519Sign)(WOLFSSL* ssl, + const unsigned char* in, unsigned int inSz, + unsigned char* out, unsigned int* outSz, + const unsigned char* keyDer, unsigned int keySz, + void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetEd25519SignCb(WOLFSSL_CTX*, + CallbackEd25519Sign); +WOLFSSL_API void wolfSSL_SetEd25519SignCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetEd25519SignCtx(WOLFSSL* ssl); + +typedef int (*CallbackEd25519Verify)(WOLFSSL* ssl, + const unsigned char* sig, unsigned int sigSz, + const unsigned char* msg, unsigned int msgSz, + const unsigned char* keyDer, unsigned int keySz, + int* result, void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetEd25519VerifyCb(WOLFSSL_CTX*, + CallbackEd25519Verify); +WOLFSSL_API void wolfSSL_SetEd25519VerifyCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetEd25519VerifyCtx(WOLFSSL* ssl); +#endif + +#ifdef HAVE_CURVE25519 +struct curve25519_key; + +typedef int (*CallbackX25519KeyGen)(WOLFSSL* ssl, struct curve25519_key* key, + unsigned int keySz, void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetX25519KeyGenCb(WOLFSSL_CTX*, CallbackX25519KeyGen); +WOLFSSL_API void wolfSSL_SetX25519KeyGenCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetX25519KeyGenCtx(WOLFSSL* ssl); + +typedef int (*CallbackX25519SharedSecret)(WOLFSSL* ssl, + struct curve25519_key* otherKey, + unsigned char* pubKeyDer, unsigned int* pubKeySz, + unsigned char* out, unsigned int* outlen, + int side, void* ctx); + /* side is WOLFSSL_CLIENT_END or WOLFSSL_SERVER_END */ +WOLFSSL_API void wolfSSL_CTX_SetX25519SharedSecretCb(WOLFSSL_CTX*, + CallbackX25519SharedSecret); +WOLFSSL_API void wolfSSL_SetX25519SharedSecretCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetX25519SharedSecretCtx(WOLFSSL* ssl); +#endif + +#ifndef NO_RSA +typedef int (*CallbackRsaSign)(WOLFSSL* ssl, + const unsigned char* in, unsigned int inSz, + unsigned char* out, unsigned int* outSz, + const unsigned char* keyDer, unsigned int keySz, + void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetRsaSignCb(WOLFSSL_CTX*, CallbackRsaSign); +WOLFSSL_API void wolfSSL_SetRsaSignCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetRsaSignCtx(WOLFSSL* ssl); + +typedef int (*CallbackRsaVerify)(WOLFSSL* ssl, + unsigned char* sig, unsigned int sigSz, + unsigned char** out, + const unsigned char* keyDer, unsigned int keySz, + void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetRsaVerifyCb(WOLFSSL_CTX*, CallbackRsaVerify); +WOLFSSL_API void wolfSSL_CTX_SetRsaSignCheckCb(WOLFSSL_CTX*, CallbackRsaVerify); +WOLFSSL_API void wolfSSL_SetRsaVerifyCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetRsaVerifyCtx(WOLFSSL* ssl); + +#ifdef WC_RSA_PSS +typedef int (*CallbackRsaPssSign)(WOLFSSL* ssl, + const unsigned char* in, unsigned int inSz, + unsigned char* out, unsigned int* outSz, + int hash, int mgf, + const unsigned char* keyDer, unsigned int keySz, + void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetRsaPssSignCb(WOLFSSL_CTX*, CallbackRsaPssSign); +WOLFSSL_API void wolfSSL_SetRsaPssSignCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetRsaPssSignCtx(WOLFSSL* ssl); + +typedef int (*CallbackRsaPssVerify)(WOLFSSL* ssl, + unsigned char* sig, unsigned int sigSz, + unsigned char** out, + int hash, int mgf, + const unsigned char* keyDer, unsigned int keySz, + void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetRsaPssVerifyCb(WOLFSSL_CTX*, + CallbackRsaPssVerify); +WOLFSSL_API void wolfSSL_CTX_SetRsaPssSignCheckCb(WOLFSSL_CTX*, + CallbackRsaPssVerify); +WOLFSSL_API void wolfSSL_SetRsaPssVerifyCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetRsaPssVerifyCtx(WOLFSSL* ssl); +#endif + +/* RSA Public Encrypt cb */ +typedef int (*CallbackRsaEnc)(WOLFSSL* ssl, + const unsigned char* in, unsigned int inSz, + unsigned char* out, unsigned int* outSz, + const unsigned char* keyDer, unsigned int keySz, + void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetRsaEncCb(WOLFSSL_CTX*, CallbackRsaEnc); +WOLFSSL_API void wolfSSL_SetRsaEncCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetRsaEncCtx(WOLFSSL* ssl); + +/* RSA Private Decrypt cb */ +typedef int (*CallbackRsaDec)(WOLFSSL* ssl, + unsigned char* in, unsigned int inSz, + unsigned char** out, + const unsigned char* keyDer, unsigned int keySz, + void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetRsaDecCb(WOLFSSL_CTX*, CallbackRsaDec); +WOLFSSL_API void wolfSSL_SetRsaDecCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl); +#endif +#endif /* HAVE_PK_CALLBACKS */ + +#ifndef NO_CERTS + WOLFSSL_API void wolfSSL_CTX_SetCACb(WOLFSSL_CTX*, CallbackCACache); + + WOLFSSL_API WOLFSSL_CERT_MANAGER* wolfSSL_CTX_GetCertManager(WOLFSSL_CTX*); + + WOLFSSL_API WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap); + WOLFSSL_API WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void); + WOLFSSL_API void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER*); + + WOLFSSL_API int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER*, const char* f, + const char* d); + WOLFSSL_API int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER*, + const unsigned char* in, long sz, int format); + WOLFSSL_API int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm); +#ifdef WOLFSSL_TRUST_PEER_CERT + WOLFSSL_API int wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER* cm); +#endif + WOLFSSL_API int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER*, const char* f, + int format); + WOLFSSL_API int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, + const unsigned char* buff, long sz, int format); + WOLFSSL_API int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER*, + unsigned char*, int sz); + WOLFSSL_API int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER*, + int options); + WOLFSSL_API int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER*); + WOLFSSL_API int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER*, + const char*, int, int); + WOLFSSL_API int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER*, + const unsigned char*, long sz, int); + WOLFSSL_API int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER*, + CbMissingCRL); + WOLFSSL_API int wolfSSL_CertManagerFreeCRL(WOLFSSL_CERT_MANAGER *); +#ifdef HAVE_CRL_IO + WOLFSSL_API int wolfSSL_CertManagerSetCRL_IOCb(WOLFSSL_CERT_MANAGER*, + CbCrlIO); +#endif +#if defined(HAVE_OCSP) + WOLFSSL_API int wolfSSL_CertManagerCheckOCSPResponse(WOLFSSL_CERT_MANAGER *, + byte *response, int responseSz, WOLFSSL_BUFFER_INFO *responseBuffer, + CertStatus *status, OcspEntry *entry, OcspRequest *ocspRequest); +#endif + WOLFSSL_API int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER*, + unsigned char*, int sz); + WOLFSSL_API int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER*, + int options); + WOLFSSL_API int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER*); + WOLFSSL_API int wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER*, + const char*); + WOLFSSL_API int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER*, + CbOCSPIO, CbOCSPRespFree, void*); + + WOLFSSL_API int wolfSSL_CertManagerEnableOCSPStapling( + WOLFSSL_CERT_MANAGER* cm); + WOLFSSL_API int wolfSSL_CertManagerDisableOCSPStapling( + WOLFSSL_CERT_MANAGER* cm); +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM) +WOLFSSL_API WOLFSSL_STACK* wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER* cm); +#endif + WOLFSSL_API int wolfSSL_EnableCRL(WOLFSSL* ssl, int options); + WOLFSSL_API int wolfSSL_DisableCRL(WOLFSSL* ssl); + WOLFSSL_API int wolfSSL_LoadCRL(WOLFSSL*, const char*, int, int); + WOLFSSL_API int wolfSSL_LoadCRLBuffer(WOLFSSL*, + const unsigned char*, long sz, int); + WOLFSSL_API int wolfSSL_SetCRL_Cb(WOLFSSL*, CbMissingCRL); +#ifdef HAVE_CRL_IO + WOLFSSL_API int wolfSSL_SetCRL_IOCb(WOLFSSL* ssl, CbCrlIO cb); +#endif + WOLFSSL_API int wolfSSL_EnableOCSP(WOLFSSL*, int options); + WOLFSSL_API int wolfSSL_DisableOCSP(WOLFSSL*); + WOLFSSL_API int wolfSSL_SetOCSP_OverrideURL(WOLFSSL*, const char*); + WOLFSSL_API int wolfSSL_SetOCSP_Cb(WOLFSSL*, CbOCSPIO, CbOCSPRespFree, void*); + WOLFSSL_API int wolfSSL_EnableOCSPStapling(WOLFSSL*); + WOLFSSL_API int wolfSSL_DisableOCSPStapling(WOLFSSL*); + + WOLFSSL_API int wolfSSL_CTX_EnableCRL(WOLFSSL_CTX* ctx, int options); + WOLFSSL_API int wolfSSL_CTX_DisableCRL(WOLFSSL_CTX* ctx); + WOLFSSL_API int wolfSSL_CTX_LoadCRL(WOLFSSL_CTX*, const char*, int, int); + WOLFSSL_API int wolfSSL_CTX_LoadCRLBuffer(WOLFSSL_CTX*, + const unsigned char*, long sz, int); + WOLFSSL_API int wolfSSL_CTX_SetCRL_Cb(WOLFSSL_CTX*, CbMissingCRL); +#ifdef HAVE_CRL_IO + WOLFSSL_API int wolfSSL_CTX_SetCRL_IOCb(WOLFSSL_CTX*, CbCrlIO); +#endif + + WOLFSSL_API int wolfSSL_CTX_EnableOCSP(WOLFSSL_CTX*, int options); + WOLFSSL_API int wolfSSL_CTX_DisableOCSP(WOLFSSL_CTX*); + WOLFSSL_API int wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX*, const char*); + WOLFSSL_API int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX*, + CbOCSPIO, CbOCSPRespFree, void*); + WOLFSSL_API int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX*); + WOLFSSL_API int wolfSSL_CTX_DisableOCSPStapling(WOLFSSL_CTX*); +#endif /* !NO_CERTS */ + + +#ifdef SINGLE_THREADED + WOLFSSL_API int wolfSSL_CTX_new_rng(WOLFSSL_CTX*); +#endif + +/* end of handshake frees temporary arrays, if user needs for get_keys or + psk hints, call KeepArrays before handshake and then FreeArrays when done + if don't want to wait for object free */ +WOLFSSL_API void wolfSSL_KeepArrays(WOLFSSL*); +WOLFSSL_API void wolfSSL_FreeArrays(WOLFSSL*); + +WOLFSSL_API int wolfSSL_KeepHandshakeResources(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_FreeHandshakeResources(WOLFSSL* ssl); + +WOLFSSL_API int wolfSSL_CTX_UseClientSuites(WOLFSSL_CTX* ctx); +WOLFSSL_API int wolfSSL_UseClientSuites(WOLFSSL* ssl); + +/* async additions */ +#define wolfSSL_UseAsync wolfSSL_SetDevId +#define wolfSSL_CTX_UseAsync wolfSSL_CTX_SetDevId +WOLFSSL_ABI WOLFSSL_API int wolfSSL_SetDevId(WOLFSSL*, int devId); +WOLFSSL_ABI WOLFSSL_API int wolfSSL_CTX_SetDevId(WOLFSSL_CTX*, int devId); + +/* helpers to get device id and heap */ +WOLFSSL_API int wolfSSL_CTX_GetDevId(WOLFSSL_CTX* ctx, WOLFSSL* ssl); +WOLFSSL_API void* wolfSSL_CTX_GetHeap(WOLFSSL_CTX* ctx, WOLFSSL* ssl); + +/* TLS Extensions */ + +/* Server Name Indication */ +#ifdef HAVE_SNI + +/* SNI types */ +enum { + WOLFSSL_SNI_HOST_NAME = 0 +}; + +WOLFSSL_ABI WOLFSSL_API int wolfSSL_UseSNI(WOLFSSL*, unsigned char, + const void*, unsigned short); +WOLFSSL_ABI WOLFSSL_API int wolfSSL_CTX_UseSNI(WOLFSSL_CTX*, unsigned char, + const void*, unsigned short); + +#ifndef NO_WOLFSSL_SERVER + +/* SNI options */ +enum { + /* Do not abort the handshake if the requested SNI didn't match. */ + WOLFSSL_SNI_CONTINUE_ON_MISMATCH = 0x01, + + /* Behave as if the requested SNI matched in a case of mismatch. */ + /* In this case, the status will be set to WOLFSSL_SNI_FAKE_MATCH. */ + WOLFSSL_SNI_ANSWER_ON_MISMATCH = 0x02, + + /* Abort the handshake if the client didn't send a SNI request. */ + WOLFSSL_SNI_ABORT_ON_ABSENCE = 0x04, +}; + +WOLFSSL_API void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, unsigned char type, + unsigned char options); +WOLFSSL_API void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, + unsigned char type, unsigned char options); +WOLFSSL_API int wolfSSL_SNI_GetFromBuffer( + const unsigned char* clientHello, unsigned int helloSz, + unsigned char type, unsigned char* sni, unsigned int* inOutSz); + +#endif /* NO_WOLFSSL_SERVER */ + +/* SNI status */ +enum { + WOLFSSL_SNI_NO_MATCH = 0, + WOLFSSL_SNI_FAKE_MATCH = 1, /**< @see WOLFSSL_SNI_ANSWER_ON_MISMATCH */ + WOLFSSL_SNI_REAL_MATCH = 2, + WOLFSSL_SNI_FORCE_KEEP = 3 /** Used with -DWOLFSSL_ALWAYS_KEEP_SNI */ +}; + +WOLFSSL_API unsigned char wolfSSL_SNI_Status(WOLFSSL* ssl, unsigned char type); + +WOLFSSL_API unsigned short wolfSSL_SNI_GetRequest(WOLFSSL *ssl, + unsigned char type, void** data); + +#endif /* HAVE_SNI */ + +/* Trusted CA Key Indication - RFC 6066 (Section 6) */ +#ifdef HAVE_TRUSTED_CA + +/* TCA Identifier Type */ +enum { + WOLFSSL_TRUSTED_CA_PRE_AGREED = 0, + WOLFSSL_TRUSTED_CA_KEY_SHA1 = 1, + WOLFSSL_TRUSTED_CA_X509_NAME = 2, + WOLFSSL_TRUSTED_CA_CERT_SHA1 = 3 +}; + +WOLFSSL_API int wolfSSL_UseTrustedCA(WOLFSSL* ssl, unsigned char type, + const unsigned char* certId, unsigned int certIdSz); +#endif /* HAVE_TRUSTED_CA */ + +/* Application-Layer Protocol Negotiation */ +#ifdef HAVE_ALPN + +/* ALPN status code */ +enum { + WOLFSSL_ALPN_NO_MATCH = 0, + WOLFSSL_ALPN_MATCH = 1, + WOLFSSL_ALPN_CONTINUE_ON_MISMATCH = 2, + WOLFSSL_ALPN_FAILED_ON_MISMATCH = 4, +}; + +enum { + WOLFSSL_MAX_ALPN_PROTO_NAME_LEN = 255, + WOLFSSL_MAX_ALPN_NUMBER = 257 +}; + +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) +typedef int (*CallbackALPNSelect)(WOLFSSL* ssl, const unsigned char** out, + unsigned char* outLen, const unsigned char* in, unsigned int inLen, + void *arg); +#endif + +WOLFSSL_ABI WOLFSSL_API int wolfSSL_UseALPN(WOLFSSL* ssl, + char *protocol_name_list, + unsigned int protocol_name_listSz, + unsigned char options); + +WOLFSSL_API int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name, + unsigned short *size); + +WOLFSSL_API int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list, + unsigned short *listSz); +WOLFSSL_API int wolfSSL_ALPN_FreePeerProtocol(WOLFSSL* ssl, char **list); +#endif /* HAVE_ALPN */ + +/* Maximum Fragment Length */ +#ifdef HAVE_MAX_FRAGMENT + +/* Fragment lengths */ +enum { + WOLFSSL_MFL_2_9 = 1, /* 512 bytes */ + WOLFSSL_MFL_2_10 = 2, /* 1024 bytes */ + WOLFSSL_MFL_2_11 = 3, /* 2048 bytes */ + WOLFSSL_MFL_2_12 = 4, /* 4096 bytes */ + WOLFSSL_MFL_2_13 = 5, /* 8192 bytes *//* wolfSSL ONLY!!! */ + WOLFSSL_MFL_2_8 = 6, /* 256 bytes *//* wolfSSL ONLY!!! */ + WOLFSSL_MFL_MIN = WOLFSSL_MFL_2_9, + WOLFSSL_MFL_MAX = WOLFSSL_MFL_2_8, +}; + +#ifndef NO_WOLFSSL_CLIENT + +WOLFSSL_API int wolfSSL_UseMaxFragment(WOLFSSL* ssl, unsigned char mfl); +WOLFSSL_API int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, unsigned char mfl); + +#endif +#endif /* HAVE_MAX_FRAGMENT */ + +/* Truncated HMAC */ +#ifdef HAVE_TRUNCATED_HMAC +#ifndef NO_WOLFSSL_CLIENT + +WOLFSSL_API int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx); + +#endif +#endif + +/* Certificate Status Request */ +/* Certificate Status Type */ +enum { + WOLFSSL_CSR_OCSP = 1 +}; + +/* Certificate Status Options (flags) */ +enum { + WOLFSSL_CSR_OCSP_USE_NONCE = 0x01 +}; + +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST +#ifndef NO_WOLFSSL_CLIENT + +WOLFSSL_API int wolfSSL_UseOCSPStapling(WOLFSSL* ssl, + unsigned char status_type, unsigned char options); + +WOLFSSL_API int wolfSSL_CTX_UseOCSPStapling(WOLFSSL_CTX* ctx, + unsigned char status_type, unsigned char options); + +#endif +#endif + +/* Certificate Status Request v2 */ +/* Certificate Status Type */ +enum { + WOLFSSL_CSR2_OCSP = 1, + WOLFSSL_CSR2_OCSP_MULTI = 2 +}; + +/* Certificate Status v2 Options (flags) */ +enum { + WOLFSSL_CSR2_OCSP_USE_NONCE = 0x01 +}; + +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 +#ifndef NO_WOLFSSL_CLIENT + +WOLFSSL_API int wolfSSL_UseOCSPStaplingV2(WOLFSSL* ssl, + unsigned char status_type, unsigned char options); + +WOLFSSL_API int wolfSSL_CTX_UseOCSPStaplingV2(WOLFSSL_CTX* ctx, + unsigned char status_type, unsigned char options); + +#endif +#endif + +/* Named Groups */ +enum { +#if 0 /* Not Supported */ + WOLFSSL_ECC_SECT163K1 = 1, + WOLFSSL_ECC_SECT163R1 = 2, + WOLFSSL_ECC_SECT163R2 = 3, + WOLFSSL_ECC_SECT193R1 = 4, + WOLFSSL_ECC_SECT193R2 = 5, + WOLFSSL_ECC_SECT233K1 = 6, + WOLFSSL_ECC_SECT233R1 = 7, + WOLFSSL_ECC_SECT239K1 = 8, + WOLFSSL_ECC_SECT283K1 = 9, + WOLFSSL_ECC_SECT283R1 = 10, + WOLFSSL_ECC_SECT409K1 = 11, + WOLFSSL_ECC_SECT409R1 = 12, + WOLFSSL_ECC_SECT571K1 = 13, + WOLFSSL_ECC_SECT571R1 = 14, +#endif + WOLFSSL_ECC_SECP160K1 = 15, + WOLFSSL_ECC_SECP160R1 = 16, + WOLFSSL_ECC_SECP160R2 = 17, + WOLFSSL_ECC_SECP192K1 = 18, + WOLFSSL_ECC_SECP192R1 = 19, + WOLFSSL_ECC_SECP224K1 = 20, + WOLFSSL_ECC_SECP224R1 = 21, + WOLFSSL_ECC_SECP256K1 = 22, + WOLFSSL_ECC_SECP256R1 = 23, + WOLFSSL_ECC_SECP384R1 = 24, + WOLFSSL_ECC_SECP521R1 = 25, + WOLFSSL_ECC_BRAINPOOLP256R1 = 26, + WOLFSSL_ECC_BRAINPOOLP384R1 = 27, + WOLFSSL_ECC_BRAINPOOLP512R1 = 28, + WOLFSSL_ECC_X25519 = 29, + /* Not implemented. */ + WOLFSSL_ECC_X448 = 30, + + WOLFSSL_FFDHE_2048 = 256, + WOLFSSL_FFDHE_3072 = 257, + WOLFSSL_FFDHE_4096 = 258, + WOLFSSL_FFDHE_6144 = 259, + WOLFSSL_FFDHE_8192 = 260, +}; + +enum { + WOLFSSL_EC_PF_UNCOMPRESSED = 0, +#if 0 /* Not Supported */ + WOLFSSL_EC_PF_X962_COMP_PRIME = 1, + WOLFSSL_EC_PF_X962_COMP_CHAR2 = 2, +#endif +}; + +#ifdef HAVE_SUPPORTED_CURVES +#ifndef NO_WOLFSSL_CLIENT + +WOLFSSL_API int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name); +WOLFSSL_API int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, + word16 name); + +#endif +#endif + +#ifdef WOLFSSL_TLS13 +WOLFSSL_API int wolfSSL_UseKeyShare(WOLFSSL* ssl, word16 group); +WOLFSSL_API int wolfSSL_NoKeyShares(WOLFSSL* ssl); +#endif + + +/* Secure Renegotiation */ +#ifdef HAVE_SECURE_RENEGOTIATION + +WOLFSSL_API int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_CTX_UseSecureRenegotiation(WOLFSSL_CTX* ctx); +WOLFSSL_API int wolfSSL_StartSecureRenegotiation(WOLFSSL* ssl, int resume); +WOLFSSL_API int wolfSSL_Rehandshake(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_SecureResume(WOLFSSL* ssl); +WOLFSSL_API long wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL* ssl); + +#endif + +/* Session Ticket */ +#ifdef HAVE_SESSION_TICKET + +#ifndef NO_WOLFSSL_CLIENT +WOLFSSL_API int wolfSSL_UseSessionTicket(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx); +WOLFSSL_API int wolfSSL_get_SessionTicket(WOLFSSL*, unsigned char*, word32*); +WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL*, const unsigned char*, word32); +typedef int (*CallbackSessionTicket)(WOLFSSL*, const unsigned char*, int, void*); +WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL*, + CallbackSessionTicket, void*); +#endif /* NO_WOLFSSL_CLIENT */ + + +#define WOLFSSL_TICKET_NAME_SZ 16 +#define WOLFSSL_TICKET_IV_SZ 16 +#define WOLFSSL_TICKET_MAC_SZ 32 + +enum TicketEncRet { + WOLFSSL_TICKET_RET_FATAL = -1, /* fatal error, don't use ticket */ + WOLFSSL_TICKET_RET_OK = 0, /* ok, use ticket */ + WOLFSSL_TICKET_RET_REJECT, /* don't use ticket, but not fatal */ + WOLFSSL_TICKET_RET_CREATE /* existing ticket ok and create new one */ +}; + +#ifndef NO_WOLFSSL_SERVER + +typedef int (*SessionTicketEncCb)(WOLFSSL*, + unsigned char key_name[WOLFSSL_TICKET_NAME_SZ], + unsigned char iv[WOLFSSL_TICKET_IV_SZ], + unsigned char mac[WOLFSSL_TICKET_MAC_SZ], + int enc, unsigned char*, int, int*, void*); +WOLFSSL_API int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, + SessionTicketEncCb); +WOLFSSL_API int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int); +WOLFSSL_API int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void*); + +#endif /* NO_WOLFSSL_SERVER */ + +#endif /* HAVE_SESSION_TICKET */ + +#ifdef HAVE_QSH +/* Quantum-safe Crypto Schemes */ +enum { + WOLFSSL_NTRU_EESS439 = 0x0101, /* max plaintext length of 65 */ + WOLFSSL_NTRU_EESS593 = 0x0102, /* max plaintext length of 86 */ + WOLFSSL_NTRU_EESS743 = 0x0103, /* max plaintext length of 106 */ + WOLFSSL_LWE_XXX = 0x0201, /* Learning With Error encryption scheme */ + WOLFSSL_HFE_XXX = 0x0301, /* Hidden Field Equation scheme */ + WOLFSSL_NULL_QSH = 0xFFFF /* QSHScheme is not used */ +}; + + +/* test if the connection is using a QSH secure connection return 1 if so */ +WOLFSSL_API int wolfSSL_isQSH(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_UseSupportedQSH(WOLFSSL* ssl, unsigned short name); +#ifndef NO_WOLFSSL_CLIENT + /* user control over sending client public key in hello + when flag = 1 will send keys if flag is 0 or function is not called + then will not send keys in the hello extension */ + WOLFSSL_API int wolfSSL_UseClientQSHKeys(WOLFSSL* ssl, unsigned char flag); +#endif + +#endif /* QSH */ + +/* TLS Extended Master Secret Extension */ +WOLFSSL_API int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx); + + +#define WOLFSSL_CRL_MONITOR 0x01 /* monitor this dir flag */ +#define WOLFSSL_CRL_START_MON 0x02 /* start monitoring flag */ + + +/* notify user the handshake is done */ +typedef int (*HandShakeDoneCb)(WOLFSSL*, void*); +WOLFSSL_API int wolfSSL_SetHsDoneCb(WOLFSSL*, HandShakeDoneCb, void*); + + +WOLFSSL_API int wolfSSL_PrintSessionStats(void); +WOLFSSL_API int wolfSSL_get_session_stats(unsigned int* active, + unsigned int* total, + unsigned int* peak, + unsigned int* maxSessions); +/* External facing KDF */ +WOLFSSL_API +int wolfSSL_MakeTlsMasterSecret(unsigned char* ms, word32 msLen, + const unsigned char* pms, word32 pmsLen, + const unsigned char* cr, const unsigned char* sr, + int tls1_2, int hash_type); + +WOLFSSL_API +int wolfSSL_MakeTlsExtendedMasterSecret(unsigned char* ms, word32 msLen, + const unsigned char* pms, word32 pmsLen, + const unsigned char* sHash, word32 sHashLen, + int tls1_2, int hash_type); + +WOLFSSL_API +int wolfSSL_DeriveTlsKeys(unsigned char* key_data, word32 keyLen, + const unsigned char* ms, word32 msLen, + const unsigned char* sr, const unsigned char* cr, + int tls1_2, int hash_type); + +#ifdef WOLFSSL_CALLBACKS + +typedef int (*HandShakeCallBack)(HandShakeInfo*); +typedef int (*TimeoutCallBack)(TimeoutInfo*); + +/* wolfSSL connect extension allowing HandShakeCallBack and/or TimeoutCallBack + for diagnostics */ +WOLFSSL_API int wolfSSL_connect_ex(WOLFSSL*, HandShakeCallBack, TimeoutCallBack, + Timeval); +WOLFSSL_API int wolfSSL_accept_ex(WOLFSSL*, HandShakeCallBack, TimeoutCallBack, + Timeval); + +#endif /* WOLFSSL_CALLBACKS */ + + +#ifdef WOLFSSL_HAVE_WOLFSCEP + WOLFSSL_API void wolfSSL_wolfSCEP(void); +#endif /* WOLFSSL_HAVE_WOLFSCEP */ + +#ifdef WOLFSSL_HAVE_CERT_SERVICE + WOLFSSL_API void wolfSSL_cert_service(void); +#endif + +#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) +/* Smaller subset of X509 compatibility functions. Avoid increasing the size of + * this subset and its memory usage */ + +#include +struct WOLFSSL_X509_NAME_ENTRY { + WOLFSSL_ASN1_OBJECT object; /* static object just for keeping grp, type */ + WOLFSSL_ASN1_STRING data; + WOLFSSL_ASN1_STRING* value; /* points to data, for lighttpd port */ + int nid; /* i.e. ASN_COMMON_NAME */ + int set; + int size; +}; + +WOLFSSL_API int wolfSSL_X509_NAME_get_index_by_OBJ(WOLFSSL_X509_NAME *name, + const WOLFSSL_ASN1_OBJECT *obj, + int idx); + +#endif /* OPENSSL_ALL || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ + + +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) + +enum { + WOLFSSL_SYS_ACCEPT = 0, + WOLFSSL_SYS_BIND, + WOLFSSL_SYS_CONNECT, + WOLFSSL_SYS_FOPEN, + WOLFSSL_SYS_FREAD, + WOLFSSL_SYS_GETADDRINFO, + WOLFSSL_SYS_GETSOCKOPT, + WOLFSSL_SYS_GETSOCKNAME, + WOLFSSL_SYS_GETHOSTBYNAME, + WOLFSSL_SYS_GETNAMEINFO, + WOLFSSL_SYS_GETSERVBYNAME, + WOLFSSL_SYS_IOCTLSOCKET, + WOLFSSL_SYS_LISTEN, + WOLFSSL_SYS_OPENDIR, + WOLFSSL_SYS_SETSOCKOPT, + WOLFSSL_SYS_SOCKET +}; + +/* Object functions */ +WOLFSSL_API const char* wolfSSL_OBJ_nid2sn(int n); +WOLFSSL_API int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o); +WOLFSSL_API int wolfSSL_OBJ_sn2nid(const char *sn); + +WOLFSSL_API char* wolfSSL_OBJ_nid2ln(int n); +WOLFSSL_API int wolfSSL_OBJ_cmp(const WOLFSSL_ASN1_OBJECT* a, + const WOLFSSL_ASN1_OBJECT* b); +WOLFSSL_API int wolfSSL_OBJ_txt2nid(const char *sn); +WOLFSSL_API WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_txt2obj(const char* s, int no_name); + +WOLFSSL_API WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_nid2obj(int n); +WOLFSSL_LOCAL WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_nid2obj_ex(int n, WOLFSSL_ASN1_OBJECT *arg_obj); +WOLFSSL_API int wolfSSL_OBJ_obj2txt(char *buf, int buf_len, WOLFSSL_ASN1_OBJECT *a, int no_name); + +WOLFSSL_API void wolfSSL_OBJ_cleanup(void); +WOLFSSL_API int wolfSSL_OBJ_create(const char *oid, const char *sn, const char *ln); +/* end of object functions */ + +WOLFSSL_API unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line); +WOLFSSL_API long wolfSSL_ctrl(WOLFSSL* ssl, int cmd, long opt, void* pt); +WOLFSSL_API long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt,void* pt); +WOLFSSL_API long wolfSSL_CTX_clear_extra_chain_certs(WOLFSSL_CTX* ctx); + +#ifndef NO_CERTS +WOLFSSL_API WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_NID( + WOLFSSL_X509_NAME_ENTRY** out, int nid, int type, + const unsigned char* data, int dataSz); +WOLFSSL_API int wolfSSL_X509_NAME_add_entry(WOLFSSL_X509_NAME* name, + WOLFSSL_X509_NAME_ENTRY* entry, int idx, int set); +WOLFSSL_API int wolfSSL_X509_NAME_add_entry_by_txt(WOLFSSL_X509_NAME *name, + const char *field, int type, const unsigned char *bytes, int len, int loc, + int set); +WOLFSSL_API int wolfSSL_X509_NAME_add_entry_by_NID(WOLFSSL_X509_NAME *name, int nid, + int type, const unsigned char *bytes, + int len, int loc, int set); +WOLFSSL_API int wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME* x, + const WOLFSSL_X509_NAME* y); +WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new(void); +WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509*); +WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(WOLFSSL_X509_NAME*); +WOLFSSL_API int wolfSSL_check_private_key(const WOLFSSL* ssl); +WOLFSSL_API void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, + int nid, int* c, int* idx); +WOLFSSL_API int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert); +WOLFSSL_API int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509 *x, int nid, int lastpos); +WOLFSSL_API int wolfSSL_X509_add_ext(WOLFSSL_X509 *x, WOLFSSL_X509_EXTENSION *ex, int loc); +WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_conf_nid( + WOLF_LHASH_OF(CONF_VALUE)* conf, WOLFSSL_X509V3_CTX* ctx, int nid, + char* value); +WOLFSSL_API void wolfSSL_X509V3_set_ctx(WOLFSSL_X509V3_CTX* ctx, + WOLFSSL_X509* issuer, WOLFSSL_X509* subject, WOLFSSL_X509* req, + WOLFSSL_X509_CRL* crl, int flag); +WOLFSSL_API void wolfSSL_X509V3_set_ctx_nodb(WOLFSSL_X509V3_CTX* ctx); +WOLFSSL_API int wolfSSL_X509_digest(const WOLFSSL_X509* x509, + const WOLFSSL_EVP_MD* digest, unsigned char* buf, unsigned int* len); +WOLFSSL_API int wolfSSL_use_certificate(WOLFSSL* ssl, WOLFSSL_X509* x509); +WOLFSSL_API int wolfSSL_use_PrivateKey(WOLFSSL* ssl, WOLFSSL_EVP_PKEY* pkey); +WOLFSSL_API int wolfSSL_use_PrivateKey_ASN1(int pri, WOLFSSL* ssl, + unsigned char* der, long derSz); +WOLFSSL_API WOLFSSL_EVP_PKEY *wolfSSL_get_privatekey(const WOLFSSL *ssl); +#ifndef NO_RSA +WOLFSSL_API int wolfSSL_use_RSAPrivateKey_ASN1(WOLFSSL* ssl, unsigned char* der, + long derSz); +#endif +WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_ASN1(int pri, WOLFSSL_CTX* ctx, + unsigned char* der, long derSz); + +#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) +WOLFSSL_API int wolfSSL_X509_cmp(const WOLFSSL_X509* a, const WOLFSSL_X509* b); +WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_get_ext(const WOLFSSL_X509* x, int loc); +WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x, int loc); +WOLFSSL_API int wolfSSL_X509_EXTENSION_get_critical(const WOLFSSL_X509_EXTENSION* ex); +WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_new(void); +WOLFSSL_API int wolfSSL_sk_X509_EXTENSION_push(WOLFSSL_STACK* sk, + WOLFSSL_X509_EXTENSION* ext); +WOLFSSL_API void wolfSSL_sk_X509_EXTENSION_free(WOLFSSL_STACK* sk); +WOLFSSL_API void wolfSSL_X509_EXTENSION_free(WOLFSSL_X509_EXTENSION* ext_to_free); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_new_x509_ext(void); +#endif + +WOLFSSL_API WOLFSSL_ASN1_OBJECT* wolfSSL_X509_EXTENSION_get_object(WOLFSSL_X509_EXTENSION* ext); +WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_X509_EXTENSION_get_data(WOLFSSL_X509_EXTENSION* ext); +#endif /* NO_CERTS */ + +WOLFSSL_API WOLFSSL_DH *wolfSSL_DSA_dup_DH(const WOLFSSL_DSA *r); + +WOLFSSL_API int wolfSSL_SESSION_get_master_key(const WOLFSSL_SESSION* ses, + unsigned char* out, int outSz); +WOLFSSL_API int wolfSSL_SESSION_get_master_key_length(const WOLFSSL_SESSION* ses); + +WOLFSSL_API void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx, + WOLFSSL_X509_STORE* str); +WOLFSSL_API int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509); +#if !defined(NO_FILESYSTEM) +WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509_fp(XFILE fp, + WOLFSSL_X509** x509); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s); +#endif +WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, + WOLFSSL_X509** x509); +WOLFSSL_API WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(WOLFSSL_CTX* ctx); + +WOLFSSL_API size_t wolfSSL_BIO_wpending(const WOLFSSL_BIO *bio); +WOLFSSL_API size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *b); + +WOLFSSL_API size_t wolfSSL_get_server_random(const WOLFSSL *ssl, + unsigned char *out, size_t outlen); +WOLFSSL_API int wolfSSL_get_server_tmp_key(const WOLFSSL*, WOLFSSL_EVP_PKEY**); + +WOLFSSL_API int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX*, int); +WOLFSSL_API int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX*, int); + +WOLFSSL_API size_t wolfSSL_get_client_random(const WOLFSSL* ssl, + unsigned char* out, size_t outSz); +WOLFSSL_API int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u); +WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_PEM_read_bio_X509_CRL(WOLFSSL_BIO *bp, + WOLFSSL_X509_CRL **x, pem_password_cb *cb, void *u); +WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX + (WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u); +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read_bio( + WOLFSSL_BIO* bio, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk, + pem_password_cb* cb, void* u); +#ifndef NO_FILESYSTEM +WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_PEM_read_X509_CRL(XFILE fp, + WOLFSSL_X509_CRL **x, pem_password_cb *cb, void *u); +#endif +WOLFSSL_API int wolfSSL_PEM_get_EVP_CIPHER_INFO(char* header, + EncryptedInfo* cipher); +WOLFSSL_API int wolfSSL_PEM_do_header(EncryptedInfo* cipher, + unsigned char* data, long* len, + pem_password_cb* callback, void* ctx); + +/*lighttp compatibility */ + +struct WOLFSSL_ASN1_BIT_STRING { + int length; + int type; + char* data; + long flags; +}; + + +#if defined(OPENSSL_EXTRA) \ + || defined(OPENSSL_ALL) \ + || defined(HAVE_LIGHTY) \ + || defined(WOLFSSL_MYSQL_COMPATIBLE) \ + || defined(HAVE_STUNNEL) \ + || defined(WOLFSSL_NGINX) \ + || defined(WOLFSSL_HAPROXY) +WOLFSSL_API void wolfSSL_X509_NAME_ENTRY_free(WOLFSSL_X509_NAME_ENTRY* ne); +WOLFSSL_API WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_new(void); +WOLFSSL_API void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME* name); +WOLFSSL_API char wolfSSL_CTX_use_certificate(WOLFSSL_CTX*, WOLFSSL_X509*); +WOLFSSL_API int wolfSSL_CTX_add1_chain_cert(WOLFSSL_CTX*, WOLFSSL_X509*); +WOLFSSL_API int wolfSSL_BIO_read_filename(WOLFSSL_BIO *b, const char *name); +/* These are to be merged shortly */ +WOLFSSL_API void wolfSSL_set_verify_depth(WOLFSSL *ssl,int depth); +WOLFSSL_API void* wolfSSL_get_app_data( const WOLFSSL *ssl); +WOLFSSL_API int wolfSSL_set_app_data(WOLFSSL *ssl, void *arg); +WOLFSSL_API WOLFSSL_ASN1_OBJECT * wolfSSL_X509_NAME_ENTRY_get_object(WOLFSSL_X509_NAME_ENTRY *ne); +WOLFSSL_API WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(WOLFSSL_X509_NAME *name, int loc); +WOLFSSL_API unsigned char *wolfSSL_SHA1(const unsigned char *d, size_t n, unsigned char *md); +WOLFSSL_API unsigned char *wolfSSL_SHA256(const unsigned char *d, size_t n, unsigned char *md); +WOLFSSL_API unsigned char *wolfSSL_SHA384(const unsigned char *d, size_t n, unsigned char *md); +WOLFSSL_API unsigned char *wolfSSL_SHA512(const unsigned char *d, size_t n, unsigned char *md); +WOLFSSL_API int wolfSSL_X509_check_private_key(WOLFSSL_X509*, WOLFSSL_EVP_PKEY*); +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list( WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk ); +WOLFSSL_API int wolfSSL_X509_check_ca(WOLFSSL_X509 *x509); + +#ifndef NO_FILESYSTEM +WOLFSSL_API long wolfSSL_BIO_set_fp(WOLFSSL_BIO *bio, XFILE fp, int c); +WOLFSSL_API long wolfSSL_BIO_get_fp(WOLFSSL_BIO *bio, XFILE* fp); +WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_fp(XFILE fp, int c); +#endif + +#endif /* OPENSSL_EXTRA || OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ + +#endif /* OPENSSL_EXTRA || OPENSSL_ALL */ + + +#if defined(OPENSSL_ALL) \ + || defined(HAVE_STUNNEL) \ + || defined(HAVE_LIGHTY) \ + || defined(WOLFSSL_MYSQL_COMPATIBLE) \ + || defined(WOLFSSL_HAPROXY) \ + || defined(OPENSSL_EXTRA) + +WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_file(const char *filename, const char *mode); +WOLFSSL_API long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX*, WOLFSSL_DH*); +WOLFSSL_API WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bp, + WOLFSSL_DH **x, pem_password_cb *cb, void *u); +WOLFSSL_API WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSAparams(WOLFSSL_BIO *bp, + WOLFSSL_DSA **x, pem_password_cb *cb, void *u); +WOLFSSL_API int wolfSSL_PEM_write_bio_X509_REQ(WOLFSSL_BIO *bp,WOLFSSL_X509 *x); +WOLFSSL_API int wolfSSL_PEM_write_bio_X509_AUX(WOLFSSL_BIO *bp,WOLFSSL_X509 *x); +WOLFSSL_API int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 *x); +#endif /* HAVE_STUNNEL || HAVE_LIGHTY */ + +#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && defined(WOLFSSL_CERT_GEN) && \ + defined(WOLFSSL_CERT_REQ) +WOLFSSL_API int wolfSSL_i2d_X509_REQ(WOLFSSL_X509* req, unsigned char** out); +WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_REQ_new(void); +WOLFSSL_API void wolfSSL_X509_REQ_free(WOLFSSL_X509* req); +WOLFSSL_API int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey, + const WOLFSSL_EVP_MD *md); +WOLFSSL_API int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req, + WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext); +WOLFSSL_API int wolfSSL_X509_REQ_set_subject_name(WOLFSSL_X509 *req, + WOLFSSL_X509_NAME *name); +WOLFSSL_API int wolfSSL_X509_REQ_set_pubkey(WOLFSSL_X509 *req, + WOLFSSL_EVP_PKEY *pkey); +#endif + + +#if defined(OPENSSL_ALL) \ + || defined(HAVE_STUNNEL) \ + || defined(WOLFSSL_NGINX) \ + || defined(WOLFSSL_HAPROXY) \ + || defined(OPENSSL_EXTRA) \ + || defined(HAVE_LIGHTY) + +#include + +/* SNI received callback type */ +typedef int (*CallbackSniRecv)(WOLFSSL *ssl, int *ret, void* exArg); + +WOLFSSL_API int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int), + void *(*r) (void *, size_t, const char *, int), void (*f) (void *)); + +WOLFSSL_API void wolfSSL_CRYPTO_cleanup_all_ex_data(void); + +WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_DH_768_prime(WOLFSSL_BIGNUM* bn); +WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_DH_1024_prime(WOLFSSL_BIGNUM* bn); +WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_DH_1536_prime(WOLFSSL_BIGNUM* bn); +WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_DH_2048_prime(WOLFSSL_BIGNUM* bn); +WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_DH_3072_prime(WOLFSSL_BIGNUM* bn); +WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_DH_4096_prime(WOLFSSL_BIGNUM* bn); +WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_DH_6144_prime(WOLFSSL_BIGNUM* bn); +WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_DH_8192_prime(WOLFSSL_BIGNUM* bn); + +WOLFSSL_API WOLFSSL_DH *wolfSSL_DH_generate_parameters(int prime_len, int generator, + void (*callback) (int, int, void *), void *cb_arg); + +WOLFSSL_API int wolfSSL_DH_generate_parameters_ex(WOLFSSL_DH*, int, int, + void (*callback) (int, int, void *)); + +WOLFSSL_API void wolfSSL_ERR_load_crypto_strings(void); + +WOLFSSL_API unsigned long wolfSSL_ERR_peek_last_error(void); + +WOLFSSL_API int wolfSSL_FIPS_mode(void); + +WOLFSSL_API int wolfSSL_FIPS_mode_set(int r); + +WOLFSSL_API int wolfSSL_RAND_set_rand_method(const void *meth); + +WOLFSSL_API int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits); + +WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_X509_new(void); +WOLFSSL_API int wolfSSL_sk_X509_num(const WOLF_STACK_OF(WOLFSSL_X509) *s); + +WOLFSSL_API WOLFSSL_X509_INFO *wolfSSL_X509_INFO_new(void); +WOLFSSL_API void wolfSSL_X509_INFO_free(WOLFSSL_X509_INFO* info); + +WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_X509_INFO_new_null(void); +WOLFSSL_API int wolfSSL_sk_X509_INFO_num(const WOLF_STACK_OF(WOLFSSL_X509_INFO)*); +WOLFSSL_API WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_value( + const WOLF_STACK_OF(WOLFSSL_X509_INFO)*, int); +WOLFSSL_API int wolfSSL_sk_X509_INFO_push(WOLF_STACK_OF(WOLFSSL_X509_INFO)*, + WOLFSSL_X509_INFO*); +WOLFSSL_API WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_pop(WOLF_STACK_OF(WOLFSSL_X509_INFO)*); +WOLFSSL_API void wolfSSL_sk_X509_INFO_pop_free(WOLF_STACK_OF(WOLFSSL_X509_INFO)*, + void (*f) (WOLFSSL_X509_INFO*)); +WOLFSSL_API void wolfSSL_sk_X509_INFO_free(WOLF_STACK_OF(WOLFSSL_X509_INFO)*); + +typedef int (*wolf_sk_compare_cb)(const void* const *a, + const void* const *b); +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_sk_X509_NAME_new( + wolf_sk_compare_cb); +WOLFSSL_API int wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)*, + WOLFSSL_X509_NAME*); +WOLFSSL_API int wolfSSL_sk_X509_NAME_find(const WOLF_STACK_OF(WOLFSSL_X509_NAME)*, + WOLFSSL_X509_NAME*); +WOLFSSL_API int wolfSSL_sk_X509_NAME_set_cmp_func( + WOLF_STACK_OF(WOLFSSL_X509_NAME)*, wolf_sk_compare_cb); +WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_value(const WOLF_STACK_OF(WOLFSSL_X509_NAME)*, int); +WOLFSSL_API int wolfSSL_sk_X509_NAME_num(const WOLF_STACK_OF(WOLFSSL_X509_NAME)*); +WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)*); +WOLFSSL_API void wolfSSL_sk_X509_NAME_pop_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)*, + void (*f) (WOLFSSL_X509_NAME*)); +WOLFSSL_API void wolfSSL_sk_X509_NAME_free(WOLF_STACK_OF(WOLFSSL_X509_NAME) *); + +WOLFSSL_API int wolfSSL_sk_X509_OBJECT_num(const WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *s); + +WOLFSSL_API int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO*,WOLFSSL_X509_NAME*,int, + unsigned long); + +WOLFSSL_API WOLFSSL_ASN1_BIT_STRING* wolfSSL_ASN1_BIT_STRING_new(void); +WOLFSSL_API void wolfSSL_ASN1_BIT_STRING_free(WOLFSSL_ASN1_BIT_STRING*); +WOLFSSL_API WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr( + const WOLFSSL_X509*); +WOLFSSL_API int wolfSSL_ASN1_BIT_STRING_get_bit( + const WOLFSSL_ASN1_BIT_STRING*, int); +WOLFSSL_API int wolfSSL_ASN1_BIT_STRING_set_bit( + WOLFSSL_ASN1_BIT_STRING*, int, int); + +WOLFSSL_API int wolfSSL_CTX_add_session(WOLFSSL_CTX*, WOLFSSL_SESSION*); + +WOLFSSL_API int wolfSSL_version(WOLFSSL*); + +WOLFSSL_API int wolfSSL_get_state(const WOLFSSL*); + +WOLFSSL_API WOLFSSL_X509* wolfSSL_sk_X509_value(WOLF_STACK_OF(WOLFSSL_X509)*, int); + +WOLFSSL_API WOLFSSL_X509* wolfSSL_sk_X509_shift(WOLF_STACK_OF(WOLFSSL_X509)*); + +WOLFSSL_API void* wolfSSL_sk_X509_OBJECT_value(WOLF_STACK_OF(WOLFSSL_X509_OBJECT)*, int); + +WOLFSSL_API void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION*, int); + +WOLFSSL_API int wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION*, int, void*); + +WOLFSSL_API int wolfSSL_SESSION_get_ex_new_index(long,void*,void*,void*, + CRYPTO_free_func*); + +WOLFSSL_API int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME*); + + +WOLFSSL_API const unsigned char* wolfSSL_SESSION_get_id(WOLFSSL_SESSION*, + unsigned int*); + +WOLFSSL_API int wolfSSL_SESSION_print(WOLFSSL_BIO*, const WOLFSSL_SESSION*); + +WOLFSSL_API int wolfSSL_set_tlsext_host_name(WOLFSSL *, const char *); + +WOLFSSL_API const char* wolfSSL_get_servername(WOLFSSL *, unsigned char); + +WOLFSSL_API WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL*,WOLFSSL_CTX*); + +WOLFSSL_API VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX*); + +WOLFSSL_API VerifyCallback wolfSSL_get_verify_callback(WOLFSSL*); + +WOLFSSL_API void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX *, + CallbackSniRecv); +WOLFSSL_API int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX *, + CallbackSniRecv); + +WOLFSSL_API int wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX *, void*); + +WOLFSSL_API void wolfSSL_ERR_remove_thread_state(void*); + +/* support for depricated old name */ +#define WOLFSSL_ERR_remove_thread_state wolfSSL_ERR_remove_thread_state + +#ifndef NO_FILESYSTEM +WOLFSSL_API void wolfSSL_print_all_errors_fp(XFILE fp); +#endif + +WOLFSSL_API void wolfSSL_THREADID_set_callback(void (*threadid_func)(void*)); + +WOLFSSL_API void wolfSSL_THREADID_set_numeric(void* id, unsigned long val); + +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs( + WOLFSSL_X509_STORE_CTX*, WOLFSSL_X509_NAME*); +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* + wolfSSL_X509_STORE_get0_objects(WOLFSSL_X509_STORE *); +WOLFSSL_API WOLFSSL_X509_OBJECT* + wolfSSL_sk_X509_OBJECT_delete(WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int i); +WOLFSSL_API void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *a); + +WOLFSSL_API void wolfSSL_sk_X509_pop_free(WOLF_STACK_OF(WOLFSSL_X509)* sk, void (*f) (WOLFSSL_X509*)); +#endif /* OPENSSL_ALL || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || HAVE_LIGHTY */ + +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) +WOLFSSL_API int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names); +WOLFSSL_API int wolfSSL_set1_curves_list(WOLFSSL* ssl, const char* names); +#endif /* OPENSSL_EXTRA && HAVE_ECC */ + +#if defined(OPENSSL_ALL) || \ + defined(HAVE_STUNNEL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \ + defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) + +WOLFSSL_API int wolfSSL_CTX_get_verify_mode(WOLFSSL_CTX* ctx); + +#endif + +#ifdef WOLFSSL_JNI +WOLFSSL_API int wolfSSL_set_jobject(WOLFSSL* ssl, void* objPtr); +WOLFSSL_API void* wolfSSL_get_jobject(WOLFSSL* ssl); +#endif /* WOLFSSL_JNI */ + + +#ifdef WOLFSSL_ASYNC_CRYPT +WOLFSSL_API int wolfSSL_AsyncPoll(WOLFSSL* ssl, WOLF_EVENT_FLAG flags); +WOLFSSL_API int wolfSSL_CTX_AsyncPoll(WOLFSSL_CTX* ctx, WOLF_EVENT** events, int maxEvents, + WOLF_EVENT_FLAG flags, int* eventCount); +#endif /* WOLFSSL_ASYNC_CRYPT */ + +#ifdef OPENSSL_EXTRA +typedef void (*SSL_Msg_Cb)(int write_p, int version, int content_type, + const void *buf, size_t len, WOLFSSL *ssl, void *arg); + +WOLFSSL_API int wolfSSL_CTX_set_msg_callback(WOLFSSL_CTX *ctx, SSL_Msg_Cb cb); +WOLFSSL_API int wolfSSL_set_msg_callback(WOLFSSL *ssl, SSL_Msg_Cb cb); +WOLFSSL_API int wolfSSL_CTX_set_msg_callback_arg(WOLFSSL_CTX *ctx, void* arg); +WOLFSSL_API int wolfSSL_set_msg_callback_arg(WOLFSSL *ssl, void* arg); +WOLFSSL_API unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, + int *line, const char **data, int *flags); +WOLFSSL_API int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx, + const unsigned char *protos, unsigned int protos_len); +WOLFSSL_API int wolfSSL_set_alpn_protos(WOLFSSL* ssl, + const unsigned char* protos, unsigned int protos_len); +WOLFSSL_API void *wolfSSL_OPENSSL_memdup(const void *data, + size_t siz, const char* file, int line); +WOLFSSL_API void wolfSSL_ERR_load_BIO_strings(void); +#endif + +#if defined(OPENSSL_ALL) \ + || defined(WOLFSSL_NGINX) \ + || defined(WOLFSSL_HAPROXY) \ + || defined(OPENSSL_EXTRA) +WOLFSSL_API void wolfSSL_OPENSSL_config(char *config_name); +#endif + +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) +/* Not an OpenSSL API. */ +WOLFSSL_LOCAL int wolfSSL_get_ocsp_response(WOLFSSL* ssl, byte** response); +/* Not an OpenSSL API. */ +WOLFSSL_LOCAL char* wolfSSL_get_ocsp_url(WOLFSSL* ssl); +/* Not an OpenSSL API. */ +WOLFSSL_API int wolfSSL_set_ocsp_url(WOLFSSL* ssl, char* url); +#endif + +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \ + || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_CIPHER) *wolfSSL_get_ciphers_compat(const WOLFSSL *ssl); +WOLFSSL_API int wolfSSL_X509_get_ex_new_index(int idx, void *arg, void *a, + void *b, void *c); +WOLFSSL_API void *wolfSSL_X509_get_ex_data(WOLFSSL_X509 *x509, int idx); +WOLFSSL_API int wolfSSL_X509_set_ex_data(WOLFSSL_X509 *x509, int idx, + void *data); +WOLFSSL_API int wolfSSL_X509_NAME_digest(const WOLFSSL_X509_NAME *data, + const WOLFSSL_EVP_MD *type, unsigned char *md, unsigned int *len); + +WOLFSSL_API long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx); +WOLFSSL_API long wolfSSL_get_timeout(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx, + WOLFSSL_EC_KEY *ecdh); +WOLFSSL_API int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *, + WOLFSSL_SESSION *c); + +WOLFSSL_API WOLFSSL_BIO *wolfSSL_SSL_get_rbio(const WOLFSSL *s); +WOLFSSL_API WOLFSSL_BIO *wolfSSL_SSL_get_wbio(const WOLFSSL *s); +WOLFSSL_API int wolfSSL_SSL_do_handshake(WOLFSSL *s); +WOLFSSL_API int wolfSSL_SSL_in_init(WOLFSSL*); +WOLFSSL_API int wolfSSL_SSL_in_connect_init(WOLFSSL*); + +#ifndef NO_SESSION_CACHE + WOLFSSL_API WOLFSSL_SESSION *wolfSSL_SSL_get0_session(const WOLFSSL *s); +#endif +WOLFSSL_API int wolfSSL_X509_check_host(WOLFSSL_X509 *x, const char *chk, + size_t chklen, unsigned int flags, char **peername); + +WOLFSSL_API int wolfSSL_i2a_ASN1_INTEGER(WOLFSSL_BIO *bp, + const WOLFSSL_ASN1_INTEGER *a); + +#ifdef HAVE_SESSION_TICKET +WOLFSSL_API int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *, int (*)( + WOLFSSL *ssl, unsigned char *name, unsigned char *iv, + WOLFSSL_EVP_CIPHER_CTX *ectx, WOLFSSL_HMAC_CTX *hctx, int enc)); +#endif + +#if defined(HAVE_OCSP) || defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \ + defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) +WOLFSSL_API int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx, + WOLF_STACK_OF(X509)** chain); +WOLFSSL_API int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx, + int(*)(WOLFSSL*, void*)); + +WOLFSSL_API int wolfSSL_X509_STORE_CTX_get1_issuer(WOLFSSL_X509 **issuer, + WOLFSSL_X509_STORE_CTX *ctx, WOLFSSL_X509 *x); + +WOLFSSL_API void wolfSSL_X509_email_free(WOLF_STACK_OF(WOLFSSL_STRING) *sk); +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ocsp(WOLFSSL_X509 *x); + +WOLFSSL_API int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, + WOLFSSL_X509 *subject); + +WOLFSSL_API char* wolfSSL_sk_WOLFSSL_STRING_value( + WOLF_STACK_OF(WOLFSSL_STRING)* strings, int idx); +#endif /* HAVE_OCSP */ + +WOLFSSL_API int PEM_write_bio_WOLFSSL_X509(WOLFSSL_BIO *bio, + WOLFSSL_X509 *cert); + +#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || + OPENSSL_EXTRA || HAVE_LIGHTY*/ + +WOLFSSL_API void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl, + const unsigned char **data, unsigned int *len); +WOLFSSL_API int wolfSSL_select_next_proto(unsigned char **out, + unsigned char *outlen, + const unsigned char *in, unsigned int inlen, + const unsigned char *client, + unsigned int client_len); +WOLFSSL_API void wolfSSL_CTX_set_alpn_select_cb(WOLFSSL_CTX *ctx, + int (*cb) (WOLFSSL *ssl, + const unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg), void *arg); +WOLFSSL_API void wolfSSL_CTX_set_next_protos_advertised_cb(WOLFSSL_CTX *s, + int (*cb) (WOLFSSL *ssl, + const unsigned char **out, + unsigned int *outlen, + void *arg), void *arg); +WOLFSSL_API void wolfSSL_CTX_set_next_proto_select_cb(WOLFSSL_CTX *s, + int (*cb) (WOLFSSL *ssl, + unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg), void *arg); +WOLFSSL_API void wolfSSL_get0_next_proto_negotiated(const WOLFSSL *s, const unsigned char **data, + unsigned *len); + + +#ifdef OPENSSL_EXTRA +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) +WOLFSSL_API const unsigned char *SSL_SESSION_get0_id_context( + const WOLFSSL_SESSION *sess, unsigned int *sid_ctx_length); +WOLFSSL_API size_t SSL_get_finished(const WOLFSSL *s, void *buf, size_t count); +WOLFSSL_API size_t SSL_get_peer_finished(const WOLFSSL *s, void *buf, size_t count); +#endif + +WOLFSSL_API int SSL_SESSION_set1_id(WOLFSSL_SESSION *s, const unsigned char *sid, unsigned int sid_len); +WOLFSSL_API int SSL_SESSION_set1_id_context(WOLFSSL_SESSION *s, const unsigned char *sid_ctx, unsigned int sid_ctx_len); +WOLFSSL_API const WOLFSSL_X509_ALGOR* wolfSSL_X509_get0_tbs_sigalg(const WOLFSSL_X509 *x); +WOLFSSL_API void wolfSSL_X509_ALGOR_get0(const WOLFSSL_ASN1_OBJECT **paobj, int *pptype, const void **ppval, const WOLFSSL_X509_ALGOR *algor); +WOLFSSL_API WOLFSSL_X509_PUBKEY *wolfSSL_X509_get_X509_PUBKEY(const WOLFSSL_X509* x509); +WOLFSSL_API int wolfSSL_X509_PUBKEY_get0_param(WOLFSSL_ASN1_OBJECT **ppkalg, const unsigned char **pk, int *ppklen, void **pa, WOLFSSL_X509_PUBKEY *pub); +WOLFSSL_API int i2t_ASN1_OBJECT(char *buf, int buf_len, WOLFSSL_ASN1_OBJECT *a); +WOLFSSL_API int wolfSSL_i2a_ASN1_OBJECT(WOLFSSL_BIO *bp, WOLFSSL_ASN1_OBJECT *a); +WOLFSSL_API void SSL_CTX_set_tmp_dh_callback(WOLFSSL_CTX *ctx, WOLFSSL_DH *(*dh) (WOLFSSL *ssl, int is_export, int keylength)); +WOLFSSL_API WOLF_STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void); +WOLFSSL_API int wolfSSL_X509_STORE_load_locations(WOLFSSL_X509_STORE *str, const char *file, const char *dir); +WOLFSSL_API int wolfSSL_X509_STORE_add_crl(WOLFSSL_X509_STORE *ctx, WOLFSSL_X509_CRL *x); +WOLFSSL_API int wolfSSL_sk_SSL_CIPHER_num(const WOLF_STACK_OF(WOLFSSL_CIPHER)* p); +WOLFSSL_API int wolfSSL_sk_SSL_CIPHER_find( + WOLF_STACK_OF(WOLFSSL_CIPHER)* sk, const WOLFSSL_CIPHER* toFind); +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_CIPHER)* wolfSSL_sk_SSL_CIPHER_dup( + WOLF_STACK_OF(WOLFSSL_CIPHER)* in); +WOLFSSL_API void wolfSSL_sk_SSL_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk); +WOLFSSL_API int wolfSSL_sk_SSL_COMP_zero(WOLFSSL_STACK* st); +WOLFSSL_API int wolfSSL_sk_SSL_COMP_num(WOLF_STACK_OF(WOLFSSL_COMP)* sk); +WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_sk_SSL_CIPHER_value(void *ciphers, int idx); +WOLFSSL_API void ERR_load_SSL_strings(void); +WOLFSSL_API void wolfSSL_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *p); + +WOLFSSL_API const char *wolfSSL_ASN1_tag2str(int tag); +WOLFSSL_API int wolfSSL_ASN1_STRING_print_ex(WOLFSSL_BIO *out, WOLFSSL_ASN1_STRING *str, unsigned long flags); +WOLFSSL_API int wolfSSL_ASN1_STRING_print(WOLFSSL_BIO *out, WOLFSSL_ASN1_STRING *str); +WOLFSSL_API int wolfSSL_ASN1_TIME_get_length(WOLFSSL_ASN1_TIME *t); +WOLFSSL_API unsigned char* wolfSSL_ASN1_TIME_get_data(WOLFSSL_ASN1_TIME *t); +WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_to_generalizedtime(WOLFSSL_ASN1_TIME *t, + WOLFSSL_ASN1_TIME **out); +WOLFSSL_API int wolfSSL_i2c_ASN1_INTEGER(WOLFSSL_ASN1_INTEGER *a, unsigned char **pp); +WOLFSSL_API int wolfSSL_X509_CA_num(WOLFSSL_X509_STORE *store); +WOLFSSL_API long wolfSSL_X509_get_version(const WOLFSSL_X509 *x); +WOLFSSL_API int wolfSSL_X509_get_signature_nid(const WOLFSSL_X509* x); + +WOLFSSL_API int wolfSSL_PEM_write_bio_PKCS8PrivateKey(WOLFSSL_BIO* bio, + WOLFSSL_EVP_PKEY* pkey, const WOLFSSL_EVP_CIPHER* enc, char* passwd, + int passwdSz, pem_password_cb* cb, void* ctx); +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PKCS8PrivateKey_bio(WOLFSSL_BIO* bio, + WOLFSSL_EVP_PKEY** pkey, pem_password_cb* cb, void* u); +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_AutoPrivateKey( + WOLFSSL_EVP_PKEY** pkey, const unsigned char** data, long length); +WOLFSSL_API unsigned long wolfSSL_X509_subject_name_hash(const WOLFSSL_X509* x509); + + +#endif /* OPENSSL_EXTRA */ + +#ifdef HAVE_PK_CALLBACKS +WOLFSSL_API int wolfSSL_IsPrivatePkSet(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_CTX_IsPrivatePkSet(WOLFSSL_CTX* ctx); +#endif + +#ifdef HAVE_ENCRYPT_THEN_MAC +WOLFSSL_API int wolfSSL_CTX_AllowEncryptThenMac(WOLFSSL_CTX *, int); +WOLFSSL_API int wolfSSL_AllowEncryptThenMac(WOLFSSL *s, int); +#endif + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* WOLFSSL_SSL_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/test.h b/wolfssl_hlavickove_subory/wolfssl/test.h new file mode 100644 index 0000000..221899a --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/test.h @@ -0,0 +1,3473 @@ +/* test.h */ + +#ifndef wolfSSL_TEST_H +#define wolfSSL_TEST_H + +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(SHOW_CERTS) && \ + (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) + #include /* for domain component NID value */ +#endif + +#ifdef ATOMIC_USER + #include + #include + #include +#endif +#ifdef HAVE_PK_CALLBACKS + #include + #ifndef NO_RSA + #include + #endif + #ifdef HAVE_ECC + #include + #endif /* HAVE_ECC */ + #ifndef NO_DH + #include + #endif /* !NO_DH */ + #ifdef HAVE_ED25519 + #include + #endif /* HAVE_ED25519 */ + #ifdef HAVE_CURVE25519 + #include + #endif /* HAVE_ECC */ +#endif /*HAVE_PK_CALLBACKS */ + +#ifdef USE_WINDOWS_API + #include + #include + #ifdef TEST_IPV6 /* don't require newer SDK for IPV4 */ + #include + #include + #endif + #define SOCKET_T SOCKET + #define SNPRINTF _snprintf +#elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) + #include + #include "rl_net.h" + #define SOCKET_T int + typedef int socklen_t ; + #define inet_addr wolfSSL_inet_addr + static unsigned long wolfSSL_inet_addr(const char *cp) + { + unsigned int a[4] ; unsigned long ret ; + sscanf(cp, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) ; + ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ; + return(ret) ; + } + #if defined(HAVE_KEIL_RTX) + #define sleep(t) os_dly_wait(t/1000+1); + #elif defined(WOLFSSL_CMSIS_RTOS) || defined(WOLFSSL_CMSIS_RTOSv2) + #define sleep(t) osDelay(t/1000+1); + #endif +#elif defined(WOLFSSL_TIRTOS) + #include + #include + #include + #include + #include + #include + struct hostent { + char *h_name; /* official name of host */ + char **h_aliases; /* alias list */ + int h_addrtype; /* host address type */ + int h_length; /* length of address */ + char **h_addr_list; /* list of addresses from name server */ + }; + #define SOCKET_T int +#elif defined(WOLFSSL_VXWORKS) + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #define SOCKET_T int +#elif defined(WOLFSSL_ZEPHYR) + #include + #include + #include + #define SOCKET_T int + #define SOL_SOCKET 1 + #define SO_REUSEADDR 201 + #define WOLFSSL_USE_GETADDRINFO + + static unsigned long inet_addr(const char *cp) + { + unsigned int a[4]; unsigned long ret; + int i, j; + for (i=0, j=0; i<4; i++) { + a[i] = 0; + while (cp[j] != '.' && cp[j] != '\0') { + a[i] *= 10; + a[i] += cp[j] - '0'; + j++; + } + } + ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ; + return(ret) ; + } +#else + #include + #include +#ifndef WOLFSSL_LEANPSK + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #ifdef TEST_IPV6 + #include + #endif +#endif + #define SOCKET_T int + #ifndef SO_NOSIGPIPE + #include /* ignore SIGPIPE */ + #endif + #define SNPRINTF snprintf +#endif /* USE_WINDOWS_API */ + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif +#ifdef HAVE_CAVIUM + #include +#endif +#ifdef _MSC_VER + /* disable conversion warning */ + /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */ + #pragma warning(disable:4244 4996) +#endif + +#ifndef WOLFSSL_CIPHER_LIST_MAX_SIZE + #define WOLFSSL_CIPHER_LIST_MAX_SIZE 4096 +#endif +/* Buffer for benchmark tests */ +#ifndef TEST_BUFFER_SIZE + #define TEST_BUFFER_SIZE 16384 +#endif + +#ifndef WOLFSSL_HAVE_MIN + #define WOLFSSL_HAVE_MIN + static WC_INLINE word32 min(word32 a, word32 b) + { + return a > b ? b : a; + } +#endif /* WOLFSSL_HAVE_MIN */ + +/* Socket Handling */ +#ifndef WOLFSSL_SOCKET_INVALID +#ifdef USE_WINDOWS_API + #define WOLFSSL_SOCKET_INVALID ((SOCKET_T)INVALID_SOCKET) +#elif defined(WOLFSSL_TIRTOS) + #define WOLFSSL_SOCKET_INVALID ((SOCKET_T)-1) +#else + #define WOLFSSL_SOCKET_INVALID (SOCKET_T)(0) +#endif +#endif /* WOLFSSL_SOCKET_INVALID */ + +#ifndef WOLFSSL_SOCKET_IS_INVALID +#if defined(USE_WINDOWS_API) || defined(WOLFSSL_TIRTOS) + #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) == WOLFSSL_SOCKET_INVALID) +#else + #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) < WOLFSSL_SOCKET_INVALID) +#endif +#endif /* WOLFSSL_SOCKET_IS_INVALID */ + +#if defined(__MACH__) || defined(USE_WINDOWS_API) + #ifndef _SOCKLEN_T + typedef int socklen_t; + #endif +#endif + + +/* HPUX doesn't use socklent_t for third parameter to accept, unless + _XOPEN_SOURCE_EXTENDED is defined */ +#if !defined(__hpux__) && !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_IAR_ARM)\ + && !defined(WOLFSSL_ROWLEY_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) + typedef socklen_t* ACCEPT_THIRD_T; +#else + #if defined _XOPEN_SOURCE_EXTENDED + typedef socklen_t* ACCEPT_THIRD_T; + #else + typedef int* ACCEPT_THIRD_T; + #endif +#endif + + + +#ifdef SINGLE_THREADED + typedef unsigned int THREAD_RETURN; + typedef void* THREAD_TYPE; + #define WOLFSSL_THREAD +#else + #if defined(_POSIX_THREADS) && !defined(__MINGW32__) + typedef void* THREAD_RETURN; + typedef pthread_t THREAD_TYPE; + #define WOLFSSL_THREAD + #define INFINITE -1 + #define WAIT_OBJECT_0 0L + #elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_KEIL_TCP_NET) + typedef unsigned int THREAD_RETURN; + typedef int THREAD_TYPE; + #define WOLFSSL_THREAD + #elif defined(WOLFSSL_TIRTOS) + typedef void THREAD_RETURN; + typedef Task_Handle THREAD_TYPE; + #define WOLFSSL_THREAD + #elif defined(WOLFSSL_ZEPHYR) + typedef void THREAD_RETURN; + typedef struct k_thread THREAD_TYPE; + #define WOLFSSL_THREAD + #else + typedef unsigned int THREAD_RETURN; + typedef intptr_t THREAD_TYPE; + #define WOLFSSL_THREAD __stdcall + #endif +#endif + + +#ifdef TEST_IPV6 + typedef struct sockaddr_in6 SOCKADDR_IN_T; + #define AF_INET_V AF_INET6 +#else + typedef struct sockaddr_in SOCKADDR_IN_T; + #define AF_INET_V AF_INET +#endif + + +#ifndef WOLFSSL_NO_TLS12 +#define SERVER_DEFAULT_VERSION 3 +#else +#define SERVER_DEFAULT_VERSION 4 +#endif +#define SERVER_DTLS_DEFAULT_VERSION (-2) +#define SERVER_INVALID_VERSION (-99) +#define SERVER_DOWNGRADE_VERSION (-98) +#ifndef WOLFSSL_NO_TLS12 +#define CLIENT_DEFAULT_VERSION 3 +#else +#define CLIENT_DEFAULT_VERSION 4 +#endif +#define CLIENT_DTLS_DEFAULT_VERSION (-2) +#define CLIENT_INVALID_VERSION (-99) +#define CLIENT_DOWNGRADE_VERSION (-98) +#define EITHER_DOWNGRADE_VERSION (-97) +#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH) + #define DEFAULT_MIN_DHKEY_BITS 2048 + #define DEFAULT_MAX_DHKEY_BITS 3072 +#else + #define DEFAULT_MIN_DHKEY_BITS 1024 + #define DEFAULT_MAX_DHKEY_BITS 2048 +#endif +#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH) + #define DEFAULT_MIN_RSAKEY_BITS 2048 +#else + #define DEFAULT_MIN_RSAKEY_BITS 1024 +#endif +#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH) + #define DEFAULT_MIN_ECCKEY_BITS 256 +#else + #define DEFAULT_MIN_ECCKEY_BITS 224 +#endif + +/* all certs relative to wolfSSL home directory now */ +#if defined(WOLFSSL_NO_CURRDIR) || defined(WOLFSSL_MDK_SHELL) +#define caCertFile "certs/ca-cert.pem" +#define eccCertFile "certs/server-ecc.pem" +#define eccKeyFile "certs/ecc-key.pem" +#define eccRsaCertFile "certs/server-ecc-rsa.pem" +#define svrCertFile "certs/server-cert.pem" +#define svrKeyFile "certs/server-key.pem" +#define cliCertFile "certs/client-cert.pem" +#define cliCertDerFile "certs/client-cert.der" +#define cliCertFileExt "certs/client-cert-ext.pem" +#define cliCertDerFileExt "certs/client-cert-ext.der" +#define cliKeyFile "certs/client-key.pem" +#define ntruCertFile "certs/ntru-cert.pem" +#define ntruKeyFile "certs/ntru-key.raw" +#define dhParamFile "certs/dh2048.pem" +#define cliEccKeyFile "certs/ecc-client-key.pem" +#define cliEccCertFile "certs/client-ecc-cert.pem" +#define caEccCertFile "certs/ca-ecc-cert.pem" +#define crlPemDir "certs/crl" +#define edCertFile "certs/ed25519/server-ed25519-cert.pem" +#define edKeyFile "certs/ed25519/server-ed25519-priv.pem" +#define cliEdCertFile "certs/ed25519/client-ed25519.pem" +#define cliEdKeyFile "certs/ed25519/client-ed25519-priv.pem" +#define caEdCertFile "certs/ed25519/ca-ed25519.pem" +#ifdef HAVE_WNR + /* Whitewood netRandom default config file */ + #define wnrConfig "wnr-example.conf" +#endif +#else +#define caCertFile "./certs/ca-cert.pem" +#define eccCertFile "./certs/server-ecc.pem" +#define eccKeyFile "./certs/ecc-key.pem" +#define eccRsaCertFile "./certs/server-ecc-rsa.pem" +#define svrCertFile "./certs/server-cert.pem" +#define svrKeyFile "./certs/server-key.pem" +#define cliCertFile "./certs/client-cert.pem" +#define cliCertDerFile "./certs/client-cert.der" +#define cliCertFileExt "./certs/client-cert-ext.pem" +#define cliCertDerFileExt "./certs/client-cert-ext.der" +#define cliKeyFile "./certs/client-key.pem" +#define ntruCertFile "./certs/ntru-cert.pem" +#define ntruKeyFile "./certs/ntru-key.raw" +#define dhParamFile "./certs/dh2048.pem" +#define cliEccKeyFile "./certs/ecc-client-key.pem" +#define cliEccCertFile "./certs/client-ecc-cert.pem" +#define caEccCertFile "./certs/ca-ecc-cert.pem" +#define crlPemDir "./certs/crl" +#define edCertFile "./certs/ed25519/server-ed25519-cert.pem" +#define edKeyFile "./certs/ed25519/server-ed25519-priv.pem" +#define cliEdCertFile "./certs/ed25519/client-ed25519.pem" +#define cliEdKeyFile "./certs/ed25519/client-ed25519-priv.pem" +#define caEdCertFile "./certs/ed25519/ca-ed25519.pem" +#ifdef HAVE_WNR + /* Whitewood netRandom default config file */ + #define wnrConfig "./wnr-example.conf" +#endif +#endif + +typedef struct tcp_ready { + word16 ready; /* predicate */ + word16 port; + char* srfName; /* server ready file name */ +#if defined(_POSIX_THREADS) && !defined(__MINGW32__) + pthread_mutex_t mutex; + pthread_cond_t cond; +#endif +} tcp_ready; + + +static WC_INLINE void InitTcpReady(tcp_ready* ready) +{ + ready->ready = 0; + ready->port = 0; + ready->srfName = NULL; +#ifdef SINGLE_THREADED +#elif defined(_POSIX_THREADS) && !defined(__MINGW32__) + pthread_mutex_init(&ready->mutex, 0); + pthread_cond_init(&ready->cond, 0); +#endif +} + + +static WC_INLINE void FreeTcpReady(tcp_ready* ready) +{ +#ifdef SINGLE_THREADED + (void)ready; +#elif defined(_POSIX_THREADS) && !defined(__MINGW32__) + pthread_mutex_destroy(&ready->mutex); + pthread_cond_destroy(&ready->cond); +#else + (void)ready; +#endif +} + +typedef WOLFSSL_METHOD* (*method_provider)(void); +typedef void (*ctx_callback)(WOLFSSL_CTX* ctx); +typedef void (*ssl_callback)(WOLFSSL* ssl); + +typedef struct callback_functions { + method_provider method; + ctx_callback ctx_ready; + ssl_callback ssl_ready; + ssl_callback on_result; + WOLFSSL_CTX* ctx; +} callback_functions; + +typedef struct func_args { + int argc; + char** argv; + int return_code; + tcp_ready* signal; + callback_functions *callbacks; +} func_args; + + + + +void wait_tcp_ready(func_args*); + +#ifdef WOLFSSL_ZEPHYR +typedef void THREAD_FUNC(void*, void*, void*); +#else +typedef THREAD_RETURN WOLFSSL_THREAD THREAD_FUNC(void*); +#endif + +void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*); +void join_thread(THREAD_TYPE); + +/* wolfSSL */ +#ifndef TEST_IPV6 + static const char* const wolfSSLIP = "127.0.0.1"; +#else + static const char* const wolfSSLIP = "::1"; +#endif +static const word16 wolfSSLPort = 11111; + + + +#ifndef MY_EX_USAGE +#define MY_EX_USAGE 2 +#endif + +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + +#if defined(WOLFSSL_FORCE_MALLOC_FAIL_TEST) || defined(WOLFSSL_ZEPHYR) + #ifndef EXIT_SUCCESS + #define EXIT_SUCCESS 0 + #endif + #define XEXIT(rc) return rc + #define XEXIT_T(rc) return (THREAD_RETURN)rc +#else + #define XEXIT(rc) exit((int)(rc)) + #define XEXIT_T(rc) exit((int)(rc)) +#endif + + +static WC_INLINE +#if defined(WOLFSSL_FORCE_MALLOC_FAIL_TEST) || defined(WOLFSSL_ZEPHYR) +THREAD_RETURN +#else +WC_NORETURN void +#endif +err_sys(const char* msg) +{ + printf("wolfSSL error: %s\n", msg); + +#if !defined(__GNUC__) + /* scan-build (which pretends to be gnuc) can get confused and think the + * msg pointer can be null even when hardcoded and then it won't exit, + * making null pointer checks above the err_sys() call useless. + * We could just always exit() but some compilers will complain about no + * possible return, with gcc we know the attribute to handle that with + * WC_NORETURN. */ + if (msg) +#endif + { + XEXIT_T(EXIT_FAILURE); + } +} + + +extern int myoptind; +extern char* myoptarg; + +static WC_INLINE int mygetopt(int argc, char** argv, const char* optstring) +{ + static char* next = NULL; + + char c; + char* cp; + + if (myoptind == 0) + next = NULL; /* we're starting new/over */ + + if (next == NULL || *next == '\0') { + if (myoptind == 0) + myoptind++; + + if (myoptind >= argc || argv[myoptind][0] != '-' || + argv[myoptind][1] == '\0') { + myoptarg = NULL; + if (myoptind < argc) + myoptarg = argv[myoptind]; + + return -1; + } + + if (strcmp(argv[myoptind], "--") == 0) { + myoptind++; + myoptarg = NULL; + + if (myoptind < argc) + myoptarg = argv[myoptind]; + + return -1; + } + + next = argv[myoptind]; + next++; /* skip - */ + myoptind++; + } + + c = *next++; + /* The C++ strchr can return a different value */ + cp = (char*)strchr(optstring, c); + + if (cp == NULL || c == ':') + return '?'; + + cp++; + + if (*cp == ':') { + if (*next != '\0') { + myoptarg = next; + next = NULL; + } + else if (myoptind < argc) { + myoptarg = argv[myoptind]; + myoptind++; + } + else + return '?'; + } + + return c; +} + + +#ifdef WOLFSSL_ENCRYPTED_KEYS + +static WC_INLINE int PasswordCallBack(char* passwd, int sz, int rw, void* userdata) +{ + (void)rw; + (void)userdata; + if (userdata != NULL) { + strncpy(passwd, (char*)userdata, sz); + return (int)XSTRLEN((char*)userdata); + } + else { + strncpy(passwd, "yassl123", sz); + return 8; + } +} + +#endif + +static const char* client_showpeer_msg[][8] = { + /* English */ + { + "SSL version is", + "SSL cipher suite is", + "SSL curve name is", + "SSL DH size is", + "SSL reused session", + "Alternate cert chain used", + "peer's cert info:", + NULL + }, +#ifndef NO_MULTIBYTE_PRINT + /* Japanese */ + { + "SSL バージョンは", + "SSL 暗号スイートは", + "SSL 曲線名は", + "SSL DH サイズは", + "SSL 再利用セッション", + "代替証明チェーンを使用", + "相手方証明書情報", + NULL + }, +#endif +}; + +#if defined(KEEP_PEER_CERT) || defined(KEEP_OUR_CERT) || defined(SESSION_CERTS) +static const char* client_showx509_msg[][5] = { + /* English */ + { + "issuer", + "subject", + "altname", + "serial number", + NULL + }, +#ifndef NO_MULTIBYTE_PRINT + /* Japanese */ + { + "発行者", + "サブジェクト", + "代替名", + "シリアル番号", + NULL + }, +#endif +}; + +/* lng_index is to specify the language for displaying message. */ +/* 0:English, 1:Japanese */ +static WC_INLINE void ShowX509Ex(WOLFSSL_X509* x509, const char* hdr, + int lng_index) +{ + char* altName; + char* issuer; + char* subject; + byte serial[32]; + int ret; + int sz = sizeof(serial); + const char** words = client_showx509_msg[lng_index]; + + if (x509 == NULL) { + printf("%s No Cert\n", hdr); + return; + } + + issuer = wolfSSL_X509_NAME_oneline( + wolfSSL_X509_get_issuer_name(x509), 0, 0); + subject = wolfSSL_X509_NAME_oneline( + wolfSSL_X509_get_subject_name(x509), 0, 0); + + printf("%s\n %s : %s\n %s: %s\n", hdr, words[0], issuer, words[1], subject); + + while ( (altName = wolfSSL_X509_get_next_altname(x509)) != NULL) + printf(" %s = %s\n", words[2], altName); + + ret = wolfSSL_X509_get_serial_number(x509, serial, &sz); + if (ret == WOLFSSL_SUCCESS) { + int i; + int strLen; + char serialMsg[80]; + + /* testsuite has multiple threads writing to stdout, get output + message ready to write once */ + strLen = sprintf(serialMsg, " %s", words[3]); + for (i = 0; i < sz; i++) + sprintf(serialMsg + strLen + (i*3), ":%02x ", serial[i]); + printf("%s\n", serialMsg); + } + + XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL); + XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL); + +#if defined(SHOW_CERTS) && defined(OPENSSL_EXTRA) + { + WOLFSSL_BIO* bio; + char buf[256]; /* should be size of ASN_NAME_MAX */ + int textSz; + + /* print out domain component if certificate has it */ + textSz = wolfSSL_X509_NAME_get_text_by_NID( + wolfSSL_X509_get_subject_name(x509), NID_domainComponent, + buf, sizeof(buf)); + if (textSz > 0) { + printf("Domain Component = %s\n", buf); + } + + bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file()); + if (bio != NULL) { + wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE); + wolfSSL_X509_print(bio, x509); + wolfSSL_BIO_free(bio); + } + } +#endif /* SHOW_CERTS && OPENSSL_EXTRA */ +} +/* original ShowX509 to maintain compatibility */ +static WC_INLINE void ShowX509(WOLFSSL_X509* x509, const char* hdr) +{ + ShowX509Ex(x509, hdr, 0); +} + +#endif /* KEEP_PEER_CERT || KEEP_OUR_CERT || SESSION_CERTS */ + +#if defined(SHOW_CERTS) && defined(SESSION_CERTS) && \ + (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) +static WC_INLINE void ShowX509Chain(WOLFSSL_X509_CHAIN* chain, int count, + const char* hdr) +{ + int i; + int length; + unsigned char buffer[3072]; + WOLFSSL_X509* chainX509; + + for (i = 0; i < count; i++) { + wolfSSL_get_chain_cert_pem(chain, i, buffer, sizeof(buffer), &length); + buffer[length] = 0; + printf("\n%s: %d has length %d data = \n%s\n", hdr, i, length, buffer); + + chainX509 = wolfSSL_get_chain_X509(chain, i); + if (chainX509) + ShowX509(chainX509, hdr); + else + printf("get_chain_X509 failed\n"); + wolfSSL_FreeX509(chainX509); + } +} +#endif /* SHOW_CERTS && SESSION_CERTS */ + +/* lng_index is to specify the language for displaying message. */ +/* 0:English, 1:Japanese */ +static WC_INLINE void showPeerEx(WOLFSSL* ssl, int lng_index) +{ + WOLFSSL_CIPHER* cipher; + const char** words = client_showpeer_msg[lng_index]; + +#if defined(HAVE_ECC) || !defined(NO_DH) + const char *name; +#endif +#ifndef NO_DH + int bits; +#endif +#ifdef KEEP_PEER_CERT + WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl); + if (peer) + ShowX509Ex(peer, words[6], lng_index); + else + printf("peer has no cert!\n"); + wolfSSL_FreeX509(peer); +#endif +#if defined(SHOW_CERTS) && defined(KEEP_OUR_CERT) && \ + (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) + ShowX509(wolfSSL_get_certificate(ssl), "our cert info:"); + printf("Peer verify result = %lu\n", wolfSSL_get_verify_result(ssl)); +#endif /* SHOW_CERTS && KEEP_OUR_CERT */ + printf("%s %s\n", words[0], wolfSSL_get_version(ssl)); + + cipher = wolfSSL_get_current_cipher(ssl); +#ifdef HAVE_QSH + printf("%s %s%s\n", words[1], (wolfSSL_isQSH(ssl))? "QSH:": "", + wolfSSL_CIPHER_get_name(cipher)); +#else + printf("%s %s\n", words[1], wolfSSL_CIPHER_get_name(cipher)); +#endif +#if defined(HAVE_ECC) || !defined(NO_DH) + if ((name = wolfSSL_get_curve_name(ssl)) != NULL) + printf("%s %s\n", words[2], name); +#endif +#ifndef NO_DH + else if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0) + printf("%s %d bits\n", words[3], bits); +#endif + if (wolfSSL_session_reused(ssl)) + printf("%s\n", words[4]); +#ifdef WOLFSSL_ALT_CERT_CHAINS + if (wolfSSL_is_peer_alt_cert_chain(ssl)) + printf("%s\n", words[5]); +#endif + +#if defined(SHOW_CERTS) && defined(SESSION_CERTS) && \ + (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) + { + WOLFSSL_X509_CHAIN* chain; + + chain = wolfSSL_get_peer_chain(ssl); + ShowX509Chain(chain, wolfSSL_get_chain_count(chain), "session cert"); + + #ifdef WOLFSSL_ALT_CERT_CHAINS + if (wolfSSL_is_peer_alt_cert_chain(ssl)) { + chain = wolfSSL_get_peer_alt_chain(ssl); + ShowX509Chain(chain, wolfSSL_get_chain_count(chain), "alt cert"); + } + #endif + } +#endif /* SHOW_CERTS && SESSION_CERTS */ + (void)ssl; +} +/* original showPeer to maintain compatibility */ +static WC_INLINE void showPeer(WOLFSSL* ssl) +{ + showPeerEx(ssl, 0); +} + +static WC_INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer, + word16 port, int udp, int sctp) +{ + int useLookup = 0; + (void)useLookup; + (void)udp; + (void)sctp; + + if (addr == NULL) + err_sys("invalid argument to build_addr, addr is NULL"); + + XMEMSET(addr, 0, sizeof(SOCKADDR_IN_T)); + +#ifndef TEST_IPV6 + /* peer could be in human readable form */ + if ( ((size_t)peer != INADDR_ANY) && isalpha((int)peer[0])) { + #ifndef WOLFSSL_USE_GETADDRINFO + #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) + int err; + struct hostent* entry = gethostbyname(peer, &err); + #elif defined(WOLFSSL_TIRTOS) + struct hostent* entry = DNSGetHostByName(peer); + #elif defined(WOLFSSL_VXWORKS) + struct hostent* entry = (struct hostent*)hostGetByName((char*)peer); + #else + struct hostent* entry = gethostbyname(peer); + #endif + + if (entry) { + XMEMCPY(&addr->sin_addr.s_addr, entry->h_addr_list[0], + entry->h_length); + useLookup = 1; + } + #else + struct zsock_addrinfo hints, *addrInfo; + char portStr[6]; + XSNPRINTF(portStr, sizeof(portStr), "%d", port); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP; + if (getaddrinfo((char*)peer, portStr, &hints, &addrInfo) == 0) { + XMEMCPY(addr, addrInfo->ai_addr, sizeof(*addr)); + useLookup = 1; + } + #endif + else + err_sys("no entry for host"); + } +#endif + + +#ifndef TEST_IPV6 + #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) + addr->sin_family = PF_INET; + #else + addr->sin_family = AF_INET_V; + #endif + addr->sin_port = XHTONS(port); + if ((size_t)peer == INADDR_ANY) + addr->sin_addr.s_addr = INADDR_ANY; + else { + if (!useLookup) + addr->sin_addr.s_addr = inet_addr(peer); + } +#else + addr->sin6_family = AF_INET_V; + addr->sin6_port = XHTONS(port); + if ((size_t)peer == INADDR_ANY) { + addr->sin6_addr = in6addr_any; + } + else { + #if defined(HAVE_GETADDRINFO) || defined(WOLF_C99) + struct addrinfo hints; + struct addrinfo* answer = NULL; + int ret; + char strPort[80]; + + XMEMSET(&hints, 0, sizeof(hints)); + + hints.ai_family = AF_INET_V; + if (udp) { + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + } + #ifdef WOLFSSL_SCTP + else if (sctp) { + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_SCTP; + } + #endif + else { + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + } + + SNPRINTF(strPort, sizeof(strPort), "%d", port); + strPort[79] = '\0'; + + ret = getaddrinfo(peer, strPort, &hints, &answer); + if (ret < 0 || answer == NULL) + err_sys("getaddrinfo failed"); + + XMEMCPY(addr, answer->ai_addr, answer->ai_addrlen); + freeaddrinfo(answer); + #else + printf("no ipv6 getaddrinfo, loopback only tests/examples\n"); + addr->sin6_addr = in6addr_loopback; + #endif + } +#endif +} + + +static WC_INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp) +{ + (void)sctp; + + if (udp) + *sockfd = socket(AF_INET_V, SOCK_DGRAM, IPPROTO_UDP); +#ifdef WOLFSSL_SCTP + else if (sctp) + *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_SCTP); +#endif + else + *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_TCP); + + if(WOLFSSL_SOCKET_IS_INVALID(*sockfd)) { + err_sys("socket failed\n"); + } + +#ifndef USE_WINDOWS_API +#ifdef SO_NOSIGPIPE + { + int on = 1; + socklen_t len = sizeof(on); + int res = setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len); + if (res < 0) + err_sys("setsockopt SO_NOSIGPIPE failed\n"); + } +#elif defined(WOLFSSL_MDK_ARM) || defined (WOLFSSL_TIRTOS) ||\ + defined(WOLFSSL_KEIL_TCP_NET) || defined(WOLFSSL_ZEPHYR) + /* nothing to define */ +#else /* no S_NOSIGPIPE */ + signal(SIGPIPE, SIG_IGN); +#endif /* S_NOSIGPIPE */ + +#if defined(TCP_NODELAY) + if (!udp && !sctp) + { + int on = 1; + socklen_t len = sizeof(on); + int res = setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, &on, len); + if (res < 0) + err_sys("setsockopt TCP_NODELAY failed\n"); + } +#endif +#endif /* USE_WINDOWS_API */ +} + +static WC_INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port, + int udp, int sctp, WOLFSSL* ssl) +{ + SOCKADDR_IN_T addr; + build_addr(&addr, ip, port, udp, sctp); + if (udp) { + wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr)); + } + tcp_socket(sockfd, udp, sctp); + + if (!udp) { + if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) + err_sys("tcp connect failed"); + } +} + + +static WC_INLINE void udp_connect(SOCKET_T* sockfd, void* addr, int addrSz) +{ + if (connect(*sockfd, (const struct sockaddr*)addr, addrSz) != 0) + err_sys("tcp connect failed"); +} + + +enum { + TEST_SELECT_FAIL, + TEST_TIMEOUT, + TEST_RECV_READY, + TEST_SEND_READY, + TEST_ERROR_READY +}; + + +#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && \ + !defined(WOLFSSL_TIRTOS) +static WC_INLINE int tcp_select_ex(SOCKET_T socketfd, int to_sec, int rx) +{ + fd_set fds, errfds; + fd_set* recvfds = NULL; + fd_set* sendfds = NULL; + SOCKET_T nfds = socketfd + 1; +#if !defined(__INTEGRITY) + struct timeval timeout = {(to_sec > 0) ? to_sec : 0, 0}; +#else + struct timeval timeout; +#endif + int result; + + FD_ZERO(&fds); + FD_SET(socketfd, &fds); + FD_ZERO(&errfds); + FD_SET(socketfd, &errfds); + + if (rx) + recvfds = &fds; + else + sendfds = &fds; + +#if defined(__INTEGRITY) + timeout.tv_sec = (long long)(to_sec > 0) ? to_sec : 0, 0; +#endif + result = select(nfds, recvfds, sendfds, &errfds, &timeout); + + if (result == 0) + return TEST_TIMEOUT; + else if (result > 0) { + if (FD_ISSET(socketfd, &fds)) { + if (rx) + return TEST_RECV_READY; + else + return TEST_SEND_READY; + } + else if(FD_ISSET(socketfd, &errfds)) + return TEST_ERROR_READY; + } + + return TEST_SELECT_FAIL; +} + +static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec) +{ + return tcp_select_ex(socketfd, to_sec, 1); +} + +static WC_INLINE int tcp_select_tx(SOCKET_T socketfd, int to_sec) +{ + return tcp_select_ex(socketfd, to_sec, 0); +} + +#elif defined(WOLFSSL_TIRTOS) || defined(WOLFSSL_KEIL_TCP_NET) +static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec) +{ + return TEST_RECV_READY; +} +static WC_INLINE int tcp_select_tx(SOCKET_T socketfd, int to_sec) +{ + return TEST_SEND_READY; +} +#endif /* !WOLFSSL_MDK_ARM */ + + +static WC_INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr, + int udp, int sctp) +{ + SOCKADDR_IN_T addr; + + /* don't use INADDR_ANY by default, firewall may block, make user switch + on */ + build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), *port, udp, sctp); + tcp_socket(sockfd, udp, sctp); + +#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)\ + && !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_ZEPHYR) + { + int res, on = 1; + socklen_t len = sizeof(on); + res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len); + if (res < 0) + err_sys("setsockopt SO_REUSEADDR failed\n"); + } +#endif + + if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) + err_sys("tcp bind failed"); + if (!udp) { + #ifdef WOLFSSL_KEIL_TCP_NET + #define SOCK_LISTEN_MAX_QUEUE 1 + #else + #define SOCK_LISTEN_MAX_QUEUE 5 + #endif + if (listen(*sockfd, SOCK_LISTEN_MAX_QUEUE) != 0) + err_sys("tcp listen failed"); + } + #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS) \ + && !defined(WOLFSSL_ZEPHYR) + if (*port == 0) { + socklen_t len = sizeof(addr); + if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) { + #ifndef TEST_IPV6 + *port = XNTOHS(addr.sin_port); + #else + *port = XNTOHS(addr.sin6_port); + #endif + } + } + #endif +} + + +#if 0 +static WC_INLINE int udp_read_connect(SOCKET_T sockfd) +{ + SOCKADDR_IN_T cliaddr; + byte b[1500]; + int n; + socklen_t len = sizeof(cliaddr); + + n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK, + (struct sockaddr*)&cliaddr, &len); + if (n > 0) { + if (connect(sockfd, (const struct sockaddr*)&cliaddr, + sizeof(cliaddr)) != 0) + err_sys("udp connect failed"); + } + else + err_sys("recvfrom failed"); + + return sockfd; +} +#endif + +static WC_INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, + int useAnyAddr, word16 port, func_args* args) +{ + SOCKADDR_IN_T addr; + + (void)args; + build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), port, 1, 0); + tcp_socket(sockfd, 1, 0); + + +#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM) \ + && !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_ZEPHYR) + { + int res, on = 1; + socklen_t len = sizeof(on); + res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len); + if (res < 0) + err_sys("setsockopt SO_REUSEADDR failed\n"); + } +#endif + + if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) + err_sys("tcp bind failed"); + + #if (defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)) && !defined(WOLFSSL_TIRTOS) + if (port == 0) { + socklen_t len = sizeof(addr); + if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) { + #ifndef TEST_IPV6 + port = XNTOHS(addr.sin_port); + #else + port = XNTOHS(addr.sin6_port); + #endif + } + } + #endif + +#if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__) + /* signal ready to accept data */ + { + tcp_ready* ready = args->signal; + pthread_mutex_lock(&ready->mutex); + ready->ready = 1; + ready->port = port; + pthread_cond_signal(&ready->cond); + pthread_mutex_unlock(&ready->mutex); + } +#elif defined (WOLFSSL_TIRTOS) + /* Need mutex? */ + tcp_ready* ready = args->signal; + ready->ready = 1; + ready->port = port; +#endif + + *clientfd = *sockfd; +} + +static WC_INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, + func_args* args, word16 port, int useAnyAddr, + int udp, int sctp, int ready_file, int do_listen) +{ + SOCKADDR_IN_T client; + socklen_t client_len = sizeof(client); + tcp_ready* ready = NULL; + + (void) ready; /* Account for case when "ready" is not used */ + + if (udp) { + udp_accept(sockfd, clientfd, useAnyAddr, port, args); + return; + } + + if(do_listen) { + tcp_listen(sockfd, &port, useAnyAddr, udp, sctp); + + #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__) + /* signal ready to tcp_accept */ + if (args) + ready = args->signal; + if (ready) { + pthread_mutex_lock(&ready->mutex); + ready->ready = 1; + ready->port = port; + pthread_cond_signal(&ready->cond); + pthread_mutex_unlock(&ready->mutex); + } + #elif defined (WOLFSSL_TIRTOS) + /* Need mutex? */ + if (args) + ready = args->signal; + if (ready) { + ready->ready = 1; + ready->port = port; + } + #endif + + if (ready_file) { + #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST) + XFILE srf = NULL; + if (args) + ready = args->signal; + + if (ready) { + srf = fopen(ready->srfName, "w"); + + if (srf) { + /* let's write port sever is listening on to ready file + external monitor can then do ephemeral ports by passing + -p 0 to server on supported platforms with -R ready_file + client can then wait for existence of ready_file and see + which port the server is listening on. */ + fprintf(srf, "%d\n", (int)port); + fclose(srf); + } + } + #endif + } + } + + *clientfd = accept(*sockfd, (struct sockaddr*)&client, + (ACCEPT_THIRD_T)&client_len); + if(WOLFSSL_SOCKET_IS_INVALID(*clientfd)) { + err_sys("tcp accept failed"); + } +} + + +static WC_INLINE void tcp_set_nonblocking(SOCKET_T* sockfd) +{ + #ifdef USE_WINDOWS_API + unsigned long blocking = 1; + int ret = ioctlsocket(*sockfd, FIONBIO, &blocking); + if (ret == SOCKET_ERROR) + err_sys("ioctlsocket failed"); + #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) \ + || defined (WOLFSSL_TIRTOS)|| defined(WOLFSSL_VXWORKS) \ + || defined(WOLFSSL_ZEPHYR) + /* non blocking not supported, for now */ + #else + int flags = fcntl(*sockfd, F_GETFL, 0); + if (flags < 0) + err_sys("fcntl get failed"); + flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK); + if (flags < 0) + err_sys("fcntl set failed"); + #endif +} + + +#ifndef NO_PSK + +/* identity is OpenSSL testing default for openssl s_client, keep same */ +static const char* kIdentityStr = "Client_identity"; + +static WC_INLINE unsigned int my_psk_client_cb(WOLFSSL* ssl, const char* hint, + char* identity, unsigned int id_max_len, unsigned char* key, + unsigned int key_max_len) +{ + (void)ssl; + (void)hint; + (void)key_max_len; + + /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */ + strncpy(identity, kIdentityStr, id_max_len); + + if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) { + /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using + unsigned binary */ + key[0] = 0x1a; + key[1] = 0x2b; + key[2] = 0x3c; + key[3] = 0x4d; + + return 4; /* length of key in octets or 0 for error */ + } + else { + int i; + int b = 0x01; + + for (i = 0; i < 32; i++, b += 0x22) { + if (b >= 0x100) + b = 0x01; + key[i] = b; + } + + return 32; /* length of key in octets or 0 for error */ + } +} + + +static WC_INLINE unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity, + unsigned char* key, unsigned int key_max_len) +{ + (void)ssl; + (void)key_max_len; + + /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */ + if (strncmp(identity, kIdentityStr, strlen(kIdentityStr)) != 0) + return 0; + + if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) { + /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using + unsigned binary */ + key[0] = 0x1a; + key[1] = 0x2b; + key[2] = 0x3c; + key[3] = 0x4d; + + return 4; /* length of key in octets or 0 for error */ + } + else { + int i; + int b = 0x01; + + for (i = 0; i < 32; i++, b += 0x22) { + if (b >= 0x100) + b = 0x01; + key[i] = b; + } + + return 32; /* length of key in octets or 0 for error */ + } +} + + +static WC_INLINE unsigned int my_psk_client_tls13_cb(WOLFSSL* ssl, + const char* hint, char* identity, unsigned int id_max_len, + unsigned char* key, unsigned int key_max_len, const char** ciphersuite) +{ + int i; + int b = 0x01; + + (void)ssl; + (void)hint; + (void)key_max_len; + + /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */ + strncpy(identity, kIdentityStr, id_max_len); + + for (i = 0; i < 32; i++, b += 0x22) { + if (b >= 0x100) + b = 0x01; + key[i] = b; + } + + *ciphersuite = "TLS13-AES128-GCM-SHA256"; + + return 32; /* length of key in octets or 0 for error */ +} + + +static WC_INLINE unsigned int my_psk_server_tls13_cb(WOLFSSL* ssl, + const char* identity, unsigned char* key, unsigned int key_max_len, + const char** ciphersuite) +{ + int i; + int b = 0x01; + + (void)ssl; + (void)key_max_len; + + /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */ + if (strncmp(identity, kIdentityStr, strlen(kIdentityStr)) != 0) + return 0; + + for (i = 0; i < 32; i++, b += 0x22) { + if (b >= 0x100) + b = 0x01; + key[i] = b; + } + + *ciphersuite = "TLS13-AES128-GCM-SHA256"; + + return 32; /* length of key in octets or 0 for error */ +} + +#endif /* NO_PSK */ + + +#if defined(WOLFSSL_USER_CURRTIME) + extern double current_time(int reset); + +#elif defined(USE_WINDOWS_API) + + #define WIN32_LEAN_AND_MEAN + #include + + static WC_INLINE double current_time(int reset) + { + static int init = 0; + static LARGE_INTEGER freq; + + LARGE_INTEGER count; + + if (!init) { + QueryPerformanceFrequency(&freq); + init = 1; + } + + QueryPerformanceCounter(&count); + + (void)reset; + return (double)count.QuadPart / freq.QuadPart; + } + +#elif defined(WOLFSSL_TIRTOS) + extern double current_time(); +#elif defined(WOLFSSL_ZEPHYR) + extern double current_time(); +#else + +#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_CHIBIOS) + #include + + static WC_INLINE double current_time(int reset) + { + struct timeval tv; + gettimeofday(&tv, 0); + (void)reset; + + return (double)tv.tv_sec + (double)tv.tv_usec / 1000000; + } +#else + extern double current_time(int reset); +#endif +#endif /* USE_WINDOWS_API */ + + +#if defined(HAVE_OCSP) && defined(WOLFSSL_NONBLOCK_OCSP) +static WC_INLINE int OCSPIOCb(void* ioCtx, const char* url, int urlSz, + unsigned char* request, int requestSz, unsigned char** response) +{ +#ifdef TEST_NONBLOCK_CERTS + static int ioCbCnt = 0; +#endif + + (void)ioCtx; + (void)url; + (void)urlSz; + (void)request; + (void)requestSz; + (void)response; + +#ifdef TEST_NONBLOCK_CERTS + if (ioCbCnt) { + ioCbCnt = 0; + return EmbedOcspLookup(ioCtx, url, urlSz, request, requestSz, response); + } + else { + ioCbCnt = 1; + return WOLFSSL_CBIO_ERR_WANT_READ; + } +#else + return EmbedOcspLookup(ioCtx, url, urlSz, request, requestSz, response); +#endif +} + +static WC_INLINE void OCSPRespFreeCb(void* ioCtx, unsigned char* response) +{ + (void)ioCtx; + (void)response; +} +#endif + +#if !defined(NO_CERTS) + #if !defined(NO_FILESYSTEM) || \ + (defined(NO_FILESYSTEM) && defined(FORCE_BUFFER_TEST)) + + /* reads file size, allocates buffer, reads into buffer, returns buffer */ + static WC_INLINE int load_file(const char* fname, byte** buf, size_t* bufLen) + { + int ret; + long int fileSz; + XFILE file; + + if (fname == NULL || buf == NULL || bufLen == NULL) + return BAD_FUNC_ARG; + + /* set defaults */ + *buf = NULL; + *bufLen = 0; + + /* open file (read-only binary) */ + file = fopen(fname, "rb"); + if (!file) { + printf("Error loading %s\n", fname); + return BAD_PATH_ERROR; + } + + fseek(file, 0, SEEK_END); + fileSz = (int)ftell(file); + rewind(file); + if (fileSz > 0) { + *bufLen = (size_t)fileSz; + *buf = (byte*)malloc(*bufLen); + if (*buf == NULL) { + ret = MEMORY_E; + printf("Error allocating %lu bytes\n", (unsigned long)*bufLen); + } + else { + size_t readLen = fread(*buf, *bufLen, 1, file); + + /* check response code */ + ret = (readLen > 0) ? 0 : -1; + } + } + else { + ret = BUFFER_E; + } + fclose(file); + + return ret; + } + + enum { + WOLFSSL_CA = 1, + WOLFSSL_CERT = 2, + WOLFSSL_KEY = 3, + WOLFSSL_CERT_CHAIN = 4, + }; + + static WC_INLINE void load_buffer(WOLFSSL_CTX* ctx, const char* fname, int type) + { + int format = WOLFSSL_FILETYPE_PEM; + byte* buff = NULL; + size_t sz = 0; + + if (load_file(fname, &buff, &sz) != 0) { + err_sys("can't open file for buffer load " + "Please run from wolfSSL home directory if not"); + } + + /* determine format */ + if (strstr(fname, ".der")) + format = WOLFSSL_FILETYPE_ASN1; + + if (type == WOLFSSL_CA) { + if (wolfSSL_CTX_load_verify_buffer(ctx, buff, (long)sz, format) + != WOLFSSL_SUCCESS) + err_sys("can't load buffer ca file"); + } + else if (type == WOLFSSL_CERT) { + if (wolfSSL_CTX_use_certificate_buffer(ctx, buff, (long)sz, + format) != WOLFSSL_SUCCESS) + err_sys("can't load buffer cert file"); + } + else if (type == WOLFSSL_KEY) { + if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, (long)sz, + format) != WOLFSSL_SUCCESS) + err_sys("can't load buffer key file"); + } + else if (type == WOLFSSL_CERT_CHAIN) { + if (wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, buff, + (long)sz, format) != WOLFSSL_SUCCESS) + err_sys("can't load cert chain buffer"); + } + + if (buff) + free(buff); + } + + static WC_INLINE void load_ssl_buffer(WOLFSSL* ssl, const char* fname, int type) + { + int format = WOLFSSL_FILETYPE_PEM; + byte* buff = NULL; + size_t sz = 0; + + if (load_file(fname, &buff, &sz) != 0) { + err_sys("can't open file for buffer load " + "Please run from wolfSSL home directory if not"); + } + + /* determine format */ + if (strstr(fname, ".der")) + format = WOLFSSL_FILETYPE_ASN1; + + if (type == WOLFSSL_CA) { + /* verify certs (CA's) use the shared ctx->cm (WOLFSSL_CERT_MANAGER) */ + WOLFSSL_CTX* ctx = wolfSSL_get_SSL_CTX(ssl); + if (wolfSSL_CTX_load_verify_buffer(ctx, buff, (long)sz, format) + != WOLFSSL_SUCCESS) + err_sys("can't load buffer ca file"); + } + else if (type == WOLFSSL_CERT) { + if (wolfSSL_use_certificate_buffer(ssl, buff, (long)sz, + format) != WOLFSSL_SUCCESS) + err_sys("can't load buffer cert file"); + } + else if (type == WOLFSSL_KEY) { + if (wolfSSL_use_PrivateKey_buffer(ssl, buff, (long)sz, + format) != WOLFSSL_SUCCESS) + err_sys("can't load buffer key file"); + } + else if (type == WOLFSSL_CERT_CHAIN) { + if (wolfSSL_use_certificate_chain_buffer_format(ssl, buff, + (long)sz, format) != WOLFSSL_SUCCESS) + err_sys("can't load cert chain buffer"); + } + + if (buff) + free(buff); + } + + #ifdef TEST_PK_PRIVKEY + static WC_INLINE int load_key_file(const char* fname, byte** derBuf, word32* derLen) + { + int ret; + byte* buf = NULL; + size_t bufLen; + + ret = load_file(fname, &buf, &bufLen); + if (ret != 0) + return ret; + + *derBuf = (byte*)malloc(bufLen); + if (*derBuf == NULL) { + free(buf); + return MEMORY_E; + } + + ret = wc_KeyPemToDer(buf, (word32)bufLen, *derBuf, (word32)bufLen, NULL); + if (ret < 0) { + free(buf); + free(*derBuf); + return ret; + } + *derLen = ret; + free(buf); + + return 0; + } + #endif /* TEST_PK_PRIVKEY */ + + #endif /* !NO_FILESYSTEM || (NO_FILESYSTEM && FORCE_BUFFER_TEST) */ +#endif /* !NO_CERTS */ + +static int myVerifyFail = 0; + +/* The verify callback is called for every certificate only when + * --enable-opensslextra is defined because it sets WOLFSSL_ALWAYS_VERIFY_CB and + * WOLFSSL_VERIFY_CB_ALL_CERTS. + * Normal cases of the verify callback only occur on certificate failures when the + * wolfSSL_set_verify(ssl, SSL_VERIFY_PEER, myVerifyCb); is called +*/ + +static WC_INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store) +{ + char buffer[WOLFSSL_MAX_ERROR_SZ]; +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + WOLFSSL_X509* peer; +#if defined(SHOW_CERTS) && !defined(NO_FILESYSTEM) + WOLFSSL_BIO* bio = NULL; + WOLFSSL_STACK* sk = NULL; + X509* x509 = NULL; + int i = 0; +#endif +#endif + (void)preverify; + + /* Verify Callback Arguments: + * preverify: 1=Verify Okay, 0=Failure + * store->error: Failure error code (0 indicates no failure) + * store->current_cert: Current WOLFSSL_X509 object (only with OPENSSL_EXTRA) + * store->error_depth: Current Index + * store->domain: Subject CN as string (null term) + * store->totalCerts: Number of certs presented by peer + * store->certs[i]: A `WOLFSSL_BUFFER_INFO` with plain DER for each cert + * store->store: WOLFSSL_X509_STORE with CA cert chain + * store->store->cm: WOLFSSL_CERT_MANAGER + * store->ex_data: The WOLFSSL object pointer + * store->discardSessionCerts: When set to non-zero value session certs + will be discarded (only with SESSION_CERTS) + */ + + printf("In verification callback, error = %d, %s\n", store->error, + wolfSSL_ERR_error_string(store->error, buffer)); +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + peer = store->current_cert; + if (peer) { + char* issuer = wolfSSL_X509_NAME_oneline( + wolfSSL_X509_get_issuer_name(peer), 0, 0); + char* subject = wolfSSL_X509_NAME_oneline( + wolfSSL_X509_get_subject_name(peer), 0, 0); + printf("\tPeer's cert info:\n issuer : %s\n subject: %s\n", issuer, + subject); + XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL); + XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL); +#if defined(SHOW_CERTS) && !defined(NO_FILESYSTEM) +/* avoid printing duplicate certs */ + if (store->depth == 1) { + /* retrieve x509 certs and display them on stdout */ + sk = wolfSSL_X509_STORE_GetCerts(store); + + for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) { + x509 = wolfSSL_sk_X509_value(sk, i); + bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file()); + if (bio != NULL) { + wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE); + wolfSSL_X509_print(bio, x509); + wolfSSL_BIO_free(bio); + } + } + wolfSSL_sk_X509_free(sk); + } +#endif + } + else + printf("\tPeer has no cert!\n"); +#else + printf("\tPeer certs: %d\n", store->totalCerts); + #ifdef SHOW_CERTS + { int i; + for (i=0; itotalCerts; i++) { + WOLFSSL_BUFFER_INFO* cert = &store->certs[i]; + printf("\t\tCert %d: Ptr %p, Len %u\n", i, cert->buffer, cert->length); + } + } + #endif /* SHOW_CERTS */ +#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ + + printf("\tSubject's domain name at %d is %s\n", store->error_depth, store->domain); + + /* Testing forced fail case by return zero */ + if (myVerifyFail) { + return 0; /* test failure case */ + } + + /* If error indicate we are overriding it for testing purposes */ + if (store->error != 0) { + printf("\tAllowing failed certificate check, testing only " + "(shouldn't do this in production)\n"); + } + + /* A non-zero return code indicates failure override */ + return 1; +} + + +static WC_INLINE int myDateCb(int preverify, WOLFSSL_X509_STORE_CTX* store) +{ + char buffer[WOLFSSL_MAX_ERROR_SZ]; + (void)preverify; + + printf("In verification callback, error = %d, %s\n", store->error, + wolfSSL_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_EXT_CACHE + +static WC_INLINE WOLFSSL_SESSION* mySessGetCb(WOLFSSL* ssl, unsigned char* id, + int id_len, int* copy) +{ + (void)ssl; + (void)id; + (void)id_len; + (void)copy; + + /* using internal cache, this is for testing only */ + return NULL; +} + +static WC_INLINE int mySessNewCb(WOLFSSL* ssl, WOLFSSL_SESSION* session) +{ + (void)ssl; + (void)session; + + /* using internal cache, this is for testing only */ + return 0; +} + +static WC_INLINE void mySessRemCb(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session) +{ + (void)ctx; + (void)session; + + /* using internal cache, this is for testing only */ +} + +#endif /* HAVE_EXT_CACHE */ + + +#ifdef HAVE_CRL + +static WC_INLINE void CRL_CallBack(const char* url) +{ + printf("CRL callback url = %s\n", url); +} + +#endif + +#ifndef NO_DH +static WC_INLINE void SetDH(WOLFSSL* ssl) +{ + /* dh1024 p */ + static const unsigned char p[] = + { + 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3, + 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E, + 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59, + 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2, + 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD, + 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF, + 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02, + 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C, + 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7, + 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50, + 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B, + }; + + /* dh1024 g */ + static const unsigned char g[] = + { + 0x02, + }; + + wolfSSL_SetTmpDH(ssl, p, sizeof(p), g, sizeof(g)); +} + +static WC_INLINE void SetDHCtx(WOLFSSL_CTX* ctx) +{ + /* dh1024 p */ + static const unsigned char p[] = + { + 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3, + 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E, + 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59, + 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2, + 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD, + 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF, + 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02, + 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C, + 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7, + 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50, + 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B, + }; + + /* dh1024 g */ + static const unsigned char g[] = + { + 0x02, + }; + + wolfSSL_CTX_SetTmpDH(ctx, p, sizeof(p), g, sizeof(g)); +} +#endif /* NO_DH */ + +#ifndef NO_CERTS + +static WC_INLINE void CaCb(unsigned char* der, int sz, int type) +{ + (void)der; + printf("Got CA cache add callback, derSz = %d, type = %d\n", sz, type); +} + +#endif /* !NO_CERTS */ + + +/* Wolf Root Directory Helper */ +/* KEIL-RL File System does not support relative directory */ +#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS) + /* Maximum depth to search for WolfSSL root */ + #define MAX_WOLF_ROOT_DEPTH 5 + + static WC_INLINE int ChangeToWolfRoot(void) + { + #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST) + int depth, res; + XFILE file; + for(depth = 0; depth <= MAX_WOLF_ROOT_DEPTH; depth++) { + file = fopen(ntruKeyFile, "rb"); + if (file != NULL) { + fclose(file); + return depth; + } + #ifdef USE_WINDOWS_API + res = SetCurrentDirectoryA("..\\"); + #else + res = chdir("../"); + #endif + if (res < 0) { + printf("chdir to ../ failed!\n"); + break; + } + } + + err_sys("wolf root not found"); + return -1; + #else + return 0; + #endif + } +#endif /* !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS) */ + +#ifdef HAVE_STACK_SIZE + +typedef THREAD_RETURN WOLFSSL_THREAD (*thread_func)(void* args); +#define STACK_CHECK_VAL 0x01 + +static WC_INLINE int StackSizeCheck(func_args* args, thread_func tf) +{ + int ret, i, used; + void* status; + unsigned char* myStack = NULL; + int stackSize = 1024*128; + pthread_attr_t myAttr; + pthread_t threadId; + +#ifdef PTHREAD_STACK_MIN + if (stackSize < PTHREAD_STACK_MIN) + stackSize = PTHREAD_STACK_MIN; +#endif + + ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize); + if (ret != 0 || myStack == NULL) + err_sys("posix_memalign failed\n"); + + XMEMSET(myStack, STACK_CHECK_VAL, stackSize); + + ret = pthread_attr_init(&myAttr); + if (ret != 0) + err_sys("attr_init failed"); + + ret = pthread_attr_setstack(&myAttr, myStack, stackSize); + if (ret != 0) + err_sys("attr_setstackaddr failed"); + + ret = pthread_create(&threadId, &myAttr, tf, args); + if (ret != 0) { + perror("pthread_create failed"); + exit(EXIT_FAILURE); + } + + ret = pthread_join(threadId, &status); + if (ret != 0) + err_sys("pthread_join failed"); + + for (i = 0; i < stackSize; i++) { + if (myStack[i] != STACK_CHECK_VAL) { + break; + } + } + + free(myStack); + + used = stackSize - i; + printf("stack used = %d\n", used); + + return (int)((size_t)status); +} + + +#endif /* HAVE_STACK_SIZE */ + + +#ifdef STACK_TRAP + +/* good settings + --enable-debug --disable-shared C_EXTRA_FLAGS="-DUSER_TIME -DTFM_TIMING_RESISTANT -DPOSITIVE_EXP_ONLY -DSTACK_TRAP" + +*/ + +#ifdef HAVE_STACK_SIZE + /* client only for now, setrlimit will fail if pthread_create() called */ + /* STACK_SIZE does pthread_create() on client */ + #error "can't use STACK_TRAP with STACK_SIZE, setrlimit will fail" +#endif /* HAVE_STACK_SIZE */ + +static WC_INLINE void StackTrap(void) +{ + struct rlimit rl; + if (getrlimit(RLIMIT_STACK, &rl) != 0) + err_sys("getrlimit failed"); + printf("rlim_cur = %llu\n", rl.rlim_cur); + rl.rlim_cur = 1024*21; /* adjust trap size here */ + if (setrlimit(RLIMIT_STACK, &rl) != 0) { + perror("setrlimit"); + err_sys("setrlimit failed"); + } +} + +#else /* STACK_TRAP */ + +static WC_INLINE void StackTrap(void) +{ +} + +#endif /* STACK_TRAP */ + + +#if defined(ATOMIC_USER) && !defined(WOLFSSL_AEAD_ONLY) + +/* Atomic Encrypt Context example */ +typedef struct AtomicEncCtx { + int keySetup; /* have we done key setup yet */ + Aes aes; /* for aes example */ +} AtomicEncCtx; + + +/* Atomic Decrypt Context example */ +typedef struct AtomicDecCtx { + int keySetup; /* have we done key setup yet */ + Aes aes; /* for aes example */ +} AtomicDecCtx; + + +static WC_INLINE int myMacEncryptCb(WOLFSSL* ssl, unsigned char* macOut, + const unsigned char* macIn, unsigned int macInSz, int macContent, + int macVerify, unsigned char* encOut, const unsigned char* encIn, + unsigned int encSz, void* ctx) +{ + int ret; + Hmac hmac; + byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ]; + AtomicEncCtx* encCtx = (AtomicEncCtx*)ctx; + const char* tlsStr = "TLS"; + + /* example supports (d)tls aes */ + if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) { + printf("myMacEncryptCb not using AES\n"); + return -1; + } + + if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) { + printf("myMacEncryptCb not using (D)TLS\n"); + return -1; + } + + /* hmac, not needed if aead mode */ + wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify); + + ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID); + if (ret != 0) + return ret; + ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl), + wolfSSL_GetMacSecret(ssl, macVerify), wolfSSL_GetHmacSize(ssl)); + if (ret != 0) + return ret; + ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner)); + if (ret != 0) + return ret; + ret = wc_HmacUpdate(&hmac, macIn, macInSz); + if (ret != 0) + return ret; + ret = wc_HmacFinal(&hmac, macOut); + if (ret != 0) + return ret; + + + /* encrypt setup on first time */ + if (encCtx->keySetup == 0) { + int keyLen = wolfSSL_GetKeySize(ssl); + const byte* key; + const byte* iv; + + if (wolfSSL_GetSide(ssl) == WOLFSSL_CLIENT_END) { + key = wolfSSL_GetClientWriteKey(ssl); + iv = wolfSSL_GetClientWriteIV(ssl); + } + else { + key = wolfSSL_GetServerWriteKey(ssl); + iv = wolfSSL_GetServerWriteIV(ssl); + } + + ret = wc_AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION); + if (ret != 0) { + printf("AesSetKey failed in myMacEncryptCb\n"); + return ret; + } + encCtx->keySetup = 1; + } + + /* encrypt */ + return wc_AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz); +} + + +static WC_INLINE int myDecryptVerifyCb(WOLFSSL* ssl, + unsigned char* decOut, const unsigned char* decIn, + unsigned int decSz, int macContent, int macVerify, + unsigned int* padSz, void* ctx) +{ + AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx; + int ret = 0; + int macInSz = 0; + int ivExtra = 0; + int digestSz = wolfSSL_GetHmacSize(ssl); + unsigned int pad = 0; + unsigned int padByte = 0; + Hmac hmac; + byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ]; + byte verify[WC_MAX_DIGEST_SIZE]; + const char* tlsStr = "TLS"; + + /* example supports (d)tls aes */ + if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) { + printf("myMacEncryptCb not using AES\n"); + return -1; + } + + if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) { + printf("myMacEncryptCb not using (D)TLS\n"); + return -1; + } + + /*decrypt */ + if (decCtx->keySetup == 0) { + int keyLen = wolfSSL_GetKeySize(ssl); + const byte* key; + const byte* iv; + + /* decrypt is from other side (peer) */ + if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) { + key = wolfSSL_GetClientWriteKey(ssl); + iv = wolfSSL_GetClientWriteIV(ssl); + } + else { + key = wolfSSL_GetServerWriteKey(ssl); + iv = wolfSSL_GetServerWriteIV(ssl); + } + + ret = wc_AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION); + if (ret != 0) { + printf("AesSetKey failed in myDecryptVerifyCb\n"); + return ret; + } + decCtx->keySetup = 1; + } + + /* decrypt */ + ret = wc_AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz); + if (ret != 0) + return ret; + + if (wolfSSL_GetCipherType(ssl) == WOLFSSL_AEAD_TYPE) { + *padSz = wolfSSL_GetAeadMacSize(ssl); + return 0; /* hmac, not needed if aead mode */ + } + + if (wolfSSL_GetCipherType(ssl) == WOLFSSL_BLOCK_TYPE) { + pad = *(decOut + decSz - 1); + padByte = 1; + if (wolfSSL_IsTLSv1_1(ssl)) + ivExtra = wolfSSL_GetCipherBlockSize(ssl); + } + + *padSz = wolfSSL_GetHmacSize(ssl) + pad + padByte; + macInSz = decSz - ivExtra - digestSz - pad - padByte; + + wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify); + + ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID); + if (ret != 0) + return ret; + ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl), + wolfSSL_GetMacSecret(ssl, macVerify), digestSz); + if (ret != 0) + return ret; + ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner)); + if (ret != 0) + return ret; + ret = wc_HmacUpdate(&hmac, decOut + ivExtra, macInSz); + if (ret != 0) + return ret; + ret = wc_HmacFinal(&hmac, verify); + if (ret != 0) + return ret; + + if (XMEMCMP(verify, decOut + decSz - digestSz - pad - padByte, + digestSz) != 0) { + printf("myDecryptVerify verify failed\n"); + return -1; + } + + return ret; +} + +#if defined(HAVE_ENCRYPT_THEN_MAC) + +static WC_INLINE int myEncryptMacCb(WOLFSSL* ssl, unsigned char* macOut, + int content, int macVerify, unsigned char* encOut, + const unsigned char* encIn, unsigned int encSz, void* ctx) +{ + int ret; + Hmac hmac; + AtomicEncCtx* encCtx = (AtomicEncCtx*)ctx; + byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ]; + const char* tlsStr = "TLS"; + + /* example supports (d)tls aes */ + if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) { + printf("myMacEncryptCb not using AES\n"); + return -1; + } + + if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) { + printf("myMacEncryptCb not using (D)TLS\n"); + return -1; + } + + /* encrypt setup on first time */ + if (encCtx->keySetup == 0) { + int keyLen = wolfSSL_GetKeySize(ssl); + const byte* key; + const byte* iv; + + if (wolfSSL_GetSide(ssl) == WOLFSSL_CLIENT_END) { + key = wolfSSL_GetClientWriteKey(ssl); + iv = wolfSSL_GetClientWriteIV(ssl); + } + else { + key = wolfSSL_GetServerWriteKey(ssl); + iv = wolfSSL_GetServerWriteIV(ssl); + } + + ret = wc_AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION); + if (ret != 0) { + printf("AesSetKey failed in myMacEncryptCb\n"); + return ret; + } + encCtx->keySetup = 1; + } + + /* encrypt */ + ret = wc_AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz); + if (ret != 0) + return ret; + + /* Reconstruct record header. */ + wolfSSL_SetTlsHmacInner(ssl, myInner, encSz, content, macVerify); + + ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID); + if (ret != 0) + return ret; + ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl), + wolfSSL_GetMacSecret(ssl, macVerify), wolfSSL_GetHmacSize(ssl)); + if (ret != 0) + return ret; + ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner)); + if (ret != 0) + return ret; + ret = wc_HmacUpdate(&hmac, encOut, encSz); + if (ret != 0) + return ret; + return wc_HmacFinal(&hmac, macOut); +} + + +static WC_INLINE int myVerifyDecryptCb(WOLFSSL* ssl, + unsigned char* decOut, const unsigned char* decIn, + unsigned int decSz, int content, int macVerify, + unsigned int* padSz, void* ctx) +{ + AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx; + int ret = 0; + int digestSz = wolfSSL_GetHmacSize(ssl); + Hmac hmac; + byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ]; + byte verify[WC_MAX_DIGEST_SIZE]; + const char* tlsStr = "TLS"; + + /* example supports (d)tls aes */ + if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) { + printf("myMacEncryptCb not using AES\n"); + return -1; + } + + if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) { + printf("myMacEncryptCb not using (D)TLS\n"); + return -1; + } + + /* Reconstruct record header. */ + wolfSSL_SetTlsHmacInner(ssl, myInner, decSz, content, macVerify); + + ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID); + if (ret != 0) + return ret; + ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl), + wolfSSL_GetMacSecret(ssl, macVerify), digestSz); + if (ret != 0) + return ret; + ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner)); + if (ret != 0) + return ret; + ret = wc_HmacUpdate(&hmac, decIn, decSz); + if (ret != 0) + return ret; + ret = wc_HmacFinal(&hmac, verify); + if (ret != 0) + return ret; + + if (XMEMCMP(verify, decOut + decSz, digestSz) != 0) { + printf("myDecryptVerify verify failed\n"); + return -1; + } + + /* decrypt */ + if (decCtx->keySetup == 0) { + int keyLen = wolfSSL_GetKeySize(ssl); + const byte* key; + const byte* iv; + + /* decrypt is from other side (peer) */ + if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) { + key = wolfSSL_GetClientWriteKey(ssl); + iv = wolfSSL_GetClientWriteIV(ssl); + } + else { + key = wolfSSL_GetServerWriteKey(ssl); + iv = wolfSSL_GetServerWriteIV(ssl); + } + + ret = wc_AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION); + if (ret != 0) { + printf("AesSetKey failed in myDecryptVerifyCb\n"); + return ret; + } + decCtx->keySetup = 1; + } + + /* decrypt */ + ret = wc_AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz); + if (ret != 0) + return ret; + + *padSz = *(decOut + decSz - 1) + 1; + + return 0; +} + +#endif + + +static WC_INLINE void SetupAtomicUser(WOLFSSL_CTX* ctx, WOLFSSL* ssl) +{ + AtomicEncCtx* encCtx; + AtomicDecCtx* decCtx; + + encCtx = (AtomicEncCtx*)malloc(sizeof(AtomicEncCtx)); + if (encCtx == NULL) + err_sys("AtomicEncCtx malloc failed"); + XMEMSET(encCtx, 0, sizeof(AtomicEncCtx)); + + decCtx = (AtomicDecCtx*)malloc(sizeof(AtomicDecCtx)); + if (decCtx == NULL) { + free(encCtx); + err_sys("AtomicDecCtx malloc failed"); + } + XMEMSET(decCtx, 0, sizeof(AtomicDecCtx)); + + wolfSSL_CTX_SetMacEncryptCb(ctx, myMacEncryptCb); + wolfSSL_SetMacEncryptCtx(ssl, encCtx); + + wolfSSL_CTX_SetDecryptVerifyCb(ctx, myDecryptVerifyCb); + wolfSSL_SetDecryptVerifyCtx(ssl, decCtx); + +#if defined(HAVE_ENCRYPT_THEN_MAC) + wolfSSL_CTX_SetEncryptMacCb(ctx, myEncryptMacCb); + wolfSSL_SetEncryptMacCtx(ssl, encCtx); + + wolfSSL_CTX_SetVerifyDecryptCb(ctx, myVerifyDecryptCb); + wolfSSL_SetVerifyDecryptCtx(ssl, decCtx); +#endif +} + + +static WC_INLINE void FreeAtomicUser(WOLFSSL* ssl) +{ + AtomicEncCtx* encCtx = (AtomicEncCtx*)wolfSSL_GetMacEncryptCtx(ssl); + AtomicDecCtx* decCtx = (AtomicDecCtx*)wolfSSL_GetDecryptVerifyCtx(ssl); + + /* Encrypt-Then-MAC callbacks use same contexts. */ + + free(decCtx); + free(encCtx); +} + +#endif /* ATOMIC_USER */ + +#ifdef WOLFSSL_STATIC_MEMORY +static WC_INLINE int wolfSSL_PrintStats(WOLFSSL_MEM_STATS* stats) +{ + word16 i; + + if (stats == NULL) { + return 0; + } + + /* print to stderr so is on the same pipe as WOLFSSL_DEBUG */ + fprintf(stderr, "Total mallocs = %d\n", stats->totalAlloc); + fprintf(stderr, "Total frees = %d\n", stats->totalFr); + fprintf(stderr, "Current mallocs = %d\n", stats->curAlloc); + fprintf(stderr, "Available IO = %d\n", stats->avaIO); + fprintf(stderr, "Max con. handshakes = %d\n", stats->maxHa); + fprintf(stderr, "Max con. IO = %d\n", stats->maxIO); + fprintf(stderr, "State of memory blocks: size : available \n"); + for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) { + fprintf(stderr, " : %d\t : %d\n", stats->blockSz[i], + stats->avaBlock[i]); + } + + return 1; +} +#endif /* WOLFSSL_STATIC_MEMORY */ + +#ifdef HAVE_PK_CALLBACKS + +typedef struct PkCbInfo { + const char* ourKey; +#ifdef TEST_PK_PRIVKEY + union { + #ifdef HAVE_ECC + ecc_key ecc; + #endif + #ifdef HAVE_CURVE25519 + curve25519_key curve; + #endif + } keyGen; +#endif +} PkCbInfo; + +#if defined(DEBUG_PK_CB) || defined(TEST_PK_PRIVKEY) + #define WOLFSSL_PKMSG(_f_, ...) printf(_f_, ##__VA_ARGS__) +#else + #define WOLFSSL_PKMSG(_f_, ...) +#endif + +#ifdef HAVE_ECC + +static WC_INLINE int myEccKeyGen(WOLFSSL* ssl, ecc_key* key, word32 keySz, + int ecc_curve, void* ctx) +{ + int ret; + WC_RNG rng; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + ecc_key* new_key = key; +#ifdef TEST_PK_PRIVKEY + byte qx[MAX_ECC_BYTES], qy[MAX_ECC_BYTES]; + word32 qxLen = sizeof(qx), qyLen = sizeof(qy); + new_key = &cbInfo->keyGen.ecc; +#endif + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK ECC KeyGen: keySz %d, Curve ID %d\n", keySz, ecc_curve); + + ret = wc_InitRng(&rng); + if (ret != 0) + return ret; + + ret = wc_ecc_init(new_key); + if (ret == 0) { + /* create new key */ + ret = wc_ecc_make_key_ex(&rng, keySz, new_key, ecc_curve); + + #ifdef TEST_PK_PRIVKEY + if (ret == 0) { + /* extract public portion from new key into `key` arg */ + ret = wc_ecc_export_public_raw(new_key, qx, &qxLen, qy, &qyLen); + if (ret == 0) { + /* load public portion only into key */ + ret = wc_ecc_import_unsigned(key, qx, qy, NULL, ecc_curve); + } + (void)qxLen; + (void)qyLen; + } + #endif + } + + WOLFSSL_PKMSG("PK ECC KeyGen: ret %d\n", ret); + + wc_FreeRng(&rng); + + return ret; +} + +static WC_INLINE int myEccSign(WOLFSSL* ssl, const byte* in, word32 inSz, + byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx) +{ + int ret; + WC_RNG rng; + word32 idx = 0; + ecc_key myKey; + byte* keyBuf = (byte*)key; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK ECC Sign: inSz %d, keySz %d\n", inSz, keySz); + +#ifdef TEST_PK_PRIVKEY + ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz); + if (ret != 0) + return ret; +#endif + + ret = wc_InitRng(&rng); + if (ret != 0) + return ret; + + ret = wc_ecc_init(&myKey); + if (ret == 0) { + ret = wc_EccPrivateKeyDecode(keyBuf, &idx, &myKey, keySz); + if (ret == 0) { + WOLFSSL_PKMSG("PK ECC Sign: Curve ID %d\n", myKey.dp->id); + ret = wc_ecc_sign_hash(in, inSz, out, outSz, &rng, &myKey); + } + wc_ecc_free(&myKey); + } + wc_FreeRng(&rng); + +#ifdef TEST_PK_PRIVKEY + free(keyBuf); +#endif + + WOLFSSL_PKMSG("PK ECC Sign: ret %d outSz %d\n", ret, *outSz); + + return ret; +} + + +static WC_INLINE int myEccVerify(WOLFSSL* ssl, const byte* sig, word32 sigSz, + const byte* hash, word32 hashSz, const byte* key, word32 keySz, + int* result, void* ctx) +{ + int ret; + word32 idx = 0; + ecc_key myKey; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK ECC Verify: sigSz %d, hashSz %d, keySz %d\n", sigSz, hashSz, keySz); + + ret = wc_ecc_init(&myKey); + if (ret == 0) { + ret = wc_EccPublicKeyDecode(key, &idx, &myKey, keySz); + if (ret == 0) + ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, result, &myKey); + wc_ecc_free(&myKey); + } + + WOLFSSL_PKMSG("PK ECC Verify: ret %d, result %d\n", ret, *result); + + return ret; +} + +static WC_INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey, + unsigned char* pubKeyDer, unsigned int* pubKeySz, + unsigned char* out, unsigned int* outlen, + int side, void* ctx) +{ + int ret; + ecc_key* privKey = NULL; + ecc_key* pubKey = NULL; + ecc_key tmpKey; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK ECC PMS: Side %s, Peer Curve %d\n", + side == WOLFSSL_CLIENT_END ? "client" : "server", otherKey->dp->id); + + ret = wc_ecc_init(&tmpKey); + if (ret != 0) { + return ret; + } + + /* for client: create and export public key */ + if (side == WOLFSSL_CLIENT_END) { + WC_RNG rng; + + privKey = &tmpKey; + pubKey = otherKey; + + ret = wc_InitRng(&rng); + if (ret == 0) { + ret = wc_ecc_make_key_ex(&rng, 0, privKey, otherKey->dp->id); + #ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E) { + ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_NONE); + } + #endif + if (ret == 0) + ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz); + wc_FreeRng(&rng); + } + } + + /* for server: import public key */ + else if (side == WOLFSSL_SERVER_END) { + #ifdef TEST_PK_PRIVKEY + privKey = &cbInfo->keyGen.ecc; + #else + privKey = otherKey; + #endif + pubKey = &tmpKey; + + ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, pubKey, + otherKey->dp->id); + } + else { + ret = BAD_FUNC_ARG; + } + + /* generate shared secret and return it */ + if (ret == 0) { + ret = wc_ecc_shared_secret(privKey, pubKey, out, outlen); + + #ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E) { + ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); + } + #endif + } + +#ifdef TEST_PK_PRIVKEY + if (side == WOLFSSL_SERVER_END) { + wc_ecc_free(&cbInfo->keyGen.ecc); + } +#endif + + wc_ecc_free(&tmpKey); + + WOLFSSL_PKMSG("PK ECC PMS: ret %d, PubKeySz %d, OutLen %d\n", ret, *pubKeySz, *outlen); + + return ret; +} + +#ifdef HAVE_ED25519 +static WC_INLINE int myEd25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz, + byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx) +{ + int ret; + word32 idx = 0; + ed25519_key myKey; + byte* keyBuf = (byte*)key; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK 25519 Sign: inSz %d, keySz %d\n", inSz, keySz); + +#ifdef TEST_PK_PRIVKEY + ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz); + if (ret != 0) + return ret; +#endif + + ret = wc_ed25519_init(&myKey); + if (ret == 0) { + ret = wc_Ed25519PrivateKeyDecode(keyBuf, &idx, &myKey, keySz); + if (ret == 0) + ret = wc_ed25519_sign_msg(in, inSz, out, outSz, &myKey); + wc_ed25519_free(&myKey); + } + +#ifdef TEST_PK_PRIVKEY + free(keyBuf); +#endif + + WOLFSSL_PKMSG("PK 25519 Sign: ret %d, outSz %d\n", ret, *outSz); + + return ret; +} + + +static WC_INLINE int myEd25519Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz, + const byte* msg, word32 msgSz, const byte* key, word32 keySz, + int* result, void* ctx) +{ + int ret; + ed25519_key myKey; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK 25519 Verify: sigSz %d, msgSz %d, keySz %d\n", sigSz, msgSz, keySz); + + ret = wc_ed25519_init(&myKey); + if (ret == 0) { + ret = wc_ed25519_import_public(key, keySz, &myKey); + if (ret == 0) { + ret = wc_ed25519_verify_msg(sig, sigSz, msg, msgSz, result, &myKey); + } + wc_ed25519_free(&myKey); + } + + WOLFSSL_PKMSG("PK 25519 Verify: ret %d, result %d\n", ret, *result); + + return ret; +} +#endif /* HAVE_ED25519 */ + +#ifdef HAVE_CURVE25519 +static WC_INLINE int myX25519KeyGen(WOLFSSL* ssl, curve25519_key* key, + unsigned int keySz, void* ctx) +{ + int ret; + WC_RNG rng; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK 25519 KeyGen: keySz %d\n", keySz); + + ret = wc_InitRng(&rng); + if (ret != 0) + return ret; + + ret = wc_curve25519_make_key(&rng, keySz, key); + + wc_FreeRng(&rng); + + WOLFSSL_PKMSG("PK 25519 KeyGen: ret %d\n", ret); + + return ret; +} + +static WC_INLINE int myX25519SharedSecret(WOLFSSL* ssl, curve25519_key* otherKey, + unsigned char* pubKeyDer, unsigned int* pubKeySz, + unsigned char* out, unsigned int* outlen, + int side, void* ctx) +{ + int ret; + curve25519_key* privKey = NULL; + curve25519_key* pubKey = NULL; + curve25519_key tmpKey; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK 25519 PMS: side %s\n", + side == WOLFSSL_CLIENT_END ? "client" : "server"); + + ret = wc_curve25519_init(&tmpKey); + if (ret != 0) { + return ret; + } + + /* for client: create and export public key */ + if (side == WOLFSSL_CLIENT_END) { + WC_RNG rng; + + privKey = &tmpKey; + pubKey = otherKey; + + ret = wc_InitRng(&rng); + if (ret == 0) { + ret = wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, privKey); + if (ret == 0) { + ret = wc_curve25519_export_public_ex(privKey, pubKeyDer, + pubKeySz, EC25519_LITTLE_ENDIAN); + } + wc_FreeRng(&rng); + } + } + + /* for server: import public key */ + else if (side == WOLFSSL_SERVER_END) { + privKey = otherKey; + pubKey = &tmpKey; + + ret = wc_curve25519_import_public_ex(pubKeyDer, *pubKeySz, pubKey, + EC25519_LITTLE_ENDIAN); + } + else { + ret = BAD_FUNC_ARG; + } + + /* generate shared secret and return it */ + if (ret == 0) { + ret = wc_curve25519_shared_secret_ex(privKey, pubKey, out, outlen, + EC25519_LITTLE_ENDIAN); + } + + wc_curve25519_free(&tmpKey); + + WOLFSSL_PKMSG("PK 25519 PMS: ret %d, pubKeySz %d, outLen %d\n", + ret, *pubKeySz, *outlen); + + return ret; +} +#endif /* HAVE_CURVE25519 */ + +#endif /* HAVE_ECC */ + +#ifndef NO_DH +static WC_INLINE int myDhCallback(WOLFSSL* ssl, struct DhKey* key, + const unsigned char* priv, unsigned int privSz, + const unsigned char* pubKeyDer, unsigned int pubKeySz, + unsigned char* out, unsigned int* outlen, + void* ctx) +{ + int ret; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + /* return 0 on success */ + ret = wc_DhAgree(key, out, outlen, priv, privSz, pubKeyDer, pubKeySz); + + WOLFSSL_PKMSG("PK ED Agree: ret %d, privSz %d, pubKeySz %d, outlen %d\n", + ret, privSz, pubKeySz, *outlen); + + return ret; +}; + +#endif /* !NO_DH */ + +#ifndef NO_RSA + +static WC_INLINE int myRsaSign(WOLFSSL* ssl, const byte* in, word32 inSz, + byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx) +{ + WC_RNG rng; + int ret; + word32 idx = 0; + RsaKey myKey; + byte* keyBuf = (byte*)key; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK RSA Sign: inSz %d, keySz %d\n", inSz, keySz); + +#ifdef TEST_PK_PRIVKEY + ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz); + if (ret != 0) + return ret; +#endif + + ret = wc_InitRng(&rng); + if (ret != 0) + return ret; + + ret = wc_InitRsaKey(&myKey, NULL); + if (ret == 0) { + ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz); + if (ret == 0) + ret = wc_RsaSSL_Sign(in, inSz, out, *outSz, &myKey, &rng); + if (ret > 0) { /* save and convert to 0 success */ + *outSz = ret; + ret = 0; + } + wc_FreeRsaKey(&myKey); + } + wc_FreeRng(&rng); + +#ifdef TEST_PK_PRIVKEY + free(keyBuf); +#endif + + WOLFSSL_PKMSG("PK RSA Sign: ret %d, outSz %d\n", ret, *outSz); + + return ret; +} + + +static WC_INLINE int myRsaVerify(WOLFSSL* ssl, byte* sig, word32 sigSz, + byte** out, const byte* key, word32 keySz, void* ctx) +{ + int ret; + word32 idx = 0; + RsaKey myKey; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK RSA Verify: sigSz %d, keySz %d\n", sigSz, keySz); + + ret = wc_InitRsaKey(&myKey, NULL); + if (ret == 0) { + ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz); + if (ret == 0) + ret = wc_RsaSSL_VerifyInline(sig, sigSz, out, &myKey); + wc_FreeRsaKey(&myKey); + } + + WOLFSSL_PKMSG("PK RSA Verify: ret %d\n", ret); + + return ret; +} + +static WC_INLINE int myRsaSignCheck(WOLFSSL* ssl, byte* sig, word32 sigSz, + byte** out, const byte* key, word32 keySz, void* ctx) +{ + int ret; + word32 idx = 0; + RsaKey myKey; + byte* keyBuf = (byte*)key; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK RSA SignCheck: sigSz %d, keySz %d\n", sigSz, keySz); + +#ifdef TEST_PK_PRIVKEY + ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz); + if (ret != 0) + return ret; +#endif + + ret = wc_InitRsaKey(&myKey, NULL); + if (ret == 0) { + ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz); + if (ret == 0) + ret = wc_RsaSSL_VerifyInline(sig, sigSz, out, &myKey); + wc_FreeRsaKey(&myKey); + } +#ifdef TEST_PK_PRIVKEY + free(keyBuf); +#endif + + WOLFSSL_PKMSG("PK RSA SignCheck: ret %d\n", ret); + + return ret; +} + +#ifdef WC_RSA_PSS +static WC_INLINE int myRsaPssSign(WOLFSSL* ssl, const byte* in, word32 inSz, + byte* out, word32* outSz, int hash, int mgf, const byte* key, + word32 keySz, void* ctx) +{ + enum wc_HashType hashType = WC_HASH_TYPE_NONE; + WC_RNG rng; + int ret; + word32 idx = 0; + RsaKey myKey; + byte* keyBuf = (byte*)key; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK RSA PSS Sign: inSz %d, hash %d, mgf %d, keySz %d\n", + inSz, hash, mgf, keySz); + +#ifdef TEST_PK_PRIVKEY + ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz); + if (ret != 0) + return ret; +#endif + + switch (hash) { +#ifndef NO_SHA256 + case SHA256h: + hashType = WC_HASH_TYPE_SHA256; + break; +#endif +#ifdef WOLFSSL_SHA384 + case SHA384h: + hashType = WC_HASH_TYPE_SHA384; + break; +#endif +#ifdef WOLFSSL_SHA512 + case SHA512h: + hashType = WC_HASH_TYPE_SHA512; + break; +#endif + } + + ret = wc_InitRng(&rng); + if (ret != 0) + return ret; + + ret = wc_InitRsaKey(&myKey, NULL); + if (ret == 0) { + ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz); + if (ret == 0) { + ret = wc_RsaPSS_Sign(in, inSz, out, *outSz, hashType, mgf, &myKey, + &rng); + } + if (ret > 0) { /* save and convert to 0 success */ + *outSz = ret; + ret = 0; + } + wc_FreeRsaKey(&myKey); + } + wc_FreeRng(&rng); + +#ifdef TEST_PK_PRIVKEY + free(keyBuf); +#endif + + WOLFSSL_PKMSG("PK RSA PSS Sign: ret %d, outSz %d\n", ret, *outSz); + + return ret; +} + + +static WC_INLINE int myRsaPssVerify(WOLFSSL* ssl, byte* sig, word32 sigSz, + byte** out, int hash, int mgf, const byte* key, word32 keySz, void* ctx) +{ + int ret; + word32 idx = 0; + RsaKey myKey; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + enum wc_HashType hashType = WC_HASH_TYPE_NONE; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK RSA PSS Verify: sigSz %d, hash %d, mgf %d, keySz %d\n", + sigSz, hash, mgf, keySz); + + switch (hash) { +#ifndef NO_SHA256 + case SHA256h: + hashType = WC_HASH_TYPE_SHA256; + break; +#endif +#ifdef WOLFSSL_SHA384 + case SHA384h: + hashType = WC_HASH_TYPE_SHA384; + break; +#endif +#ifdef WOLFSSL_SHA512 + case SHA512h: + hashType = WC_HASH_TYPE_SHA512; + break; +#endif + } + + ret = wc_InitRsaKey(&myKey, NULL); + if (ret == 0) { + ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz); + if (ret == 0) { + ret = wc_RsaPSS_VerifyInline(sig, sigSz, out, hashType, mgf, + &myKey); + } + wc_FreeRsaKey(&myKey); + } + + WOLFSSL_PKMSG("PK RSA PSS Verify: ret %d\n", ret); + + return ret; +} + +static WC_INLINE int myRsaPssSignCheck(WOLFSSL* ssl, byte* sig, word32 sigSz, + byte** out, int hash, int mgf, const byte* key, word32 keySz, void* ctx) +{ + int ret; + word32 idx = 0; + RsaKey myKey; + byte* keyBuf = (byte*)key; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + enum wc_HashType hashType = WC_HASH_TYPE_NONE; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK RSA PSS SignCheck: sigSz %d, hash %d, mgf %d, keySz %d\n", + sigSz, hash, mgf, keySz); + +#ifdef TEST_PK_PRIVKEY + ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz); + if (ret != 0) + return ret; +#endif + + switch (hash) { +#ifndef NO_SHA256 + case SHA256h: + hashType = WC_HASH_TYPE_SHA256; + break; +#endif +#ifdef WOLFSSL_SHA384 + case SHA384h: + hashType = WC_HASH_TYPE_SHA384; + break; +#endif +#ifdef WOLFSSL_SHA512 + case SHA512h: + hashType = WC_HASH_TYPE_SHA512; + break; +#endif + } + + ret = wc_InitRsaKey(&myKey, NULL); + if (ret == 0) { + ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz); + if (ret == 0) { + ret = wc_RsaPSS_VerifyInline(sig, sigSz, out, hashType, mgf, + &myKey); + } + wc_FreeRsaKey(&myKey); + } + +#ifdef TEST_PK_PRIVKEY + free(keyBuf); +#endif + + WOLFSSL_PKMSG("PK RSA PSS SignCheck: ret %d\n", ret); + + return ret; +} +#endif + + +static WC_INLINE int myRsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz, + byte* out, word32* outSz, const byte* key, + word32 keySz, void* ctx) +{ + int ret; + word32 idx = 0; + RsaKey myKey; + WC_RNG rng; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK RSA Enc: inSz %d, keySz %d\n", inSz, keySz); + + ret = wc_InitRng(&rng); + if (ret != 0) + return ret; + + ret = wc_InitRsaKey(&myKey, NULL); + if (ret == 0) { + ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz); + if (ret == 0) { + ret = wc_RsaPublicEncrypt(in, inSz, out, *outSz, &myKey, &rng); + if (ret > 0) { + *outSz = ret; + ret = 0; /* reset to success */ + } + } + wc_FreeRsaKey(&myKey); + } + wc_FreeRng(&rng); + + WOLFSSL_PKMSG("PK RSA Enc: ret %d, outSz %d\n", ret, *outSz); + + return ret; +} + +static WC_INLINE int myRsaDec(WOLFSSL* ssl, byte* in, word32 inSz, + byte** out, + const byte* key, word32 keySz, void* ctx) +{ + int ret; + word32 idx = 0; + RsaKey myKey; + byte* keyBuf = (byte*)key; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK RSA Dec: inSz %d, keySz %d\n", inSz, keySz); + +#ifdef TEST_PK_PRIVKEY + ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz); + if (ret != 0) + return ret; +#endif + + ret = wc_InitRsaKey(&myKey, NULL); + if (ret == 0) { + ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz); + if (ret == 0) { + #ifdef WC_RSA_BLINDING + ret = wc_RsaSetRNG(&myKey, wolfSSL_GetRNG(ssl)); + if (ret != 0) { + wc_FreeRsaKey(&myKey); + return ret; + } + #endif + ret = wc_RsaPrivateDecryptInline(in, inSz, out, &myKey); + } + wc_FreeRsaKey(&myKey); + } + +#ifdef TEST_PK_PRIVKEY + free(keyBuf); +#endif + + WOLFSSL_PKMSG("PK RSA Dec: ret %d\n", ret); + + return ret; +} + +#endif /* NO_RSA */ + +static WC_INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx) +{ + (void)ctx; + + #ifdef HAVE_ECC + wolfSSL_CTX_SetEccKeyGenCb(ctx, myEccKeyGen); + wolfSSL_CTX_SetEccSignCb(ctx, myEccSign); + wolfSSL_CTX_SetEccVerifyCb(ctx, myEccVerify); + wolfSSL_CTX_SetEccSharedSecretCb(ctx, myEccSharedSecret); + #endif /* HAVE_ECC */ + #ifndef NO_DH + wolfSSL_CTX_SetDhAgreeCb(ctx, myDhCallback); + #endif + #ifdef HAVE_ED25519 + wolfSSL_CTX_SetEd25519SignCb(ctx, myEd25519Sign); + wolfSSL_CTX_SetEd25519VerifyCb(ctx, myEd25519Verify); + #endif + #ifdef HAVE_CURVE25519 + wolfSSL_CTX_SetX25519KeyGenCb(ctx, myX25519KeyGen); + wolfSSL_CTX_SetX25519SharedSecretCb(ctx, myX25519SharedSecret); + #endif + #ifndef NO_RSA + wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign); + wolfSSL_CTX_SetRsaVerifyCb(ctx, myRsaVerify); + wolfSSL_CTX_SetRsaSignCheckCb(ctx, myRsaSignCheck); + #ifdef WC_RSA_PSS + wolfSSL_CTX_SetRsaPssSignCb(ctx, myRsaPssSign); + wolfSSL_CTX_SetRsaPssVerifyCb(ctx, myRsaPssVerify); + wolfSSL_CTX_SetRsaPssSignCheckCb(ctx, myRsaPssSignCheck); + #endif + wolfSSL_CTX_SetRsaEncCb(ctx, myRsaEnc); + wolfSSL_CTX_SetRsaDecCb(ctx, myRsaDec); + #endif /* NO_RSA */ +} + +static WC_INLINE void SetupPkCallbackContexts(WOLFSSL* ssl, void* myCtx) +{ + #ifdef HAVE_ECC + wolfSSL_SetEccKeyGenCtx(ssl, myCtx); + wolfSSL_SetEccSignCtx(ssl, myCtx); + wolfSSL_SetEccVerifyCtx(ssl, myCtx); + wolfSSL_SetEccSharedSecretCtx(ssl, myCtx); + #endif /* HAVE_ECC */ + #ifndef NO_DH + wolfSSL_SetDhAgreeCtx(ssl, myCtx); + #endif + #ifdef HAVE_ED25519 + wolfSSL_SetEd25519SignCtx(ssl, myCtx); + wolfSSL_SetEd25519VerifyCtx(ssl, myCtx); + #endif + #ifdef HAVE_CURVE25519 + wolfSSL_SetX25519KeyGenCtx(ssl, myCtx); + wolfSSL_SetX25519SharedSecretCtx(ssl, myCtx); + #endif + #ifndef NO_RSA + wolfSSL_SetRsaSignCtx(ssl, myCtx); + wolfSSL_SetRsaVerifyCtx(ssl, myCtx); + #ifdef WC_RSA_PSS + wolfSSL_SetRsaPssSignCtx(ssl, myCtx); + wolfSSL_SetRsaPssVerifyCtx(ssl, myCtx); + #endif + wolfSSL_SetRsaEncCtx(ssl, myCtx); + wolfSSL_SetRsaDecCtx(ssl, myCtx); + #endif /* NO_RSA */ +} + +#endif /* HAVE_PK_CALLBACKS */ + + + + +#if defined(__hpux__) || defined(__MINGW32__) || defined (WOLFSSL_TIRTOS) \ + || defined(_MSC_VER) + +/* HP/UX doesn't have strsep, needed by test/suites.c */ +static WC_INLINE char* strsep(char **stringp, const char *delim) +{ + char* start; + char* end; + + start = *stringp; + if (start == NULL) + return NULL; + + if ((end = strpbrk(start, delim))) { + *end++ = '\0'; + *stringp = end; + } else { + *stringp = NULL; + } + + return start; +} + +#endif /* __hpux__ and others */ + +/* Create unique filename, len is length of tempfn name, assuming + len does not include null terminating character, + num is number of characters in tempfn name to randomize */ +static WC_INLINE const char* mymktemp(char *tempfn, int len, int num) +{ + int x, size; + static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + WC_RNG rng; + byte out; + + if (tempfn == NULL || len < 1 || num < 1 || len <= num) { + printf("Bad input\n"); + return NULL; + } + + size = len - 1; + + if (wc_InitRng(&rng) != 0) { + printf("InitRng failed\n"); + return NULL; + } + + for (x = size; x > size - num; x--) { + if (wc_RNG_GenerateBlock(&rng,(byte*)&out, sizeof(out)) != 0) { + printf("RNG_GenerateBlock failed\n"); + return NULL; + } + tempfn[x] = alphanum[out % (sizeof(alphanum) - 1)]; + } + tempfn[len] = '\0'; + + wc_FreeRng(&rng); + (void)rng; /* for WC_NO_RNG case */ + + return tempfn; +} + + + +#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \ + defined(HAVE_POLY1305) + + #include + + typedef struct key_ctx { + byte name[WOLFSSL_TICKET_NAME_SZ]; /* name for this context */ + byte key[CHACHA20_POLY1305_AEAD_KEYSIZE]; /* cipher key */ + } key_ctx; + + static THREAD_LS_T key_ctx myKey_ctx; + static THREAD_LS_T WC_RNG myKey_rng; + + static WC_INLINE int TicketInit(void) + { + int ret = wc_InitRng(&myKey_rng); + if (ret != 0) return ret; + + ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.key, sizeof(myKey_ctx.key)); + if (ret != 0) return ret; + + ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.name,sizeof(myKey_ctx.name)); + if (ret != 0) return ret; + + return 0; + } + + static WC_INLINE void TicketCleanup(void) + { + wc_FreeRng(&myKey_rng); + } + + static WC_INLINE int myTicketEncCb(WOLFSSL* ssl, + byte key_name[WOLFSSL_TICKET_NAME_SZ], + byte iv[WOLFSSL_TICKET_IV_SZ], + byte mac[WOLFSSL_TICKET_MAC_SZ], + int enc, byte* ticket, int inLen, int* outLen, + void* userCtx) + { + (void)ssl; + (void)userCtx; + + int ret; + word16 sLen = XHTONS(inLen); + byte aad[WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2]; + int aadSz = WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2; + byte* tmp = aad; + + if (enc) { + XMEMCPY(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ); + + ret = wc_RNG_GenerateBlock(&myKey_rng, iv, WOLFSSL_TICKET_IV_SZ); + if (ret != 0) return WOLFSSL_TICKET_RET_REJECT; + + /* build aad from key name, iv, and length */ + XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ); + tmp += WOLFSSL_TICKET_NAME_SZ; + XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ); + tmp += WOLFSSL_TICKET_IV_SZ; + XMEMCPY(tmp, &sLen, 2); + + ret = wc_ChaCha20Poly1305_Encrypt(myKey_ctx.key, iv, + aad, aadSz, + ticket, inLen, + ticket, + mac); + if (ret != 0) return WOLFSSL_TICKET_RET_REJECT; + *outLen = inLen; /* no padding in this mode */ + } else { + /* decrypt */ + + /* see if we know this key */ + if (XMEMCMP(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ) != 0){ + printf("client presented unknown ticket key name "); + return WOLFSSL_TICKET_RET_FATAL; + } + + /* build aad from key name, iv, and length */ + XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ); + tmp += WOLFSSL_TICKET_NAME_SZ; + XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ); + tmp += WOLFSSL_TICKET_IV_SZ; + XMEMCPY(tmp, &sLen, 2); + + ret = wc_ChaCha20Poly1305_Decrypt(myKey_ctx.key, iv, + aad, aadSz, + ticket, inLen, + mac, + ticket); + if (ret != 0) return WOLFSSL_TICKET_RET_REJECT; + *outLen = inLen; /* no padding in this mode */ + } + + return WOLFSSL_TICKET_RET_OK; + } + +#endif /* HAVE_SESSION_TICKET && CHACHA20 && POLY1305 */ + +static WC_INLINE word16 GetRandomPort(void) +{ + word16 port = 0; + + /* Generate random port for testing */ + WC_RNG rng; + if (wc_InitRng(&rng) == 0) { + if (wc_RNG_GenerateBlock(&rng, (byte*)&port, sizeof(port)) == 0) { + port |= 0xC000; /* Make sure its in the 49152 - 65535 range */ + } + wc_FreeRng(&rng); + } + (void)rng; /* for WC_NO_RNG case */ + return port; +} + +#endif /* wolfSSL_TEST_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/version.h b/wolfssl_hlavickove_subory/wolfssl/version.h new file mode 100644 index 0000000..0bc3996 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/version.h @@ -0,0 +1,40 @@ +/* wolfssl_version.h.in + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLFSSL_VERSION_H +#define WOLFSSL_VERSION_H + + +#ifdef __cplusplus +extern "C" { +#endif + +#define LIBWOLFSSL_VERSION_STRING "4.3.0" +#define LIBWOLFSSL_VERSION_HEX 0x04003000 + +#ifdef __cplusplus +} +#endif + + +#endif /* WOLFSSL_VERSION_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/version.h.in b/wolfssl_hlavickove_subory/wolfssl/version.h.in new file mode 100644 index 0000000..099afb2 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/version.h.in @@ -0,0 +1,40 @@ +/* wolfssl_version.h.in + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLFSSL_VERSION_H +#define WOLFSSL_VERSION_H + + +#ifdef __cplusplus +extern "C" { +#endif + +#define LIBWOLFSSL_VERSION_STRING "@VERSION@" +#define LIBWOLFSSL_VERSION_HEX @HEX_VERSION@ + +#ifdef __cplusplus +} +#endif + + +#endif /* WOLFSSL_VERSION_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/aes.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/aes.h new file mode 100644 index 0000000..a9547cf --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/aes.h @@ -0,0 +1,408 @@ +/* aes.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/aes.h +*/ + + +#ifndef WOLF_CRYPT_AES_H +#define WOLF_CRYPT_AES_H + +#include + +#ifndef NO_AES + +#if defined(HAVE_FIPS) && \ + defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) + #include +#endif /* HAVE_FIPS_VERSION >= 2 */ + +/* included for fips @wc_fips */ +#if defined(HAVE_FIPS) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) +#include +#if defined(CYASSL_AES_COUNTER) && !defined(WOLFSSL_AES_COUNTER) + #define WOLFSSL_AES_COUNTER +#endif +#if !defined(WOLFSSL_AES_DIRECT) && defined(CYASSL_AES_DIRECT) + #define WOLFSSL_AES_DIRECT +#endif +#endif + +#ifndef WC_NO_RNG + #include +#endif +#ifdef STM32_CRYPTO + #include +#endif + +#ifdef WOLFSSL_AESNI + +#include +#include +#include + +#endif /* WOLFSSL_AESNI */ + + +#ifdef WOLFSSL_XILINX_CRYPT +#include "xsecure_aes.h" +#endif + +#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES) +/* included for struct msghdr */ +#include +#endif + +#if defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC) +#include +#endif + +#if defined(HAVE_AESGCM) && !defined(WC_NO_RNG) + #include +#endif + +#if defined(WOLFSSL_CRYPTOCELL) + #include +#endif + +#if defined(WOLFSSL_RENESAS_TSIP_TLS) && \ + defined(WOLFSSL_RENESAS_TSIP_TLS_AES_CRYPT) + #include +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +/* these are required for FIPS and non-FIPS */ +enum { + AES_128_KEY_SIZE = 16, /* for 128 bit */ + AES_192_KEY_SIZE = 24, /* for 192 bit */ + AES_256_KEY_SIZE = 32, /* for 256 bit */ + + AES_IV_SIZE = 16, /* always block size */ +}; + + +/* avoid redefinition of structs */ +#if !defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif + +enum { + AES_ENC_TYPE = WC_CIPHER_AES, /* cipher unique type */ + AES_ENCRYPTION = 0, + AES_DECRYPTION = 1, + + AES_BLOCK_SIZE = 16, + + KEYWRAP_BLOCK_SIZE = 8, + + GCM_NONCE_MAX_SZ = 16, /* wolfCrypt's maximum nonce size allowed. */ + GCM_NONCE_MID_SZ = 12, /* The usual default nonce size for AES-GCM. */ + GCM_NONCE_MIN_SZ = 8, /* wolfCrypt's minimum nonce size allowed. */ + CCM_NONCE_MIN_SZ = 7, + CCM_NONCE_MAX_SZ = 13, + CTR_SZ = 4, + AES_IV_FIXED_SZ = 4, + +#ifdef HAVE_PKCS11 + AES_MAX_ID_LEN = 32, +#endif +}; + + +struct Aes { + /* AESNI needs key first, rounds 2nd, not sure why yet */ + ALIGN16 word32 key[60]; + word32 rounds; + int keylen; + + ALIGN16 word32 reg[AES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */ + ALIGN16 word32 tmp[AES_BLOCK_SIZE / sizeof(word32)]; /* same */ + +#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) + word32 invokeCtr[2]; + word32 nonceSz; +#endif +#ifdef HAVE_AESGCM + ALIGN16 byte H[AES_BLOCK_SIZE]; +#ifdef OPENSSL_EXTRA + word32 aadH[4]; /* additional authenticated data GHASH */ + word32 aadLen; /* additional authenticated data len */ +#endif + +#ifdef GCM_TABLE + /* key-based fast multiplication table. */ + ALIGN16 byte M0[256][AES_BLOCK_SIZE]; +#endif /* GCM_TABLE */ +#ifdef HAVE_CAVIUM_OCTEON_SYNC + word32 y0; +#endif +#endif /* HAVE_AESGCM */ +#ifdef WOLFSSL_AESNI + byte use_aesni; +#endif /* WOLFSSL_AESNI */ +#ifdef WOLF_CRYPTO_CB + int devId; + void* devCtx; +#endif +#ifdef HAVE_PKCS11 + byte id[AES_MAX_ID_LEN]; + int idLen; +#endif +#ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV asyncDev; +#endif /* WOLFSSL_ASYNC_CRYPT */ +#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) + word32 left; /* unused bytes left from last call */ +#endif +#ifdef WOLFSSL_XILINX_CRYPT + XSecure_Aes xilAes; + XCsuDma dma; + word32 key_init[8]; + word32 kup; +#endif +#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES) + int alFd; /* server socket to bind to */ + int rdFd; /* socket to read from */ + struct msghdr msg; + int dir; /* flag for encrpyt or decrypt */ +#ifdef WOLFSSL_AFALG_XILINX_AES + word32 msgBuf[CMSG_SPACE(4) + CMSG_SPACE(sizeof(struct af_alg_iv) + + GCM_NONCE_MID_SZ)]; +#endif +#endif +#if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \ + (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \ + (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)) + word32 devKey[AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE/sizeof(word32)]; /* raw key */ +#ifdef HAVE_CAVIUM_OCTEON_SYNC + int keySet; +#endif +#endif +#if defined(WOLFSSL_DEVCRYPTO) && \ + (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC)) + WC_CRYPTODEV ctx; +#endif +#if defined(WOLFSSL_CRYPTOCELL) + aes_context_t ctx; +#endif +#if defined(WOLFSSL_RENESAS_TSIP_TLS) && \ + defined(WOLFSSL_RENESAS_TSIP_TLS_AES_CRYPT) + TSIP_AES_CTX ctx; +#endif + void* heap; /* memory hint to use */ +}; + +#ifndef WC_AES_TYPE_DEFINED + typedef struct Aes Aes; + #define WC_AES_TYPE_DEFINED +#endif + +#ifdef WOLFSSL_AES_XTS +typedef struct XtsAes { + Aes aes; + Aes tweak; +} XtsAes; +#endif + +#ifdef HAVE_AESGCM +typedef struct Gmac { + Aes aes; +} Gmac; +#endif /* HAVE_AESGCM */ +#endif /* HAVE_FIPS */ + + +/* Authenticate cipher function prototypes */ +typedef int (*wc_AesAuthEncryptFunc)(Aes* aes, byte* out, + const byte* in, word32 sz, + const byte* iv, word32 ivSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); +typedef int (*wc_AesAuthDecryptFunc)(Aes* aes, byte* out, + const byte* in, word32 sz, + const byte* iv, word32 ivSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); + +/* AES-CBC */ +WOLFSSL_API int wc_AesSetKey(Aes* aes, const byte* key, word32 len, + const byte* iv, int dir); +WOLFSSL_API int wc_AesSetIV(Aes* aes, const byte* iv); + +#ifdef HAVE_AES_CBC +WOLFSSL_API int wc_AesCbcEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +WOLFSSL_API int wc_AesCbcDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#endif + +#ifdef WOLFSSL_AES_CFB +WOLFSSL_API int wc_AesCfbEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#ifdef HAVE_AES_DECRYPT +WOLFSSL_API int wc_AesCfbDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#endif /* HAVE_AES_DECRYPT */ +#endif /* WOLFSSL_AES_CFB */ + +#ifdef HAVE_AES_ECB +WOLFSSL_API int wc_AesEcbEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +WOLFSSL_API int wc_AesEcbDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#endif + +/* AES-CTR */ +#ifdef WOLFSSL_AES_COUNTER + WOLFSSL_API int wc_AesCtrEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#endif +/* AES-DIRECT */ +#if defined(WOLFSSL_AES_DIRECT) + WOLFSSL_API void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in); + WOLFSSL_API void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in); + WOLFSSL_API int wc_AesSetKeyDirect(Aes* aes, const byte* key, word32 len, + const byte* iv, int dir); +#endif + +#ifdef HAVE_AESGCM +#ifdef WOLFSSL_XILINX_CRYPT + WOLFSSL_API int wc_AesGcmSetKey_ex(Aes* aes, const byte* key, word32 len, + word32 kup); +#elif defined(WOLFSSL_AFALG_XILINX_AES) + WOLFSSL_LOCAL int wc_AesGcmSetKey_ex(Aes* aes, const byte* key, word32 len, + word32 kup); +#endif + WOLFSSL_API int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len); + WOLFSSL_API int wc_AesGcmEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz, + const byte* iv, word32 ivSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); + WOLFSSL_API int wc_AesGcmDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz, + const byte* iv, word32 ivSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); + +#ifndef WC_NO_RNG + WOLFSSL_API int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz); + WOLFSSL_API int wc_AesGcmSetIV(Aes* aes, word32 ivSz, + const byte* ivFixed, word32 ivFixedSz, + WC_RNG* rng); + WOLFSSL_API int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, + const byte* in, word32 sz, + byte* ivOut, word32 ivOutSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); +#endif /* WC_NO_RNG */ + + WOLFSSL_API int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len); + WOLFSSL_API int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz, + const byte* authIn, word32 authInSz, + byte* authTag, word32 authTagSz); +#ifndef WC_NO_RNG + WOLFSSL_API int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz, + const byte* authIn, word32 authInSz, + byte* authTag, word32 authTagSz, WC_RNG* rng); + WOLFSSL_API int wc_GmacVerify(const byte* key, word32 keySz, + const byte* iv, word32 ivSz, + const byte* authIn, word32 authInSz, + const byte* authTag, word32 authTagSz); +#endif /* WC_NO_RNG */ + WOLFSSL_LOCAL void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, + word32 cSz, byte* s, word32 sSz); +#endif /* HAVE_AESGCM */ +#ifdef HAVE_AESCCM + WOLFSSL_API int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz); + WOLFSSL_API int wc_AesCcmEncrypt(Aes* aes, byte* out, + const byte* in, word32 inSz, + const byte* nonce, word32 nonceSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); + WOLFSSL_API int wc_AesCcmDecrypt(Aes* aes, byte* out, + const byte* in, word32 inSz, + const byte* nonce, word32 nonceSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); + WOLFSSL_API int wc_AesCcmSetNonce(Aes* aes, + const byte* nonce, word32 nonceSz); + WOLFSSL_API int wc_AesCcmEncrypt_ex(Aes* aes, byte* out, + const byte* in, word32 sz, + byte* ivOut, word32 ivOutSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); +#endif /* HAVE_AESCCM */ +#ifdef HAVE_AES_KEYWRAP + WOLFSSL_API int wc_AesKeyWrap(const byte* key, word32 keySz, + const byte* in, word32 inSz, + byte* out, word32 outSz, + const byte* iv); + WOLFSSL_API int wc_AesKeyUnWrap(const byte* key, word32 keySz, + const byte* in, word32 inSz, + byte* out, word32 outSz, + const byte* iv); +#endif /* HAVE_AES_KEYWRAP */ + +#ifdef WOLFSSL_AES_XTS + +WOLFSSL_API int wc_AesXtsSetKey(XtsAes* aes, const byte* key, + word32 len, int dir, void* heap, int devId); + +WOLFSSL_API int wc_AesXtsEncryptSector(XtsAes* aes, byte* out, + const byte* in, word32 sz, word64 sector); + +WOLFSSL_API int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, + const byte* in, word32 sz, word64 sector); + +WOLFSSL_API int wc_AesXtsEncrypt(XtsAes* aes, byte* out, + const byte* in, word32 sz, const byte* i, word32 iSz); + +WOLFSSL_API int wc_AesXtsDecrypt(XtsAes* aes, byte* out, + const byte* in, word32 sz, const byte* i, word32 iSz); + +WOLFSSL_API int wc_AesXtsFree(XtsAes* aes); +#endif + +WOLFSSL_API int wc_AesGetKeySize(Aes* aes, word32* keySize); + +WOLFSSL_API int wc_AesInit(Aes* aes, void* heap, int devId); +#ifdef HAVE_PKCS11 +WOLFSSL_API int wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap, + int devId); +#endif +WOLFSSL_API void wc_AesFree(Aes* aes); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* NO_AES */ +#endif /* WOLF_CRYPT_AES_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/arc4.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/arc4.h new file mode 100644 index 0000000..3a76099 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/arc4.h @@ -0,0 +1,68 @@ +/* arc4.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/arc4.h +*/ + +#ifndef WOLF_CRYPT_ARC4_H +#define WOLF_CRYPT_ARC4_H + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif + +enum { + ARC4_ENC_TYPE = 4, /* cipher unique type */ + ARC4_STATE_SIZE = 256, + RC4_KEY_SIZE = 16, /* always 128bit */ +}; + +/* ARC4 encryption and decryption */ +typedef struct Arc4 { + byte x; + byte y; + byte state[ARC4_STATE_SIZE]; +#ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV asyncDev; +#endif + void* heap; +} Arc4; + +WOLFSSL_API int wc_Arc4Process(Arc4*, byte*, const byte*, word32); +WOLFSSL_API int wc_Arc4SetKey(Arc4*, const byte*, word32); + +WOLFSSL_API int wc_Arc4Init(Arc4*, void*, int); +WOLFSSL_API void wc_Arc4Free(Arc4*); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* WOLF_CRYPT_ARC4_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/asn.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/asn.h new file mode 100644 index 0000000..ce13f81 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/asn.h @@ -0,0 +1,1416 @@ +/* asn.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/asn.h +*/ + +#ifndef WOLF_CRYPT_ASN_H +#define WOLF_CRYPT_ASN_H + +#include + +#ifndef NO_ASN + + +#if !defined(NO_ASN_TIME) && defined(NO_TIME_H) + #define NO_ASN_TIME /* backwards compatibility with NO_TIME_H */ +#endif + +#include + +/* fips declare of RsaPrivateKeyDecode @wc_fips */ +#if defined(HAVE_FIPS) && !defined(NO_RSA) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) + #include +#endif + +#ifndef NO_DH + #include +#endif +#ifndef NO_DSA + #include +#endif +#ifndef NO_SHA + #include +#endif +#ifndef NO_MD5 + #include +#endif +#include +#include /* public interface */ + +#if defined(NO_SHA) && defined(NO_SHA256) + #define WC_SHA256_DIGEST_SIZE 32 +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef EXTERNAL_SERIAL_SIZE + #define EXTERNAL_SERIAL_SIZE 32 +#endif + +enum { + ISSUER = 0, + SUBJECT = 1, + + BEFORE = 0, + AFTER = 1 +}; + +/* ASN Tags */ +enum ASN_Tags { + ASN_EOC = 0x00, + ASN_BOOLEAN = 0x01, + ASN_INTEGER = 0x02, + ASN_BIT_STRING = 0x03, + ASN_OCTET_STRING = 0x04, + ASN_TAG_NULL = 0x05, + ASN_OBJECT_ID = 0x06, + ASN_ENUMERATED = 0x0a, + ASN_UTF8STRING = 0x0c, + ASN_SEQUENCE = 0x10, + ASN_SET = 0x11, + ASN_PRINTABLE_STRING = 0x13, + ASN_UTC_TIME = 0x17, + ASN_OTHER_TYPE = 0x00, + ASN_RFC822_TYPE = 0x01, + ASN_DNS_TYPE = 0x02, + ASN_DIR_TYPE = 0x04, + ASN_URI_TYPE = 0x06, /* the value 6 is from GeneralName OID */ + ASN_GENERALIZED_TIME = 0x18, + CRL_EXTENSIONS = 0xa0, + ASN_EXTENSIONS = 0xa3, + ASN_LONG_LENGTH = 0x80, + ASN_INDEF_LENGTH = 0x80, + + /* ASN_Flags - Bitmask */ + ASN_CONSTRUCTED = 0x20, + ASN_APPLICATION = 0x40, + ASN_CONTEXT_SPECIFIC = 0x80, +}; + +#define ASN_UTC_TIME_SIZE 14 +#define ASN_GENERALIZED_TIME_SIZE 16 +#define ASN_GENERALIZED_TIME_MAX 68 + +enum DN_Tags { + ASN_DN_NULL = 0x00, + ASN_COMMON_NAME = 0x03, /* CN */ + ASN_SUR_NAME = 0x04, /* SN */ + ASN_SERIAL_NUMBER = 0x05, /* serialNumber */ + ASN_COUNTRY_NAME = 0x06, /* C */ + ASN_LOCALITY_NAME = 0x07, /* L */ + ASN_STATE_NAME = 0x08, /* ST */ + ASN_ORG_NAME = 0x0a, /* O */ + ASN_ORGUNIT_NAME = 0x0b, /* OU */ + ASN_BUS_CAT = 0x0f, /* businessCategory */ + ASN_EMAIL_NAME = 0x98, /* not oid number there is 97 in 2.5.4.0-97 */ + + /* pilot attribute types + * OID values of 0.9.2342.19200300.100.1.* */ + ASN_USER_ID = 0x01, /* UID */ + ASN_DOMAIN_COMPONENT = 0x19 /* DC */ +}; + +/* DN Tag Strings */ +#define WOLFSSL_COMMON_NAME "/CN=" +#define WOLFSSL_SUR_NAME "/SN=" +#define WOLFSSL_SERIAL_NUMBER "/serialNumber=" +#define WOLFSSL_COUNTRY_NAME "/C=" +#define WOLFSSL_LOCALITY_NAME "/L=" +#define WOLFSSL_STATE_NAME "/ST=" +#define WOLFSSL_ORG_NAME "/O=" +#define WOLFSSL_ORGUNIT_NAME "/OU=" +#define WOLFSSL_DOMAIN_COMPONENT "/DC=" +#define WOLFSSL_BUS_CAT "/businessCategory=" +#define WOLFSSL_JOI_C "/jurisdictionC=" +#define WOLFSSL_JOI_ST "/jurisdictionST=" +#define WOLFSSL_EMAIL_ADDR "/emailAddress=" + +#define WOLFSSL_USER_ID "/UID=" +#define WOLFSSL_DOMAIN_COMPONENT "/DC=" + +#if defined(WOLFSSL_APACHE_HTTPD) + /* otherName strings */ + #define WOLFSSL_SN_MS_UPN "msUPN" + #define WOLFSSL_LN_MS_UPN "Microsoft Universal Principal Name" + #define WOLFSSL_MS_UPN_SUM 265 + #define WOLFSSL_SN_DNS_SRV "id-on-dnsSRV" + #define WOLFSSL_LN_DNS_SRV "SRVName otherName form" + /* TLS features extension strings */ + #define WOLFSSL_SN_TLS_FEATURE "tlsfeature" + #define WOLFSSL_LN_TLS_FEATURE "TLS Feature" + #define WOLFSSL_TLS_FEATURE_SUM 92 +#endif + +/* NIDs */ +enum +{ + NID_undef = 0, + NID_netscape_cert_type = NID_undef, + NID_des = 66, + NID_des3 = 67, + NID_sha256 = 672, + NID_sha384 = 673, + NID_sha512 = 674, + NID_hw_name_oid = 73, + NID_id_pkix_OCSP_basic = 74, + NID_any_policy = 75, + NID_anyExtendedKeyUsage = 76, + NID_givenName = 99, + NID_initials = 101, + NID_title = 106, + NID_description = 107, + NID_basic_constraints = 133, + NID_key_usage = 129, /* 2.5.29.15 */ + NID_ext_key_usage = 151, /* 2.5.29.37 */ + NID_subject_key_identifier = 128, + NID_authority_key_identifier = 149, + NID_private_key_usage_period = 130, /* 2.5.29.16 */ + NID_subject_alt_name = 131, + NID_issuer_alt_name = 132, + NID_info_access = 69, + NID_sinfo_access = 79, /* id-pe 11 */ + NID_name_constraints = 144, /* 2.5.29.30 */ + NID_crl_distribution_points = 145, /* 2.5.29.31 */ + NID_certificate_policies = 146, + NID_policy_mappings = 147, + NID_policy_constraints = 150, + NID_inhibit_any_policy = 168, /* 2.5.29.54 */ + NID_tlsfeature = 1020, /* id-pe 24 */ + NID_commonName = 0x03, /* matchs ASN_COMMON_NAME in asn.h */ + + + NID_surname = 0x04, /* SN */ + NID_serialNumber = 0x05, /* serialNumber */ + NID_countryName = 0x06, /* C */ + NID_localityName = 0x07, /* L */ + NID_stateOrProvinceName = 0x08, /* ST */ + NID_organizationName = 0x0a, /* O */ + NID_organizationalUnitName = 0x0b, /* OU */ + NID_domainComponent = 0x19, /* matchs ASN_DOMAIN_COMPONENT in asn.h */ + NID_emailAddress = 0x30, /* emailAddress */ + NID_id_on_dnsSRV = 82, /* 1.3.6.1.5.5.7.8.7 */ + NID_ms_upn = 265 /* 1.3.6.1.4.1.311.20.2.3 */ +}; + +enum ECC_TYPES +{ + ECC_PREFIX_0 = 160, + ECC_PREFIX_1 = 161 +}; + +#ifdef WOLFSSL_CERT_PIV + enum PIV_Tags { + ASN_PIV_CERT = 0x0A, + ASN_PIV_NONCE = 0x0B, + ASN_PIV_SIGNED_NONCE = 0x0C, + + ASN_PIV_TAG_CERT = 0x70, + ASN_PIV_TAG_CERT_INFO = 0x71, + ASN_PIV_TAG_MSCUID = 0x72, + ASN_PIV_TAG_ERR_DET = 0xFE, + + /* certificate info masks */ + ASN_PIV_CERT_INFO_COMPRESSED = 0x03, + ASN_PIV_CERT_INFO_ISX509 = 0x04, + }; +#endif /* WOLFSSL_CERT_PIV */ + + +#define ASN_JOI_PREFIX_SZ 10 +#define ASN_JOI_PREFIX "\x2b\x06\x01\x04\x01\x82\x37\x3c\x02\x01" +#define ASN_JOI_C 0x3 +#define ASN_JOI_ST 0x2 + +#ifndef WC_ASN_NAME_MAX + #ifdef OPENSSL_EXTRA + #define WC_ASN_NAME_MAX 300 + #else + #define WC_ASN_NAME_MAX 256 + #endif +#endif +#define ASN_NAME_MAX WC_ASN_NAME_MAX + +enum Misc_ASN { + MAX_SALT_SIZE = 64, /* MAX PKCS Salt length */ + MAX_IV_SIZE = 64, /* MAX PKCS Iv length */ + ASN_BOOL_SIZE = 2, /* including type */ + ASN_ECC_HEADER_SZ = 2, /* String type + 1 byte len */ + ASN_ECC_CONTEXT_SZ = 2, /* Content specific type + 1 byte len */ +#ifdef NO_SHA + KEYID_SIZE = WC_SHA256_DIGEST_SIZE, +#else + KEYID_SIZE = WC_SHA_DIGEST_SIZE, +#endif + RSA_INTS = 8, /* RSA ints in private key */ + DSA_INTS = 5, /* DSA ints in private key */ + MIN_DATE_SIZE = 13, + MAX_DATE_SIZE = 32, + ASN_GEN_TIME_SZ = 15, /* 7 numbers * 2 + Zulu tag */ +#ifndef NO_RSA + MAX_ENCODED_SIG_SZ = 512, +#elif defined(HAVE_ECC) + MAX_ENCODED_SIG_SZ = 140, +#else + MAX_ENCODED_SIG_SZ = 64, +#endif + MAX_SIG_SZ = 256, + MAX_ALGO_SZ = 20, + MAX_SHORT_SZ = 6, /* asn int + byte len + 4 byte length */ + MAX_SEQ_SZ = 5, /* enum(seq | con) + length(4) */ + MAX_SET_SZ = 5, /* enum(set | con) + length(4) */ + MAX_OCTET_STR_SZ = 5, /* enum(set | con) + length(4) */ + MAX_EXP_SZ = 5, /* enum(contextspec|con|exp) + length(4) */ + MAX_PRSTR_SZ = 5, /* enum(prstr) + length(4) */ + MAX_VERSION_SZ = 5, /* enum + id + version(byte) + (header(2))*/ + MAX_ENCODED_DIG_ASN_SZ= 9, /* enum(bit or octet) + length(4) */ + MAX_ENCODED_DIG_SZ = 64 + MAX_ENCODED_DIG_ASN_SZ, /* asn header + sha512 */ + MAX_RSA_INT_SZ = 517, /* RSA raw sz 4096 for bits + tag + len(4) */ + MAX_NTRU_KEY_SZ = 610, /* NTRU 112 bit public key */ + MAX_NTRU_ENC_SZ = 628, /* NTRU 112 bit DER public encoding */ + MAX_LENGTH_SZ = 4, /* Max length size for DER encoding */ + MAX_RSA_E_SZ = 16, /* Max RSA public e size */ + MAX_CA_SZ = 32, /* Max encoded CA basic constraint length */ + MAX_SN_SZ = 35, /* Max encoded serial number (INT) length */ + MAX_DER_DIGEST_SZ = MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ, + /* Maximum DER digest size */ + MAX_DER_DIGEST_ASN_SZ = MAX_ENCODED_DIG_ASN_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ, + /* Maximum DER digest ASN header size */ +#ifdef WOLFSSL_CERT_GEN + #ifdef WOLFSSL_CERT_REQ + /* Max encoded cert req attributes length */ + MAX_ATTRIB_SZ = MAX_SEQ_SZ * 3 + (11 + MAX_SEQ_SZ) * 2 + + MAX_PRSTR_SZ + CTC_NAME_SIZE, /* 11 is the OID size */ + #endif + #if defined(WOLFSSL_ALT_NAMES) || defined(WOLFSSL_CERT_EXT) + MAX_EXTENSIONS_SZ = 1 + MAX_LENGTH_SZ + CTC_MAX_ALT_SIZE, + #else + MAX_EXTENSIONS_SZ = 1 + MAX_LENGTH_SZ + MAX_CA_SZ, + #endif + /* Max total extensions, id + len + others */ +#endif +#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || defined(HAVE_PKCS7) + MAX_OID_SZ = 32, /* Max DER length of OID*/ + MAX_OID_STRING_SZ = 64, /* Max string length representation of OID*/ +#endif +#ifdef WOLFSSL_CERT_EXT + MAX_KID_SZ = 45, /* Max encoded KID length (SHA-256 case) */ + MAX_KEYUSAGE_SZ = 18, /* Max encoded Key Usage length */ + MAX_EXTKEYUSAGE_SZ = 12 + (6 * (8 + 2)) + + CTC_MAX_EKU_OID_SZ, /* Max encoded ExtKeyUsage + (SEQ/LEN + OBJID + OCTSTR/LEN + SEQ + + (6 * (SEQ + OID))) */ + MAX_CERTPOL_NB = CTC_MAX_CERTPOL_NB,/* Max number of Cert Policy */ + MAX_CERTPOL_SZ = CTC_MAX_CERTPOL_SZ, +#endif + MAX_NAME_ENTRIES = 5, /* extra entries added to x509 name struct */ + OCSP_NONCE_EXT_SZ = 35, /* OCSP Nonce Extension size */ + MAX_OCSP_EXT_SZ = 58, /* Max OCSP Extension length */ + MAX_OCSP_NONCE_SZ = 16, /* OCSP Nonce size */ + EIGHTK_BUF = 8192, /* Tmp buffer size */ + MAX_PUBLIC_KEY_SZ = MAX_NTRU_ENC_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2, + /* use bigger NTRU size */ +#ifdef WOLFSSL_ENCRYPTED_KEYS + HEADER_ENCRYPTED_KEY_SIZE = 88,/* Extra header size for encrypted key */ +#else + HEADER_ENCRYPTED_KEY_SIZE = 0, +#endif + TRAILING_ZERO = 1, /* Used for size of zero pad */ + ASN_TAG_SZ = 1, /* single byte ASN.1 tag */ + MIN_VERSION_SZ = 3, /* Min bytes needed for GetMyVersion */ +#if defined(OPENSSL_ALL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \ + defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ + defined(OPENSSL_EXTRA) || defined(HAVE_PKCS7) + MAX_TIME_STRING_SZ = 25, /* Max length of formatted time string */ +#endif + + PKCS5_SALT_SZ = 8, + + PEM_LINE_LEN = 80, /* PEM line max + fudge */ +}; + + +enum Oid_Types { + oidHashType = 0, + oidSigType = 1, + oidKeyType = 2, + oidCurveType = 3, + oidBlkType = 4, + oidOcspType = 5, + oidCertExtType = 6, + oidCertAuthInfoType = 7, + oidCertPolicyType = 8, + oidCertAltNameType = 9, + oidCertKeyUseType = 10, + oidKdfType = 11, + oidKeyWrapType = 12, + oidCmsKeyAgreeType = 13, + oidPBEType = 14, + oidHmacType = 15, + oidCompressType = 16, + oidCertNameType = 17, + oidTlsExtType = 18, + oidCrlExtType = 19, + oidIgnoreType +}; + + +enum Hash_Sum { + MD2h = 646, + MD5h = 649, + SHAh = 88, + SHA224h = 417, + SHA256h = 414, + SHA384h = 415, + SHA512h = 416, + SHA3_224h = 420, + SHA3_256h = 421, + SHA3_384h = 422, + SHA3_512h = 423 +}; + + +#if !defined(NO_DES3) || !defined(NO_AES) +enum Block_Sum { +#ifdef WOLFSSL_AES_128 + AES128CBCb = 414, + AES128GCMb = 418, + AES128CCMb = 419, +#endif +#ifdef WOLFSSL_AES_192 + AES192CBCb = 434, + AES192GCMb = 438, + AES192CCMb = 439, +#endif +#ifdef WOLFSSL_AES_256 + AES256CBCb = 454, + AES256GCMb = 458, + AES256CCMb = 459, +#endif +#ifndef NO_DES3 + DESb = 69, + DES3b = 652 +#endif +}; +#endif /* !NO_DES3 || !NO_AES */ + + +enum Key_Sum { + DSAk = 515, + RSAk = 645, + NTRUk = 274, + ECDSAk = 518, + ED25519k = 256 +}; + + +#if !defined(NO_AES) || defined(HAVE_PKCS7) +enum KeyWrap_Sum { +#ifdef WOLFSSL_AES_128 + AES128_WRAP = 417, +#endif +#ifdef WOLFSSL_AES_192 + AES192_WRAP = 437, +#endif +#ifdef WOLFSSL_AES_256 + AES256_WRAP = 457, +#endif +#ifdef HAVE_PKCS7 + PWRI_KEK_WRAP = 680 /*id-alg-PWRI-KEK, 1.2.840.113549.1.9.16.3.9 */ +#endif +}; +#endif /* !NO_AES || PKCS7 */ + +enum Key_Agree { + dhSinglePass_stdDH_sha1kdf_scheme = 464, + dhSinglePass_stdDH_sha224kdf_scheme = 188, + dhSinglePass_stdDH_sha256kdf_scheme = 189, + dhSinglePass_stdDH_sha384kdf_scheme = 190, + dhSinglePass_stdDH_sha512kdf_scheme = 191, +}; + + + +enum KDF_Sum { + PBKDF2_OID = 660 +}; + + +enum HMAC_Sum { + HMAC_SHA224_OID = 652, + HMAC_SHA256_OID = 653, + HMAC_SHA384_OID = 654, + HMAC_SHA512_OID = 655, + HMAC_SHA3_224_OID = 426, + HMAC_SHA3_256_OID = 427, + HMAC_SHA3_384_OID = 428, + HMAC_SHA3_512_OID = 429 +}; + + +enum Extensions_Sum { + BASIC_CA_OID = 133, + ALT_NAMES_OID = 131, + CRL_DIST_OID = 145, + AUTH_INFO_OID = 69, /* id-pe 1 */ + AUTH_KEY_OID = 149, + SUBJ_KEY_OID = 128, + CERT_POLICY_OID = 146, + KEY_USAGE_OID = 129, /* 2.5.29.15 */ + INHIBIT_ANY_OID = 168, /* 2.5.29.54 */ + EXT_KEY_USAGE_OID = 151, /* 2.5.29.37 */ + NAME_CONS_OID = 144, /* 2.5.29.30 */ + PRIV_KEY_USAGE_PERIOD_OID = 130, /* 2.5.29.16 */ + SUBJECT_INFO_ACCESS = 79, /* id-pe 11 */ + POLICY_MAP_OID = 147, + POLICY_CONST_OID = 150, + ISSUE_ALT_NAMES_OID = 132, + TLS_FEATURE_OID = 92 /* id-pe 24 */ +}; + +enum CertificatePolicy_Sum { + CP_ANY_OID = 146 /* id-ce 32 0 */ +}; + +enum SepHardwareName_Sum { + HW_NAME_OID = 79 /* 1.3.6.1.5.5.7.8.4 from RFC 4108*/ +}; + +enum AuthInfo_Sum { + AIA_OCSP_OID = 116, /* 1.3.6.1.5.5.7.48.1 */ + AIA_CA_ISSUER_OID = 117 /* 1.3.6.1.5.5.7.48.2 */ +}; + +enum ExtKeyUsage_Sum { /* From RFC 5280 */ + EKU_ANY_OID = 151, /* 2.5.29.37.0, anyExtendedKeyUsage */ + EKU_SERVER_AUTH_OID = 71, /* 1.3.6.1.5.5.7.3.1, id-kp-serverAuth */ + EKU_CLIENT_AUTH_OID = 72, /* 1.3.6.1.5.5.7.3.2, id-kp-clientAuth */ + EKU_CODESIGNING_OID = 73, /* 1.3.6.1.5.5.7.3.3, id-kp-codeSigning */ + EKU_EMAILPROTECT_OID = 74, /* 1.3.6.1.5.5.7.3.4, id-kp-emailProtection */ + EKU_TIMESTAMP_OID = 78, /* 1.3.6.1.5.5.7.3.8, id-kp-timeStamping */ + EKU_OCSP_SIGN_OID = 79 /* 1.3.6.1.5.5.7.3.9, id-kp-OCSPSigning */ +}; + +#ifdef HAVE_LIBZ +enum CompressAlg_Sum { + ZLIBc = 679 /* 1.2.840.113549.1.9.16.3.8, id-alg-zlibCompress */ +}; +#endif + +enum VerifyType { + NO_VERIFY = 0, + VERIFY = 1, + VERIFY_CRL = 2, + VERIFY_OCSP = 3, + VERIFY_NAME = 4, + VERIFY_SKIP_DATE = 5 +}; + +#ifdef WOLFSSL_CERT_EXT +enum KeyIdType { + SKID_TYPE = 0, + AKID_TYPE = 1 +}; +#endif + +/* Key usage extension bits (based on RFC 5280) */ +#define KEYUSE_DIGITAL_SIG 0x0080 +#define KEYUSE_CONTENT_COMMIT 0x0040 +#define KEYUSE_KEY_ENCIPHER 0x0020 +#define KEYUSE_DATA_ENCIPHER 0x0010 +#define KEYUSE_KEY_AGREE 0x0008 +#define KEYUSE_KEY_CERT_SIGN 0x0004 +#define KEYUSE_CRL_SIGN 0x0002 +#define KEYUSE_ENCIPHER_ONLY 0x0001 +#define KEYUSE_DECIPHER_ONLY 0x8000 + +/* Extended Key Usage bits (internal mapping only) */ +#define EXTKEYUSE_USER 0x80 +#define EXTKEYUSE_OCSP_SIGN 0x40 +#define EXTKEYUSE_TIMESTAMP 0x20 +#define EXTKEYUSE_EMAILPROT 0x10 +#define EXTKEYUSE_CODESIGN 0x08 +#define EXTKEYUSE_CLIENT_AUTH 0x04 +#define EXTKEYUSE_SERVER_AUTH 0x02 +#define EXTKEYUSE_ANY 0x01 + +typedef struct DNS_entry DNS_entry; + +struct DNS_entry { + DNS_entry* next; /* next on DNS list */ + int type; /* i.e. ASN_DNS_TYPE */ + int len; /* actual DNS len */ + char* name; /* actual DNS name */ +}; + + +typedef struct Base_entry Base_entry; + +struct Base_entry { + Base_entry* next; /* next on name base list */ + char* name; /* actual name base */ + int nameSz; /* name length */ + byte type; /* Name base type (DNS or RFC822) */ +}; + +#define DOMAIN_COMPONENT_MAX 10 +#define DN_NAMES_MAX 9 + +struct DecodedName { + char* fullName; + int fullNameLen; + int entryCount; + int cnIdx; + int cnLen; + int cnNid; + int snIdx; + int snLen; + int snNid; + int cIdx; + int cLen; + int cNid; + int lIdx; + int lLen; + int lNid; + int stIdx; + int stLen; + int stNid; + int oIdx; + int oLen; + int oNid; + int ouIdx; + int ouLen; +#ifdef WOLFSSL_CERT_EXT + int bcIdx; + int bcLen; + int jcIdx; + int jcLen; + int jsIdx; + int jsLen; +#endif + int ouNid; + int emailIdx; + int emailLen; + int emailNid; + int uidIdx; + int uidLen; + int uidNid; + int serialIdx; + int serialLen; + int serialNid; + int dcIdx[DOMAIN_COMPONENT_MAX]; + int dcLen[DOMAIN_COMPONENT_MAX]; + int dcNum; + int dcMode; +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + /* hold the location / order with which each of the DN tags was found + * + * example of ASN_DOMAIN_COMPONENT at index 0 if first found and so on. + */ + int loc[DOMAIN_COMPONENT_MAX + DN_NAMES_MAX]; + int locSz; +#endif +}; + +enum SignatureState { + SIG_STATE_BEGIN, + SIG_STATE_HASH, + SIG_STATE_KEY, + SIG_STATE_DO, + SIG_STATE_CHECK, +}; + + +#ifdef HAVE_PK_CALLBACKS +#ifdef HAVE_ECC + typedef int (*wc_CallbackEccVerify)( + const unsigned char* sig, unsigned int sigSz, + const unsigned char* hash, unsigned int hashSz, + const unsigned char* keyDer, unsigned int keySz, + int* result, void* ctx); +#endif +#ifndef NO_RSA + typedef int (*wc_CallbackRsaVerify)( + unsigned char* sig, unsigned int sigSz, + unsigned char** out, + const unsigned char* keyDer, unsigned int keySz, + void* ctx); +#endif +#endif /* HAVE_PK_CALLBACKS */ + +struct SignatureCtx { + void* heap; + byte* digest; +#ifndef NO_RSA + byte* out; + byte* plain; +#endif +#if defined(HAVE_ECC) || defined(HAVE_ED25519) + int verify; +#endif + union { + #ifndef NO_RSA + struct RsaKey* rsa; + #endif + #ifdef HAVE_ECC + struct ecc_key* ecc; + #endif + #ifdef HAVE_ED25519 + struct ed25519_key* ed25519; + #endif + void* ptr; + } key; + int devId; + int state; + int typeH; + int digestSz; + word32 keyOID; +#ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV* asyncDev; + void* asyncCtx; +#endif + +#ifdef HAVE_PK_CALLBACKS +#ifdef HAVE_ECC + wc_CallbackEccVerify pkCbEcc; + void* pkCtxEcc; +#endif +#ifndef NO_RSA + wc_CallbackRsaVerify pkCbRsa; + void* pkCtxRsa; +#endif +#endif /* HAVE_PK_CALLBACKS */ +#ifndef NO_RSA +#ifdef WOLFSSL_RENESAS_TSIP_TLS + byte verifyByTSIP; + word32 certBegin; + word32 pubkey_n_start; + word32 pubkey_n_len; + word32 pubkey_e_start; + word32 pubkey_e_len; +#endif +#endif +}; + +enum CertSignState { + CERTSIGN_STATE_BEGIN, + CERTSIGN_STATE_DIGEST, + CERTSIGN_STATE_ENCODE, + CERTSIGN_STATE_DO, +}; + +struct CertSignCtx { + byte* sig; + byte* digest; + #ifndef NO_RSA + byte* encSig; + int encSigSz; + #endif + int state; /* enum CertSignState */ +}; + +#ifndef WOLFSSL_MAX_PATH_LEN + /* RFC 5280 Section 6.1.2. "Initialization" - item (k) defines + * (k) max_path_length: this integer is initialized to "n", is + * decremented for each non-self-issued certificate in the path, + * and may be reduced to the value in the path length constraint + * field within the basic constraints extension of a CA + * certificate. + * + * wolfSSL has arbitrarily selected the value 127 for "n" in the above + * description. Users can modify the maximum path length by setting + * WOLFSSL_MAX_PATH_LEN to a preferred value at build time + */ + #define WOLFSSL_MAX_PATH_LEN 127 +#endif + +typedef struct DecodedCert DecodedCert; +typedef struct DecodedName DecodedName; +typedef struct Signer Signer; +#ifdef WOLFSSL_TRUST_PEER_CERT +typedef struct TrustedPeerCert TrustedPeerCert; +#endif /* WOLFSSL_TRUST_PEER_CERT */ +typedef struct SignatureCtx SignatureCtx; +typedef struct CertSignCtx CertSignCtx; + + +struct DecodedCert { + const byte* publicKey; + word32 pubKeySize; + int pubKeyStored; + word32 certBegin; /* offset to start of cert */ + word32 sigIndex; /* offset to start of signature */ + word32 sigLength; /* length of signature */ + word32 signatureOID; /* sum of algorithm object id */ + word32 keyOID; /* sum of key algo object id */ + int version; /* cert version, 1 or 3 */ + DNS_entry* altNames; /* alt names list of dns entries */ +#ifndef IGNORE_NAME_CONSTRAINTS + DNS_entry* altEmailNames; /* alt names list of RFC822 entries */ + Base_entry* permittedNames; /* Permitted name bases */ + Base_entry* excludedNames; /* Excluded name bases */ +#endif /* IGNORE_NAME_CONSTRAINTS */ + byte subjectHash[KEYID_SIZE]; /* hash of all Names */ + byte issuerHash[KEYID_SIZE]; /* hash of all Names */ +#ifdef HAVE_OCSP + byte subjectKeyHash[KEYID_SIZE]; /* hash of the public Key */ + byte issuerKeyHash[KEYID_SIZE]; /* hash of the public Key */ +#endif /* HAVE_OCSP */ + const byte* signature; /* not owned, points into raw cert */ + char* subjectCN; /* CommonName */ + int subjectCNLen; /* CommonName Length */ + char subjectCNEnc; /* CommonName Encoding */ + char issuer[ASN_NAME_MAX]; /* full name including common name */ + char subject[ASN_NAME_MAX]; /* full name including common name */ + int verify; /* Default to yes, but could be off */ + const byte* source; /* byte buffer holder cert, NOT owner */ + word32 srcIdx; /* current offset into buffer */ + word32 maxIdx; /* max offset based on init size */ + void* heap; /* for user memory overrides */ + byte serial[EXTERNAL_SERIAL_SIZE]; /* raw serial number */ + int serialSz; /* raw serial bytes stored */ + const byte* extensions; /* not owned, points into raw cert */ + int extensionsSz; /* length of cert extensions */ + word32 extensionsIdx; /* if want to go back and parse later */ + const byte* extAuthInfo; /* Authority Information Access URI */ + int extAuthInfoSz; /* length of the URI */ + const byte* extCrlInfo; /* CRL Distribution Points */ + int extCrlInfoSz; /* length of the URI */ + byte extSubjKeyId[KEYID_SIZE]; /* Subject Key ID */ + byte extAuthKeyId[KEYID_SIZE]; /* Authority Key ID */ + byte pathLength; /* CA basic constraint path length */ + byte maxPathLen; /* max_path_len see RFC 5280 section + * 6.1.2 "Initialization" - (k) for + * description of max_path_len */ + word16 extKeyUsage; /* Key usage bitfield */ + byte extExtKeyUsage; /* Extended Key usage bitfield */ + +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + const byte* extExtKeyUsageSrc; + word32 extExtKeyUsageSz; + word32 extExtKeyUsageCount; + const byte* extAuthKeyIdSrc; + word32 extAuthKeyIdSz; + const byte* extSubjKeyIdSrc; + word32 extSubjKeyIdSz; +#endif + +#if defined(HAVE_ECC) || defined(HAVE_ED25519) + word32 pkCurveOID; /* Public Key's curve OID */ +#endif /* HAVE_ECC */ + const byte* beforeDate; + int beforeDateLen; + const byte* afterDate; + int afterDateLen; +#if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT) + const byte* issuerRaw; /* pointer to issuer inside source */ + int issuerRawLen; +#endif +#if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT) + const byte* subjectRaw; /* pointer to subject inside source */ + int subjectRawLen; +#endif +#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) + /* 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* subjectSND; + int subjectSNDLen; + char subjectSNDEnc; +#ifdef WOLFSSL_CERT_EXT + char* subjectBC; + int subjectBCLen; + char subjectBCEnc; + char* subjectJC; + int subjectJCLen; + char subjectJCEnc; + char* subjectJS; + int subjectJSLen; + char subjectJSEnc; +#endif + char* subjectEmail; + int subjectEmailLen; +#endif /* WOLFSSL_CERT_GEN */ +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + DecodedName issuerName; + DecodedName subjectName; +#endif /* OPENSSL_EXTRA */ +#ifdef WOLFSSL_SEP + int deviceTypeSz; + byte* deviceType; + int hwTypeSz; + byte* hwType; + int hwSerialNumSz; + byte* hwSerialNum; +#endif /* WOLFSSL_SEP */ +#ifdef WOLFSSL_CERT_EXT + char extCertPolicies[MAX_CERTPOL_NB][MAX_CERTPOL_SZ]; + int extCertPoliciesNb; +#endif /* defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) */ + + Signer* ca; +#ifndef NO_CERTS + SignatureCtx sigCtx; +#endif +#ifdef WOLFSSL_RENESAS_TSIP + byte* tsip_encRsaKeyIdx; +#endif + + int badDate; + int criticalExt; + + /* Option Bits */ + byte subjectCNStored : 1; /* have we saved a copy we own */ + byte extSubjKeyIdSet : 1; /* Set when the SKID was read from cert */ + byte extAuthKeyIdSet : 1; /* Set when the AKID was read from cert */ +#ifndef IGNORE_NAME_CONSTRAINTS + byte extNameConstraintSet : 1; +#endif + byte isCA : 1; /* CA basic constraint true */ + byte pathLengthSet : 1; /* CA basic const path length set */ + byte weOwnAltNames : 1; /* altNames haven't been given to copy */ + byte extKeyUsageSet : 1; + byte extExtKeyUsageSet : 1; /* Extended Key Usage set */ + byte extCRLdistSet : 1; + byte extAuthInfoSet : 1; + byte extBasicConstSet : 1; + byte extSubjAltNameSet : 1; + byte inhibitAnyOidSet : 1; + byte selfSigned : 1; /* Indicates subject and issuer are same */ +#ifdef WOLFSSL_SEP + byte extCertPolicySet : 1; +#endif +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + byte extCRLdistCrit : 1; + byte extAuthInfoCrit : 1; + byte extBasicConstCrit : 1; + byte extSubjAltNameCrit : 1; + byte extAuthKeyIdCrit : 1; + #ifndef IGNORE_NAME_CONSTRAINTS + byte extNameConstraintCrit : 1; + #endif + byte extSubjKeyIdCrit : 1; + byte extKeyUsageCrit : 1; + byte extExtKeyUsageCrit : 1; +#endif /* OPENSSL_EXTRA */ +#ifdef WOLFSSL_SEP + byte extCertPolicyCrit : 1; +#endif + +}; + + +#ifdef NO_SHA + #define SIGNER_DIGEST_SIZE WC_SHA256_DIGEST_SIZE +#else + #define SIGNER_DIGEST_SIZE WC_SHA_DIGEST_SIZE +#endif + +/* CA Signers */ +/* if change layout change PERSIST_CERT_CACHE functions too */ +struct Signer { + word32 pubKeySize; + word32 keyOID; /* key type */ + word16 keyUsage; + byte maxPathLen; + byte pathLength; + byte pathLengthSet : 1; + byte selfSigned : 1; + const byte* publicKey; + int nameLen; + char* name; /* common name */ +#ifndef IGNORE_NAME_CONSTRAINTS + Base_entry* permittedNames; + Base_entry* excludedNames; +#endif /* IGNORE_NAME_CONSTRAINTS */ + byte subjectNameHash[SIGNER_DIGEST_SIZE]; + /* sha hash of names in certificate */ + #ifndef NO_SKID + byte subjectKeyIdHash[SIGNER_DIGEST_SIZE]; + /* sha hash of names in certificate */ + #endif + #ifdef HAVE_OCSP + byte subjectKeyHash[KEYID_SIZE]; + #endif +#ifdef WOLFSSL_SIGNER_DER_CERT + DerBuffer* derCert; +#endif +#ifdef WOLFSSL_RENESAS_TSIP_TLS + word32 cm_idx; +#endif + Signer* next; +}; + + +#ifdef WOLFSSL_TRUST_PEER_CERT +/* used for having trusted peer certs rather then CA */ +struct TrustedPeerCert { + int nameLen; + char* name; /* common name */ + #ifndef IGNORE_NAME_CONSTRAINTS + Base_entry* permittedNames; + Base_entry* excludedNames; + #endif /* IGNORE_NAME_CONSTRAINTS */ + byte subjectNameHash[SIGNER_DIGEST_SIZE]; + /* sha hash of names in certificate */ + #ifndef NO_SKID + byte subjectKeyIdHash[SIGNER_DIGEST_SIZE]; + /* sha hash of names in certificate */ + #endif + word32 sigLen; + byte* sig; + struct TrustedPeerCert* next; +}; +#endif /* WOLFSSL_TRUST_PEER_CERT */ + + +/* for testing or custom openssl wrappers */ +#if defined(WOLFSSL_TEST_CERT) || defined(OPENSSL_EXTRA) || \ + defined(OPENSSL_EXTRA_X509_SMALL) + #define WOLFSSL_ASN_API WOLFSSL_API +#else + #define WOLFSSL_ASN_API WOLFSSL_LOCAL +#endif + +WOLFSSL_LOCAL int CalcHashId(const byte* data, word32 len, byte* hash); + +WOLFSSL_ASN_API int wc_BerToDer(const byte* ber, word32 berSz, byte* der, + word32* derSz); + +WOLFSSL_ASN_API void FreeAltNames(DNS_entry*, void*); +#ifndef IGNORE_NAME_CONSTRAINTS + WOLFSSL_ASN_API void FreeNameSubtrees(Base_entry*, void*); +#endif /* IGNORE_NAME_CONSTRAINTS */ +WOLFSSL_ASN_API void InitDecodedCert(DecodedCert*, const byte*, word32, void*); +WOLFSSL_ASN_API void FreeDecodedCert(DecodedCert*); +WOLFSSL_ASN_API int ParseCert(DecodedCert*, int type, int verify, void* cm); + +WOLFSSL_LOCAL int DecodePolicyOID(char *o, word32 oSz, + const byte *in, word32 inSz); +WOLFSSL_LOCAL int EncodePolicyOID(byte *out, word32 *outSz, + const char *in, void* heap); +WOLFSSL_API int CheckCertSignature(const byte*,word32,void*,void* cm); +WOLFSSL_LOCAL int CheckCertSignaturePubKey(const byte* cert, word32 certSz, + void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID); +WOLFSSL_LOCAL int ParseCertRelative(DecodedCert*,int type,int verify,void* cm); +WOLFSSL_LOCAL int DecodeToKey(DecodedCert*, int verify); +WOLFSSL_LOCAL int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate); + +WOLFSSL_LOCAL const byte* OidFromId(word32 id, word32 type, word32* oidSz); +WOLFSSL_LOCAL Signer* MakeSigner(void*); +WOLFSSL_LOCAL void FreeSigner(Signer*, void*); +WOLFSSL_LOCAL void FreeSignerTable(Signer**, int, void*); +#ifdef WOLFSSL_TRUST_PEER_CERT +WOLFSSL_LOCAL void FreeTrustedPeer(TrustedPeerCert*, void*); +WOLFSSL_LOCAL void FreeTrustedPeerTable(TrustedPeerCert**, int, void*); +#endif /* WOLFSSL_TRUST_PEER_CERT */ + +WOLFSSL_ASN_API int ToTraditional(byte* buffer, word32 length); +WOLFSSL_ASN_API int ToTraditional_ex(byte* buffer, word32 length, + word32* algId); +WOLFSSL_LOCAL int ToTraditionalInline(const byte* input, word32* inOutIdx, + word32 length); +WOLFSSL_LOCAL int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, + word32 length, word32* algId); +WOLFSSL_LOCAL int ToTraditionalEnc(byte* buffer, word32 length,const char*,int, + word32* algId); +WOLFSSL_ASN_API int UnTraditionalEnc(byte* key, word32 keySz, byte* out, + word32* outSz, const char* password, int passwordSz, int vPKCS, + int vAlgo, byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap); +WOLFSSL_ASN_API int TraditionalEnc(byte* key, word32 keySz, byte* out, + word32* outSz, const char* password, int passwordSz, int vPKCS, + int vAlgo, int encAlgId, byte* salt, word32 saltSz, int itt, + WC_RNG* rng, void* heap); +WOLFSSL_LOCAL int DecryptContent(byte* input, word32 sz,const char* psw,int pswSz); +WOLFSSL_LOCAL int EncryptContent(byte* input, word32 sz, byte* out, word32* outSz, + const char* password,int passwordSz, int vPKCS, int vAlgo, + byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap); +WOLFSSL_LOCAL int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, + word32* oidSz, int* algoID, void* heap); + +typedef struct tm wolfssl_tm; +#if defined(OPENSSL_ALL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA) || \ + defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) +WOLFSSL_LOCAL int GetTimeString(byte* date, int format, char* buf, int len); +#endif +#if !defined(NO_ASN_TIME) && defined(HAVE_PKCS7) +WOLFSSL_LOCAL int GetAsnTimeString(void* currTime, byte* buf, word32 len); +#endif +WOLFSSL_LOCAL int ExtractDate(const unsigned char* date, unsigned char format, + wolfssl_tm* certTime, int* idx); +WOLFSSL_LOCAL int DateGreaterThan(const struct tm* a, const struct tm* b); +WOLFSSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType); +WOLFSSL_LOCAL int wc_OBJ_sn2nid(const char *sn); + +/* ASN.1 helper functions */ +#ifdef WOLFSSL_CERT_GEN +WOLFSSL_ASN_API int SetName(byte* output, word32 outputSz, CertName* name); +#endif +WOLFSSL_LOCAL int GetShortInt(const byte* input, word32* inOutIdx, int* number, + word32 maxIdx); +WOLFSSL_LOCAL int SetShortInt(byte* input, word32* inOutIdx, word32 number, + word32 maxIdx); + +WOLFSSL_LOCAL char* GetSigName(int oid); +WOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len, + word32 maxIdx); +WOLFSSL_LOCAL int GetLength_ex(const byte* input, word32* inOutIdx, int* len, + word32 maxIdx, int check); +WOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len, + word32 maxIdx); +WOLFSSL_LOCAL int GetSequence_ex(const byte* input, word32* inOutIdx, int* len, + word32 maxIdx, int check); +WOLFSSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len, + word32 maxIdx); +WOLFSSL_LOCAL int GetSet_ex(const byte* input, word32* inOutIdx, int* len, + word32 maxIdx, int check); +WOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx, + int* version, word32 maxIdx); +WOLFSSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, + word32 maxIdx); +#ifdef HAVE_OID_ENCODING + WOLFSSL_LOCAL int EncodeObjectId(const word16* in, word32 inSz, + byte* out, word32* outSz); +#endif +#ifdef HAVE_OID_DECODING + WOLFSSL_LOCAL int DecodeObjectId(const byte* in, word32 inSz, + word16* out, word32* outSz); +#endif +WOLFSSL_LOCAL int GetASNObjectId(const byte* input, word32* inOutIdx, int* len, + word32 maxIdx); +WOLFSSL_LOCAL int SetObjectId(int len, byte* output); +WOLFSSL_LOCAL int GetObjectId(const byte* input, word32* inOutIdx, word32* oid, + word32 oidType, word32 maxIdx); +WOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid, + word32 oidType, word32 maxIdx); +WOLFSSL_LOCAL int GetASNTag(const byte* input, word32* idx, byte* tag, + word32 inputSz); +WOLFSSL_LOCAL word32 SetLength(word32 length, byte* output); +WOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output); +WOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output); +WOLFSSL_LOCAL word32 SetImplicit(byte tag,byte number,word32 len,byte* output); +WOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output); +WOLFSSL_LOCAL word32 SetSet(word32 len, byte* output); +WOLFSSL_LOCAL word32 SetAlgoID(int algoOID,byte* output,int type,int curveSz); +WOLFSSL_LOCAL int SetMyVersion(word32 version, byte* output, int header); +WOLFSSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output, + word32 outputSz, int maxSnSz); +WOLFSSL_LOCAL int GetSerialNumber(const byte* input, word32* inOutIdx, + byte* serial, int* serialSz, word32 maxIdx); +WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash, + int maxIdx); +WOLFSSL_LOCAL int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der); + +#ifdef HAVE_ECC + /* ASN sig helpers */ + WOLFSSL_LOCAL int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, + mp_int* s); + WOLFSSL_LOCAL int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, + mp_int* r, mp_int* s); +#endif + +WOLFSSL_LOCAL void InitSignatureCtx(SignatureCtx* sigCtx, void* heap, int devId); +WOLFSSL_LOCAL void FreeSignatureCtx(SignatureCtx* sigCtx); + +#ifndef NO_CERTS + +WOLFSSL_LOCAL int wc_EncryptedInfoParse(EncryptedInfo* info, char** pBuffer, + size_t bufSz); + +WOLFSSL_LOCAL int PemToDer(const unsigned char* buff, long sz, int type, + DerBuffer** pDer, void* heap, EncryptedInfo* info, + int* eccKey); +WOLFSSL_LOCAL int AllocDer(DerBuffer** der, word32 length, int type, void* heap); +WOLFSSL_LOCAL void FreeDer(DerBuffer** der); + +#endif /* !NO_CERTS */ + +#ifdef WOLFSSL_CERT_GEN + +enum cert_enums { +#ifdef WOLFSSL_CERT_EXT + NAME_ENTRIES = 10, +#else + NAME_ENTRIES = 9, +#endif + JOINT_LEN = 2, + EMAIL_JOINT_LEN = 9, + PILOT_JOINT_LEN = 10, + RSA_KEY = 10, + NTRU_KEY = 11, + ECC_KEY = 12, + ED25519_KEY = 13 +}; + +#endif /* WOLFSSL_CERT_GEN */ + + + +/* for pointer use */ +typedef struct CertStatus CertStatus; + +#ifdef HAVE_OCSP + +enum Ocsp_Response_Status { + OCSP_SUCCESSFUL = 0, /* Response has valid confirmations */ + OCSP_MALFORMED_REQUEST = 1, /* Illegal confirmation request */ + OCSP_INTERNAL_ERROR = 2, /* Internal error in issuer */ + OCSP_TRY_LATER = 3, /* Try again later */ + OCSP_SIG_REQUIRED = 5, /* Must sign the request (4 is skipped) */ + OCSP_UNAUTHROIZED = 6 /* Request unauthorized */ +}; + + +enum Ocsp_Cert_Status { + CERT_GOOD = 0, + CERT_REVOKED = 1, + CERT_UNKNOWN = 2 +}; + + +enum Ocsp_Sums { + OCSP_BASIC_OID = 117, + OCSP_NONCE_OID = 118 +}; + +#ifdef OPENSSL_EXTRA +enum Ocsp_Verify_Error { + OCSP_VERIFY_ERROR_NONE = 0, + OCSP_BAD_ISSUER = 1 +}; +#endif + + +typedef struct OcspRequest OcspRequest; +typedef struct OcspResponse OcspResponse; + + +struct CertStatus { + CertStatus* next; + + byte serial[EXTERNAL_SERIAL_SIZE]; + int serialSz; + + int status; + + byte thisDate[MAX_DATE_SIZE]; + byte nextDate[MAX_DATE_SIZE]; + byte thisDateFormat; + byte nextDateFormat; +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) + WOLFSSL_ASN1_TIME thisDateParsed; + WOLFSSL_ASN1_TIME nextDateParsed; + byte* thisDateAsn; + byte* nextDateAsn; +#endif + + byte* rawOcspResponse; + word32 rawOcspResponseSz; +}; + + +struct OcspResponse { + int responseStatus; /* return code from Responder */ + + byte* response; /* Pointer to beginning of OCSP Response */ + word32 responseSz; /* length of the OCSP Response */ + + byte producedDate[MAX_DATE_SIZE]; + /* Date at which this response was signed */ + byte producedDateFormat; /* format of the producedDate */ + byte* issuerHash; + byte* issuerKeyHash; + + byte* cert; + word32 certSz; + + byte* sig; /* Pointer to sig in source */ + word32 sigSz; /* Length in octets for the sig */ + word32 sigOID; /* OID for hash used for sig */ + + CertStatus* status; /* certificate status to fill out */ + + byte* nonce; /* pointer to nonce inside ASN.1 response */ + int nonceSz; /* length of the nonce string */ + + byte* source; /* pointer to source buffer, not owned */ + word32 maxIdx; /* max offset based on init size */ + +#ifdef OPENSSL_EXTRA + int verifyError; +#endif +}; + + +struct OcspRequest { + byte issuerHash[KEYID_SIZE]; + byte issuerKeyHash[KEYID_SIZE]; + byte* serial; /* copy of the serial number in source cert */ + int serialSz; +#ifdef OPENSSL_EXTRA + WOLFSSL_ASN1_INTEGER* serialInt; +#endif + byte* url; /* copy of the extAuthInfo in source cert */ + int urlSz; + + byte nonce[MAX_OCSP_NONCE_SZ]; + int nonceSz; + void* heap; + void* ssl; +}; + +typedef struct OcspEntry OcspEntry; + +#ifdef NO_SHA +#define OCSP_DIGEST_SIZE WC_SHA256_DIGEST_SIZE +#else +#define OCSP_DIGEST_SIZE WC_SHA_DIGEST_SIZE +#endif + +struct OcspEntry +{ + OcspEntry *next; /* next entry */ + byte issuerHash[OCSP_DIGEST_SIZE]; /* issuer hash */ + byte issuerKeyHash[OCSP_DIGEST_SIZE]; /* issuer public key hash */ + CertStatus *status; /* OCSP response list */ + int totalStatus; /* number on list */ +}; + +WOLFSSL_LOCAL void InitOcspResponse(OcspResponse*, CertStatus*, byte*, word32); +WOLFSSL_LOCAL int OcspResponseDecode(OcspResponse*, void*, void* heap, int); + +WOLFSSL_LOCAL int InitOcspRequest(OcspRequest*, DecodedCert*, byte, void*); +WOLFSSL_LOCAL void FreeOcspRequest(OcspRequest*); +WOLFSSL_LOCAL int EncodeOcspRequest(OcspRequest*, byte*, word32); +WOLFSSL_LOCAL word32 EncodeOcspRequestExtensions(OcspRequest*, byte*, word32); + + +WOLFSSL_LOCAL int CompareOcspReqResp(OcspRequest*, OcspResponse*); + + +#endif /* HAVE_OCSP */ + + +/* for pointer use */ +typedef struct RevokedCert RevokedCert; + +#ifdef HAVE_CRL + +struct RevokedCert { + byte serialNumber[EXTERNAL_SERIAL_SIZE]; + int serialSz; + RevokedCert* next; +}; + +typedef struct DecodedCRL DecodedCRL; + +struct DecodedCRL { + word32 certBegin; /* offset to start of cert */ + word32 sigIndex; /* offset to start of signature */ + word32 sigLength; /* length of signature */ + word32 signatureOID; /* sum of algorithm object id */ + byte* signature; /* pointer into raw source, not owned */ + byte issuerHash[SIGNER_DIGEST_SIZE]; /* issuer name hash */ + byte crlHash[SIGNER_DIGEST_SIZE]; /* raw crl data hash */ + byte lastDate[MAX_DATE_SIZE]; /* last date updated */ + byte nextDate[MAX_DATE_SIZE]; /* next update date */ + byte lastDateFormat; /* format of last date */ + byte nextDateFormat; /* format of next date */ + RevokedCert* certs; /* revoked cert list */ + int totalCerts; /* number on list */ + void* heap; +#ifndef NO_SKID + byte extAuthKeyIdSet; + byte extAuthKeyId[SIGNER_DIGEST_SIZE]; /* Authority Key ID */ +#endif +}; + +WOLFSSL_LOCAL void InitDecodedCRL(DecodedCRL*, void* heap); +WOLFSSL_LOCAL int VerifyCRL_Signature(SignatureCtx* sigCtx, + const byte* toBeSigned, word32 tbsSz, + const byte* signature, word32 sigSz, + word32 signatureOID, Signer *ca, + void* heap); +WOLFSSL_LOCAL int ParseCRL(DecodedCRL*, const byte* buff, word32 sz, void* cm); +WOLFSSL_LOCAL void FreeDecodedCRL(DecodedCRL*); + + +#endif /* HAVE_CRL */ + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* !NO_ASN */ + + +#if !defined(NO_ASN) || !defined(NO_PWDBASED) + +#ifndef MAX_KEY_SIZE + #define MAX_KEY_SIZE 64 /* MAX PKCS Key length */ +#endif +#ifndef MAX_UNICODE_SZ + #define MAX_UNICODE_SZ 256 +#endif + +enum PBESTypes { + PBE_MD5_DES = 0, + PBE_SHA1_RC4_128 = 1, + PBE_SHA1_DES = 2, + PBE_SHA1_DES3 = 3, + PBE_AES256_CBC = 4, + + PBE_SHA1_RC4_128_SUM = 657, + PBE_SHA1_DES3_SUM = 659, + PBES2 = 13 /* algo ID */ +}; + +enum PKCSTypes { + PKCS5v2 = 6, /* PKCS #5 v2.0 */ + PKCS12v1 = 12, /* PKCS #12 */ + PKCS5 = 5, /* PKCS oid tag */ + PKCS8v0 = 0, /* default PKCS#8 version */ +}; + +#endif /* !NO_ASN || !NO_PWDBASED */ + +#endif /* WOLF_CRYPT_ASN_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/asn_public.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/asn_public.h new file mode 100644 index 0000000..743ddf6 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/asn_public.h @@ -0,0 +1,578 @@ +/* asn_public.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/asn_public.h +*/ + +#ifndef WOLF_CRYPT_ASN_PUBLIC_H +#define WOLF_CRYPT_ASN_PUBLIC_H + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/* guard on redeclaration */ +#ifndef WC_ECCKEY_TYPE_DEFINED + typedef struct ecc_key ecc_key; + #define WC_ECCKEY_TYPE_DEFINED +#endif +#ifndef WC_ED25519KEY_TYPE_DEFINED + typedef struct ed25519_key ed25519_key; + #define WC_ED25519KEY_TYPE_DEFINED +#endif +#ifndef WC_RSAKEY_TYPE_DEFINED + typedef struct RsaKey RsaKey; + #define WC_RSAKEY_TYPE_DEFINED +#endif +#ifndef WC_RNG_TYPE_DEFINED + typedef struct WC_RNG WC_RNG; + #define WC_RNG_TYPE_DEFINED +#endif + +enum Ecc_Sum { + ECC_SECP112R1_OID = 182, + ECC_SECP112R2_OID = 183, + ECC_SECP128R1_OID = 204, + ECC_SECP128R2_OID = 205, + ECC_SECP160R1_OID = 184, + ECC_SECP160R2_OID = 206, + ECC_SECP160K1_OID = 185, + ECC_BRAINPOOLP160R1_OID = 98, + ECC_SECP192R1_OID = 520, + ECC_PRIME192V2_OID = 521, + ECC_PRIME192V3_OID = 522, + ECC_SECP192K1_OID = 207, + ECC_BRAINPOOLP192R1_OID = 100, + ECC_SECP224R1_OID = 209, + ECC_SECP224K1_OID = 208, + ECC_BRAINPOOLP224R1_OID = 102, + ECC_PRIME239V1_OID = 523, + ECC_PRIME239V2_OID = 524, + ECC_PRIME239V3_OID = 525, + ECC_SECP256R1_OID = 526, + ECC_SECP256K1_OID = 186, + ECC_BRAINPOOLP256R1_OID = 104, + ECC_X25519_OID = 365, + ECC_ED25519_OID = 256, + ECC_BRAINPOOLP320R1_OID = 106, + ECC_SECP384R1_OID = 210, + ECC_BRAINPOOLP384R1_OID = 108, + ECC_BRAINPOOLP512R1_OID = 110, + ECC_SECP521R1_OID = 211, +}; + + +/* Certificate file Type */ +enum CertType { + CERT_TYPE = 0, + PRIVATEKEY_TYPE, + DH_PARAM_TYPE, + DSA_PARAM_TYPE, + CRL_TYPE, + CA_TYPE, + ECC_PRIVATEKEY_TYPE, + DSA_PRIVATEKEY_TYPE, + CERTREQ_TYPE, + DSA_TYPE, + ECC_TYPE, + RSA_TYPE, + PUBLICKEY_TYPE, + RSA_PUBLICKEY_TYPE, + ECC_PUBLICKEY_TYPE, + TRUSTED_PEER_TYPE, + EDDSA_PRIVATEKEY_TYPE, + ED25519_TYPE, + PKCS12_TYPE, + PKCS8_PRIVATEKEY_TYPE, + PKCS8_ENC_PRIVATEKEY_TYPE, + DETECT_CERT_TYPE, + DH_PRIVATEKEY_TYPE, +}; + + +/* Signature type, by OID sum */ +enum Ctc_SigType { + CTC_SHAwDSA = 517, + CTC_MD2wRSA = 646, + CTC_MD5wRSA = 648, + CTC_SHAwRSA = 649, + CTC_SHAwECDSA = 520, + CTC_SHA224wRSA = 658, + CTC_SHA224wECDSA = 523, + CTC_SHA256wRSA = 655, + CTC_SHA256wECDSA = 524, + CTC_SHA384wRSA = 656, + CTC_SHA384wECDSA = 525, + CTC_SHA512wRSA = 657, + CTC_SHA512wECDSA = 526, + CTC_ED25519 = 256 +}; + +enum Ctc_Encoding { + CTC_UTF8 = 0x0c, /* utf8 */ + CTC_PRINTABLE = 0x13 /* printable */ +}; + +#ifndef WC_CTC_NAME_SIZE + #define WC_CTC_NAME_SIZE 64 +#endif +#ifndef WC_CTC_MAX_ALT_SIZE + #define WC_CTC_MAX_ALT_SIZE 16384 +#endif + +enum Ctc_Misc { + CTC_COUNTRY_SIZE = 2, + CTC_NAME_SIZE = WC_CTC_NAME_SIZE, + CTC_DATE_SIZE = 32, + CTC_MAX_ALT_SIZE = WC_CTC_MAX_ALT_SIZE, /* may be huge, default: 16384 */ + CTC_SERIAL_SIZE = 20, + CTC_GEN_SERIAL_SZ = 16, +#ifdef WOLFSSL_CERT_EXT + /* AKID could contains: hash + (Option) AuthCertIssuer,AuthCertSerialNum + * We support only hash */ + CTC_MAX_SKID_SIZE = 32, /* SHA256_DIGEST_SIZE */ + CTC_MAX_AKID_SIZE = 32, /* SHA256_DIGEST_SIZE */ + CTC_MAX_CERTPOL_SZ = 64, + CTC_MAX_CERTPOL_NB = 2 /* Max number of Certificate Policy */ +#endif /* WOLFSSL_CERT_EXT */ +}; + +/* DER buffer */ +typedef struct DerBuffer { + byte* buffer; + void* heap; + word32 length; + int type; /* enum CertType */ + int dynType; /* DYNAMIC_TYPE_* */ +} DerBuffer; + +typedef struct WOLFSSL_ASN1_TIME { + unsigned char data[CTC_DATE_SIZE]; /* date bytes */ + int length; + int type; +} WOLFSSL_ASN1_TIME; + +enum { + IV_SZ = 32, /* max iv sz */ + NAME_SZ = 80, /* max one line */ + + PEM_PASS_READ = 0, + PEM_PASS_WRITE = 1, +}; + + +typedef int (pem_password_cb)(char* passwd, int sz, int rw, void* userdata); + +typedef struct EncryptedInfo { + pem_password_cb* passwd_cb; + void* passwd_userdata; + + long consumed; /* tracks PEM bytes consumed */ + + int cipherType; + word32 keySz; + word32 ivSz; /* salt or encrypted IV size */ + + char name[NAME_SZ]; /* cipher name, such as "DES-CBC" */ + byte iv[IV_SZ]; /* salt or encrypted IV */ + + word16 set:1; /* if encryption set */ +} EncryptedInfo; + + +#define WOLFSSL_ASN1_INTEGER_MAX 20 +typedef struct WOLFSSL_ASN1_INTEGER { + /* size can be increased set at 20 for tag, length then to hold at least 16 + * byte type */ + unsigned char intData[WOLFSSL_ASN1_INTEGER_MAX]; + /* ASN_INTEGER | LENGTH | hex of number */ + unsigned char negative; /* negative number flag */ + + unsigned char* data; + unsigned int dataMax; /* max size of data buffer */ + unsigned int isDynamic:1; /* flag for if data pointer dynamic (1 is yes 0 is no) */ + + int length; + int type; +} WOLFSSL_ASN1_INTEGER; + + +#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) +#ifdef WOLFSSL_EKU_OID + #ifndef CTC_MAX_EKU_NB + #define CTC_MAX_EKU_NB 1 + #endif + #ifndef CTC_MAX_EKU_OID_SZ + #define CTC_MAX_EKU_OID_SZ 30 + #endif +#else + #undef CTC_MAX_EKU_OID_SZ + #define CTC_MAX_EKU_OID_SZ 0 +#endif +#endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */ + +#ifdef WOLFSSL_MULTI_ATTRIB +#ifndef CTC_MAX_ATTRIB + #define CTC_MAX_ATTRIB 4 +#endif + +/* ASN Encoded Name field */ +typedef struct NameAttrib { + int sz; /* actual string value length */ + int id; /* id of name */ + int type; /* enc of name */ + char value[CTC_NAME_SIZE]; /* name */ +} NameAttrib; +#endif /* WOLFSSL_MULTI_ATTRIB */ + + +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 serialDev[CTC_NAME_SIZE]; + char serialDevEnc; +#ifdef WOLFSSL_CERT_EXT + char busCat[CTC_NAME_SIZE]; + char busCatEnc; + char joiC[CTC_NAME_SIZE]; + char joiCEnc; + char joiSt[CTC_NAME_SIZE]; + char joiStEnc; +#endif + char email[CTC_NAME_SIZE]; /* !!!! email has to be last !!!! */ +#ifdef WOLFSSL_MULTI_ATTRIB + NameAttrib name[CTC_MAX_ATTRIB]; +#endif +} CertName; + + +/* for user to fill for certificate generation */ +typedef struct Cert { + int version; /* x509 version */ + byte serial[CTC_SERIAL_SIZE]; /* serial number */ + int serialSz; /* serial size */ + int sigType; /* signature algo type */ + CertName issuer; /* issuer info */ + int daysValid; /* validity days */ + int selfSigned; /* self signed flag */ + CertName subject; /* subject info */ + int isCA; /* is this going to be a CA */ + /* internal use only */ + int bodySz; /* pre sign total size */ + int keyType; /* public key type of subject */ +#ifdef WOLFSSL_ALT_NAMES + byte altNames[CTC_MAX_ALT_SIZE]; /* altNames copy */ + int altNamesSz; /* altNames size in bytes */ + byte beforeDate[CTC_DATE_SIZE]; /* before date copy */ + int beforeDateSz; /* size of copy */ + byte afterDate[CTC_DATE_SIZE]; /* after date copy */ + int afterDateSz; /* size of copy */ +#endif +#ifdef WOLFSSL_CERT_EXT + byte skid[CTC_MAX_SKID_SIZE]; /* Subject Key Identifier */ + int skidSz; /* SKID size in bytes */ + byte akid[CTC_MAX_AKID_SIZE]; /* Authority Key Identifier */ + int akidSz; /* AKID size in bytes */ + word16 keyUsage; /* Key Usage */ + byte extKeyUsage; /* Extended Key Usage */ +#ifdef WOLFSSL_EKU_OID + /* Extended Key Usage OIDs */ + byte extKeyUsageOID[CTC_MAX_EKU_NB][CTC_MAX_EKU_OID_SZ]; + byte extKeyUsageOIDSz[CTC_MAX_EKU_NB]; +#endif + char certPolicies[CTC_MAX_CERTPOL_NB][CTC_MAX_CERTPOL_SZ]; + word16 certPoliciesNb; /* Number of Cert Policy */ + byte issRaw[sizeof(CertName)]; /* raw issuer info */ + byte sbjRaw[sizeof(CertName)]; /* raw subject info */ +#endif +#ifdef WOLFSSL_CERT_REQ + char challengePw[CTC_NAME_SIZE]; + int challengePwPrintableString; /* encode as PrintableString */ +#endif + void* decodedCert; /* internal DecodedCert allocated from heap */ + byte* der; /* Pointer to buffer of current DecodedCert cache */ + void* heap; /* heap hint */ +} Cert; + + +/* Initialize and Set Certificate defaults: + version = 3 (0x2) + serial = 0 (Will be randomly generated) + sigType = SHA_WITH_RSA + issuer = blank + daysValid = 500 + selfSigned = 1 (true) use subject as issuer + subject = blank + isCA = 0 (false) + keyType = RSA_KEY (default) +*/ +WOLFSSL_API int wc_InitCert(Cert*); +WOLFSSL_API int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, + int keyType, void* key, WC_RNG* rng); +WOLFSSL_API int wc_MakeCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*, + ecc_key*, WC_RNG*); +#ifdef WOLFSSL_CERT_REQ + WOLFSSL_API int wc_MakeCertReq_ex(Cert*, byte* derBuffer, word32 derSz, + int, void*); + WOLFSSL_API int wc_MakeCertReq(Cert*, byte* derBuffer, word32 derSz, + RsaKey*, ecc_key*); +#endif +WOLFSSL_API int wc_SignCert_ex(int requestSz, int sType, byte* buffer, + word32 buffSz, int keyType, void* key, + WC_RNG* rng); +WOLFSSL_API int wc_SignCert(int requestSz, int sigType, byte* derBuffer, + word32 derSz, RsaKey*, ecc_key*, WC_RNG*); +WOLFSSL_API int wc_MakeSelfCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*, + WC_RNG*); +WOLFSSL_API int wc_SetIssuer(Cert*, const char*); +WOLFSSL_API int wc_SetSubject(Cert*, const char*); +#ifdef WOLFSSL_ALT_NAMES + WOLFSSL_API int wc_SetAltNames(Cert*, const char*); +#endif + +#ifdef WOLFSSL_CERT_GEN_CACHE +WOLFSSL_API void wc_SetCert_Free(Cert* cert); +#endif + +WOLFSSL_API int wc_SetIssuerBuffer(Cert*, const byte*, int); +WOLFSSL_API int wc_SetSubjectBuffer(Cert*, const byte*, int); +WOLFSSL_API int wc_SetAltNamesBuffer(Cert*, const byte*, int); +WOLFSSL_API int wc_SetDatesBuffer(Cert*, const byte*, int); + +#ifndef NO_ASN_TIME +WOLFSSL_API int wc_GetCertDates(Cert* cert, struct tm* before, + struct tm* after); +#endif + +#ifdef WOLFSSL_CERT_EXT +WOLFSSL_API int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, + void* key); +WOLFSSL_API int wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, + ecc_key *eckey); +WOLFSSL_API int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz); +WOLFSSL_API int wc_SetAuthKeyId(Cert *cert, const char* file); +WOLFSSL_API int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, + void* key); +WOLFSSL_API int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, + ecc_key *eckey); +WOLFSSL_API int wc_SetSubjectKeyId(Cert *cert, const char* file); +WOLFSSL_API int wc_GetSubjectRaw(byte **subjectRaw, Cert *cert); +WOLFSSL_API int wc_SetSubjectRaw(Cert* cert, const byte* der, int derSz); +WOLFSSL_API int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz); + +#ifdef HAVE_NTRU +WOLFSSL_API int wc_SetSubjectKeyIdFromNtruPublicKey(Cert *cert, byte *ntruKey, + word16 ntruKeySz); +#endif + +/* Set the KeyUsage. + * Value is a string separated tokens with ','. Accepted tokens are : + * digitalSignature,nonRepudiation,contentCommitment,keyCertSign,cRLSign, + * dataEncipherment,keyAgreement,keyEncipherment,encipherOnly and decipherOnly. + * + * nonRepudiation and contentCommitment are for the same usage. + */ +WOLFSSL_API int wc_SetKeyUsage(Cert *cert, const char *value); + +/* Set ExtendedKeyUsage + * Value is a string separated tokens with ','. Accepted tokens are : + * any,serverAuth,clientAuth,codeSigning,emailProtection,timeStamping,OCSPSigning + */ +WOLFSSL_API int wc_SetExtKeyUsage(Cert *cert, const char *value); + + +#ifdef WOLFSSL_EKU_OID +/* Set ExtendedKeyUsage with unique OID + * oid is expected to be in byte representation + */ +WOLFSSL_API int wc_SetExtKeyUsageOID(Cert *cert, const char *oid, word32 sz, + byte idx, void* heap); +#endif /* WOLFSSL_EKU_OID */ +#endif /* WOLFSSL_CERT_EXT */ + + #ifdef HAVE_NTRU + WOLFSSL_API int wc_MakeNtruCert(Cert*, byte* derBuffer, word32 derSz, + const byte* ntruKey, word16 keySz, + WC_RNG*); + #endif + +WOLFSSL_API int wc_GetDateInfo(const byte* certDate, int certDateSz, + const byte** date, byte* format, int* length); +#ifndef NO_ASN_TIME +WOLFSSL_API int wc_GetDateAsCalendarTime(const byte* date, int length, + byte format, struct tm* time); +#endif + +#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM) + + WOLFSSL_API int wc_PemGetHeaderFooter(int type, const char** header, + const char** footer); + +#endif + +WOLFSSL_API int wc_AllocDer(DerBuffer** pDer, word32 length, int type, void* heap); +WOLFSSL_API void wc_FreeDer(DerBuffer** pDer); + +#ifdef WOLFSSL_PEM_TO_DER + WOLFSSL_API int wc_PemToDer(const unsigned char* buff, long longSz, int type, + DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey); + + WOLFSSL_API int wc_KeyPemToDer(const unsigned char*, int, + unsigned char*, int, const char*); + WOLFSSL_API int wc_CertPemToDer(const unsigned char*, int, + unsigned char*, int, int); +#endif /* WOLFSSL_PEM_TO_DER */ + +#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER) + #ifndef NO_FILESYSTEM + WOLFSSL_API int wc_PemPubKeyToDer(const char* fileName, + unsigned char* derBuf, int derSz); + #endif + + WOLFSSL_API int wc_PubKeyPemToDer(const unsigned char*, int, + unsigned char*, int); +#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */ + +#ifdef WOLFSSL_CERT_GEN + #ifndef NO_FILESYSTEM + WOLFSSL_API int wc_PemCertToDer(const char* fileName, + unsigned char* derBuf, int derSz); + #endif +#endif /* WOLFSSL_CERT_GEN */ + +#ifdef WOLFSSL_DER_TO_PEM + WOLFSSL_API int wc_DerToPem(const byte* der, word32 derSz, byte* output, + word32 outputSz, int type); + WOLFSSL_API int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, + word32 outputSz, byte *cipherIno, int type); +#endif + +#ifndef NO_RSA + #if !defined(HAVE_USER_RSA) + WOLFSSL_API int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, + word32 inSz, const byte** n, word32* nSz, const byte** e, word32* eSz); + #endif + WOLFSSL_API int wc_RsaPublicKeyDerSize(RsaKey* key, int with_header); +#endif + + /* private key helpers */ + WOLFSSL_API int wc_EccPrivateKeyDecode(const byte*, word32*, + ecc_key*, word32); + WOLFSSL_API int wc_EccKeyToDer(ecc_key*, byte* output, word32 inLen); + WOLFSSL_API int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, + word32 inLen); + WOLFSSL_API int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, + word32* outLen); + + /* public key helper */ + WOLFSSL_API int wc_EccPublicKeyDecode(const byte*, word32*, + ecc_key*, word32); + WOLFSSL_API int wc_EccPublicKeyToDer(ecc_key*, byte* output, + word32 inLen, int with_AlgCurve); + WOLFSSL_API int wc_EccPublicKeyDerSize(ecc_key*, int with_AlgCurve); + +#ifdef HAVE_ED25519 + /* private key helpers */ + WOLFSSL_API int wc_Ed25519PrivateKeyDecode(const byte*, word32*, + ed25519_key*, word32); + WOLFSSL_API int wc_Ed25519KeyToDer(ed25519_key* key, byte* output, + word32 inLen); + WOLFSSL_API int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output, + word32 inLen); + + /* public key helper */ + WOLFSSL_API int wc_Ed25519PublicKeyDecode(const byte*, word32*, + ed25519_key*, word32); + #if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) + WOLFSSL_API int wc_Ed25519PublicKeyToDer(ed25519_key*, byte* output, + word32 inLen, int with_AlgCurve); + #endif +#endif + +/* DER encode signature */ +WOLFSSL_API word32 wc_EncodeSignature(byte* out, const byte* digest, + word32 digSz, int hashOID); +WOLFSSL_API int wc_GetCTC_HashOID(int type); + +WOLFSSL_API int wc_GetPkcs8TraditionalOffset(byte* input, + word32* inOutIdx, word32 sz); +WOLFSSL_API int wc_CreatePKCS8Key(byte* out, word32* outSz, + byte* key, word32 keySz, int algoID, const byte* curveOID, word32 oidSz); + +#ifndef NO_ASN_TIME +/* Time */ +/* Returns seconds (Epoch/UTC) + * timePtr: is "time_t", which is typically "long" + * Example: + long lTime; + rc = wc_GetTime(&lTime, (word32)sizeof(lTime)); +*/ +WOLFSSL_API int wc_GetTime(void* timePtr, word32 timeSize); +#endif + +#ifdef WOLFSSL_ENCRYPTED_KEYS + WOLFSSL_API int wc_EncryptedInfoGet(EncryptedInfo* info, + const char* cipherInfo); +#endif + + +#ifdef WOLFSSL_CERT_PIV + +typedef struct _wc_CertPIV { + const byte* cert; + word32 certSz; + const byte* certErrDet; + word32 certErrDetSz; + const byte* nonce; /* Identiv Only */ + word32 nonceSz; /* Identiv Only */ + const byte* signedNonce; /* Identiv Only */ + word32 signedNonceSz; /* Identiv Only */ + + /* flags */ + word16 compression:2; + word16 isX509:1; + word16 isIdentiv:1; +} wc_CertPIV; + +WOLFSSL_API int wc_ParseCertPIV(wc_CertPIV* cert, const byte* buf, word32 totalSz); +#endif /* WOLFSSL_CERT_PIV */ + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLF_CRYPT_ASN_PUBLIC_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/async.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/async.h new file mode 100644 index 0000000..e69de29 diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/blake2-impl.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/blake2-impl.h new file mode 100644 index 0000000..6c43d81 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/blake2-impl.h @@ -0,0 +1,155 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . +*/ +/* blake2-impl.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +#ifndef WOLFCRYPT_BLAKE2_IMPL_H +#define WOLFCRYPT_BLAKE2_IMPL_H + +#include + +static WC_INLINE word32 load32( const void *src ) +{ +#if defined(LITTLE_ENDIAN_ORDER) + return *( word32 * )( src ); +#else + const byte *p = ( byte * )src; + word32 w = *p++; + w |= ( word32 )( *p++ ) << 8; + w |= ( word32 )( *p++ ) << 16; + w |= ( word32 )( *p++ ) << 24; + return w; +#endif +} + +static WC_INLINE word64 load64( const void *src ) +{ +#if defined(LITTLE_ENDIAN_ORDER) + return *( word64 * )( src ); +#else + const byte *p = ( byte * )src; + word64 w = *p++; + w |= ( word64 )( *p++ ) << 8; + w |= ( word64 )( *p++ ) << 16; + w |= ( word64 )( *p++ ) << 24; + w |= ( word64 )( *p++ ) << 32; + w |= ( word64 )( *p++ ) << 40; + w |= ( word64 )( *p++ ) << 48; + w |= ( word64 )( *p++ ) << 56; + return w; +#endif +} + +static WC_INLINE void store32( void *dst, word32 w ) +{ +#if defined(LITTLE_ENDIAN_ORDER) + *( word32 * )( dst ) = w; +#else + byte *p = ( byte * )dst; + *p++ = ( byte )w; w >>= 8; + *p++ = ( byte )w; w >>= 8; + *p++ = ( byte )w; w >>= 8; + *p++ = ( byte )w; +#endif +} + +static WC_INLINE void store64( void *dst, word64 w ) +{ +#if defined(LITTLE_ENDIAN_ORDER) + *( word64 * )( dst ) = w; +#else + byte *p = ( byte * )dst; + *p++ = ( byte )w; w >>= 8; + *p++ = ( byte )w; w >>= 8; + *p++ = ( byte )w; w >>= 8; + *p++ = ( byte )w; w >>= 8; + *p++ = ( byte )w; w >>= 8; + *p++ = ( byte )w; w >>= 8; + *p++ = ( byte )w; w >>= 8; + *p++ = ( byte )w; +#endif +} + +static WC_INLINE word64 load48( const void *src ) +{ + const byte *p = ( const byte * )src; + word64 w = *p++; + w |= ( word64 )( *p++ ) << 8; + w |= ( word64 )( *p++ ) << 16; + w |= ( word64 )( *p++ ) << 24; + w |= ( word64 )( *p++ ) << 32; + w |= ( word64 )( *p++ ) << 40; + return w; +} + +static WC_INLINE void store48( void *dst, word64 w ) +{ + byte *p = ( byte * )dst; + *p++ = ( byte )w; w >>= 8; + *p++ = ( byte )w; w >>= 8; + *p++ = ( byte )w; w >>= 8; + *p++ = ( byte )w; w >>= 8; + *p++ = ( byte )w; w >>= 8; + *p++ = ( byte )w; +} + +static WC_INLINE word32 rotl32( const word32 w, const unsigned c ) +{ + return ( w << c ) | ( w >> ( 32 - c ) ); +} + +static WC_INLINE word64 rotl64( const word64 w, const unsigned c ) +{ + return ( w << c ) | ( w >> ( 64 - c ) ); +} + +static WC_INLINE word32 rotr32( const word32 w, const unsigned c ) +{ + return ( w >> c ) | ( w << ( 32 - c ) ); +} + +static WC_INLINE word64 rotr64( const word64 w, const unsigned c ) +{ + return ( w >> c ) | ( w << ( 64 - c ) ); +} + +/* prevents compiler optimizing out memset() */ +static WC_INLINE void secure_zero_memory( void *v, word64 n ) +{ + volatile byte *p = ( volatile byte * )v; + + while( n-- ) *p++ = 0; +} + +#endif /* WOLFCRYPT_BLAKE2_IMPL_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/blake2-int.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/blake2-int.h new file mode 100644 index 0000000..a63784c --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/blake2-int.h @@ -0,0 +1,184 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . +*/ +/* blake2-int.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + + +#ifndef WOLFCRYPT_BLAKE2_INT_H +#define WOLFCRYPT_BLAKE2_INT_H + +#include + + +#if defined(_MSC_VER) + #define ALIGN(x) __declspec(align(x)) +#elif defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) + #define ALIGN(x) __attribute__((aligned(x))) +#else + #define ALIGN(x) +#endif + + +#if defined(__cplusplus) + extern "C" { +#endif + + enum blake2s_constant + { + BLAKE2S_BLOCKBYTES = 64, + BLAKE2S_OUTBYTES = 32, + BLAKE2S_KEYBYTES = 32, + BLAKE2S_SALTBYTES = 8, + BLAKE2S_PERSONALBYTES = 8 + }; + + enum blake2b_constant + { + BLAKE2B_BLOCKBYTES = 128, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, + BLAKE2B_PERSONALBYTES = 16 + }; + +#pragma pack(push, 1) + typedef struct __blake2s_param + { + byte digest_length; /* 1 */ + byte key_length; /* 2 */ + byte fanout; /* 3 */ + byte depth; /* 4 */ + word32 leaf_length; /* 8 */ + byte node_offset[6];/* 14 */ + byte node_depth; /* 15 */ + byte inner_length; /* 16 */ + /* byte reserved[0]; */ + byte salt[BLAKE2B_SALTBYTES]; /* 24 */ + byte personal[BLAKE2S_PERSONALBYTES]; /* 32 */ + } blake2s_param; + + ALIGN( 32 ) typedef struct __blake2s_state + { + word32 h[8]; + word32 t[2]; + word32 f[2]; + byte buf[2 * BLAKE2S_BLOCKBYTES]; + word32 buflen; + byte last_node; + } blake2s_state ; + + typedef struct __blake2b_param + { + byte digest_length; /* 1 */ + byte key_length; /* 2 */ + byte fanout; /* 3 */ + byte depth; /* 4 */ + word32 leaf_length; /* 8 */ + word64 node_offset; /* 16 */ + byte node_depth; /* 17 */ + byte inner_length; /* 18 */ + byte reserved[14]; /* 32 */ + byte salt[BLAKE2B_SALTBYTES]; /* 48 */ + byte personal[BLAKE2B_PERSONALBYTES]; /* 64 */ + } blake2b_param; + + ALIGN( 64 ) typedef struct __blake2b_state + { + word64 h[8]; + word64 t[2]; + word64 f[2]; + byte buf[2 * BLAKE2B_BLOCKBYTES]; + word64 buflen; + byte last_node; + } blake2b_state; + + typedef struct __blake2sp_state + { + blake2s_state S[8][1]; + blake2s_state R[1]; + byte buf[8 * BLAKE2S_BLOCKBYTES]; + word32 buflen; + } blake2sp_state; + + typedef struct __blake2bp_state + { + blake2b_state S[4][1]; + blake2b_state R[1]; + byte buf[4 * BLAKE2B_BLOCKBYTES]; + word64 buflen; + } blake2bp_state; +#pragma pack(pop) + + /* Streaming API */ + int blake2s_init( blake2s_state *S, const byte outlen ); + int blake2s_init_key( blake2s_state *S, const byte outlen, const void *key, const byte keylen ); + int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); + int blake2s_update( blake2s_state *S, const byte *in, word32 inlen ); + int blake2s_final( blake2s_state *S, byte *out, byte outlen ); + + int blake2b_init( blake2b_state *S, const byte outlen ); + int blake2b_init_key( blake2b_state *S, const byte outlen, const void *key, const byte keylen ); + int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); + int blake2b_update( blake2b_state *S, const byte *in, word64 inlen ); + int blake2b_final( blake2b_state *S, byte *out, byte outlen ); + + int blake2sp_init( blake2sp_state *S, const byte outlen ); + int blake2sp_init_key( blake2sp_state *S, const byte outlen, const void *key, const byte keylen ); + int blake2sp_update( blake2sp_state *S, const byte *in, word32 inlen ); + int blake2sp_final( blake2sp_state *S, byte *out, byte outlen ); + + int blake2bp_init( blake2bp_state *S, const byte outlen ); + int blake2bp_init_key( blake2bp_state *S, const byte outlen, const void *key, const byte keylen ); + int blake2bp_update( blake2bp_state *S, const byte *in, word64 inlen ); + int blake2bp_final( blake2bp_state *S, byte *out, byte outlen ); + + /* Simple API */ + int blake2s( byte *out, const void *in, const void *key, const byte outlen, const word32 inlen, byte keylen ); + int blake2b( byte *out, const void *in, const void *key, const byte outlen, const word64 inlen, byte keylen ); + + int blake2sp( byte *out, const void *in, const void *key, const byte outlen, const word32 inlen, byte keylen ); + int blake2bp( byte *out, const void *in, const void *key, const byte outlen, const word64 inlen, byte keylen ); + + static WC_INLINE int blake2( byte *out, const void *in, const void *key, const byte outlen, const word64 inlen, byte keylen ) + { + return blake2b( out, in, key, outlen, inlen, keylen ); + } + + + +#if defined(__cplusplus) + } +#endif + +#endif /* WOLFCRYPT_BLAKE2_INT_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/blake2.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/blake2.h new file mode 100644 index 0000000..bf34f31 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/blake2.h @@ -0,0 +1,96 @@ +/* blake2.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/blake2.h +*/ + +#ifndef WOLF_CRYPT_BLAKE2_H +#define WOLF_CRYPT_BLAKE2_H + +#include + +#if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S) + +#include + +/* call old functions if using fips for the sake of hmac @wc_fips */ +#ifdef HAVE_FIPS + /* Since hmac can call blake functions provide original calls */ + #define wc_InitBlake2b InitBlake2b + #define wc_Blake2bUpdate Blake2bUpdate + #define wc_Blake2bFinal Blake2bFinal +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +/* in bytes, variable digest size up to 512 bits (64 bytes) */ +enum { +#ifdef HAVE_BLAKE2B + BLAKE2B_ID = WC_HASH_TYPE_BLAKE2B, + BLAKE2B_256 = 32, /* 256 bit type, SSL default */ +#endif +#ifdef HAVE_BLAKE2S + BLAKE2S_ID = WC_HASH_TYPE_BLAKE2S, + BLAKE2S_256 = 32 /* 256 bit type */ +#endif +}; + + +#ifdef HAVE_BLAKE2B +/* BLAKE2b digest */ +typedef struct Blake2b { + blake2b_state S[1]; /* our state */ + word32 digestSz; /* digest size used on init */ +} Blake2b; +#endif + +#ifdef HAVE_BLAKE2S +/* BLAKE2s digest */ +typedef struct Blake2s { + blake2s_state S[1]; /* our state */ + word32 digestSz; /* digest size used on init */ +} Blake2s; +#endif + + +#ifdef HAVE_BLAKE2B +WOLFSSL_API int wc_InitBlake2b(Blake2b*, word32); +WOLFSSL_API int wc_Blake2bUpdate(Blake2b*, const byte*, word32); +WOLFSSL_API int wc_Blake2bFinal(Blake2b*, byte*, word32); +#endif + +#ifdef HAVE_BLAKE2S +WOLFSSL_API int wc_InitBlake2s(Blake2s*, word32); +WOLFSSL_API int wc_Blake2sUpdate(Blake2s*, const byte*, word32); +WOLFSSL_API int wc_Blake2sFinal(Blake2s*, byte*, word32); +#endif + + +#ifdef __cplusplus + } +#endif + +#endif /* HAVE_BLAKE2 || HAVE_BLAKE2S */ +#endif /* WOLF_CRYPT_BLAKE2_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/camellia.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/camellia.h new file mode 100644 index 0000000..612a464 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/camellia.h @@ -0,0 +1,101 @@ +/* camellia.h ver 1.2.0 + * + * Copyright (c) 2006,2007 + * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer as + * the first lines of this file unmodified. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY NTT ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* camellia.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/camellia.h +*/ + + +#ifndef WOLF_CRYPT_CAMELLIA_H +#define WOLF_CRYPT_CAMELLIA_H + +#include + +#ifdef HAVE_CAMELLIA + +#ifdef __cplusplus + extern "C" { +#endif + +enum { + CAMELLIA_BLOCK_SIZE = 16 +}; + +#define CAMELLIA_TABLE_BYTE_LEN 272 +#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / sizeof(word32)) + +typedef word32 KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; + +typedef struct Camellia { + word32 keySz; + KEY_TABLE_TYPE key; + word32 reg[CAMELLIA_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */ + word32 tmp[CAMELLIA_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */ +} Camellia; + + +WOLFSSL_API int wc_CamelliaSetKey(Camellia* cam, + const byte* key, word32 len, const byte* iv); +WOLFSSL_API int wc_CamelliaSetIV(Camellia* cam, const byte* iv); +WOLFSSL_API int wc_CamelliaEncryptDirect(Camellia* cam, byte* out, + const byte* in); +WOLFSSL_API int wc_CamelliaDecryptDirect(Camellia* cam, byte* out, + const byte* in); +WOLFSSL_API int wc_CamelliaCbcEncrypt(Camellia* cam, + byte* out, const byte* in, word32 sz); +WOLFSSL_API int wc_CamelliaCbcDecrypt(Camellia* cam, + byte* out, const byte* in, word32 sz); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_CAMELLIA */ +#endif /* WOLF_CRYPT_CAMELLIA_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/chacha.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/chacha.h new file mode 100644 index 0000000..274a2d9 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/chacha.h @@ -0,0 +1,82 @@ +/* chacha.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/chacha.h +*/ + + +#ifndef WOLF_CRYPT_CHACHA_H +#define WOLF_CRYPT_CHACHA_H + +#include + +#ifdef HAVE_CHACHA + +#ifdef __cplusplus + extern "C" { +#endif + +/* Size of the IV */ +#define CHACHA_IV_WORDS 3 +#define CHACHA_IV_BYTES (CHACHA_IV_WORDS * sizeof(word32)) + +/* Size of ChaCha chunks */ +#define CHACHA_CHUNK_WORDS 16 +#define CHACHA_CHUNK_BYTES (CHACHA_CHUNK_WORDS * sizeof(word32)) + +#ifdef WOLFSSL_X86_64_BUILD +#if defined(USE_INTEL_SPEEDUP) && !defined(NO_CHACHA_ASM) + #define USE_INTEL_CHACHA_SPEEDUP + #define HAVE_INTEL_AVX1 +#endif +#endif + +enum { + CHACHA_ENC_TYPE = WC_CIPHER_CHACHA, /* cipher unique type */ + CHACHA_MAX_KEY_SZ = 32, +}; + +typedef struct ChaCha { + word32 X[CHACHA_CHUNK_WORDS]; /* state of cipher */ +#ifdef HAVE_INTEL_AVX1 + /* vpshufd reads 16 bytes but we only use bottom 4. */ + byte extra[12]; +#endif +} ChaCha; + +/** + * IV(nonce) changes with each record + * counter is for what value the block counter should start ... usually 0 + */ +WOLFSSL_API int wc_Chacha_SetIV(ChaCha* ctx, const byte* inIv, word32 counter); + +WOLFSSL_API int wc_Chacha_Process(ChaCha* ctx, byte* cipher, const byte* plain, + word32 msglen); +WOLFSSL_API int wc_Chacha_SetKey(ChaCha* ctx, const byte* key, word32 keySz); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_CHACHA */ +#endif /* WOLF_CRYPT_CHACHA_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/chacha20_poly1305.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/chacha20_poly1305.h new file mode 100644 index 0000000..aef7254 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/chacha20_poly1305.h @@ -0,0 +1,84 @@ +/* chacha20_poly1305.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +/* This implementation of the ChaCha20-Poly1305 AEAD is based on "ChaCha20 + * and Poly1305 for IETF protocols" (draft-irtf-cfrg-chacha20-poly1305-10): + * https://tools.ietf.org/html/draft-irtf-cfrg-chacha20-poly1305-10 + */ + +/*! + \file wolfssl/wolfcrypt/chacha20_poly1305.h +*/ + +#ifndef WOLF_CRYPT_CHACHA20_POLY1305_H +#define WOLF_CRYPT_CHACHA20_POLY1305_H + +#include + +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + +#ifdef __cplusplus + extern "C" { +#endif + +#define CHACHA20_POLY1305_AEAD_KEYSIZE 32 +#define CHACHA20_POLY1305_AEAD_IV_SIZE 12 +#define CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE 16 + +enum { + CHACHA20_POLY_1305_ENC_TYPE = 8 /* cipher unique type */ +}; + + /* + * The IV for this implementation is 96 bits to give the most flexibility. + * + * Some protocols may have unique per-invocation inputs that are not + * 96-bit in length. For example, IPsec may specify a 64-bit nonce. In + * such a case, it is up to the protocol document to define how to + * transform the protocol nonce into a 96-bit nonce, for example by + * concatenating a constant value. + */ + +WOLFSSL_API +int wc_ChaCha20Poly1305_Encrypt( + const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE], + const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE], + const byte* inAAD, const word32 inAADLen, + const byte* inPlaintext, const word32 inPlaintextLen, + byte* outCiphertext, + byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]); + +WOLFSSL_API +int wc_ChaCha20Poly1305_Decrypt( + const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE], + const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE], + const byte* inAAD, const word32 inAADLen, + const byte* inCiphertext, const word32 inCiphertextLen, + const byte inAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE], + byte* outPlaintext); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_CHACHA && HAVE_POLY1305 */ +#endif /* WOLF_CRYPT_CHACHA20_POLY1305_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/cmac.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/cmac.h new file mode 100644 index 0000000..e361651 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/cmac.h @@ -0,0 +1,97 @@ +/* cmac.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLF_CRYPT_CMAC_H +#define WOLF_CRYPT_CMAC_H + +#include +#include + +#if !defined(NO_AES) && defined(WOLFSSL_CMAC) + +#if defined(HAVE_FIPS) && \ + defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) + #include +#endif /* HAVE_FIPS_VERSION >= 2 */ + +#ifdef __cplusplus + extern "C" { +#endif + +/* avoid redefinition of structs */ +#if !defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + +#ifndef WC_CMAC_TYPE_DEFINED + typedef struct Cmac Cmac; + #define WC_CMAC_TYPE_DEFINED +#endif +struct Cmac { + Aes aes; + byte buffer[AES_BLOCK_SIZE]; /* partially stored block */ + byte digest[AES_BLOCK_SIZE]; /* running digest */ + byte k1[AES_BLOCK_SIZE]; + byte k2[AES_BLOCK_SIZE]; + word32 bufferSz; + word32 totalSz; +}; + + + +typedef enum CmacType { + WC_CMAC_AES = 1 +} CmacType; + +#define WC_CMAC_TAG_MAX_SZ AES_BLOCK_SIZE +#define WC_CMAC_TAG_MIN_SZ (AES_BLOCK_SIZE/4) + +#endif /* HAVE_FIPS */ + +WOLFSSL_API +int wc_InitCmac(Cmac* cmac, + const byte* key, word32 keySz, + int type, void* unused); +WOLFSSL_API +int wc_CmacUpdate(Cmac* cmac, + const byte* in, word32 inSz); +WOLFSSL_API +int wc_CmacFinal(Cmac* cmac, + byte* out, word32* outSz); + +WOLFSSL_API +int wc_AesCmacGenerate(byte* out, word32* outSz, + const byte* in, word32 inSz, + const byte* key, word32 keySz); + +WOLFSSL_API +int wc_AesCmacVerify(const byte* check, word32 checkSz, + const byte* in, word32 inSz, + const byte* key, word32 keySz); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* NO_AES && WOLFSSL_CMAC */ +#endif /* WOLF_CRYPT_CMAC_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/coding.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/coding.h new file mode 100644 index 0000000..07d193b --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/coding.h @@ -0,0 +1,88 @@ +/* coding.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/coding.h +*/ + +#ifndef WOLF_CRYPT_CODING_H +#define WOLF_CRYPT_CODING_H + +#include + +#ifdef __cplusplus + extern "C" { +#endif + + +WOLFSSL_API int Base64_Decode(const byte* in, word32 inLen, byte* out, + word32* outLen); + +#if defined(OPENSSL_EXTRA) || defined(SESSION_CERTS) || defined(WOLFSSL_KEY_GEN) \ + || defined(WOLFSSL_CERT_GEN) || defined(HAVE_WEBSERVER) || !defined(NO_DSA) + #ifndef WOLFSSL_BASE64_ENCODE + #define WOLFSSL_BASE64_ENCODE + #endif +#endif + + +#ifdef WOLFSSL_BASE64_ENCODE + enum Escaped { + WC_STD_ENC = 0, /* normal \n line ending encoding */ + WC_ESC_NL_ENC, /* use escape sequence encoding */ + WC_NO_NL_ENC /* no encoding at all */ + }; /* Encoding types */ + + /* encode isn't */ + WOLFSSL_API + int Base64_Encode(const byte* in, word32 inLen, byte* out, + word32* outLen); + WOLFSSL_API + int Base64_EncodeEsc(const byte* in, word32 inLen, byte* out, + word32* outLen); + WOLFSSL_API + int Base64_Encode_NoNl(const byte* in, word32 inLen, byte* out, + word32* outLen); +#endif + +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \ + defined(HAVE_WEBSERVER) || defined(HAVE_FIPS) || \ + defined(HAVE_ECC_CDH) || defined(HAVE_SELFTEST) || \ + defined(WOLFSSL_ENCRYPTED_KEYS) + #ifndef WOLFSSL_BASE16 + #define WOLFSSL_BASE16 + #endif +#endif + +#ifdef WOLFSSL_BASE16 + WOLFSSL_API + int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen); + WOLFSSL_API + int Base16_Encode(const byte* in, word32 inLen, byte* out, word32* outLen); +#endif + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLF_CRYPT_CODING_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/compress.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/compress.h new file mode 100644 index 0000000..620f775 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/compress.h @@ -0,0 +1,58 @@ +/* compress.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/compress.h +*/ + + +#ifndef WOLF_CRYPT_COMPRESS_H +#define WOLF_CRYPT_COMPRESS_H + +#include + +#ifdef HAVE_LIBZ + +#ifdef __cplusplus + extern "C" { +#endif + + +#define COMPRESS_FIXED 1 + +#define LIBZ_WINBITS_GZIP 16 + + +WOLFSSL_API int wc_Compress(byte*, word32, const byte*, word32, word32); +WOLFSSL_API int wc_Compress_ex(byte* out, word32 outSz, const byte* in, + word32 inSz, word32 flags, word32 windowBits); +WOLFSSL_API int wc_DeCompress(byte*, word32, const byte*, word32); +WOLFSSL_API int wc_DeCompress_ex(byte* out, word32 outSz, const byte* in, + word32 inSz, int windowBits); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* HAVE_LIBZ */ +#endif /* WOLF_CRYPT_COMPRESS_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/cpuid.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/cpuid.h new file mode 100644 index 0000000..4452abc --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/cpuid.h @@ -0,0 +1,62 @@ +/* cpuid.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +#ifndef WOLF_CRYPT_CPUID_H +#define WOLF_CRYPT_CPUID_H + + +#include + + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(WOLFSSL_X86_64_BUILD) || defined(USE_INTEL_SPEEDUP) || \ + defined(WOLFSSL_AESNI) + #define CPUID_AVX1 0x0001 + #define CPUID_AVX2 0x0002 + #define CPUID_RDRAND 0x0004 + #define CPUID_RDSEED 0x0008 + #define CPUID_BMI2 0x0010 /* MULX, RORX */ + #define CPUID_AESNI 0x0020 + #define CPUID_ADX 0x0040 /* ADCX, ADOX */ + + #define IS_INTEL_AVX1(f) ((f) & CPUID_AVX1) + #define IS_INTEL_AVX2(f) ((f) & CPUID_AVX2) + #define IS_INTEL_RDRAND(f) ((f) & CPUID_RDRAND) + #define IS_INTEL_RDSEED(f) ((f) & CPUID_RDSEED) + #define IS_INTEL_BMI2(f) ((f) & CPUID_BMI2) + #define IS_INTEL_AESNI(f) ((f) & CPUID_AESNI) + #define IS_INTEL_ADX(f) ((f) & CPUID_ADX) + + void cpuid_set_flags(void); + word32 cpuid_get_flags(void); +#endif + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* WOLF_CRYPT_CPUID_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/cryptocb.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/cryptocb.h new file mode 100644 index 0000000..389c2d0 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/cryptocb.h @@ -0,0 +1,299 @@ +/* cryptocb.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _WOLF_CRYPTO_CB_H_ +#define _WOLF_CRYPTO_CB_H_ + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/* Defines the Crypto Callback interface version, for compatibility */ +/* Increment this when Crypto Callback interface changes are made */ +#define CRYPTO_CB_VER 2 + + +#ifdef WOLF_CRYPTO_CB + +#ifndef NO_RSA + #include +#endif +#ifdef HAVE_ECC + #include +#endif +#ifndef NO_AES + #include +#endif +#ifndef NO_SHA + #include +#endif +#ifndef NO_SHA256 + #include +#endif +#ifndef NO_HMAC + #include +#endif +#ifndef WC_NO_RNG + #include +#endif +#ifndef NO_DES3 + #include +#endif + + +/* Crypto Information Structure for callbacks */ +typedef struct wc_CryptoInfo { + int algo_type; /* enum wc_AlgoType */ +#if !defined(NO_RSA) || defined(HAVE_ECC) + struct { + int type; /* enum wc_PkType */ + union { + #ifndef NO_RSA + struct { + const byte* in; + word32 inLen; + byte* out; + word32* outLen; + int type; + RsaKey* key; + WC_RNG* rng; + } rsa; + #ifdef WOLFSSL_KEY_GEN + struct { + RsaKey* key; + int size; + long e; + WC_RNG* rng; + } rsakg; + #endif + #endif + #ifdef HAVE_ECC + struct { + WC_RNG* rng; + int size; + ecc_key* key; + int curveId; + } eckg; + struct { + ecc_key* private_key; + ecc_key* public_key; + byte* out; + word32* outlen; + } ecdh; + struct { + const byte* in; + word32 inlen; + byte* out; + word32* outlen; + WC_RNG* rng; + ecc_key* key; + } eccsign; + struct { + const byte* sig; + word32 siglen; + const byte* hash; + word32 hashlen; + int* res; + ecc_key* key; + } eccverify; + #endif + }; + } pk; +#endif /* !NO_RSA || HAVE_ECC */ +#if !defined(NO_AES) || !defined(NO_DES3) + struct { + int type; /* enum wc_CipherType */ + int enc; + union { + #ifdef HAVE_AESGCM + struct { + Aes* aes; + byte* out; + const byte* in; + word32 sz; + const byte* iv; + word32 ivSz; + byte* authTag; + word32 authTagSz; + const byte* authIn; + word32 authInSz; + } aesgcm_enc; + struct { + Aes* aes; + byte* out; + const byte* in; + word32 sz; + const byte* iv; + word32 ivSz; + const byte* authTag; + word32 authTagSz; + const byte* authIn; + word32 authInSz; + } aesgcm_dec; + #endif /* HAVE_AESGCM */ + #ifdef HAVE_AES_CBC + struct { + Aes* aes; + byte* out; + const byte* in; + word32 sz; + } aescbc; + #endif /* HAVE_AES_CBC */ + #ifndef NO_DES3 + struct { + Des3* des; + byte* out; + const byte* in; + word32 sz; + } des3; + #endif + }; + } cipher; +#endif /* !NO_AES || !NO_DES3 */ +#if !defined(NO_SHA) || !defined(NO_SHA256) + struct { + int type; /* enum wc_HashType */ + const byte* in; + word32 inSz; + byte* digest; + union { + #ifndef NO_SHA + wc_Sha* sha1; + #endif + #ifndef NO_SHA256 + wc_Sha256* sha256; + #endif + }; + } hash; +#endif /* !NO_SHA || !NO_SHA256 */ +#ifndef NO_HMAC + struct { + int macType; /* enum wc_HashType */ + const byte* in; + word32 inSz; + byte* digest; + Hmac* hmac; + } hmac; +#endif +#ifndef WC_NO_RNG + struct { + WC_RNG* rng; + byte* out; + word32 sz; + } rng; + struct { + OS_Seed* os; + byte* seed; + word32 sz; + } seed; +#endif +} wc_CryptoInfo; + + +typedef int (*CryptoDevCallbackFunc)(int devId, wc_CryptoInfo* info, void* ctx); + +WOLFSSL_LOCAL void wc_CryptoCb_Init(void); + +WOLFSSL_API int wc_CryptoCb_RegisterDevice(int devId, CryptoDevCallbackFunc cb, void* ctx); +WOLFSSL_API void wc_CryptoCb_UnRegisterDevice(int devId); + +/* old function names */ +#define wc_CryptoDev_RegisterDevice wc_CryptoCb_RegisterDevice +#define wc_CryptoDev_UnRegisterDevice wc_CryptoCb_UnRegisterDevice + + +#ifndef NO_RSA +WOLFSSL_LOCAL int wc_CryptoCb_Rsa(const byte* in, word32 inLen, byte* out, + word32* outLen, int type, RsaKey* key, WC_RNG* rng); + +#ifdef WOLFSSL_KEY_GEN +WOLFSSL_LOCAL int wc_CryptoCb_MakeRsaKey(RsaKey* key, int size, long e, + WC_RNG* rng); +#endif /* WOLFSSL_KEY_GEN */ +#endif /* !NO_RSA */ + +#ifdef HAVE_ECC +WOLFSSL_LOCAL int wc_CryptoCb_MakeEccKey(WC_RNG* rng, int keySize, + ecc_key* key, int curveId); + +WOLFSSL_LOCAL int wc_CryptoCb_Ecdh(ecc_key* private_key, ecc_key* public_key, + byte* out, word32* outlen); + +WOLFSSL_LOCAL int wc_CryptoCb_EccSign(const byte* in, word32 inlen, byte* out, + word32 *outlen, WC_RNG* rng, ecc_key* key); + +WOLFSSL_LOCAL int wc_CryptoCb_EccVerify(const byte* sig, word32 siglen, + const byte* hash, word32 hashlen, int* res, ecc_key* key); +#endif /* HAVE_ECC */ + +#ifndef NO_AES +#ifdef HAVE_AESGCM +WOLFSSL_LOCAL int wc_CryptoCb_AesGcmEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz, const byte* iv, word32 ivSz, + byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz); + +WOLFSSL_LOCAL int wc_CryptoCb_AesGcmDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz, const byte* iv, word32 ivSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); +#endif /* HAVE_AESGCM */ +#ifdef HAVE_AES_CBC +WOLFSSL_LOCAL int wc_CryptoCb_AesCbcEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +WOLFSSL_LOCAL int wc_CryptoCb_AesCbcDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#endif /* HAVE_AES_CBC */ +#endif /* !NO_AES */ + +#ifndef NO_DES3 +WOLFSSL_LOCAL int wc_CryptoCb_Des3Encrypt(Des3* des3, byte* out, + const byte* in, word32 sz); +WOLFSSL_LOCAL int wc_CryptoCb_Des3Decrypt(Des3* des3, byte* out, + const byte* in, word32 sz); +#endif /* !NO_DES3 */ + +#ifndef NO_SHA +WOLFSSL_LOCAL int wc_CryptoCb_ShaHash(wc_Sha* sha, const byte* in, + word32 inSz, byte* digest); +#endif /* !NO_SHA */ + +#ifndef NO_SHA256 +WOLFSSL_LOCAL int wc_CryptoCb_Sha256Hash(wc_Sha256* sha256, const byte* in, + word32 inSz, byte* digest); +#endif /* !NO_SHA256 */ +#ifndef NO_HMAC +WOLFSSL_LOCAL int wc_CryptoCb_Hmac(Hmac* hmac, int macType, const byte* in, + word32 inSz, byte* digest); +#endif /* !NO_HMAC */ + +#ifndef WC_NO_RNG +WOLFSSL_LOCAL int wc_CryptoCb_RandomBlock(WC_RNG* rng, byte* out, word32 sz); +WOLFSSL_LOCAL int wc_CryptoCb_RandomSeed(OS_Seed* os, byte* seed, word32 sz); +#endif + +#endif /* WOLF_CRYPTO_CB */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* _WOLF_CRYPTO_CB_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/curve25519.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/curve25519.h new file mode 100644 index 0000000..5f85fd9 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/curve25519.h @@ -0,0 +1,159 @@ +/* curve25519.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/curve25519.h +*/ + + +#ifndef WOLF_CRYPT_CURVE25519_H +#define WOLF_CRYPT_CURVE25519_H + +#include + +#ifdef HAVE_CURVE25519 + +#include +#include + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#define CURVE25519_KEYSIZE 32 + +/* curve25519 set type */ +typedef struct { + int size; /* The size of the curve in octets */ + const char* name; /* name of this curve */ +} curve25519_set_type; + + +/* ECC point, the internal structure is Little endian + * the mathematical functions used the endianess */ +typedef struct { + byte point[CURVE25519_KEYSIZE]; + #ifdef FREESCALE_LTC_ECC + byte pointY[CURVE25519_KEYSIZE]; + #endif +} ECPoint; + +/* A CURVE25519 Key */ +typedef struct curve25519_key { + int idx; /* Index into the ecc_sets[] for the parameters of + this curve if -1, this key is using user supplied + curve in dp */ + const curve25519_set_type* dp; /* domain parameters, either points to + curves (idx >= 0) or user supplied */ + ECPoint p; /* public key */ + ECPoint k; /* private key */ + +#ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV asyncDev; +#endif +} curve25519_key; + +enum { + EC25519_LITTLE_ENDIAN=0, + EC25519_BIG_ENDIAN=1 +}; + +WOLFSSL_API +int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key); + +WOLFSSL_API +int wc_curve25519_shared_secret(curve25519_key* private_key, + curve25519_key* public_key, + byte* out, word32* outlen); + +WOLFSSL_API +int wc_curve25519_shared_secret_ex(curve25519_key* private_key, + curve25519_key* public_key, + byte* out, word32* outlen, int endian); + +WOLFSSL_API +int wc_curve25519_init(curve25519_key* key); + +WOLFSSL_API +void wc_curve25519_free(curve25519_key* key); + + +/* raw key helpers */ +WOLFSSL_API +int wc_curve25519_import_private(const byte* priv, word32 privSz, + curve25519_key* key); +WOLFSSL_API +int wc_curve25519_import_private_ex(const byte* priv, word32 privSz, + curve25519_key* key, int endian); + +WOLFSSL_API +int wc_curve25519_import_private_raw(const byte* priv, word32 privSz, + const byte* pub, word32 pubSz, curve25519_key* key); +WOLFSSL_API +int wc_curve25519_import_private_raw_ex(const byte* priv, word32 privSz, + const byte* pub, word32 pubSz, + curve25519_key* key, int endian); +WOLFSSL_API +int wc_curve25519_export_private_raw(curve25519_key* key, byte* out, + word32* outLen); +WOLFSSL_API +int wc_curve25519_export_private_raw_ex(curve25519_key* key, byte* out, + word32* outLen, int endian); + +WOLFSSL_API +int wc_curve25519_import_public(const byte* in, word32 inLen, + curve25519_key* key); +WOLFSSL_API +int wc_curve25519_import_public_ex(const byte* in, word32 inLen, + curve25519_key* key, int endian); +WOLFSSL_API +int wc_curve25519_check_public(const byte* pub, word32 pubSz, int endian); + +WOLFSSL_API +int wc_curve25519_export_public(curve25519_key* key, byte* out, word32* outLen); +WOLFSSL_API +int wc_curve25519_export_public_ex(curve25519_key* key, byte* out, + word32* outLen, int endian); + +WOLFSSL_API +int wc_curve25519_export_key_raw(curve25519_key* key, + byte* priv, word32 *privSz, + byte* pub, word32 *pubSz); +WOLFSSL_API +int wc_curve25519_export_key_raw_ex(curve25519_key* key, + byte* priv, word32 *privSz, + byte* pub, word32 *pubSz, + int endian); +/* size helper */ +WOLFSSL_API +int wc_curve25519_size(curve25519_key* key); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_CURVE25519 */ +#endif /* WOLF_CRYPT_CURVE25519_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/des3.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/des3.h new file mode 100644 index 0000000..b6ac1ec --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/des3.h @@ -0,0 +1,158 @@ +/* des3.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/des3.h +*/ + +#ifndef WOLF_CRYPT_DES3_H +#define WOLF_CRYPT_DES3_H + +#include + +#ifndef NO_DES3 + +#if defined(HAVE_FIPS) && \ + defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) + #include +#endif /* HAVE_FIPS_VERSION >= 2 */ + +#if defined(HAVE_FIPS) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) +/* included for fips @wc_fips */ +#include +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +/* these are required for FIPS and non-FIPS */ +enum { + DES_KEY_SIZE = 8, /* des */ + DES3_KEY_SIZE = 24, /* 3 des ede */ + DES_IV_SIZE = 8, /* should be the same as DES_BLOCK_SIZE */ +}; + + +/* avoid redefinition of structs */ +#if !defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif + +enum { + DES_ENC_TYPE = WC_CIPHER_DES, /* cipher unique type */ + DES3_ENC_TYPE = WC_CIPHER_DES3, /* cipher unique type */ + + DES_BLOCK_SIZE = 8, + DES_KS_SIZE = 32, /* internal DES key buffer size */ + + DES_ENCRYPTION = 0, + DES_DECRYPTION = 1 +}; + +#define DES_IVLEN 8 +#define DES_KEYLEN 8 +#define DES3_IVLEN 8 +#define DES3_KEYLEN 24 + + +#if defined(STM32_CRYPTO) +enum { + DES_CBC = 0, + DES_ECB = 1 +}; +#endif + + +/* DES encryption and decryption */ +typedef struct Des { + word32 reg[DES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */ + word32 tmp[DES_BLOCK_SIZE / sizeof(word32)]; /* same */ + word32 key[DES_KS_SIZE]; +} Des; + + +/* DES3 encryption and decryption */ +struct Des3 { + word32 key[3][DES_KS_SIZE]; + word32 reg[DES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */ + word32 tmp[DES_BLOCK_SIZE / sizeof(word32)]; /* same */ +#ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV asyncDev; +#endif +#if defined(WOLF_CRYPTO_CB) || \ + (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)) + word32 devKey[DES3_KEYLEN/sizeof(word32)]; /* raw key */ +#endif +#ifdef WOLF_CRYPTO_CB + int devId; + void* devCtx; +#endif + void* heap; +}; + +#ifndef WC_DES3_TYPE_DEFINED + typedef struct Des3 Des3; + #define WC_DES3_TYPE_DEFINED +#endif +#endif /* HAVE_FIPS */ + + +WOLFSSL_API int wc_Des_SetKey(Des* des, const byte* key, + const byte* iv, int dir); +WOLFSSL_API void wc_Des_SetIV(Des* des, const byte* iv); +WOLFSSL_API int wc_Des_CbcEncrypt(Des* des, byte* out, + const byte* in, word32 sz); +WOLFSSL_API int wc_Des_CbcDecrypt(Des* des, byte* out, + const byte* in, word32 sz); +WOLFSSL_API int wc_Des_EcbEncrypt(Des* des, byte* out, + const byte* in, word32 sz); +WOLFSSL_API int wc_Des3_EcbEncrypt(Des3* des, byte* out, + const byte* in, word32 sz); + +/* ECB decrypt same process as encrypt but with decrypt key */ +#define wc_Des_EcbDecrypt wc_Des_EcbEncrypt +#define wc_Des3_EcbDecrypt wc_Des3_EcbEncrypt + +WOLFSSL_API int wc_Des3_SetKey(Des3* des, const byte* key, + const byte* iv,int dir); +WOLFSSL_API int wc_Des3_SetIV(Des3* des, const byte* iv); +WOLFSSL_API int wc_Des3_CbcEncrypt(Des3* des, byte* out, + const byte* in,word32 sz); +WOLFSSL_API int wc_Des3_CbcDecrypt(Des3* des, byte* out, + const byte* in,word32 sz); + +/* These are only required when using either: + static memory (WOLFSSL_STATIC_MEMORY) or asynchronous (WOLFSSL_ASYNC_CRYPT) */ +WOLFSSL_API int wc_Des3Init(Des3*, void*, int); +WOLFSSL_API void wc_Des3Free(Des3*); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* NO_DES3 */ +#endif /* WOLF_CRYPT_DES3_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/dh.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/dh.h new file mode 100644 index 0000000..0d1b1e3 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/dh.h @@ -0,0 +1,131 @@ +/* dh.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/dh.h +*/ + +#ifndef WOLF_CRYPT_DH_H +#define WOLF_CRYPT_DH_H + +#include + +#ifndef NO_DH + +#if defined(HAVE_FIPS) && \ + defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) + #include +#endif /* HAVE_FIPS_VERSION >= 2 */ + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif +typedef struct DhParams { + #ifdef HAVE_FFDHE_Q + const byte* q; + word32 q_len; + #endif /* HAVE_FFDHE_Q */ + const byte* p; + word32 p_len; + const byte* g; + word32 g_len; +} DhParams; + +/* Diffie-Hellman Key */ +struct DhKey { + mp_int p, g, q; /* group parameters */ + void* heap; +#ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV asyncDev; +#endif +}; + +#ifndef WC_DH_TYPE_DEFINED + typedef struct DhKey DhKey; + #define WC_DH_TYPE_DEFINED +#endif + +#ifdef HAVE_FFDHE_2048 +WOLFSSL_API const DhParams* wc_Dh_ffdhe2048_Get(void); +#endif +#ifdef HAVE_FFDHE_3072 +WOLFSSL_API const DhParams* wc_Dh_ffdhe3072_Get(void); +#endif +#ifdef HAVE_FFDHE_4096 +WOLFSSL_API const DhParams* wc_Dh_ffdhe4096_Get(void); +#endif +#ifdef HAVE_FFDHE_6144 +WOLFSSL_API const DhParams* wc_Dh_ffdhe6144_Get(void); +#endif +#ifdef HAVE_FFDHE_8192 +WOLFSSL_API const DhParams* wc_Dh_ffdhe8192_Get(void); +#endif + +WOLFSSL_API int wc_InitDhKey(DhKey* key); +WOLFSSL_API int wc_InitDhKey_ex(DhKey* key, void* heap, int devId); +WOLFSSL_API int wc_FreeDhKey(DhKey* key); + +WOLFSSL_API int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng, byte* priv, + word32* privSz, byte* pub, word32* pubSz); +WOLFSSL_API int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, + const byte* priv, word32 privSz, const byte* otherPub, + word32 pubSz); + +WOLFSSL_API int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, + word32); +WOLFSSL_API int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, + word32 gSz); +WOLFSSL_API int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, + const byte* g, word32 gSz, const byte* q, word32 qSz); +WOLFSSL_API int wc_DhSetCheckKey(DhKey* key, const byte* p, word32 pSz, + const byte* g, word32 gSz, const byte* q, word32 qSz, + int trusted, WC_RNG* rng); +WOLFSSL_API int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, + word32* pInOutSz, byte* g, word32* gInOutSz); +WOLFSSL_API int wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz); +WOLFSSL_API int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz, + const byte* prime, word32 primeSz); +WOLFSSL_API int wc_DhCheckPubValue(const byte* prime, word32 primeSz, + const byte* pub, word32 pubSz); +WOLFSSL_API int wc_DhCheckPrivKey(DhKey* key, const byte* priv, word32 pubSz); +WOLFSSL_API int wc_DhCheckPrivKey_ex(DhKey* key, const byte* priv, word32 pubSz, + const byte* prime, word32 primeSz); +WOLFSSL_API int wc_DhCheckKeyPair(DhKey* key, const byte* pub, word32 pubSz, + const byte* priv, word32 privSz); +WOLFSSL_API int wc_DhGenerateParams(WC_RNG *rng, int modSz, DhKey *dh); +WOLFSSL_API int wc_DhExportParamsRaw(DhKey* dh, byte* p, word32* pSz, + byte* q, word32* qSz, byte* g, word32* gSz); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* NO_DH */ +#endif /* WOLF_CRYPT_DH_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/dsa.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/dsa.h new file mode 100644 index 0000000..657dc0b --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/dsa.h @@ -0,0 +1,97 @@ +/* dsa.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/dsa.h +*/ + +#ifndef WOLF_CRYPT_DSA_H +#define WOLF_CRYPT_DSA_H + +#include + +#ifndef NO_DSA + +#include +#include + +/* for DSA reverse compatibility */ +#define InitDsaKey wc_InitDsaKey +#define FreeDsaKey wc_FreeDsaKey +#define DsaSign wc_DsaSign +#define DsaVerify wc_DsaVerify +#define DsaPublicKeyDecode wc_DsaPublicKeyDecode +#define DsaPrivateKeyDecode wc_DsaPrivateKeyDecode +#define DsaKeyToDer wc_DsaKeyToDer + +#ifdef __cplusplus + extern "C" { +#endif + + +enum { + DSA_PUBLIC = 0, + DSA_PRIVATE = 1 +}; + +/* DSA */ +typedef struct DsaKey { + mp_int p, q, g, y, x; + int type; /* public or private */ + void* heap; /* memory hint */ +} DsaKey; + +WOLFSSL_API int wc_InitDsaKey(DsaKey* key); +WOLFSSL_API int wc_InitDsaKey_h(DsaKey* key, void* h); +WOLFSSL_API void wc_FreeDsaKey(DsaKey* key); +WOLFSSL_API int wc_DsaSign(const byte* digest, byte* out, + DsaKey* key, WC_RNG* rng); +WOLFSSL_API int wc_DsaVerify(const byte* digest, const byte* sig, + DsaKey* key, int* answer); +WOLFSSL_API int wc_DsaPublicKeyDecode(const byte* input, word32* inOutIdx, + DsaKey*, word32); +WOLFSSL_API int wc_DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, + DsaKey*, word32); +WOLFSSL_API int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen); + +#ifdef WOLFSSL_KEY_GEN +WOLFSSL_API int wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa); +WOLFSSL_API int wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa); +#endif + +/* raw export functions */ +WOLFSSL_API int wc_DsaImportParamsRaw(DsaKey* dsa, const char* p, + const char* q, const char* g); +WOLFSSL_API int wc_DsaImportParamsRawCheck(DsaKey* dsa, const char* p, + const char* q, const char* g, + int trusted, WC_RNG* rng); +WOLFSSL_API int wc_DsaExportParamsRaw(DsaKey* dsa, byte* p, word32* pSz, + byte* q, word32* qSz, byte* g, + word32* gSz); +WOLFSSL_API int wc_DsaExportKeyRaw(DsaKey* dsa, byte* x, word32* xSz, byte* y, + word32* ySz); +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* NO_DSA */ +#endif /* WOLF_CRYPT_DSA_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/ecc.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/ecc.h new file mode 100644 index 0000000..5d2475d --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/ecc.h @@ -0,0 +1,730 @@ +/* ecc.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/ecc.h +*/ + + +#ifndef WOLF_CRYPT_ECC_H +#define WOLF_CRYPT_ECC_H + +#include + +#if defined(HAVE_FIPS) && \ + defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) + #include +#endif /* HAVE_FIPS_VERSION >= 2 */ + +#include +#include + +#ifdef HAVE_X963_KDF + #include +#endif + +#ifdef WOLFSSL_ASYNC_CRYPT + #include + #ifdef WOLFSSL_CERT_GEN + #include + #endif +#endif + +#ifdef WOLFSSL_ATECC508A + #include +#endif /* WOLFSSL_ATECC508A */ + +#if defined(WOLFSSL_CRYPTOCELL) + #include +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Enable curve B parameter if needed */ +#if defined(HAVE_COMP_KEY) || defined(ECC_CACHE_CURVE) + #ifndef USE_ECC_B_PARAM /* Allow someone to force enable */ + #define USE_ECC_B_PARAM + #endif +#endif + + +/* Use this as the key->idx if a custom ecc_set is used for key->dp */ +#define ECC_CUSTOM_IDX (-1) + + +/* Determine max ECC bits based on enabled curves */ +#if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) + #define MAX_ECC_BITS 521 +#elif defined(HAVE_ECC512) + #define MAX_ECC_BITS 512 +#elif defined(HAVE_ECC384) + #define MAX_ECC_BITS 384 +#elif defined(HAVE_ECC320) + #define MAX_ECC_BITS 320 +#elif !defined(NO_ECC256) + #define MAX_ECC_BITS 256 +#elif defined(HAVE_ECC239) + #define MAX_ECC_BITS 239 +#elif defined(HAVE_ECC224) + #define MAX_ECC_BITS 224 +#elif defined(HAVE_ECC192) + #define MAX_ECC_BITS 192 +#elif defined(HAVE_ECC160) + #define MAX_ECC_BITS 160 +#elif defined(HAVE_ECC128) + #define MAX_ECC_BITS 128 +#elif defined(HAVE_ECC112) + #define MAX_ECC_BITS 112 +#endif + +/* calculate max ECC bytes */ +#if ((MAX_ECC_BITS * 2) % 8) == 0 + #define MAX_ECC_BYTES (MAX_ECC_BITS / 8) +#else + /* add byte if not aligned */ + #define MAX_ECC_BYTES ((MAX_ECC_BITS / 8) + 1) +#endif + +#ifndef ECC_MAX_PAD_SZ + /* ECC maximum padding size (when MSB is set extra byte required for R and S) */ + #define ECC_MAX_PAD_SZ 2 +#endif + +enum { + ECC_PUBLICKEY = 1, + ECC_PRIVATEKEY = 2, + ECC_PRIVATEKEY_ONLY = 3, + ECC_MAXNAME = 16, /* MAX CURVE NAME LENGTH */ + SIG_HEADER_SZ = 7, /* ECC signature header size (30 81 87 02 42 [R] 02 42 [S]) */ + ECC_BUFSIZE = 256, /* for exported keys temp buffer */ + ECC_MINSIZE = 20, /* MIN Private Key size */ + ECC_MAXSIZE = 66, /* MAX Private Key size */ + ECC_MAXSIZE_GEN = 74, /* MAX Buffer size required when generating ECC keys*/ + ECC_MAX_OID_LEN = 16, + ECC_MAX_SIG_SIZE= ((MAX_ECC_BYTES * 2) + ECC_MAX_PAD_SZ + SIG_HEADER_SZ), + + /* max crypto hardware size */ +#ifdef WOLFSSL_ATECC508A + ECC_MAX_CRYPTO_HW_SIZE = ATECC_KEY_SIZE, /* from port/atmel/atmel.h */ + ECC_MAX_CRYPTO_HW_PUBKEY_SIZE = (ATECC_KEY_SIZE*2), +#elif defined(PLUTON_CRYPTO_ECC) + ECC_MAX_CRYPTO_HW_SIZE = 32, +#elif defined(WOLFSSL_CRYPTOCELL) + #ifndef CRYPTOCELL_KEY_SIZE + CRYPTOCELL_KEY_SIZE = ECC_MAXSIZE, + #endif + ECC_MAX_CRYPTO_HW_SIZE = CRYPTOCELL_KEY_SIZE, +#endif + + /* point compression type */ + ECC_POINT_COMP_EVEN = 0x02, + ECC_POINT_COMP_ODD = 0x03, + ECC_POINT_UNCOMP = 0x04, + + /* Shamir's dual add constants */ + SHAMIR_PRECOMP_SZ = 16, + +#ifdef HAVE_PKCS11 + ECC_MAX_ID_LEN = 32, +#endif +}; + +/* Curve Types */ +typedef enum ecc_curve_id { + ECC_CURVE_INVALID = -1, + ECC_CURVE_DEF = 0, /* NIST or SECP */ + + /* NIST Prime Curves */ + ECC_SECP192R1, + ECC_PRIME192V2, + ECC_PRIME192V3, + ECC_PRIME239V1, + ECC_PRIME239V2, + ECC_PRIME239V3, + ECC_SECP256R1, + + /* SECP Curves */ + ECC_SECP112R1, + ECC_SECP112R2, + ECC_SECP128R1, + ECC_SECP128R2, + ECC_SECP160R1, + ECC_SECP160R2, + ECC_SECP224R1, + ECC_SECP384R1, + ECC_SECP521R1, + + /* Koblitz */ + ECC_SECP160K1, + ECC_SECP192K1, + ECC_SECP224K1, + ECC_SECP256K1, + + /* Brainpool Curves */ + ECC_BRAINPOOLP160R1, + ECC_BRAINPOOLP192R1, + ECC_BRAINPOOLP224R1, + ECC_BRAINPOOLP256R1, + ECC_BRAINPOOLP320R1, + ECC_BRAINPOOLP384R1, + ECC_BRAINPOOLP512R1, + + /* Twisted Edwards Curves */ +#ifdef HAVE_CURVE25519 + ECC_X25519, +#endif +#ifdef HAVE_X448 + ECC_X448, +#endif + +#ifdef WOLFSSL_CUSTOM_CURVES + ECC_CURVE_CUSTOM, +#endif +} ecc_curve_id; + +#ifdef HAVE_OID_ENCODING +typedef word16 ecc_oid_t; +#else +typedef byte ecc_oid_t; + /* OID encoded with ASN scheme: + first element = (oid[0] * 40) + oid[1] + if any element > 127 then MSB 0x80 indicates additional byte */ +#endif + +/* ECC set type defined a GF(p) curve */ +#ifndef USE_WINDOWS_API +typedef struct ecc_set_type { + int size; /* The size of the curve in octets */ + int id; /* id of this curve */ + const char* name; /* name of this curve */ + const char* prime; /* prime that defines the field, curve is in (hex) */ + const char* Af; /* fields A param (hex) */ + const char* Bf; /* fields B param (hex) */ + const char* order; /* order of the curve (hex) */ + const char* Gx; /* x coordinate of the base point on curve (hex) */ + const char* Gy; /* y coordinate of the base point on curve (hex) */ + const ecc_oid_t* oid; + word32 oidSz; + word32 oidSum; /* sum of encoded OID bytes */ + int cofactor; +} ecc_set_type; +#else +/* MSC does something different with the pointers to the arrays than GCC, + * and it causes the FIPS checksum to fail. In the case of windows builds, + * store everything as arrays instead of pointers to strings. */ + +#define MAX_ECC_NAME 16 +#define MAX_ECC_STRING ((MAX_ECC_BYTES * 2) + 1) + /* The values are stored as text strings. */ + +typedef struct ecc_set_type { + int size; /* The size of the curve in octets */ + int id; /* id of this curve */ + const char name[MAX_ECC_NAME]; /* name of this curve */ + const char prime[MAX_ECC_STRING]; /* prime that defines the field, curve is in (hex) */ + const char Af[MAX_ECC_STRING]; /* fields A param (hex) */ + const char Bf[MAX_ECC_STRING]; /* fields B param (hex) */ + const char order[MAX_ECC_STRING]; /* order of the curve (hex) */ + const char Gx[MAX_ECC_STRING]; /* x coordinate of the base point on curve (hex) */ + const char Gy[MAX_ECC_STRING]; /* y coordinate of the base point on curve (hex) */ + const ecc_oid_t oid[10]; + word32 oidSz; + word32 oidSum; /* sum of encoded OID bytes */ + int cofactor; +} ecc_set_type; +#endif + + +#ifdef ALT_ECC_SIZE + +/* Note on ALT_ECC_SIZE: + * The fast math code uses an array of a fixed size to store the big integers. + * By default, the array is big enough for RSA keys. There is a size, + * FP_MAX_BITS which can be used to make the array smaller when one wants ECC + * but not RSA. Some people want fast math sized for both RSA and ECC, where + * ECC won't use as much as RSA. The flag ALT_ECC_SIZE switches in an alternate + * ecc_point structure that uses an alternate fp_int that has a shorter array + * of fp_digits. + * + * Now, without ALT_ECC_SIZE, the ecc_point has three single item arrays of + * mp_ints for the components of the point. With ALT_ECC_SIZE, the components + * of the point are pointers that are set to each of a three item array of + * alt_fp_ints. While an mp_int will have 4096 bits of digit inside the + * structure, the alt_fp_int will only have 528 bits. A size value was added + * in the ALT case, as well, and is set by mp_init() and alt_fp_init(). The + * functions fp_zero() and fp_copy() use the size parameter. An int needs to + * be initialized before using it instead of just fp_zeroing it, the init will + * call zero. FP_MAX_BITS_ECC defaults to 528, but can be set to change the + * number of bits used in the alternate FP_INT. + * + * Do not enable ALT_ECC_SIZE and disable fast math in the configuration. + */ + +#ifndef USE_FAST_MATH + #error USE_FAST_MATH must be defined to use ALT_ECC_SIZE +#endif + +/* determine max bits required for ECC math */ +#ifndef FP_MAX_BITS_ECC + /* check alignment */ + #if ((MAX_ECC_BITS * 2) % DIGIT_BIT) == 0 + /* max bits is double */ + #define FP_MAX_BITS_ECC (MAX_ECC_BITS * 2) + #else + /* max bits is doubled, plus one digit of fudge */ + #define FP_MAX_BITS_ECC ((MAX_ECC_BITS * 2) + DIGIT_BIT) + #endif +#else + /* verify alignment */ + #if FP_MAX_BITS_ECC % CHAR_BIT + #error FP_MAX_BITS_ECC must be a multiple of CHAR_BIT + #endif +#endif + +/* determine buffer size */ +#define FP_SIZE_ECC (FP_MAX_BITS_ECC/DIGIT_BIT) + + +/* This needs to match the size of the fp_int struct, except the + * fp_digit array will be shorter. */ +typedef struct alt_fp_int { + int used, sign, size; + mp_digit dp[FP_SIZE_ECC]; +} alt_fp_int; +#endif /* ALT_ECC_SIZE */ + +#ifndef WC_ECCKEY_TYPE_DEFINED + typedef struct ecc_key ecc_key; + #define WC_ECCKEY_TYPE_DEFINED +#endif + + +/* A point on an ECC curve, stored in Jacbobian format such that (x,y,z) => + (x/z^2, y/z^3, 1) when interpreted as affine */ +typedef struct { +#ifndef ALT_ECC_SIZE + mp_int x[1]; /* The x coordinate */ + mp_int y[1]; /* The y coordinate */ + mp_int z[1]; /* The z coordinate */ +#else + mp_int* x; /* The x coordinate */ + mp_int* y; /* The y coordinate */ + mp_int* z; /* The z coordinate */ + alt_fp_int xyz[3]; +#endif +#ifdef WOLFSSL_SMALL_STACK_CACHE + ecc_key* key; +#endif +} ecc_point; + +/* ECC Flags */ +enum { + WC_ECC_FLAG_NONE = 0x00, +#ifdef HAVE_ECC_CDH + WC_ECC_FLAG_COFACTOR = 0x01, +#endif +}; + +/* An ECC Key */ +struct ecc_key { + int type; /* Public or Private */ + int idx; /* Index into the ecc_sets[] for the parameters of + this curve if -1, this key is using user supplied + curve in dp */ + int state; + word32 flags; + const ecc_set_type* dp; /* domain parameters, either points to NIST + curves (idx >= 0) or user supplied */ +#ifdef WOLFSSL_CUSTOM_CURVES + int deallocSet; +#endif + void* heap; /* heap hint */ + ecc_point pubkey; /* public key */ + mp_int k; /* private key */ +#ifdef WOLFSSL_ATECC508A + int slot; /* Key Slot Number (-1 unknown) */ + byte pubkey_raw[ECC_MAX_CRYPTO_HW_PUBKEY_SIZE]; +#endif +#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB) + int devId; +#endif +#ifdef WOLFSSL_ASYNC_CRYPT + mp_int* r; /* sign/verify temps */ + mp_int* s; + WC_ASYNC_DEV asyncDev; + #ifdef HAVE_CAVIUM_V + mp_int* e; /* Sign, Verify and Shared Secret */ + mp_int* signK; + #endif + #ifdef WOLFSSL_CERT_GEN + CertSignCtx certSignCtx; /* context info for cert sign (MakeSignature) */ + #endif +#endif /* WOLFSSL_ASYNC_CRYPT */ +#ifdef HAVE_PKCS11 + byte id[ECC_MAX_ID_LEN]; + int idLen; +#endif +#if defined(WOLFSSL_CRYPTOCELL) + ecc_context_t ctx; +#endif + +#ifdef WOLFSSL_ECDSA_SET_K + mp_int *sign_k; +#endif + +#ifdef WOLFSSL_SMALL_STACK_CACHE + mp_int* t1; + mp_int* t2; +#ifdef ALT_ECC_SIZE + mp_int* x; + mp_int* y; + mp_int* z; +#endif +#endif +}; + + +WOLFSSL_ABI WOLFSSL_API ecc_key* wc_ecc_key_new(void*); +WOLFSSL_ABI WOLFSSL_API void wc_ecc_key_free(ecc_key*); + + +/* ECC predefined curve sets */ +extern const ecc_set_type ecc_sets[]; + +WOLFSSL_API +const char* wc_ecc_get_name(int curve_id); + +#ifndef WOLFSSL_ATECC508A + +#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL + #define ECC_API WOLFSSL_API +#else + #define ECC_API WOLFSSL_LOCAL +#endif + +ECC_API int ecc_mul2add(ecc_point* A, mp_int* kA, + ecc_point* B, mp_int* kB, + ecc_point* C, mp_int* a, mp_int* modulus, void* heap); + +ECC_API int ecc_map(ecc_point*, mp_int*, mp_digit); +ECC_API int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, + mp_int* a, mp_int* modulus, mp_digit mp); +ECC_API int ecc_projective_dbl_point(ecc_point* P, ecc_point* R, mp_int* a, + mp_int* modulus, mp_digit mp); + +#endif + +WOLFSSL_API +int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key); +WOLFSSL_ABI WOLFSSL_API +int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id); +WOLFSSL_API +int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut); +WOLFSSL_API +int wc_ecc_check_key(ecc_key* key); +WOLFSSL_API +int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime); + +#ifdef HAVE_ECC_DHE +WOLFSSL_API +int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, + word32* outlen); +WOLFSSL_LOCAL +int wc_ecc_shared_secret_gen(ecc_key* private_key, ecc_point* point, + byte* out, word32 *outlen); +WOLFSSL_API +int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point, + byte* out, word32 *outlen); + +#if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) +#define wc_ecc_shared_secret_ssh wc_ecc_shared_secret +#else +#define wc_ecc_shared_secret_ssh wc_ecc_shared_secret_ex /* For backwards compat */ +#endif + +#endif /* HAVE_ECC_DHE */ + +#ifdef HAVE_ECC_SIGN +WOLFSSL_ABI WOLFSSL_API +int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, + WC_RNG* rng, ecc_key* key); +WOLFSSL_API +int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, + ecc_key* key, mp_int *r, mp_int *s); +#ifdef WOLFSSL_ECDSA_SET_K +WOLFSSL_API +int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key); +#endif +#endif /* HAVE_ECC_SIGN */ + +#ifdef HAVE_ECC_VERIFY +WOLFSSL_API +int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, + word32 hashlen, int* stat, ecc_key* key); +WOLFSSL_API +int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, + word32 hashlen, int* stat, ecc_key* key); +#endif /* HAVE_ECC_VERIFY */ + +WOLFSSL_API +int wc_ecc_init(ecc_key* key); +WOLFSSL_ABI WOLFSSL_API +int wc_ecc_init_ex(ecc_key* key, void* heap, int devId); +#ifdef HAVE_PKCS11 +WOLFSSL_API +int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap, + int devId); +#endif +#ifdef WOLFSSL_CUSTOM_CURVES +WOLFSSL_LOCAL +void wc_ecc_free_curve(const ecc_set_type* curve, void* heap); +#endif +WOLFSSL_ABI WOLFSSL_API +int wc_ecc_free(ecc_key* key); +WOLFSSL_API +int wc_ecc_set_flags(ecc_key* key, word32 flags); +WOLFSSL_API +void wc_ecc_fp_free(void); + +WOLFSSL_API +int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id); + +WOLFSSL_API +int wc_ecc_is_valid_idx(int n); +WOLFSSL_API +int wc_ecc_get_curve_idx(int curve_id); +WOLFSSL_API +int wc_ecc_get_curve_id(int curve_idx); +#define wc_ecc_get_curve_name_from_id wc_ecc_get_name +WOLFSSL_API +int wc_ecc_get_curve_size_from_id(int curve_id); + +WOLFSSL_API +int wc_ecc_get_curve_idx_from_name(const char* curveName); +WOLFSSL_API +int wc_ecc_get_curve_size_from_name(const char* curveName); +WOLFSSL_API +int wc_ecc_get_curve_id_from_name(const char* curveName); +WOLFSSL_API +int wc_ecc_get_curve_id_from_params(int fieldSize, + const byte* prime, word32 primeSz, const byte* Af, word32 AfSz, + const byte* Bf, word32 BfSz, const byte* order, word32 orderSz, + const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor); +WOLFSSL_API +int wc_ecc_get_curve_id_from_dp_params(const ecc_set_type* dp); + +WOLFSSL_API +int wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len); + +WOLFSSL_API const ecc_set_type* wc_ecc_get_curve_params(int curve_idx); + +WOLFSSL_API +ecc_point* wc_ecc_new_point(void); +WOLFSSL_API +ecc_point* wc_ecc_new_point_h(void* h); +WOLFSSL_API +void wc_ecc_del_point(ecc_point* p); +WOLFSSL_API +void wc_ecc_del_point_h(ecc_point* p, void* h); +WOLFSSL_API +int wc_ecc_copy_point(ecc_point* p, ecc_point *r); +WOLFSSL_API +int wc_ecc_cmp_point(ecc_point* a, ecc_point *b); +WOLFSSL_API +int wc_ecc_point_is_at_infinity(ecc_point *p); + +#ifndef WOLFSSL_ATECC508A +WOLFSSL_API +int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, + mp_int* a, mp_int* modulus, int map); +WOLFSSL_LOCAL +int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, + mp_int* a, mp_int* modulus, int map, void* heap); +#endif /* !WOLFSSL_ATECC508A */ + + +#ifdef HAVE_ECC_KEY_EXPORT +/* ASN key helpers */ +WOLFSSL_API +int wc_ecc_export_x963(ecc_key*, byte* out, word32* outLen); +WOLFSSL_API +int wc_ecc_export_x963_ex(ecc_key*, byte* out, word32* outLen, int compressed); + /* extended functionality with compressed option */ +#endif /* HAVE_ECC_KEY_EXPORT */ + +#ifdef HAVE_ECC_KEY_IMPORT +WOLFSSL_API +int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key); +WOLFSSL_API +int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, + int curve_id); +WOLFSSL_API +int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub, + word32 pubSz, ecc_key* key); +WOLFSSL_API +int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz, + const byte* pub, word32 pubSz, ecc_key* key, int curve_id); +WOLFSSL_API +int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen); +WOLFSSL_API +int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz, + byte* out, word32* outlen); +WOLFSSL_API +int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen, + byte* s, word32* sLen); +WOLFSSL_API +int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy, + const char* d, const char* curveName); +WOLFSSL_API +int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy, + const char* d, int curve_id); +WOLFSSL_API +int wc_ecc_import_unsigned(ecc_key* key, byte* qx, byte* qy, + byte* d, int curve_id); +#endif /* HAVE_ECC_KEY_IMPORT */ + +#ifdef HAVE_ECC_KEY_EXPORT +WOLFSSL_API +int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen, + byte* qy, word32* qyLen, byte* d, word32* dLen, + int encType); +WOLFSSL_API +int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen); +WOLFSSL_API +int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen, + byte* qy, word32* qyLen); +WOLFSSL_API +int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen, + byte* qy, word32* qyLen, byte* d, word32* dLen); +#endif /* HAVE_ECC_KEY_EXPORT */ + +#ifdef HAVE_ECC_KEY_EXPORT + +WOLFSSL_API +int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, + byte* out, word32* outLen); +#endif /* HAVE_ECC_KEY_EXPORT */ + + +#ifdef HAVE_ECC_KEY_IMPORT +WOLFSSL_API +int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx, + ecc_point* point); +#endif /* HAVE_ECC_KEY_IMPORT */ + +/* size helper */ +WOLFSSL_API +int wc_ecc_size(ecc_key* key); +WOLFSSL_API +int wc_ecc_sig_size_calc(int sz); +WOLFSSL_API +int wc_ecc_sig_size(ecc_key* key); + +WOLFSSL_API +int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz); + +#ifdef WOLFSSL_CUSTOM_CURVES + WOLFSSL_API + int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp); +#endif + +#ifdef HAVE_ECC_ENCRYPT +/* ecc encrypt */ + +enum ecEncAlgo { + ecAES_128_CBC = 1, /* default */ + ecAES_256_CBC = 2 +}; + +enum ecKdfAlgo { + ecHKDF_SHA256 = 1, /* default */ + ecHKDF_SHA1 = 2 +}; + +enum ecMacAlgo { + ecHMAC_SHA256 = 1, /* default */ + ecHMAC_SHA1 = 2 +}; + +enum { + KEY_SIZE_128 = 16, + KEY_SIZE_256 = 32, + IV_SIZE_64 = 8, + IV_SIZE_128 = 16, + EXCHANGE_SALT_SZ = 16, + EXCHANGE_INFO_SZ = 23 +}; + +enum ecFlags { + REQ_RESP_CLIENT = 1, + REQ_RESP_SERVER = 2 +}; + + +typedef struct ecEncCtx ecEncCtx; + +WOLFSSL_API +ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng); +WOLFSSL_API +ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap); +WOLFSSL_API +void wc_ecc_ctx_free(ecEncCtx*); +WOLFSSL_API +int wc_ecc_ctx_reset(ecEncCtx*, WC_RNG*); /* reset for use again w/o alloc/free */ + +WOLFSSL_API +const byte* wc_ecc_ctx_get_own_salt(ecEncCtx*); +WOLFSSL_API +int wc_ecc_ctx_set_peer_salt(ecEncCtx*, const byte* salt); +WOLFSSL_API +int wc_ecc_ctx_set_info(ecEncCtx*, const byte* info, int sz); + +WOLFSSL_API +int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, + word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx); +WOLFSSL_API +int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, + word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx); + +#endif /* HAVE_ECC_ENCRYPT */ + +#ifdef HAVE_X963_KDF +WOLFSSL_API int wc_X963_KDF(enum wc_HashType type, const byte* secret, + word32 secretSz, const byte* sinfo, word32 sinfoSz, + byte* out, word32 outSz); +#endif + +#ifdef ECC_CACHE_CURVE +WOLFSSL_API int wc_ecc_curve_cache_init(void); +WOLFSSL_API void wc_ecc_curve_cache_free(void); +#endif + +WOLFSSL_API +int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_ECC */ \ No newline at end of file diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/ed25519.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/ed25519.h new file mode 100644 index 0000000..de7c087 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/ed25519.h @@ -0,0 +1,169 @@ +/* ed25519.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/ed25519.h +*/ + + +#ifndef WOLF_CRYPT_ED25519_H +#define WOLF_CRYPT_ED25519_H + +#include + +#ifdef HAVE_ED25519 + +#include +#include +#include +#include + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + +/* info about EdDSA curve specifically ed25519, defined as an elliptic curve + over GF(p) */ +/* + 32, key size + "ED25519", curve name + "2^255-19", prime number + "SHA512", hash function + "-121665/121666", value of d +*/ + +#define ED25519_KEY_SIZE 32 /* private key only */ +#define ED25519_SIG_SIZE 64 + +#define ED25519_PUB_KEY_SIZE 32 /* compressed */ +/* both private and public key */ +#define ED25519_PRV_KEY_SIZE (ED25519_PUB_KEY_SIZE+ED25519_KEY_SIZE) + + +enum { + Ed25519 = -1, + Ed25519ctx = 0, + Ed25519ph = 1, +}; + +#ifndef WC_ED25519KEY_TYPE_DEFINED + typedef struct ed25519_key ed25519_key; + #define WC_ED25519KEY_TYPE_DEFINED +#endif + +/* An ED25519 Key */ +struct ed25519_key { + byte p[ED25519_PUB_KEY_SIZE]; /* compressed public key */ + byte k[ED25519_PRV_KEY_SIZE]; /* private key : 32 secret -- 32 public */ +#ifdef FREESCALE_LTC_ECC + /* uncompressed point coordinates */ + byte pointX[ED25519_KEY_SIZE]; /* recovered X coordinate */ + byte pointY[ED25519_KEY_SIZE]; /* Y coordinate is the public key with The most significant bit of the final octet always zero. */ +#endif + word16 pubKeySet:1; +#ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV asyncDev; +#endif +}; + + +WOLFSSL_API +int wc_ed25519_make_public(ed25519_key* key, unsigned char* pubKey, + word32 pubKeySz); +WOLFSSL_API +int wc_ed25519_make_key(WC_RNG* rng, int keysize, ed25519_key* key); +WOLFSSL_API +int wc_ed25519_sign_msg(const byte* in, word32 inLen, byte* out, + word32 *outLen, ed25519_key* key); +WOLFSSL_API +int wc_ed25519ctx_sign_msg(const byte* in, word32 inLen, byte* out, + word32 *outLen, ed25519_key* key, + const byte* context, byte contextLen); +WOLFSSL_API +int wc_ed25519ph_sign_hash(const byte* hash, word32 hashLen, byte* out, + word32 *outLen, ed25519_key* key, + const byte* context, byte contextLen); +WOLFSSL_API +int wc_ed25519ph_sign_msg(const byte* in, word32 inLen, byte* out, + word32 *outLen, ed25519_key* key, const byte* context, + byte contextLen); +WOLFSSL_API +int wc_ed25519_verify_msg(const byte* sig, word32 sigLen, const byte* msg, + word32 msgLen, int* stat, ed25519_key* key); +WOLFSSL_API +int wc_ed25519ctx_verify_msg(const byte* sig, word32 sigLen, const byte* msg, + word32 msgLen, int* stat, ed25519_key* key, + const byte* context, byte contextLen); +WOLFSSL_API +int wc_ed25519ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash, + word32 hashLen, int* stat, ed25519_key* key, + const byte* context, byte contextLen); +WOLFSSL_API +int wc_ed25519ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg, + word32 msgLen, int* stat, ed25519_key* key, + const byte* context, byte contextLen); +WOLFSSL_API +int wc_ed25519_init(ed25519_key* key); +WOLFSSL_API +void wc_ed25519_free(ed25519_key* key); +WOLFSSL_API +int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key); +WOLFSSL_API +int wc_ed25519_import_private_only(const byte* priv, word32 privSz, + ed25519_key* key); +WOLFSSL_API +int wc_ed25519_import_private_key(const byte* priv, word32 privSz, + const byte* pub, word32 pubSz, ed25519_key* key); +WOLFSSL_API +int wc_ed25519_export_public(ed25519_key*, byte* out, word32* outLen); +WOLFSSL_API +int wc_ed25519_export_private_only(ed25519_key* key, byte* out, word32* outLen); +WOLFSSL_API +int wc_ed25519_export_private(ed25519_key* key, byte* out, word32* outLen); +WOLFSSL_API +int wc_ed25519_export_key(ed25519_key* key, + byte* priv, word32 *privSz, + byte* pub, word32 *pubSz); + +WOLFSSL_API +int wc_ed25519_check_key(ed25519_key* key); + +/* size helper */ +WOLFSSL_API +int wc_ed25519_size(ed25519_key* key); +WOLFSSL_API +int wc_ed25519_priv_size(ed25519_key* key); +WOLFSSL_API +int wc_ed25519_pub_size(ed25519_key* key); +WOLFSSL_API +int wc_ed25519_sig_size(ed25519_key* key); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_ED25519 */ +#endif /* WOLF_CRYPT_ED25519_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/error-crypt.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/error-crypt.h new file mode 100644 index 0000000..a8b8e57 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/error-crypt.h @@ -0,0 +1,253 @@ +/* error-crypt.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/error-crypt.h +*/ + +#ifndef WOLF_CRYPT_ERROR_H +#define WOLF_CRYPT_ERROR_H + +#include + +#if defined(HAVE_FIPS) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) + #include +#endif /* HAVE_FIPS V1 */ + +#ifdef __cplusplus + extern "C" { +#endif + + +/* error codes, add string for new errors !!! */ +enum { + 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 */ + CRYPTGEN_E = -104, /* windows crypt generation error */ + RAN_BLOCK_E = -105, /* reading random device would block */ + BAD_MUTEX_E = -106, /* Bad mutex operation */ + WC_TIMEOUT_E = -107, /* timeout error */ + WC_PENDING_E = -108, /* wolfCrypt operation pending (would block) */ + WC_NOT_PENDING_E = -109, /* wolfCrypt operation not pending */ + + MP_INIT_E = -110, /* mp_init error state */ + MP_READ_E = -111, /* mp_read error state */ + MP_EXPTMOD_E = -112, /* mp_exptmod error state */ + MP_TO_E = -113, /* mp_to_xxx error state, can't convert */ + MP_SUB_E = -114, /* mp_sub error state, can't subtract */ + MP_ADD_E = -115, /* mp_add error state, can't add */ + MP_MUL_E = -116, /* mp_mul error state, can't multiply */ + MP_MULMOD_E = -117, /* mp_mulmod error state, can't multiply mod */ + MP_MOD_E = -118, /* mp_mod error state, can't mod */ + MP_INVMOD_E = -119, /* mp_invmod error state, can't inv mod */ + MP_CMP_E = -120, /* mp_cmp error state */ + MP_ZERO_E = -121, /* got a mp zero result, not expected */ + + MEMORY_E = -125, /* out of memory error */ + VAR_STATE_CHANGE_E = -126, /* var state modified by different thread */ + + RSA_WRONG_TYPE_E = -130, /* RSA wrong block type for RSA function */ + RSA_BUFFER_E = -131, /* RSA buffer error, output too small or + input too large */ + BUFFER_E = -132, /* output buffer too small or input too large */ + ALGO_ID_E = -133, /* setting algo id error */ + PUBLIC_KEY_E = -134, /* setting public key error */ + DATE_E = -135, /* setting date validity error */ + SUBJECT_E = -136, /* setting subject name error */ + ISSUER_E = -137, /* setting issuer name error */ + CA_TRUE_E = -138, /* setting CA basic constraint true error */ + EXTENSIONS_E = -139, /* setting extensions error */ + + ASN_PARSE_E = -140, /* ASN parsing error, invalid input */ + ASN_VERSION_E = -141, /* ASN version error, invalid number */ + ASN_GETINT_E = -142, /* ASN get big int error, invalid data */ + ASN_RSA_KEY_E = -143, /* ASN key init error, invalid input */ + ASN_OBJECT_ID_E = -144, /* ASN object id error, invalid id */ + ASN_TAG_NULL_E = -145, /* ASN tag error, not null */ + ASN_EXPECT_0_E = -146, /* ASN expect error, not zero */ + ASN_BITSTR_E = -147, /* ASN bit string error, wrong id */ + ASN_UNKNOWN_OID_E = -148, /* ASN oid error, unknown sum id */ + ASN_DATE_SZ_E = -149, /* ASN date error, bad size */ + ASN_BEFORE_DATE_E = -150, /* ASN date error, current date before */ + ASN_AFTER_DATE_E = -151, /* ASN date error, current date after */ + ASN_SIG_OID_E = -152, /* ASN signature error, mismatched oid */ + ASN_TIME_E = -153, /* ASN time error, unknown time type */ + ASN_INPUT_E = -154, /* ASN input error, not enough data */ + ASN_SIG_CONFIRM_E = -155, /* ASN sig error, confirm failure */ + ASN_SIG_HASH_E = -156, /* ASN sig error, unsupported hash type */ + ASN_SIG_KEY_E = -157, /* ASN sig error, unsupported key type */ + ASN_DH_KEY_E = -158, /* ASN key init error, invalid input */ + ASN_NTRU_KEY_E = -159, /* ASN ntru key decode error, invalid input */ + ASN_CRIT_EXT_E = -160, /* ASN unsupported critical extension */ + ASN_ALT_NAME_E = -161, /* ASN alternate name error */ + ASN_NO_PEM_HEADER = -162, /* ASN no PEM header found */ + + ECC_BAD_ARG_E = -170, /* ECC input argument of wrong type */ + ASN_ECC_KEY_E = -171, /* ASN ECC bad input */ + ECC_CURVE_OID_E = -172, /* Unsupported ECC OID curve type */ + BAD_FUNC_ARG = -173, /* Bad function argument provided */ + NOT_COMPILED_IN = -174, /* Feature not compiled in */ + UNICODE_SIZE_E = -175, /* Unicode password too big */ + NO_PASSWORD = -176, /* no password provided by user */ + ALT_NAME_E = -177, /* alt name size problem, too big */ + BAD_OCSP_RESPONDER = -178, /* missing key usage extensions */ + + AES_GCM_AUTH_E = -180, /* AES-GCM Authentication check failure */ + AES_CCM_AUTH_E = -181, /* AES-CCM Authentication check failure */ + + ASYNC_INIT_E = -182, /* Async Init type error */ + + COMPRESS_INIT_E = -183, /* Compress init error */ + COMPRESS_E = -184, /* Compress error */ + DECOMPRESS_INIT_E = -185, /* DeCompress init error */ + DECOMPRESS_E = -186, /* DeCompress error */ + + BAD_ALIGN_E = -187, /* Bad alignment for operation, no alloc */ + ASN_NO_SIGNER_E = -188, /* ASN no signer to confirm failure */ + ASN_CRL_CONFIRM_E = -189, /* ASN CRL signature confirm failure */ + ASN_CRL_NO_SIGNER_E = -190, /* ASN CRL no signer to confirm failure */ + ASN_OCSP_CONFIRM_E = -191, /* ASN OCSP signature confirm failure */ + + BAD_STATE_E = -192, /* Bad state operation */ + BAD_PADDING_E = -193, /* Bad padding, msg not correct length */ + + REQ_ATTRIBUTE_E = -194, /* setting cert request attributes error */ + + PKCS7_OID_E = -195, /* PKCS#7, mismatched OID error */ + PKCS7_RECIP_E = -196, /* PKCS#7, recipient error */ + FIPS_NOT_ALLOWED_E = -197, /* FIPS not allowed error */ + ASN_NAME_INVALID_E = -198, /* ASN name constraint error */ + + RNG_FAILURE_E = -199, /* RNG Failed, Reinitialize */ + HMAC_MIN_KEYLEN_E = -200, /* FIPS Mode HMAC Minimum Key Length error */ + RSA_PAD_E = -201, /* RSA Padding Error */ + LENGTH_ONLY_E = -202, /* Returning output length only */ + + IN_CORE_FIPS_E = -203, /* In Core Integrity check failure */ + AES_KAT_FIPS_E = -204, /* AES KAT failure */ + DES3_KAT_FIPS_E = -205, /* DES3 KAT failure */ + HMAC_KAT_FIPS_E = -206, /* HMAC KAT failure */ + RSA_KAT_FIPS_E = -207, /* RSA KAT failure */ + DRBG_KAT_FIPS_E = -208, /* HASH DRBG KAT failure */ + DRBG_CONT_FIPS_E = -209, /* HASH DRBG Continuous test failure */ + AESGCM_KAT_FIPS_E = -210, /* AESGCM KAT failure */ + THREAD_STORE_KEY_E = -211, /* Thread local storage key create failure */ + THREAD_STORE_SET_E = -212, /* Thread local storage key set failure */ + + MAC_CMP_FAILED_E = -213, /* MAC comparison failed */ + IS_POINT_E = -214, /* ECC is point on curve failed */ + ECC_INF_E = -215, /* ECC point infinity error */ + ECC_PRIV_KEY_E = -216, /* ECC private key not valid error */ + ECC_OUT_OF_RANGE_E = -217, /* ECC key component out of range */ + + SRP_CALL_ORDER_E = -218, /* SRP function called in the wrong order. */ + SRP_VERIFY_E = -219, /* SRP proof verification failed. */ + SRP_BAD_KEY_E = -220, /* SRP bad ephemeral values. */ + + ASN_NO_SKID = -221, /* ASN no Subject Key Identifier found */ + ASN_NO_AKID = -222, /* ASN no Authority Key Identifier found */ + ASN_NO_KEYUSAGE = -223, /* ASN no Key Usage found */ + SKID_E = -224, /* setting Subject Key Identifier error */ + AKID_E = -225, /* setting Authority Key Identifier error */ + KEYUSAGE_E = -226, /* Bad Key Usage value */ + CERTPOLICIES_E = -227, /* setting Certificate Policies error */ + + WC_INIT_E = -228, /* wolfcrypt failed to initialize */ + SIG_VERIFY_E = -229, /* wolfcrypt signature verify error */ + BAD_COND_E = -230, /* Bad condition variable operation */ + SIG_TYPE_E = -231, /* Signature Type not enabled/available */ + HASH_TYPE_E = -232, /* Hash Type not enabled/available */ + + WC_KEY_SIZE_E = -234, /* Key size error, either too small or large */ + ASN_COUNTRY_SIZE_E = -235, /* ASN Cert Gen, invalid country code size */ + MISSING_RNG_E = -236, /* RNG required but not provided */ + ASN_PATHLEN_SIZE_E = -237, /* ASN CA path length too large error */ + ASN_PATHLEN_INV_E = -238, /* ASN CA path length inversion error */ + + BAD_KEYWRAP_ALG_E = -239, + BAD_KEYWRAP_IV_E = -240, /* Decrypted AES key wrap IV incorrect */ + WC_CLEANUP_E = -241, /* wolfcrypt cleanup failed */ + ECC_CDH_KAT_FIPS_E = -242, /* ECC CDH Known Answer Test failure */ + DH_CHECK_PUB_E = -243, /* DH Check Pub Key error */ + BAD_PATH_ERROR = -244, /* Bad path for opendir */ + + ASYNC_OP_E = -245, /* Async operation error */ + + ECC_PRIVATEONLY_E = -246, /* Invalid use of private only ECC key*/ + EXTKEYUSAGE_E = -247, /* Bad Extended Key Usage value */ + WC_HW_E = -248, /* Error with hardware crypto use */ + WC_HW_WAIT_E = -249, /* Hardware waiting on resource */ + + PSS_SALTLEN_E = -250, /* PSS length of salt is too long for hash */ + PRIME_GEN_E = -251, /* Failure finding a prime. */ + BER_INDEF_E = -252, /* Cannot decode indefinite length BER. */ + RSA_OUT_OF_RANGE_E = -253, /* Ciphertext to decrypt out of range. */ + RSAPSS_PAT_FIPS_E = -254, /* RSA-PSS PAT failure */ + ECDSA_PAT_FIPS_E = -255, /* ECDSA PAT failure */ + DH_KAT_FIPS_E = -256, /* DH KAT failure */ + AESCCM_KAT_FIPS_E = -257, /* AESCCM KAT failure */ + SHA3_KAT_FIPS_E = -258, /* SHA-3 KAT failure */ + ECDHE_KAT_FIPS_E = -259, /* ECDHE KAT failure */ + AES_GCM_OVERFLOW_E = -260, /* AES-GCM invocation counter overflow. */ + AES_CCM_OVERFLOW_E = -261, /* AES-CCM invocation counter overflow. */ + RSA_KEY_PAIR_E = -262, /* RSA Key Pair-Wise Consistency check fail. */ + DH_CHECK_PRIV_E = -263, /* DH Check Priv Key error */ + + WC_AFALG_SOCK_E = -264, /* AF_ALG socket error */ + WC_DEVCRYPTO_E = -265, /* /dev/crypto error */ + + ZLIB_INIT_ERROR = -266, /* zlib init error */ + ZLIB_COMPRESS_ERROR = -267, /* zlib compression error */ + ZLIB_DECOMPRESS_ERROR = -268, /* zlib decompression error */ + + PKCS7_NO_SIGNER_E = -269, /* No signer in PKCS#7 signed data msg */ + WC_PKCS7_WANT_READ_E= -270, /* PKCS7 operations wants more input */ + + CRYPTOCB_UNAVAILABLE= -271, /* Crypto callback unavailable */ + PKCS7_SIGNEEDS_CHECK= -272, /* signature needs verified by caller */ + PSS_SALTLEN_RECOVER_E=-273, /* PSS slat length not recoverable */ + + WC_LAST_E = -273, /* Update this to indicate last error */ + MIN_CODE_E = -300 /* errors -101 - -299 */ + + /* add new companion error id strings for any new error codes + wolfcrypt/src/error.c !!! */ +}; + + +#ifdef NO_ERROR_STRINGS + #define wc_GetErrorString(error) "no support for error strings built in" + #define wc_ErrorString(err, buf) \ + (void)err; XSTRNCPY((buf), wc_GetErrorString((err)), \ + WOLFSSL_MAX_ERROR_SZ); + +#else +WOLFSSL_API void wc_ErrorString(int err, char* buff); +WOLFSSL_API const char* wc_GetErrorString(int error); +#endif + +#ifdef __cplusplus + } /* extern "C" */ +#endif +#endif /* WOLF_CRYPT_ERROR_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/fe_operations.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/fe_operations.h new file mode 100644 index 0000000..61d17bb --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/fe_operations.h @@ -0,0 +1,210 @@ +/* fe_operations.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLF_CRYPT_FE_OPERATIONS_H +#define WOLF_CRYPT_FE_OPERATIONS_H + +#include + +#if defined(HAVE_CURVE25519) || defined(HAVE_ED25519) + +#if !defined(CURVE25519_SMALL) || !defined(ED25519_SMALL) + #include +#endif + +#include + +#if defined(USE_INTEL_SPEEDUP) && !defined(NO_CURVED25519_X64) + #define CURVED25519_X64 +#elif defined(HAVE___UINT128_T) && !defined(NO_CURVED25519_128BIT) + #define CURVED25519_128BIT +#endif + +#if defined(CURVED25519_X64) + #define CURVED25519_ASM_64BIT + #define CURVED25519_ASM +#endif +#if defined(WOLFSSL_ARMASM) + #ifdef __aarch64__ + #define CURVED25519_ASM_64BIT + #else + #define CURVED25519_ASM_32BIT + #endif + #define CURVED25519_ASM +#endif + +/* +fe means field element. +Here the field is \Z/(2^255-19). +An element t, entries t[0]...t[9], represents the integer +t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. +Bounds on each t[i] vary depending on context. +*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(CURVE25519_SMALL) || defined(ED25519_SMALL) + #define F25519_SIZE 32 + + WOLFSSL_LOCAL void lm_copy(byte*, const byte*); + WOLFSSL_LOCAL void lm_add(byte*, const byte*, const byte*); + WOLFSSL_LOCAL void lm_sub(byte*, const byte*, const byte*); + WOLFSSL_LOCAL void lm_neg(byte*,const byte*); + WOLFSSL_LOCAL void lm_invert(byte*, const byte*); + WOLFSSL_LOCAL void lm_mul(byte*,const byte*,const byte*); +#endif + + +#if !defined(FREESCALE_LTC_ECC) +WOLFSSL_LOCAL void fe_init(void); + +WOLFSSL_LOCAL int curve25519(byte * q, byte * n, byte * p); +#endif + +/* default to be faster but take more memory */ +#if !defined(CURVE25519_SMALL) || !defined(ED25519_SMALL) + +#ifdef CURVED25519_ASM_64BIT + typedef int64_t fe[4]; +#elif defined(CURVED25519_ASM_32BIT) + typedef int32_t fe[8]; +#elif defined(CURVED25519_128BIT) + typedef int64_t fe[5]; +#else + typedef int32_t fe[10]; +#endif + +WOLFSSL_LOCAL void fe_copy(fe, const fe); +WOLFSSL_LOCAL void fe_add(fe, const fe, const fe); +WOLFSSL_LOCAL void fe_neg(fe,const fe); +WOLFSSL_LOCAL void fe_sub(fe, const fe, const fe); +WOLFSSL_LOCAL void fe_invert(fe, const fe); +WOLFSSL_LOCAL void fe_mul(fe,const fe,const fe); + + +/* Based On Daniel J Bernstein's curve25519 and ed25519 Public Domain ref10 + work. */ + +WOLFSSL_LOCAL void fe_0(fe); +WOLFSSL_LOCAL void fe_1(fe); +WOLFSSL_LOCAL int fe_isnonzero(const fe); +WOLFSSL_LOCAL int fe_isnegative(const fe); +WOLFSSL_LOCAL void fe_tobytes(unsigned char *, const fe); +WOLFSSL_LOCAL void fe_sq(fe, const fe); +WOLFSSL_LOCAL void fe_sq2(fe,const fe); +WOLFSSL_LOCAL void fe_frombytes(fe,const unsigned char *); +WOLFSSL_LOCAL void fe_cswap(fe, fe, int); +WOLFSSL_LOCAL void fe_mul121666(fe,fe); +WOLFSSL_LOCAL void fe_cmov(fe,const fe, int); +WOLFSSL_LOCAL void fe_pow22523(fe,const fe); + +/* 64 type needed for SHA512 */ +WOLFSSL_LOCAL uint64_t load_3(const unsigned char *in); +WOLFSSL_LOCAL uint64_t load_4(const unsigned char *in); + +#ifdef CURVED25519_ASM +WOLFSSL_LOCAL void fe_ge_to_p2(fe rx, fe ry, fe rz, const fe px, const fe py, + const fe pz, const fe pt); +WOLFSSL_LOCAL void fe_ge_to_p3(fe rx, fe ry, fe rz, fe rt, const fe px, + const fe py, const fe pz, const fe pt); +WOLFSSL_LOCAL void fe_ge_dbl(fe rx, fe ry, fe rz, fe rt, const fe px, + const fe py, const fe pz); +WOLFSSL_LOCAL void fe_ge_madd(fe rx, fe ry, fe rz, fe rt, const fe px, + const fe py, const fe pz, const fe pt, + const fe qxy2d, const fe qyplusx, + const fe qyminusx); +WOLFSSL_LOCAL void fe_ge_msub(fe rx, fe ry, fe rz, fe rt, const fe px, + const fe py, const fe pz, const fe pt, + const fe qxy2d, const fe qyplusx, + const fe qyminusx); +WOLFSSL_LOCAL void fe_ge_add(fe rx, fe ry, fe rz, fe rt, const fe px, + const fe py, const fe pz, const fe pt, const fe qz, + const fe qt2d, const fe qyplusx, + const fe qyminusx); +WOLFSSL_LOCAL void fe_ge_sub(fe rx, fe ry, fe rz, fe rt, const fe px, + const fe py, const fe pz, const fe pt, const fe qz, + const fe qt2d, const fe qyplusx, + const fe qyminusx); +WOLFSSL_LOCAL void fe_cmov_table(fe* r, fe* base, signed char b); +#endif /* CURVED25519_ASM */ +#endif /* !CURVE25519_SMALL || !ED25519_SMALL */ + +/* Use less memory and only 32bit types or less, but is slower + Based on Daniel Beer's public domain work. */ +#if defined(CURVE25519_SMALL) || defined(ED25519_SMALL) +static const byte c25519_base_x[F25519_SIZE] = {9}; +static const byte f25519_zero[F25519_SIZE] = {0}; +static const byte f25519_one[F25519_SIZE] = {1}; +static const byte fprime_zero[F25519_SIZE] = {0}; +static const byte fprime_one[F25519_SIZE] = {1}; + +WOLFSSL_LOCAL void fe_load(byte *x, word32 c); +WOLFSSL_LOCAL void fe_normalize(byte *x); +WOLFSSL_LOCAL void fe_inv__distinct(byte *r, const byte *x); + +/* Conditional copy. If condition == 0, then zero is copied to dst. If + * condition == 1, then one is copied to dst. Any other value results in + * undefined behavior. + */ +WOLFSSL_LOCAL void fe_select(byte *dst, const byte *zero, const byte *one, + byte condition); + +/* Multiply a point by a small constant. The two pointers are not + * required to be distinct. + * + * The constant must be less than 2^24. + */ +WOLFSSL_LOCAL void fe_mul_c(byte *r, const byte *a, word32 b); +WOLFSSL_LOCAL void fe_mul__distinct(byte *r, const byte *a, const byte *b); + +/* Compute one of the square roots of the field element, if the element + * is square. The other square is -r. + * + * If the input is not square, the returned value is a valid field + * element, but not the correct answer. If you don't already know that + * your element is square, you should square the return value and test. + */ +WOLFSSL_LOCAL void fe_sqrt(byte *r, const byte *x); + +/* Conditional copy. If condition == 0, then zero is copied to dst. If + * condition == 1, then one is copied to dst. Any other value results in + * undefined behavior. + */ +WOLFSSL_LOCAL void fprime_select(byte *dst, const byte *zero, const byte *one, + byte condition); +WOLFSSL_LOCAL void fprime_add(byte *r, const byte *a, const byte *modulus); +WOLFSSL_LOCAL void fprime_sub(byte *r, const byte *a, const byte *modulus); +WOLFSSL_LOCAL void fprime_mul(byte *r, const byte *a, const byte *b, + const byte *modulus); +WOLFSSL_LOCAL void fprime_copy(byte *x, const byte *a); + +#endif /* CURVE25519_SMALL || ED25519_SMALL */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_CURVE25519 || HAVE_ED25519 */ + +#endif /* WOLF_CRYPT_FE_OPERATIONS_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/fips.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/fips.h new file mode 100644 index 0000000..e69de29 diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/fips_test.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/fips_test.h new file mode 100644 index 0000000..1358400 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/fips_test.h @@ -0,0 +1,59 @@ +/* fips_test.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +#ifndef WOLF_CRYPT_FIPS_TEST_H +#define WOLF_CRYPT_FIPS_TEST_H + +#include + + +#ifdef __cplusplus + extern "C" { +#endif + +/* Known Answer Test string inputs are hex, internal */ +WOLFSSL_LOCAL int DoKnownAnswerTests(char*, int); + + +/* FIPS failure callback */ +typedef void(*wolfCrypt_fips_cb)(int ok, int err, const char* hash); + +/* Public set function */ +WOLFSSL_API int wolfCrypt_SetCb_fips(wolfCrypt_fips_cb cbf); + +/* Public get status functions */ +WOLFSSL_API int wolfCrypt_GetStatus_fips(void); +WOLFSSL_API const char* wolfCrypt_GetCoreHash_fips(void); + +#ifdef HAVE_FORCE_FIPS_FAILURE + /* Public function to force failure mode for operational testing */ + WOLFSSL_API int wolfCrypt_SetStatus_fips(int); +#endif + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLF_CRYPT_FIPS_TEST_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/ge_operations.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/ge_operations.h new file mode 100644 index 0000000..69de2fc --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/ge_operations.h @@ -0,0 +1,113 @@ +/* ge_operations.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + /* Based On Daniel J Bernstein's ed25519 Public Domain ref10 work. */ + +#ifndef WOLF_CRYPT_GE_OPERATIONS_H +#define WOLF_CRYPT_GE_OPERATIONS_H + +#include + +#ifdef HAVE_ED25519 + +#include + +/* +ge means group element. + +Here the group is the set of pairs (x,y) of field elements (see fe.h) +satisfying -x^2 + y^2 = 1 + d x^2y^2 +where d = -121665/121666. + +Representations: + ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z + ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT + ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T + ge_precomp (Duif): (y+x,y-x,2dxy) +*/ + +#ifdef ED25519_SMALL + typedef byte ge[F25519_SIZE]; +#elif defined(CURVED25519_ASM_64BIT) + typedef int64_t ge[4]; +#elif defined(CURVED25519_ASM_32BIT) + typedef int32_t ge[8]; +#elif defined(CURVED25519_128BIT) + typedef int64_t ge[5]; +#else + typedef int32_t ge[10]; +#endif + +typedef struct { + ge X; + ge Y; + ge Z; +} ge_p2; + +typedef struct { + ge X; + ge Y; + ge Z; + ge T; +} ge_p3; + + +WOLFSSL_LOCAL int ge_compress_key(byte* out, const byte* xIn, const byte* yIn, + word32 keySz); +WOLFSSL_LOCAL int ge_frombytes_negate_vartime(ge_p3 *,const unsigned char *); + +WOLFSSL_LOCAL int ge_double_scalarmult_vartime(ge_p2 *,const unsigned char *, + const ge_p3 *,const unsigned char *); +WOLFSSL_LOCAL void ge_scalarmult_base(ge_p3 *,const unsigned char *); +WOLFSSL_LOCAL void sc_reduce(byte* s); +WOLFSSL_LOCAL void sc_muladd(byte* s, const byte* a, const byte* b, + const byte* c); +WOLFSSL_LOCAL void ge_tobytes(unsigned char *,const ge_p2 *); +WOLFSSL_LOCAL void ge_p3_tobytes(unsigned char *,const ge_p3 *); + + +#ifndef ED25519_SMALL +typedef struct { + ge X; + ge Y; + ge Z; + ge T; +} ge_p1p1; + +typedef struct { + ge yplusx; + ge yminusx; + ge xy2d; +} ge_precomp; + +typedef struct { + ge YplusX; + ge YminusX; + ge Z; + ge T2d; +} ge_cached; + +#endif /* !ED25519_SMALL */ + +#endif /* HAVE_ED25519 */ + +#endif /* WOLF_CRYPT_GE_OPERATIONS_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/hash.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/hash.h new file mode 100644 index 0000000..4115d60 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/hash.h @@ -0,0 +1,244 @@ +/* hash.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/hash.h +*/ + +#ifndef WOLF_CRYPT_HASH_H +#define WOLF_CRYPT_HASH_H + +#include + +#ifndef NO_MD5 + #include +#endif +#ifndef NO_SHA + #include +#endif +#if defined(WOLFSSL_SHA224) || !defined(NO_SHA256) + #include +#endif +#if defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512) + #include +#endif +#ifdef HAVE_BLAKE2 + #include +#endif +#ifdef WOLFSSL_SHA3 + #include +#endif +#ifndef NO_MD4 + #include +#endif +#ifdef WOLFSSL_MD2 + #include +#endif +#if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S) + #include +#endif + + +#ifdef __cplusplus + extern "C" { +#endif + +#if !defined(HAVE_FIPS) && !defined(NO_OLD_WC_NAMES) + #define MAX_DIGEST_SIZE WC_MAX_DIGEST_SIZE +#endif + + +/* Supported Message Authentication Codes from page 43 */ +enum wc_MACAlgorithm { + no_mac, + md5_mac, + sha_mac, + sha224_mac, + sha256_mac, /* needs to match external KDF_MacAlgorithm */ + sha384_mac, + sha512_mac, + rmd_mac, + blake2b_mac +}; + +enum wc_HashFlags { + WC_HASH_FLAG_NONE = 0x00000000, + WC_HASH_FLAG_WILLCOPY = 0x00000001, /* flag to indicate hash will be copied */ + WC_HASH_FLAG_ISCOPY = 0x00000002, /* hash is copy */ +#ifdef WOLFSSL_SHA3 + WC_HASH_SHA3_KECCAK256 =0x00010000, /* Older KECCAK256 */ +#endif +}; + + +typedef union { + #ifndef NO_MD5 + wc_Md5 md5; + #endif + #ifndef NO_SHA + wc_Sha sha; + #endif + #ifdef WOLFSSL_SHA224 + wc_Sha224 sha224; + #endif + #ifndef NO_SHA256 + wc_Sha256 sha256; + #endif + #ifdef WOLFSSL_SHA384 + wc_Sha384 sha384; + #endif + #ifdef WOLFSSL_SHA512 + wc_Sha512 sha512; + #endif + #ifdef WOLFSSL_SHA3 + wc_Sha3 sha3; + #endif +} wc_HashAlg; + +/* Find largest possible digest size + Note if this gets up to the size of 80 or over check smallstack build */ +#if defined(WOLFSSL_SHA3) + #define WC_MAX_DIGEST_SIZE WC_SHA3_512_DIGEST_SIZE + #define WC_MAX_BLOCK_SIZE WC_SHA3_224_BLOCK_SIZE /* 224 is the largest block size */ +#elif defined(WOLFSSL_SHA512) + #define WC_MAX_DIGEST_SIZE WC_SHA512_DIGEST_SIZE + #define WC_MAX_BLOCK_SIZE WC_SHA512_BLOCK_SIZE +#elif defined(HAVE_BLAKE2) + #define WC_MAX_DIGEST_SIZE BLAKE2B_OUTBYTES + #define WC_MAX_BLOCK_SIZE BLAKE2B_BLOCKBYTES +#elif defined(WOLFSSL_SHA384) + #define WC_MAX_DIGEST_SIZE WC_SHA384_DIGEST_SIZE + #define WC_MAX_BLOCK_SIZE WC_SHA384_BLOCK_SIZE +#elif !defined(NO_SHA256) + #define WC_MAX_DIGEST_SIZE WC_SHA256_DIGEST_SIZE + #define WC_MAX_BLOCK_SIZE WC_SHA256_BLOCK_SIZE +#elif defined(WOLFSSL_SHA224) + #define WC_MAX_DIGEST_SIZE WC_SHA224_DIGEST_SIZE + #define WC_MAX_BLOCK_SIZE WC_SHA224_BLOCK_SIZE +#elif !defined(NO_SHA) + #define WC_MAX_DIGEST_SIZE WC_SHA_DIGEST_SIZE + #define WC_MAX_BLOCK_SIZE WC_SHA_BLOCK_SIZE +#elif !defined(NO_MD5) + #define WC_MAX_DIGEST_SIZE WC_MD5_DIGEST_SIZE + #define WC_MAX_BLOCK_SIZE WC_MD5_BLOCK_SIZE +#else + #define WC_MAX_DIGEST_SIZE 64 /* default to max size of 64 */ + #define WC_MAX_BLOCK_SIZE 128 +#endif + +#if !defined(NO_ASN) || !defined(NO_DH) || defined(HAVE_ECC) +WOLFSSL_API int wc_HashGetOID(enum wc_HashType hash_type); +WOLFSSL_API enum wc_HashType wc_OidGetHash(int oid); +#endif + +WOLFSSL_API enum wc_HashType wc_HashTypeConvert(int hashType); + +WOLFSSL_API int wc_HashGetDigestSize(enum wc_HashType hash_type); +WOLFSSL_API int wc_HashGetBlockSize(enum wc_HashType hash_type); +WOLFSSL_API int wc_Hash(enum wc_HashType hash_type, + const byte* data, word32 data_len, + byte* hash, word32 hash_len); + +/* generic hash operation wrappers */ +WOLFSSL_API int wc_HashInit_ex(wc_HashAlg* hash, enum wc_HashType type, + void* heap, int devId); +WOLFSSL_API int wc_HashInit(wc_HashAlg* hash, enum wc_HashType type); +WOLFSSL_API int wc_HashUpdate(wc_HashAlg* hash, enum wc_HashType type, + const byte* data, word32 dataSz); +WOLFSSL_API int wc_HashFinal(wc_HashAlg* hash, enum wc_HashType type, + byte* out); +WOLFSSL_API int wc_HashFree(wc_HashAlg* hash, enum wc_HashType type); + +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + WOLFSSL_API int wc_HashSetFlags(wc_HashAlg* hash, enum wc_HashType type, + word32 flags); + WOLFSSL_API int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, + word32* flags); +#endif + +#ifndef NO_MD5 +#include +WOLFSSL_API int wc_Md5Hash(const byte* data, word32 len, byte* hash); +#endif + +#ifndef NO_SHA +#include +WOLFSSL_API int wc_ShaHash(const byte*, word32, byte*); +#endif + +#ifdef WOLFSSL_SHA224 +#include +WOLFSSL_API int wc_Sha224Hash(const byte*, word32, byte*); +#endif /* defined(WOLFSSL_SHA224) */ + +#ifndef NO_SHA256 +#include +WOLFSSL_API int wc_Sha256Hash(const byte*, word32, byte*); +#endif + +#ifdef WOLFSSL_SHA384 +#include +WOLFSSL_API int wc_Sha384Hash(const byte*, word32, byte*); +#endif /* defined(WOLFSSL_SHA384) */ + +#ifdef WOLFSSL_SHA512 +#include +WOLFSSL_API int wc_Sha512Hash(const byte*, word32, byte*); +#endif /* WOLFSSL_SHA512 */ + +#ifdef WOLFSSL_SHA3 +#include +WOLFSSL_API int wc_Sha3_224Hash(const byte*, word32, byte*); +WOLFSSL_API int wc_Sha3_256Hash(const byte*, word32, byte*); +WOLFSSL_API int wc_Sha3_384Hash(const byte*, word32, byte*); +WOLFSSL_API int wc_Sha3_512Hash(const byte*, word32, byte*); +#endif /* WOLFSSL_SHA3 */ + +enum max_prf { +#ifdef HAVE_FFDHE_8192 + MAX_PRF_HALF = 516, /* Maximum half secret len */ +#elif defined(HAVE_FFDHE_6144) + MAX_PRF_HALF = 388, /* Maximum half secret len */ +#else + MAX_PRF_HALF = 260, /* Maximum half secret len */ +#endif + MAX_PRF_LABSEED = 128, /* Maximum label + seed len */ + MAX_PRF_DIG = 224 /* Maximum digest len */ +}; + +#ifdef WOLFSSL_HAVE_PRF +WOLFSSL_API int wc_PRF(byte* result, word32 resLen, const byte* secret, + word32 secLen, const byte* seed, word32 seedLen, int hash, + void* heap, int devId); +WOLFSSL_API int wc_PRF_TLSv1(byte* digest, word32 digLen, const byte* secret, + word32 secLen, const byte* label, word32 labLen, + const byte* seed, word32 seedLen, void* heap, int devId); +WOLFSSL_API int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, + word32 secLen, const byte* label, word32 labLen, + const byte* seed, word32 seedLen, int useAtLeastSha256, + int hash_type, void* heap, int devId); +#endif /* WOLFSSL_HAVE_PRF */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLF_CRYPT_HASH_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/hc128.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/hc128.h new file mode 100644 index 0000000..7b81f2e --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/hc128.h @@ -0,0 +1,67 @@ +/* hc128.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/hc128.h +*/ + + +#ifndef WOLF_CRYPT_HC128_H +#define WOLF_CRYPT_HC128_H + +#include + +#ifndef NO_HC128 + +#ifdef __cplusplus + extern "C" { +#endif + +enum { + HC128_ENC_TYPE = WC_CIPHER_HC128, /* cipher unique type */ +}; + +/* HC-128 stream cipher */ +typedef struct HC128 { + word32 T[1024]; /* P[i] = T[i]; Q[i] = T[1024 + i ]; */ + word32 X[16]; + word32 Y[16]; + word32 counter1024; /* counter1024 = i mod 1024 at the ith step */ + word32 key[8]; + word32 iv[8]; +#ifdef XSTREAM_ALIGN + void* heap; /* heap hint, currently XMALLOC only used with aligning */ +#endif +} HC128; + + +WOLFSSL_API int wc_Hc128_Process(HC128*, byte*, const byte*, word32); +WOLFSSL_API int wc_Hc128_SetKey(HC128*, const byte* key, const byte* iv); + +WOLFSSL_LOCAL int wc_Hc128_SetHeap(HC128* ctx, void* heap); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_HC128 */ +#endif /* WOLF_CRYPT_HC128_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/hmac.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/hmac.h new file mode 100644 index 0000000..02a7586 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/hmac.h @@ -0,0 +1,207 @@ +/* hmac.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/hmac.h +*/ + +#ifndef NO_HMAC + +#ifndef WOLF_CRYPT_HMAC_H +#define WOLF_CRYPT_HMAC_H + +#include + +#if defined(HAVE_FIPS) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) +/* for fips @wc_fips */ + #include + #define WC_HMAC_BLOCK_SIZE HMAC_BLOCK_SIZE +#endif + + +#if defined(HAVE_FIPS) && \ + defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) + #include +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +/* avoid redefinition of structs */ +#if !defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif + +#ifndef NO_OLD_WC_NAMES + #define HMAC_BLOCK_SIZE WC_HMAC_BLOCK_SIZE +#endif + +#define WC_HMAC_INNER_HASH_KEYED_SW 1 +#define WC_HMAC_INNER_HASH_KEYED_DEV 2 + +enum { + HMAC_FIPS_MIN_KEY = 14, /* 112 bit key length minimum */ + + IPAD = 0x36, + OPAD = 0x5C, + +/* If any hash is not enabled, add the ID here. */ +#ifdef NO_MD5 + WC_MD5 = WC_HASH_TYPE_MD5, +#endif +#ifdef NO_SHA + WC_SHA = WC_HASH_TYPE_SHA, +#endif +#ifdef NO_SHA256 + WC_SHA256 = WC_HASH_TYPE_SHA256, +#endif +#ifndef WOLFSSL_SHA512 + WC_SHA512 = WC_HASH_TYPE_SHA512, +#endif +#ifndef WOLFSSL_SHA384 + WC_SHA384 = WC_HASH_TYPE_SHA384, +#endif +#ifndef WOLFSSL_SHA224 + WC_SHA224 = WC_HASH_TYPE_SHA224, +#endif +#ifndef WOLFSSL_SHA3 + WC_SHA3_224 = WC_HASH_TYPE_SHA3_224, + WC_SHA3_256 = WC_HASH_TYPE_SHA3_256, + WC_SHA3_384 = WC_HASH_TYPE_SHA3_384, + WC_SHA3_512 = WC_HASH_TYPE_SHA3_512, +#endif +#ifdef HAVE_PKCS11 + HMAC_MAX_ID_LEN = 32, +#endif +}; + +/* Select the largest available hash for the buffer size. */ +#define WC_HMAC_BLOCK_SIZE WC_MAX_BLOCK_SIZE + +#if !defined(WOLFSSL_SHA3) && !defined(WOLFSSL_SHA512) && \ + !defined(WOLFSSL_SHA384) && defined(NO_SHA256) && \ + defined(WOLFSSL_SHA224) && defined(NO_SHA) && defined(NO_MD5) + #error "You have to have some kind of hash if you want to use HMAC." +#endif + + +/* hash union */ +typedef union { +#ifndef NO_MD5 + wc_Md5 md5; +#endif +#ifndef NO_SHA + wc_Sha sha; +#endif +#ifdef WOLFSSL_SHA224 + wc_Sha224 sha224; +#endif +#ifndef NO_SHA256 + wc_Sha256 sha256; +#endif +#ifdef WOLFSSL_SHA384 + wc_Sha384 sha384; +#endif +#ifdef WOLFSSL_SHA512 + wc_Sha512 sha512; +#endif +#ifdef WOLFSSL_SHA3 + wc_Sha3 sha3; +#endif +} Hash; + +/* Hmac digest */ +struct Hmac { + Hash hash; + word32 ipad[WC_HMAC_BLOCK_SIZE / sizeof(word32)]; /* same block size all*/ + word32 opad[WC_HMAC_BLOCK_SIZE / sizeof(word32)]; + word32 innerHash[WC_MAX_DIGEST_SIZE / sizeof(word32)]; + void* heap; /* heap hint */ + byte macType; /* md5 sha or sha256 */ + byte innerHashKeyed; /* keyed flag */ +#ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV asyncDev; +#endif /* WOLFSSL_ASYNC_CRYPT */ +#ifdef WOLF_CRYPTO_CB + int devId; + void* devCtx; + const byte* keyRaw; +#endif +#ifdef HAVE_PKCS11 + byte id[HMAC_MAX_ID_LEN]; + int idLen; +#endif +#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) + word16 keyLen; /* hmac key length (key in ipad) */ +#endif +}; + +#ifndef WC_HMAC_TYPE_DEFINED + typedef struct Hmac Hmac; + #define WC_HMAC_TYPE_DEFINED +#endif + + +#endif /* HAVE_FIPS */ + +/* does init */ +WOLFSSL_API int wc_HmacSetKey(Hmac*, int type, const byte* key, word32 keySz); +WOLFSSL_API int wc_HmacUpdate(Hmac*, const byte*, word32); +WOLFSSL_API int wc_HmacFinal(Hmac*, byte*); +WOLFSSL_API int wc_HmacSizeByType(int type); + +WOLFSSL_API int wc_HmacInit(Hmac* hmac, void* heap, int devId); +WOLFSSL_API int wc_HmacInit_Id(Hmac* hmac, byte* id, int len, void* heap, + int devId); +WOLFSSL_API void wc_HmacFree(Hmac*); + +WOLFSSL_API int wolfSSL_GetHmacMaxSize(void); + +WOLFSSL_LOCAL int _InitHmac(Hmac* hmac, int type, void* heap); + +#ifdef HAVE_HKDF + +WOLFSSL_API int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz, + const byte* inKey, word32 inKeySz, byte* out); +WOLFSSL_API int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz, + const byte* info, word32 infoSz, + byte* out, word32 outSz); + +WOLFSSL_API int wc_HKDF(int type, const byte* inKey, word32 inKeySz, + const byte* salt, word32 saltSz, + const byte* info, word32 infoSz, + byte* out, word32 outSz); + +#endif /* HAVE_HKDF */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLF_CRYPT_HMAC_H */ + +#endif /* NO_HMAC */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/idea.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/idea.h new file mode 100644 index 0000000..706ac3c --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/idea.h @@ -0,0 +1,70 @@ +/* idea.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/idea.h +*/ + +#ifndef WOLF_CRYPT_IDEA_H +#define WOLF_CRYPT_IDEA_H + +#include + +#ifdef HAVE_IDEA + +#ifdef __cplusplus + extern "C" { +#endif + +enum { + IDEA_MODULO = 0x10001, /* 2^16+1 */ + IDEA_2EXP16 = 0x10000, /* 2^16 */ + IDEA_MASK = 0xFFFF, /* 16 bits set to one */ + IDEA_ROUNDS = 8, /* number of rounds for IDEA */ + IDEA_SK_NUM = (6*IDEA_ROUNDS + 4), /* number of subkeys */ + IDEA_KEY_SIZE = 16, /* size of key in bytes */ + IDEA_BLOCK_SIZE = 8, /* size of IDEA blocks in bytes */ + IDEA_IV_SIZE = 8, /* size of IDEA IV in bytes */ + IDEA_ENCRYPTION = 0, + IDEA_DECRYPTION = 1 +}; + +/* IDEA encryption and decryption */ +typedef struct Idea { + word32 reg[IDEA_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */ + word32 tmp[IDEA_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */ + word16 skey[IDEA_SK_NUM]; /* 832 bits expanded key */ +} Idea; + +WOLFSSL_API int wc_IdeaSetKey(Idea *idea, const byte* key, word16 keySz, + const byte *iv, int dir); +WOLFSSL_API int wc_IdeaSetIV(Idea *idea, const byte* iv); +WOLFSSL_API int wc_IdeaCipher(Idea *idea, byte* out, const byte* in); +WOLFSSL_API int wc_IdeaCbcEncrypt(Idea *idea, byte* out, + const byte* in, word32 len); +WOLFSSL_API int wc_IdeaCbcDecrypt(Idea *idea, byte* out, + const byte* in, word32 len); +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_IDEA */ +#endif /* WOLF_CRYPT_IDEA_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/include.am b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/include.am new file mode 100644 index 0000000..56f5efe --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/include.am @@ -0,0 +1,137 @@ +# vim:ft=automake +# All paths should be given relative to the root + +nobase_include_HEADERS+= \ + wolfssl/wolfcrypt/aes.h \ + wolfssl/wolfcrypt/arc4.h \ + wolfssl/wolfcrypt/asn.h \ + wolfssl/wolfcrypt/asn_public.h \ + wolfssl/wolfcrypt/poly1305.h \ + wolfssl/wolfcrypt/camellia.h \ + wolfssl/wolfcrypt/cmac.h \ + wolfssl/wolfcrypt/coding.h \ + wolfssl/wolfcrypt/compress.h \ + wolfssl/wolfcrypt/des3.h \ + wolfssl/wolfcrypt/dh.h \ + wolfssl/wolfcrypt/dsa.h \ + wolfssl/wolfcrypt/ecc.h \ + wolfssl/wolfcrypt/curve25519.h \ + wolfssl/wolfcrypt/ed25519.h \ + wolfssl/wolfcrypt/fe_operations.h \ + wolfssl/wolfcrypt/ge_operations.h \ + wolfssl/wolfcrypt/error-crypt.h \ + wolfssl/wolfcrypt/fips_test.h \ + wolfssl/wolfcrypt/hash.h \ + wolfssl/wolfcrypt/hc128.h \ + wolfssl/wolfcrypt/hmac.h \ + wolfssl/wolfcrypt/integer.h \ + wolfssl/wolfcrypt/md2.h \ + wolfssl/wolfcrypt/md4.h \ + wolfssl/wolfcrypt/md5.h \ + wolfssl/wolfcrypt/misc.h \ + wolfssl/wolfcrypt/pkcs7.h \ + wolfssl/wolfcrypt/wc_encrypt.h \ + wolfssl/wolfcrypt/wc_port.h \ + wolfssl/wolfcrypt/pwdbased.h \ + wolfssl/wolfcrypt/rabbit.h \ + wolfssl/wolfcrypt/chacha.h \ + wolfssl/wolfcrypt/chacha20_poly1305.h \ + wolfssl/wolfcrypt/random.h \ + wolfssl/wolfcrypt/ripemd.h \ + wolfssl/wolfcrypt/rsa.h \ + wolfssl/wolfcrypt/settings.h \ + wolfssl/wolfcrypt/sha256.h \ + wolfssl/wolfcrypt/sha512.h \ + wolfssl/wolfcrypt/sha.h \ + wolfssl/wolfcrypt/signature.h \ + wolfssl/wolfcrypt/blake2.h \ + wolfssl/wolfcrypt/blake2-int.h \ + wolfssl/wolfcrypt/blake2-impl.h \ + wolfssl/wolfcrypt/tfm.h \ + wolfssl/wolfcrypt/srp.h \ + wolfssl/wolfcrypt/idea.h \ + wolfssl/wolfcrypt/types.h \ + wolfssl/wolfcrypt/visibility.h \ + wolfssl/wolfcrypt/logging.h \ + wolfssl/wolfcrypt/memory.h \ + wolfssl/wolfcrypt/mpi_class.h \ + wolfssl/wolfcrypt/mpi_superclass.h \ + wolfssl/wolfcrypt/mem_track.h \ + wolfssl/wolfcrypt/wolfevent.h \ + wolfssl/wolfcrypt/pkcs12.h \ + wolfssl/wolfcrypt/wolfmath.h \ + wolfssl/wolfcrypt/sha3.h \ + wolfssl/wolfcrypt/cpuid.h \ + wolfssl/wolfcrypt/cryptocb.h + +noinst_HEADERS+= \ + wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h \ + wolfssl/wolfcrypt/port/ti/ti-hash.h \ + wolfssl/wolfcrypt/port/ti/ti-ccm.h \ + wolfssl/wolfcrypt/port/nrf51.h \ + wolfssl/wolfcrypt/port/nxp/ksdk_port.h \ + wolfssl/wolfcrypt/port/xilinx/xil-sha3.h \ + wolfssl/wolfcrypt/port/caam/caam_driver.h \ + wolfssl/wolfcrypt/port/caam/wolfcaam.h \ + wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h \ + wolfssl/wolfcrypt/port/st/stm32.h \ + wolfssl/wolfcrypt/port/st/stsafe.h \ + wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h \ + wolfssl/wolfcrypt/port/arm/cryptoCell.h \ + wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h + +if BUILD_CRYPTOAUTHLIB +nobase_include_HEADERS+= wolfssl/wolfcrypt/port/atmel/atmel.h +endif + +if BUILD_AFALG +nobase_include_HEADERS+= wolfssl/wolfcrypt/port/af_alg/afalg_hash.h +nobase_include_HEADERS+= wolfssl/wolfcrypt/port/af_alg/wc_afalg.h +endif + +if BUILD_DEVCRYPTO +nobase_include_HEADERS+= wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h +endif + +if BUILD_ASYNCCRYPT +nobase_include_HEADERS+= wolfssl/wolfcrypt/async.h +endif + +if BUILD_PKCS11 +nobase_include_HEADERS+= wolfssl/wolfcrypt/wc_pkcs11.h +nobase_include_HEADERS+= wolfssl/wolfcrypt/pkcs11.h +endif + +if BUILD_CAVIUM +nobase_include_HEADERS+= wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h +endif + +if BUILD_OCTEON_SYNC +nobase_include_HEADERS+= wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h +endif + +if BUILD_INTEL_QA +nobase_include_HEADERS+= wolfssl/wolfcrypt/port/intel/quickassist.h +nobase_include_HEADERS+= wolfssl/wolfcrypt/port/intel/quickassist_mem.h +endif + +if BUILD_INTEL_QA_SYNC +nobase_include_HEADERS+= wolfssl/wolfcrypt/port/intel/quickassist_sync.h +endif + +if BUILD_SP +nobase_include_HEADERS+= wolfssl/wolfcrypt/sp.h +nobase_include_HEADERS+= wolfssl/wolfcrypt/sp_int.h +endif + +if BUILD_SELFTEST +nobase_include_HEADERS+= wolfssl/wolfcrypt/selftest.h +endif + +if BUILD_FIPS_V2 +nobase_include_HEADERS+= wolfssl/wolfcrypt/fips.h +endif + +if BUILD_FIPS_RAND +nobase_include_HEADERS+= wolfssl/wolfcrypt/fips.h +endif diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/integer.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/integer.h new file mode 100644 index 0000000..406b34e --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/integer.h @@ -0,0 +1,405 @@ +/* integer.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +/* + * Based on public domain LibTomMath 0.38 by Tom St Denis, tomstdenis@iahu.ca, + * http://math.libtomcrypt.com + */ + + +#ifndef WOLF_CRYPT_INTEGER_H +#define WOLF_CRYPT_INTEGER_H + +/* may optionally use fast math instead, not yet supported on all platforms and + may not be faster on all +*/ +#include /* will set MP_xxBIT if not default */ +#ifdef WOLFSSL_SP_MATH + #include +#elif defined(USE_FAST_MATH) + #include +#else + +#include + +#ifndef CHAR_BIT + #include +#endif + +#include + + +#ifdef __cplusplus +extern "C" { + +/* C++ compilers don't like assigning void * to mp_digit * */ +#define OPT_CAST(x) (x *) + +#elif defined(_SH3) + +/* SuperH SH3 compiler doesn't like assigning voi* to mp_digit* */ +#define OPT_CAST(x) (x *) + +#else + +/* C on the other hand doesn't care */ +#define OPT_CAST(x) + +#endif /* __cplusplus */ + + +/* detect 64-bit mode if possible */ +#if defined(__x86_64__) && !(defined (_MSC_VER) && defined(__clang__)) + #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT)) + #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 + + +/* allow user to define on mp_digit, mp_word, DIGIT_BIT types */ +#ifndef WOLFSSL_BIGINT_TYPES + +/* some default configurations. + * + * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits + * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits + * + * At the very least a mp_digit must be able to hold 7 bits + * [any size beyond that is ok provided it doesn't overflow the data type] + */ +#ifdef MP_8BIT + /* 8-bit */ + typedef unsigned char mp_digit; + typedef unsigned short mp_word; + /* don't define DIGIT_BIT, so its calculated below */ +#elif defined(MP_16BIT) + /* 16-bit */ + typedef unsigned int mp_digit; + typedef unsigned long mp_word; + /* don't define DIGIT_BIT, so its calculated below */ +#elif defined(NO_64BIT) + /* 32-bit forced to 16-bit */ + typedef unsigned short mp_digit; + typedef unsigned int mp_word; + #define DIGIT_BIT 12 +#elif defined(MP_64BIT) + /* 64-bit */ + /* for GCC only on supported platforms */ + typedef unsigned long long mp_digit; /* 64 bit type, 128 uses mode(TI) */ + typedef unsigned long mp_word __attribute__ ((mode(TI))); + #define DIGIT_BIT 60 +#else + /* 32-bit default case */ + + #if defined(_MSC_VER) || defined(__BORLANDC__) + typedef unsigned __int64 ulong64; + #else + typedef unsigned long long ulong64; + #endif + + typedef unsigned int mp_digit; /* long could be 64 now, changed TAO */ + typedef ulong64 mp_word; + + #ifdef MP_31BIT + /* this is an extension that uses 31-bit digits */ + #define DIGIT_BIT 31 + #else + /* default case is 28-bit digits, defines MP_28BIT as a handy test macro */ + #define DIGIT_BIT 28 + #define MP_28BIT + #endif +#endif + +#endif /* WOLFSSL_BIGINT_TYPES */ + +/* otherwise the bits per digit is calculated automatically from the size of + a mp_digit */ +#ifndef DIGIT_BIT + #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) + /* bits per digit */ +#endif + +#define MP_DIGIT_BIT DIGIT_BIT +#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) +#define MP_DIGIT_MAX MP_MASK + +/* equalities */ +#define MP_LT -1 /* less than */ +#define MP_EQ 0 /* equal to */ +#define MP_GT 1 /* greater than */ + +#define MP_ZPOS 0 /* positive integer */ +#define MP_NEG 1 /* negative */ + +#define MP_OKAY 0 /* ok result */ +#define MP_MEM -2 /* out of mem */ +#define MP_VAL -3 /* invalid input */ +#define MP_NOT_INF -4 /* point not at infinity */ +#define MP_RANGE MP_NOT_INF + +#define MP_YES 1 /* yes response */ +#define MP_NO 0 /* no response */ + +/* Primality generation flags */ +#define LTM_PRIME_BBS 0x0001 /* BBS style prime */ +#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */ +#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */ + +typedef int mp_err; + +/* define this to use lower memory usage routines (exptmods mostly) */ +#define MP_LOW_MEM + +/* default precision */ +#ifndef MP_PREC + #ifndef MP_LOW_MEM + #define MP_PREC 32 /* default digits of precision */ + #else + #define MP_PREC 1 /* default digits of precision */ + #endif +#endif + +/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - + BITS_PER_DIGIT*2) */ +#define MP_WARRAY ((mp_word)1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1)) + +#ifdef HAVE_WOLF_BIGINT + /* raw big integer */ + typedef struct WC_BIGINT { + byte* buf; + word32 len; + void* heap; + } WC_BIGINT; + #define WOLF_BIGINT_DEFINED +#endif + +/* the mp_int structure */ +typedef struct mp_int { + int used, alloc, sign; + mp_digit *dp; + +#ifdef HAVE_WOLF_BIGINT + struct WC_BIGINT raw; /* unsigned binary (big endian) */ +#endif +} mp_int; + +/* wolf big int and common functions */ +#include + + +/* callback for mp_prime_random, should fill dst with random bytes and return + how many read [up to len] */ +typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); + + +#define USED(m) ((m)->used) +#define DIGIT(m,k) ((m)->dp[(k)]) +#define SIGN(m) ((m)->sign) + + +/* ---> Basic Manipulations <--- */ +#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) +#define mp_isone(a) \ + (((((a)->used == 1)) && ((a)->dp[0] == 1u)) ? MP_YES : MP_NO) +#define mp_iseven(a) \ + (((a)->used > 0 && (((a)->dp[0] & 1u) == 0u)) ? MP_YES : MP_NO) +#define mp_isodd(a) \ + (((a)->used > 0 && (((a)->dp[0] & 1u) == 1u)) ? MP_YES : MP_NO) +#define mp_isneg(a) (((a)->sign != MP_ZPOS) ? MP_YES : MP_NO) + +/* number of primes */ +#ifdef MP_8BIT + #define PRIME_SIZE 31 +#else + #define PRIME_SIZE 256 +#endif + +#ifndef MAX_INVMOD_SZ + #if defined(WOLFSSL_MYSQL_COMPATIBLE) + #define MAX_INVMOD_SZ 8192 + #else + #define MAX_INVMOD_SZ 4096 + #endif +#endif + +#define mp_prime_random(a, t, size, bbs, cb, dat) \ + mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat) + +#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) +#define mp_raw_size(mp) mp_signed_bin_size(mp) +#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) +#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) +#define mp_mag_size(mp) mp_unsigned_bin_size(mp) +#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) + +#define MP_RADIX_BIN 2 +#define MP_RADIX_OCT 8 +#define MP_RADIX_DEC 10 +#define MP_RADIX_HEX 16 +#define MP_RADIX_MAX 64 + +#define mp_tobinary(M, S) mp_toradix((M), (S), MP_RADIX_BIN) +#define mp_tooctal(M, S) mp_toradix((M), (S), MP_RADIX_OCT) +#define mp_todecimal(M, S) mp_toradix((M), (S), MP_RADIX_DEC) +#define mp_tohex(M, S) mp_toradix((M), (S), MP_RADIX_HEX) + +#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1) + +#if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \ + defined(WOLFSSL_DEBUG_MATH) || defined(DEBUG_WOLFSSL) +extern const char *mp_s_rmap; +#endif + +/* 6 functions needed by Rsa */ +MP_API int mp_init (mp_int * a); +MP_API void mp_clear (mp_int * a); +MP_API void mp_free (mp_int * a); +MP_API void mp_forcezero(mp_int * a); +MP_API int mp_unsigned_bin_size(mp_int * a); +MP_API int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c); +MP_API int mp_to_unsigned_bin_at_pos(int x, mp_int *t, unsigned char *b); +MP_API int mp_to_unsigned_bin (mp_int * a, unsigned char *b); +MP_API int mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c); +MP_API int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y); +MP_API int mp_exptmod_ex (mp_int * G, mp_int * X, int digits, mp_int * P, + mp_int * Y); +/* end functions needed by Rsa */ + +/* functions added to support above needed, removed TOOM and KARATSUBA */ +MP_API int mp_count_bits (mp_int * a); +MP_API int mp_leading_bit (mp_int * a); +MP_API int mp_init_copy (mp_int * a, mp_int * b); +MP_API int mp_copy (mp_int * a, mp_int * b); +MP_API int mp_grow (mp_int * a, int size); +MP_API int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d); +MP_API void mp_zero (mp_int * a); +MP_API void mp_clamp (mp_int * a); +MP_API void mp_exch (mp_int * a, mp_int * b); +MP_API void mp_rshd (mp_int * a, int b); +MP_API void mp_rshb (mp_int * a, int b); +MP_API int mp_mod_2d (mp_int * a, int b, mp_int * c); +MP_API int mp_mul_2d (mp_int * a, int b, mp_int * c); +MP_API int mp_lshd (mp_int * a, int b); +MP_API int mp_abs (mp_int * a, mp_int * b); +MP_API int mp_invmod (mp_int * a, mp_int * b, mp_int * c); +int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c); +MP_API int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c); +MP_API int mp_cmp_mag (mp_int * a, mp_int * b); +MP_API int mp_cmp (mp_int * a, mp_int * b); +MP_API int mp_cmp_d(mp_int * a, mp_digit b); +MP_API int mp_set (mp_int * a, mp_digit b); +MP_API int mp_is_bit_set (mp_int * a, mp_digit b); +MP_API int mp_mod (mp_int * a, mp_int * b, mp_int * c); +MP_API int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d); +MP_API int mp_div_2(mp_int * a, mp_int * b); +MP_API int mp_add (mp_int * a, mp_int * b, mp_int * c); +int s_mp_add (mp_int * a, mp_int * b, mp_int * c); +int s_mp_sub (mp_int * a, mp_int * b, mp_int * c); +MP_API int mp_sub (mp_int * a, mp_int * b, mp_int * c); +MP_API int mp_reduce_is_2k_l(mp_int *a); +MP_API int mp_reduce_is_2k(mp_int *a); +MP_API int mp_dr_is_modulus(mp_int *a); +MP_API int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, + int); +MP_API int mp_exptmod_base_2 (mp_int * X, mp_int * P, mp_int * Y); +MP_API int mp_montgomery_setup (mp_int * n, mp_digit * rho); +int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho); +MP_API int mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho); +MP_API void mp_dr_setup(mp_int *a, mp_digit *d); +MP_API int mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k); +MP_API int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d); +int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs); +int s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs); +MP_API int mp_reduce_2k_setup_l(mp_int *a, mp_int *d); +MP_API int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d); +MP_API int mp_reduce (mp_int * x, mp_int * m, mp_int * mu); +MP_API int mp_reduce_setup (mp_int * a, mp_int * b); +int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode); +MP_API int mp_montgomery_calc_normalization (mp_int * a, mp_int * b); +int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs); +int s_mp_sqr (mp_int * a, mp_int * b); +int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs); +int fast_s_mp_sqr (mp_int * a, mp_int * b); +MP_API int mp_init_size (mp_int * a, int size); +MP_API int mp_div_3 (mp_int * a, mp_int *c, mp_digit * d); +MP_API int mp_mul_2(mp_int * a, mp_int * b); +MP_API int mp_mul (mp_int * a, mp_int * b, mp_int * c); +MP_API int mp_sqr (mp_int * a, mp_int * b); +MP_API int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d); +MP_API int mp_submod (mp_int* a, mp_int* b, mp_int* c, mp_int* d); +MP_API int mp_addmod (mp_int* a, mp_int* b, mp_int* c, mp_int* d); +MP_API int mp_mul_d (mp_int * a, mp_digit b, mp_int * c); +MP_API int mp_2expt (mp_int * a, int b); +MP_API int mp_set_bit (mp_int * a, int b); +MP_API int mp_reduce_2k_setup(mp_int *a, mp_digit *d); +MP_API int mp_add_d (mp_int* a, mp_digit b, mp_int* c); +MP_API int mp_set_int (mp_int * a, unsigned long b); +MP_API int mp_sub_d (mp_int * a, mp_digit b, mp_int * c); +/* end support added functions */ + +/* added */ +MP_API int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e, + mp_int* f); +MP_API int mp_toradix (mp_int *a, char *str, int radix); +MP_API int mp_radix_size (mp_int * a, int radix, int *size); + +#ifdef WOLFSSL_DEBUG_MATH + MP_API void mp_dump(const char* desc, mp_int* a, byte verbose); +#else + #define mp_dump(desc, a, verbose) +#endif + +#if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || !defined(NO_RSA) || \ + !defined(NO_DSA) || !defined(NO_DH) + MP_API int mp_sqrmod(mp_int* a, mp_int* b, mp_int* c); +#endif +#if !defined(NO_DSA) || defined(HAVE_ECC) + MP_API int mp_read_radix(mp_int* a, const char* str, int radix); +#endif + +#if defined(WOLFSSL_KEY_GEN) || !defined(NO_RSA) || !defined(NO_DSA) || !defined(NO_DH) + MP_API int mp_prime_is_prime (mp_int * a, int t, int *result); + MP_API int mp_prime_is_prime_ex (mp_int * a, int t, int *result, WC_RNG*); +#endif /* WOLFSSL_KEY_GEN NO_RSA NO_DSA NO_DH */ +#ifdef WOLFSSL_KEY_GEN + MP_API int mp_gcd (mp_int * a, mp_int * b, mp_int * c); + MP_API int mp_lcm (mp_int * a, mp_int * b, mp_int * c); + MP_API int mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap); +#endif + +MP_API int mp_cnt_lsb(mp_int *a); +MP_API int mp_mod_d(mp_int* a, mp_digit b, mp_digit* c); + + +#ifdef __cplusplus + } +#endif + + +#endif /* USE_FAST_MATH */ + +#endif /* WOLF_CRYPT_INTEGER_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/logging.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/logging.h new file mode 100644 index 0000000..25ae998 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/logging.h @@ -0,0 +1,189 @@ +/* logging.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/logging.h +*/ + + +/* submitted by eof */ + + +#ifndef WOLFSSL_LOGGING_H +#define WOLFSSL_LOGGING_H + +#include + +#ifdef __cplusplus + extern "C" { +#endif + + +enum wc_LogLevels { + ERROR_LOG = 0, + INFO_LOG, + ENTER_LOG, + LEAVE_LOG, + OTHER_LOG +}; + +#ifdef WOLFSSL_FUNC_TIME +/* WARNING: This code is only to be used for debugging performance. + * The code is not thread-safe. + * Do not use WOLFSSL_FUNC_TIME in production code. + */ +enum wc_FuncNum { + WC_FUNC_HELLO_REQUEST_SEND = 0, + WC_FUNC_HELLO_REQUEST_DO, + WC_FUNC_CLIENT_HELLO_SEND, + WC_FUNC_CLIENT_HELLO_DO, + WC_FUNC_SERVER_HELLO_SEND, + WC_FUNC_SERVER_HELLO_DO, + WC_FUNC_ENCRYPTED_EXTENSIONS_SEND, + WC_FUNC_ENCRYPTED_EXTENSIONS_DO, + WC_FUNC_CERTIFICATE_REQUEST_SEND, + WC_FUNC_CERTIFICATE_REQUEST_DO, + WC_FUNC_CERTIFICATE_SEND, + WC_FUNC_CERTIFICATE_DO, + WC_FUNC_CERTIFICATE_VERIFY_SEND, + WC_FUNC_CERTIFICATE_VERIFY_DO, + WC_FUNC_FINISHED_SEND, + WC_FUNC_FINISHED_DO, + WC_FUNC_KEY_UPDATE_SEND, + WC_FUNC_KEY_UPDATE_DO, + WC_FUNC_EARLY_DATA_SEND, + WC_FUNC_EARLY_DATA_DO, + WC_FUNC_NEW_SESSION_TICKET_SEND, + WC_FUNC_NEW_SESSION_TICKET_DO, + WC_FUNC_SERVER_HELLO_DONE_SEND, + WC_FUNC_SERVER_HELLO_DONE_DO, + WC_FUNC_TICKET_SEND, + WC_FUNC_TICKET_DO, + WC_FUNC_CLIENT_KEY_EXCHANGE_SEND, + WC_FUNC_CLIENT_KEY_EXCHANGE_DO, + WC_FUNC_CERTIFICATE_STATUS_SEND, + WC_FUNC_CERTIFICATE_STATUS_DO, + WC_FUNC_SERVER_KEY_EXCHANGE_SEND, + WC_FUNC_SERVER_KEY_EXCHANGE_DO, + WC_FUNC_END_OF_EARLY_DATA_SEND, + WC_FUNC_END_OF_EARLY_DATA_DO, + WC_FUNC_COUNT +}; +#endif + +typedef void (*wolfSSL_Logging_cb)(const int logLevel, + const char *const logMessage); + +WOLFSSL_API int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb log_function); + +/* turn logging on, only if compiled in */ +WOLFSSL_API int wolfSSL_Debugging_ON(void); +/* turn logging off */ +WOLFSSL_API void wolfSSL_Debugging_OFF(void); + + +#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) + WOLFSSL_LOCAL int wc_LoggingInit(void); + WOLFSSL_LOCAL int wc_LoggingCleanup(void); + WOLFSSL_LOCAL int wc_AddErrorNode(int error, int line, char* buf, + char* file); + WOLFSSL_LOCAL int wc_PeekErrorNode(int index, const char **file, + const char **reason, int *line); + WOLFSSL_LOCAL void wc_RemoveErrorNode(int index); + WOLFSSL_LOCAL void wc_ClearErrorNodes(void); + WOLFSSL_LOCAL int wc_PullErrorNode(const char **file, const char **reason, + int *line); + WOLFSSL_API int wc_SetLoggingHeap(void* h); + WOLFSSL_API int wc_ERR_remove_state(void); + #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) + WOLFSSL_API void wc_ERR_print_errors_fp(XFILE fp); + #endif +#endif /* OPENSSL_EXTRA || DEBUG_WOLFSSL_VERBOSE */ + +#ifdef WOLFSSL_FUNC_TIME + /* WARNING: This code is only to be used for debugging performance. + * The code is not thread-safe. + * Do not use WOLFSSL_FUNC_TIME in production code. + */ + WOLFSSL_API void WOLFSSL_START(int funcNum); + WOLFSSL_API void WOLFSSL_END(int funcNum); + WOLFSSL_API void WOLFSSL_TIME(int count); +#else + #define WOLFSSL_START(n) + #define WOLFSSL_END(n) + #define WOLFSSL_TIME(n) +#endif + +#if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_DEBUG_ERRORS_ONLY) + #if defined(_WIN32) + #if defined(INTIME_RTOS) + #define __func__ NULL + #else + #define __func__ __FUNCTION__ + #endif + #endif + + /* a is prepended to m and b is appended, creating a log msg a + m + b */ + #define WOLFSSL_LOG_CAT(a, m, b) #a " " m " " #b + + WOLFSSL_API void WOLFSSL_ENTER(const char* msg); + WOLFSSL_API void WOLFSSL_LEAVE(const char* msg, int ret); + #define WOLFSSL_STUB(m) \ + WOLFSSL_MSG(WOLFSSL_LOG_CAT(wolfSSL Stub, m, not implemented)) + + WOLFSSL_API void WOLFSSL_MSG(const char* msg); + WOLFSSL_API void WOLFSSL_BUFFER(const byte* buffer, word32 length); + +#else + + #define WOLFSSL_ENTER(m) + #define WOLFSSL_LEAVE(m, r) + #define WOLFSSL_STUB(m) + + #define WOLFSSL_MSG(m) + #define WOLFSSL_BUFFER(b, l) + +#endif /* DEBUG_WOLFSSL && !WOLFSSL_DEBUG_ERRORS_ONLY */ + +#if defined(DEBUG_WOLFSSL) || defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) ||\ + defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) + + #if (!defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && !defined(_WIN32))\ + || defined(DEBUG_WOLFSSL_VERBOSE) + WOLFSSL_API void WOLFSSL_ERROR_LINE(int err, const char* func, unsigned int line, + const char* file, void* ctx); + #define WOLFSSL_ERROR(x) \ + WOLFSSL_ERROR_LINE((x), __func__, __LINE__, __FILE__, NULL) + #else + WOLFSSL_API void WOLFSSL_ERROR(int err); + #endif + WOLFSSL_API void WOLFSSL_ERROR_MSG(const char* msg); + +#else + #define WOLFSSL_ERROR(e) + #define WOLFSSL_ERROR_MSG(m) +#endif + +#ifdef __cplusplus +} +#endif +#endif /* WOLFSSL_LOGGING_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/md2.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/md2.h new file mode 100644 index 0000000..51b261a --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/md2.h @@ -0,0 +1,69 @@ +/* md2.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/md2.h +*/ + + +#ifndef WOLF_CRYPT_MD2_H +#define WOLF_CRYPT_MD2_H + +#include + +#ifdef WOLFSSL_MD2 + +#ifdef __cplusplus + extern "C" { +#endif + +/* in bytes */ +enum { + MD2 = WC_HASH_TYPE_MD2, + MD2_BLOCK_SIZE = 16, + MD2_DIGEST_SIZE = 16, + MD2_PAD_SIZE = 16, + MD2_X_SIZE = 48 +}; + + +/* Md2 digest */ +typedef struct Md2 { + word32 count; /* bytes % PAD_SIZE */ + byte X[MD2_X_SIZE]; + byte C[MD2_BLOCK_SIZE]; + byte buffer[MD2_BLOCK_SIZE]; +} Md2; + + +WOLFSSL_API void wc_InitMd2(Md2*); +WOLFSSL_API void wc_Md2Update(Md2*, const byte*, word32); +WOLFSSL_API void wc_Md2Final(Md2*, byte*); +WOLFSSL_API int wc_Md2Hash(const byte*, word32, byte*); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_MD2 */ +#endif /* WOLF_CRYPT_MD2_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/md4.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/md4.h new file mode 100644 index 0000000..8b79efe --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/md4.h @@ -0,0 +1,67 @@ +/* md4.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/md4.h +*/ + +#ifndef WOLF_CRYPT_MD4_H +#define WOLF_CRYPT_MD4_H + +#include + +#ifndef NO_MD4 + +#ifdef __cplusplus + extern "C" { +#endif + +/* in bytes */ +enum { + MD4 = WC_HASH_TYPE_MD4, + MD4_BLOCK_SIZE = 64, + MD4_DIGEST_SIZE = 16, + MD4_PAD_SIZE = 56 +}; + + +/* MD4 digest */ +typedef struct Md4 { + word32 buffLen; /* in bytes */ + word32 loLen; /* length in bytes */ + word32 hiLen; /* length in bytes */ + word32 digest[MD4_DIGEST_SIZE / sizeof(word32)]; + word32 buffer[MD4_BLOCK_SIZE / sizeof(word32)]; +} Md4; + + +WOLFSSL_API void wc_InitMd4(Md4*); +WOLFSSL_API void wc_Md4Update(Md4*, const byte*, word32); +WOLFSSL_API void wc_Md4Final(Md4*, byte*); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* NO_MD4 */ +#endif /* WOLF_CRYPT_MD4_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/md5.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/md5.h new file mode 100644 index 0000000..dcb22c5 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/md5.h @@ -0,0 +1,130 @@ +/* md5.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/md5.h +*/ + + +#ifndef WOLF_CRYPT_MD5_H +#define WOLF_CRYPT_MD5_H + +#include + +#ifndef NO_MD5 + +#ifdef HAVE_FIPS + #define wc_InitMd5 InitMd5 + #define wc_Md5Update Md5Update + #define wc_Md5Final Md5Final + #define wc_Md5Hash Md5Hash +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef NO_OLD_WC_NAMES + #define Md5 wc_Md5 + #define MD5 WC_MD5 + #define MD5_BLOCK_SIZE WC_MD5_BLOCK_SIZE + #define MD5_DIGEST_SIZE WC_MD5_DIGEST_SIZE + #define WC_MD5_PAD_SIZE WC_MD5_PAD_SIZE +#endif + +/* in bytes */ +enum { + WC_MD5 = WC_HASH_TYPE_MD5, + WC_MD5_BLOCK_SIZE = 64, + WC_MD5_DIGEST_SIZE = 16, + WC_MD5_PAD_SIZE = 56 +}; + + +#ifdef WOLFSSL_MICROCHIP_PIC32MZ + #include +#endif +#ifdef STM32_HASH + #include +#endif +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif + +#ifdef WOLFSSL_TI_HASH + #include "wolfssl/wolfcrypt/port/ti/ti-hash.h" +#elif defined(WOLFSSL_IMX6_CAAM) + #include "wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h" +#else + +/* MD5 digest */ +typedef struct wc_Md5 { +#ifdef STM32_HASH + STM32_HASH_Context stmCtx; +#else + word32 buffLen; /* in bytes */ + word32 loLen; /* length in bytes */ + word32 hiLen; /* length in bytes */ + word32 buffer[WC_MD5_BLOCK_SIZE / sizeof(word32)]; +#ifdef WOLFSSL_PIC32MZ_HASH + word32 digest[PIC32_DIGEST_SIZE / sizeof(word32)]; +#else + word32 digest[WC_MD5_DIGEST_SIZE / sizeof(word32)]; +#endif + void* heap; +#ifdef WOLFSSL_PIC32MZ_HASH + hashUpdCache cache; /* cache for updates */ +#endif +#endif /* STM32_HASH */ +#ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV asyncDev; +#endif /* WOLFSSL_ASYNC_CRYPT */ +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + word32 flags; /* enum wc_HashFlags in hash.h */ +#endif +} wc_Md5; + +#endif /* WOLFSSL_TI_HASH */ + +WOLFSSL_API int wc_InitMd5(wc_Md5*); +WOLFSSL_API int wc_InitMd5_ex(wc_Md5*, void*, int); +WOLFSSL_API int wc_Md5Update(wc_Md5*, const byte*, word32); +WOLFSSL_API int wc_Md5Final(wc_Md5*, byte*); +WOLFSSL_API void wc_Md5Free(wc_Md5*); + +WOLFSSL_API int wc_Md5GetHash(wc_Md5*, byte*); +WOLFSSL_API int wc_Md5Copy(wc_Md5*, wc_Md5*); + +#ifdef WOLFSSL_PIC32MZ_HASH +WOLFSSL_API void wc_Md5SizeSet(wc_Md5* md5, word32 len); +#endif + +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + WOLFSSL_API int wc_Md5SetFlags(wc_Md5* md5, word32 flags); + WOLFSSL_API int wc_Md5GetFlags(wc_Md5* md5, word32* flags); +#endif + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* NO_MD5 */ +#endif /* WOLF_CRYPT_MD5_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/mem_track.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/mem_track.h new file mode 100644 index 0000000..9754797 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/mem_track.h @@ -0,0 +1,401 @@ +/* mem_track.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +/* The memory tracker overrides the wolfSSL memory callback system and uses a + * static to track the total, peak and currently allocated bytes. + * + * If you are already using the memory callbacks then enabling this will + * override the memory callbacks and prevent your memory callbacks from + * working. This assumes malloc() and free() are available. Feel free to + * customize this for your needs. + + * The enable this feature define the following: + * #define USE_WOLFSSL_MEMORY + * #define WOLFSSL_TRACK_MEMORY + * + * On startup call: + * InitMemoryTracker(); + * + * When ready to dump the memory report call: + * ShowMemoryTracker(); + * + * Report example: + * total Allocs = 228 + * total Bytes = 93442 + * peak Bytes = 8840 + * current Bytes = 0 + * + * + * You can also: + * #define WOLFSSL_DEBUG_MEMORY + * + * To print every alloc/free along with the function and line number. + * Example output: + * Alloc: 0x7fa14a500010 -> 120 at wc_InitRng:496 + * Free: 0x7fa14a500010 -> 120 at wc_FreeRng:606 + */ + + +#ifndef WOLFSSL_MEM_TRACK_H +#define WOLFSSL_MEM_TRACK_H + +#if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY) + + #include "wolfssl/wolfcrypt/logging.h" + + #if defined(WOLFSSL_TRACK_MEMORY) + #define DO_MEM_STATS + #if defined(__linux__) || defined(__MACH__) + #define DO_MEM_LIST + #endif + #endif + + + typedef struct memoryStats { + long totalAllocs; /* number of allocations */ + long totalDeallocs; /* number of deallocations */ + long totalBytes; /* total number of bytes allocated */ + long peakBytes; /* concurrent max bytes */ + long currentBytes; /* total current bytes in use */ + } memoryStats; + + typedef struct memHint { + size_t thisSize; /* size of this memory */ + + #ifdef DO_MEM_LIST + struct memHint* next; + struct memHint* prev; + #ifdef WOLFSSL_DEBUG_MEMORY + const char* func; + unsigned int line; + #endif + #endif + void* thisMemory; /* actual memory for user */ + } memHint; + + typedef struct memoryTrack { + union { + memHint hint; + byte alignit[sizeof(memHint) + ((16-1) & ~(16-1))]; /* make sure we have strong alignment */ + } u; + } memoryTrack; + +#ifdef DO_MEM_LIST + /* track allocations and report at end */ + typedef struct memoryList { + memHint* head; + memHint* tail; + word32 count; + } memoryList; +#endif + +#if defined(WOLFSSL_TRACK_MEMORY) + static memoryStats ourMemStats; + + #ifdef DO_MEM_LIST + #include + static memoryList ourMemList; + static pthread_mutex_t memLock = PTHREAD_MUTEX_INITIALIZER; + #endif +#endif + + + /* if defined to not using inline then declare function prototypes */ + #ifdef NO_INLINE + #define WC_STATIC + #ifdef WOLFSSL_DEBUG_MEMORY + WOLFSSL_LOCAL void* TrackMalloc(size_t sz, const char* func, unsigned int line); + WOLFSSL_LOCAL void TrackFree(void* ptr, const char* func, unsigned int line); + WOLFSSL_LOCAL void* TrackRealloc(void* ptr, size_t sz, const char* func, unsigned int line); + #else + WOLFSSL_LOCAL void* TrackMalloc(size_t sz); + WOLFSSL_LOCAL void TrackFree(void* ptr); + WOLFSSL_LOCAL void* TrackRealloc(void* ptr, size_t sz); + #endif + WOLFSSL_LOCAL int InitMemoryTracker(void); + WOLFSSL_LOCAL void ShowMemoryTracker(void); + #else + #define WC_STATIC static + #endif + +#ifdef WOLFSSL_DEBUG_MEMORY + WC_STATIC WC_INLINE void* TrackMalloc(size_t sz, const char* func, unsigned int line) +#else + WC_STATIC WC_INLINE void* TrackMalloc(size_t sz) +#endif + { + memoryTrack* mt; + memHint* header; + + if (sz == 0) + return NULL; + + mt = (memoryTrack*)malloc(sizeof(memoryTrack) + sz); + if (mt == NULL) + return NULL; + + header = &mt->u.hint; + header->thisSize = sz; + header->thisMemory = (byte*)mt + sizeof(memoryTrack); + + #ifdef WOLFSSL_DEBUG_MEMORY + #ifdef WOLFSSL_DEBUG_MEMORY_PRINT + printf("Alloc: %p -> %u at %s:%d\n", header->thisMemory, (word32)sz, func, line); + #else + (void)func; + (void)line; + #endif + #endif + + #ifdef DO_MEM_STATS + ourMemStats.totalAllocs++; + ourMemStats.totalBytes += sz; + ourMemStats.currentBytes += sz; + if (ourMemStats.currentBytes > ourMemStats.peakBytes) + ourMemStats.peakBytes = ourMemStats.currentBytes; + #endif + #ifdef DO_MEM_LIST + if (pthread_mutex_lock(&memLock) == 0) { + #ifdef WOLFSSL_DEBUG_MEMORY + header->func = func; + header->line = line; + #endif + + /* Setup event */ + header->next = NULL; + if (ourMemList.tail == NULL) { + ourMemList.head = header; + header->prev = NULL; + } + else { + ourMemList.tail->next = header; + header->prev = ourMemList.tail; + } + ourMemList.tail = header; /* add to the end either way */ + ourMemList.count++; + + pthread_mutex_unlock(&memLock); + } + #endif + + return header->thisMemory; + } + + +#ifdef WOLFSSL_DEBUG_MEMORY + WC_STATIC WC_INLINE void TrackFree(void* ptr, const char* func, unsigned int line) +#else + WC_STATIC WC_INLINE void TrackFree(void* ptr) +#endif + { + memoryTrack* mt; + memHint* header; + size_t sz; + + if (ptr == NULL) { + return; + } + + mt = (memoryTrack*)((byte*)ptr - sizeof(memoryTrack)); + header = &mt->u.hint; + sz = header->thisSize; + + #ifdef DO_MEM_LIST + if (pthread_mutex_lock(&memLock) == 0) + { + #endif + + #ifdef DO_MEM_STATS + ourMemStats.currentBytes -= header->thisSize; + ourMemStats.totalDeallocs++; + #endif + + #ifdef DO_MEM_LIST + if (header == ourMemList.head && header == ourMemList.tail) { + ourMemList.head = NULL; + ourMemList.tail = NULL; + } + else if (header == ourMemList.head) { + ourMemList.head = header->next; + ourMemList.head->prev = NULL; + } + else if (header == ourMemList.tail) { + ourMemList.tail = header->prev; + ourMemList.tail->next = NULL; + } + else { + memHint* next = header->next; + memHint* prev = header->prev; + if (next) + next->prev = prev; + if (prev) + prev->next = next; + } + ourMemList.count--; + + pthread_mutex_unlock(&memLock); + } + #endif + +#ifdef WOLFSSL_DEBUG_MEMORY +#ifdef WOLFSSL_DEBUG_MEMORY_PRINT + printf("Free: %p -> %u at %s:%d\n", ptr, (word32)sz, func, line); +#else + (void)func; + (void)line; +#endif +#endif + (void)sz; + + free(mt); + } + + +#ifdef WOLFSSL_DEBUG_MEMORY + WC_STATIC WC_INLINE void* TrackRealloc(void* ptr, size_t sz, const char* func, unsigned int line) +#else + WC_STATIC WC_INLINE void* TrackRealloc(void* ptr, size_t sz) +#endif + { + #ifdef WOLFSSL_DEBUG_MEMORY + void* ret = TrackMalloc(sz, func, line); + #else + void* ret = TrackMalloc(sz); + #endif + + if (ptr) { + /* if realloc is bigger, don't overread old ptr */ + memoryTrack* mt; + memHint* header; + + mt = (memoryTrack*)((byte*)ptr - sizeof(memoryTrack)); + header = &mt->u.hint; + + if (header->thisSize < sz) + sz = header->thisSize; + } + + if (ret && ptr) + XMEMCPY(ret, ptr, sz); + + if (ret) { + #ifdef WOLFSSL_DEBUG_MEMORY + TrackFree(ptr, func, line); + #else + TrackFree(ptr); + #endif + } + + return ret; + } + +#ifdef WOLFSSL_TRACK_MEMORY + static wolfSSL_Malloc_cb mfDefault = NULL; + static wolfSSL_Free_cb ffDefault = NULL; + static wolfSSL_Realloc_cb rfDefault = NULL; + + WC_STATIC WC_INLINE int InitMemoryTracker(void) + { + int ret; + + ret = wolfSSL_GetAllocators(&mfDefault, &ffDefault, &rfDefault); + if (ret < 0) { + printf("wolfSSL GetAllocators failed to get the defaults\n"); + } + ret = wolfSSL_SetAllocators(TrackMalloc, TrackFree, TrackRealloc); + if (ret < 0) { + printf("wolfSSL SetAllocators failed for track memory\n"); + return ret; + } + + #ifdef DO_MEM_LIST + if (pthread_mutex_lock(&memLock) == 0) + { + #endif + + #ifdef DO_MEM_STATS + ourMemStats.totalAllocs = 0; + ourMemStats.totalDeallocs = 0; + ourMemStats.totalBytes = 0; + ourMemStats.peakBytes = 0; + ourMemStats.currentBytes = 0; + #endif + + #ifdef DO_MEM_LIST + XMEMSET(&ourMemList, 0, sizeof(ourMemList)); + + pthread_mutex_unlock(&memLock); + } + #endif + + return ret; + } + + WC_STATIC WC_INLINE void ShowMemoryTracker(void) + { + #ifdef DO_MEM_LIST + if (pthread_mutex_lock(&memLock) == 0) + { + #endif + + #ifdef DO_MEM_STATS + printf("total Allocs = %9ld\n", ourMemStats.totalAllocs); + printf("total Deallocs = %9ld\n", ourMemStats.totalDeallocs); + printf("total Bytes = %9ld\n", ourMemStats.totalBytes); + printf("peak Bytes = %9ld\n", ourMemStats.peakBytes); + printf("current Bytes = %9ld\n", ourMemStats.currentBytes); + #endif + + #ifdef DO_MEM_LIST + if (ourMemList.count > 0) { + /* print list of allocations */ + memHint* header; + for (header = ourMemList.head; header != NULL; header = header->next) { + printf("Leak: Ptr %p, Size %u" + #ifdef WOLFSSL_DEBUG_MEMORY + ", Func %s, Line %d" + #endif + "\n", + (byte*)header + sizeof(memHint), (unsigned int)header->thisSize + #ifdef WOLFSSL_DEBUG_MEMORY + , header->func, header->line + #endif + ); + } + } + + pthread_mutex_unlock(&memLock); + } + #endif + } + + WC_STATIC WC_INLINE int CleanupMemoryTracker(void) + { + /* restore default allocators */ + return wolfSSL_SetAllocators(mfDefault, ffDefault, rfDefault); + } +#endif + +#endif /* USE_WOLFSSL_MEMORY */ + +#endif /* WOLFSSL_MEM_TRACK_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/memory.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/memory.h new file mode 100644 index 0000000..cb806cf --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/memory.h @@ -0,0 +1,233 @@ +/* memory.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +/* submitted by eof */ + +/*! + \file wolfssl/wolfcrypt/memory.h +*/ + +#ifndef WOLFSSL_MEMORY_H +#define WOLFSSL_MEMORY_H + +#ifndef STRING_USER +#include +#endif +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST + WOLFSSL_API void wolfSSL_SetMemFailCount(int memFailCount); +#endif + +#ifdef WOLFSSL_STATIC_MEMORY + #ifdef WOLFSSL_DEBUG_MEMORY + typedef void *(*wolfSSL_Malloc_cb)(size_t size, void* heap, int type, const char* func, unsigned int line); + typedef void (*wolfSSL_Free_cb)(void *ptr, void* heap, int type, const char* func, unsigned int line); + typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size, void* heap, int type, const char* func, unsigned int line); + WOLFSSL_API void* wolfSSL_Malloc(size_t size, void* heap, int type, const char* func, unsigned int line); + WOLFSSL_API void wolfSSL_Free(void *ptr, void* heap, int type, const char* func, unsigned int line); + WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type, const char* func, unsigned int line); + #else + typedef void *(*wolfSSL_Malloc_cb)(size_t size, void* heap, int type); + typedef void (*wolfSSL_Free_cb)(void *ptr, void* heap, int type); + typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size, void* heap, int type); + WOLFSSL_API void* wolfSSL_Malloc(size_t size, void* heap, int type); + WOLFSSL_API void wolfSSL_Free(void *ptr, void* heap, int type); + WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type); + #endif /* WOLFSSL_DEBUG_MEMORY */ +#else + #ifdef WOLFSSL_DEBUG_MEMORY + typedef void *(*wolfSSL_Malloc_cb)(size_t size, const char* func, unsigned int line); + typedef void (*wolfSSL_Free_cb)(void *ptr, const char* func, unsigned int line); + typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size, const char* func, unsigned int line); + + /* Public in case user app wants to use XMALLOC/XFREE */ + WOLFSSL_API void* wolfSSL_Malloc(size_t size, const char* func, unsigned int line); + WOLFSSL_API void wolfSSL_Free(void *ptr, const char* func, unsigned int line); + WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size, const char* func, unsigned int line); + #else + typedef void *(*wolfSSL_Malloc_cb)(size_t size); + typedef void (*wolfSSL_Free_cb)(void *ptr); + typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size); + /* Public in case user app wants to use XMALLOC/XFREE */ + WOLFSSL_API void* wolfSSL_Malloc(size_t size); + WOLFSSL_API void wolfSSL_Free(void *ptr); + WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size); + #endif /* WOLFSSL_DEBUG_MEMORY */ +#endif /* WOLFSSL_STATIC_MEMORY */ + +/* Public get/set functions */ +WOLFSSL_API int wolfSSL_SetAllocators(wolfSSL_Malloc_cb, + wolfSSL_Free_cb, + wolfSSL_Realloc_cb); +WOLFSSL_API int wolfSSL_GetAllocators(wolfSSL_Malloc_cb*, + wolfSSL_Free_cb*, + wolfSSL_Realloc_cb*); + +#ifdef WOLFSSL_STATIC_MEMORY + #define WOLFSSL_STATIC_TIMEOUT 1 + #ifndef WOLFSSL_STATIC_ALIGN + #define WOLFSSL_STATIC_ALIGN 16 + #endif + #ifndef WOLFMEM_MAX_BUCKETS + #define WOLFMEM_MAX_BUCKETS 9 + #endif + #define WOLFMEM_DEF_BUCKETS 9 /* number of default memory blocks */ + #ifndef WOLFMEM_IO_SZ + #define WOLFMEM_IO_SZ 16992 /* 16 byte aligned */ + #endif + #ifndef WOLFMEM_BUCKETS + #ifndef SESSION_CERTS + /* default size of chunks of memory to separate into */ + #ifndef LARGEST_MEM_BUCKET + #define LARGEST_MEM_BUCKET 16128 + #endif + #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,\ + LARGEST_MEM_BUCKET + #elif defined (OPENSSL_EXTRA) + /* extra storage in structs for multiple attributes and order */ + #ifndef LARGEST_MEM_BUCKET + #define LARGEST_MEM_BUCKET 25536 + #endif + #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3360,4480,\ + LARGEST_MEM_BUCKET + #elif defined (WOLFSSL_CERT_EXT) + /* certificate extensions requires 24k for the SSL struct */ + #ifndef LARGEST_MEM_BUCKET + #define LARGEST_MEM_BUCKET 24576 + #endif + #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,\ + LARGEST_MEM_BUCKET + #else + /* increase 23k for object member of WOLFSSL_X509_NAME_ENTRY */ + #ifndef LARGEST_MEM_BUCKET + #define LARGEST_MEM_BUCKET 23440 + #endif + #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,\ + LARGEST_MEM_BUCKET + #endif + #endif + #ifndef WOLFMEM_DIST + #ifndef WOLFSSL_STATIC_MEMORY_SMALL + #define WOLFMEM_DIST 49,10,6,14,5,6,9,1,1 + #else + /* Low resource and not RSA */ + #define WOLFMEM_DIST 29, 7,6, 9,4,4,0,0,0 + #endif + #endif + + /* flags for loading static memory (one hot bit) */ + #define WOLFMEM_GENERAL 0x01 + #define WOLFMEM_IO_POOL 0x02 + #define WOLFMEM_IO_POOL_FIXED 0x04 + #define WOLFMEM_TRACK_STATS 0x08 + + #ifndef WOLFSSL_MEM_GUARD + #define WOLFSSL_MEM_GUARD + typedef struct WOLFSSL_MEM_STATS WOLFSSL_MEM_STATS; + typedef struct WOLFSSL_MEM_CONN_STATS WOLFSSL_MEM_CONN_STATS; + #endif + + struct WOLFSSL_MEM_CONN_STATS { + word32 peakMem; /* peak memory usage */ + word32 curMem; /* current memory usage */ + word32 peakAlloc; /* peak memory allocations */ + word32 curAlloc; /* current memory allocations */ + word32 totalAlloc;/* total memory allocations for lifetime */ + word32 totalFr; /* total frees for lifetime */ + }; + + struct WOLFSSL_MEM_STATS { + word32 curAlloc; /* current memory allocations */ + word32 totalAlloc;/* total memory allocations for lifetime */ + word32 totalFr; /* total frees for lifetime */ + word32 totalUse; /* total amount of memory used in blocks */ + word32 avaIO; /* available IO specific pools */ + word32 maxHa; /* max number of concurent handshakes allowed */ + word32 maxIO; /* max number of concurent IO connections allowed */ + word32 blockSz[WOLFMEM_MAX_BUCKETS]; /* block sizes in stacks */ + word32 avaBlock[WOLFMEM_MAX_BUCKETS];/* ava block sizes */ + word32 usedBlock[WOLFMEM_MAX_BUCKETS]; + int flag; /* flag used */ + }; + + typedef struct wc_Memory wc_Memory; /* internal structure for mem bucket */ + typedef struct WOLFSSL_HEAP { + wc_Memory* ava[WOLFMEM_MAX_BUCKETS]; + wc_Memory* io; /* list of buffers to use for IO */ + word32 maxHa; /* max concurent handshakes */ + word32 curHa; + word32 maxIO; /* max concurrent IO connections */ + word32 curIO; + word32 sizeList[WOLFMEM_MAX_BUCKETS];/* memory sizes in ava list */ + word32 distList[WOLFMEM_MAX_BUCKETS];/* general distribution */ + word32 inUse; /* amount of memory currently in use */ + word32 ioUse; + word32 alloc; /* total number of allocs */ + word32 frAlc; /* total number of frees */ + int flag; + wolfSSL_Mutex memory_mutex; + } WOLFSSL_HEAP; + + /* structure passed into XMALLOC as heap hint + * having this abstraction allows tracking statistics of individual ssl's + */ + typedef struct WOLFSSL_HEAP_HINT { + WOLFSSL_HEAP* memory; + WOLFSSL_MEM_CONN_STATS* stats; /* hold individual connection stats */ + wc_Memory* outBuf; /* set if using fixed io buffers */ + wc_Memory* inBuf; + byte haFlag; /* flag used for checking handshake count */ + } WOLFSSL_HEAP_HINT; + + WOLFSSL_API int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, + unsigned char* buf, unsigned int sz, int flag, int max); + + WOLFSSL_LOCAL int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap); + WOLFSSL_LOCAL int wolfSSL_load_static_memory(byte* buffer, word32 sz, + int flag, WOLFSSL_HEAP* heap); + WOLFSSL_LOCAL int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap, + WOLFSSL_MEM_STATS* stats); + WOLFSSL_LOCAL int SetFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io); + WOLFSSL_LOCAL int FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io); + + WOLFSSL_API int wolfSSL_StaticBufferSz(byte* buffer, word32 sz, int flag); + WOLFSSL_API int wolfSSL_MemoryPaddingSz(void); +#endif /* WOLFSSL_STATIC_MEMORY */ + +#ifdef WOLFSSL_STACK_LOG + WOLFSSL_API void __attribute__((no_instrument_function)) + __cyg_profile_func_enter(void *func, void *caller); + WOLFSSL_API void __attribute__((no_instrument_function)) + __cyg_profile_func_exit(void *func, void *caller); +#endif /* WOLFSSL_STACK_LOG */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_MEMORY_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/misc.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/misc.h new file mode 100644 index 0000000..d4dc7a1 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/misc.h @@ -0,0 +1,116 @@ +/* misc.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +#ifndef WOLF_CRYPT_MISC_H +#define WOLF_CRYPT_MISC_H + + +#include + + +#ifdef __cplusplus + extern "C" { +#endif + + +#ifdef NO_INLINE +WOLFSSL_LOCAL +word32 rotlFixed(word32, word32); +WOLFSSL_LOCAL +word32 rotrFixed(word32, word32); + +WOLFSSL_LOCAL +word32 ByteReverseWord32(word32); +WOLFSSL_LOCAL +void ByteReverseWords(word32*, const word32*, word32); + +WOLFSSL_LOCAL +void XorWords(wolfssl_word*, const wolfssl_word*, word32); +WOLFSSL_LOCAL +void xorbuf(void*, const void*, word32); + +WOLFSSL_LOCAL +void ForceZero(const void*, word32); + +WOLFSSL_LOCAL +int ConstantCompare(const byte*, const byte*, int); + +#ifdef WORD64_AVAILABLE +WOLFSSL_LOCAL +word64 rotlFixed64(word64, word64); +WOLFSSL_LOCAL +word64 rotrFixed64(word64, word64); + +WOLFSSL_LOCAL +word64 ByteReverseWord64(word64); +WOLFSSL_LOCAL +void ByteReverseWords64(word64*, const word64*, word32); +#endif /* WORD64_AVAILABLE */ + +#ifndef WOLFSSL_HAVE_MIN + #if defined(HAVE_FIPS) && !defined(min) /* so ifdef check passes */ + #define min min + #endif + WOLFSSL_LOCAL word32 min(word32 a, word32 b); +#endif + +#ifndef WOLFSSL_HAVE_MAX + #if defined(HAVE_FIPS) && !defined(max) /* so ifdef check passes */ + #define max max + #endif + WOLFSSL_LOCAL word32 max(word32 a, word32 b); +#endif /* WOLFSSL_HAVE_MAX */ + + +void c32to24(word32 in, word24 out); +void c16toa(word16 u16, byte* c); +void c32toa(word32 u32, byte* c); +void c24to32(const word24 u24, word32* u32); +void ato16(const byte* c, word16* u16); +void ato24(const byte* c, word32* u24); +void ato32(const byte* c, word32* u32); +word32 btoi(byte b); + + +WOLFSSL_LOCAL byte ctMaskGT(int a, int b); +WOLFSSL_LOCAL byte ctMaskGTE(int a, int b); +WOLFSSL_LOCAL int ctMaskIntGTE(int a, int b); +WOLFSSL_LOCAL byte ctMaskLT(int a, int b); +WOLFSSL_LOCAL byte ctMaskLTE(int a, int b); +WOLFSSL_LOCAL byte ctMaskEq(int a, int b); +WOLFSSL_LOCAL word16 ctMask16Eq(int a, int b); +WOLFSSL_LOCAL byte ctMaskNotEq(int a, int b); +WOLFSSL_LOCAL byte ctMaskSel(byte m, byte a, byte b); +WOLFSSL_LOCAL int ctMaskSelInt(byte m, int a, int b); +WOLFSSL_LOCAL byte ctSetLTE(int a, int b); + +#endif /* NO_INLINE */ + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* WOLF_CRYPT_MISC_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/mpi_class.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/mpi_class.h new file mode 100644 index 0000000..30f0a9f --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/mpi_class.h @@ -0,0 +1,1021 @@ +/* mpi_class.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +#if !(defined(LTM1) && defined(LTM2) && defined(LTM3)) +#if defined(LTM2) +#define LTM3 +#endif +#if defined(LTM1) +#define LTM2 +#endif +#define LTM1 + +#if defined(LTM_ALL) +#define BN_ERROR_C +#define BN_FAST_MP_INVMOD_C +#define BN_FAST_MP_MONTGOMERY_REDUCE_C +#define BN_FAST_S_MP_MUL_DIGS_C +#define BN_FAST_S_MP_MUL_HIGH_DIGS_C +#define BN_FAST_S_MP_SQR_C +#define BN_MP_2EXPT_C +#define BN_MP_ABS_C +#define BN_MP_ADD_C +#define BN_MP_ADD_D_C +#define BN_MP_ADDMOD_C +#define BN_MP_AND_C +#define BN_MP_CLAMP_C +#define BN_MP_CLEAR_C +#define BN_MP_CLEAR_MULTI_C +#define BN_MP_CMP_C +#define BN_MP_CMP_D_C +#define BN_MP_CMP_MAG_C +#define BN_MP_CNT_LSB_C +#define BN_MP_COPY_C +#define BN_MP_COUNT_BITS_C +#define BN_MP_DIV_C +#define BN_MP_DIV_2_C +#define BN_MP_DIV_2D_C +#define BN_MP_DIV_3_C +#define BN_MP_DIV_D_C +#define BN_MP_DR_IS_MODULUS_C +#define BN_MP_DR_REDUCE_C +#define BN_MP_DR_SETUP_C +#define BN_MP_EXCH_C +#define BN_MP_EXPT_D_C +#define BN_MP_EXPTMOD_BASE_2 +#define BN_MP_EXPTMOD_C +#define BN_MP_EXPTMOD_FAST_C +#define BN_MP_EXTEUCLID_C +#define BN_MP_FREAD_C +#define BN_MP_FWRITE_C +#define BN_MP_GCD_C +#define BN_MP_GET_INT_C +#define BN_MP_GROW_C +#define BN_MP_INIT_C +#define BN_MP_INIT_COPY_C +#define BN_MP_INIT_MULTI_C +#define BN_MP_INIT_SET_C +#define BN_MP_INIT_SET_INT_C +#define BN_MP_INIT_SIZE_C +#define BN_MP_INVMOD_C +#define BN_MP_INVMOD_SLOW_C +#define BN_MP_IS_SQUARE_C +#define BN_MP_JACOBI_C +#define BN_MP_KARATSUBA_MUL_C +#define BN_MP_KARATSUBA_SQR_C +#define BN_MP_LCM_C +#define BN_MP_LSHD_C +#define BN_MP_MOD_C +#define BN_MP_MOD_2D_C +#define BN_MP_MOD_D_C +#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +#define BN_MP_MONTGOMERY_REDUCE_C +#define BN_MP_MONTGOMERY_SETUP_C +#define BN_MP_MUL_C +#define BN_MP_MUL_2_C +#define BN_MP_MUL_2D_C +#define BN_MP_MUL_D_C +#define BN_MP_MULMOD_C +#define BN_MP_N_ROOT_C +#define BN_MP_NEG_C +#define BN_MP_OR_C +#define BN_MP_PRIME_FERMAT_C +#define BN_MP_PRIME_IS_DIVISIBLE_C +#define BN_MP_PRIME_IS_PRIME_C +#define BN_MP_PRIME_MILLER_RABIN_C +#define BN_MP_PRIME_NEXT_PRIME_C +#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C +#define BN_MP_PRIME_RANDOM_EX_C +#define BN_MP_RADIX_SIZE_C +#define BN_MP_RADIX_SMAP_C +#define BN_MP_RAND_C +#define BN_MP_READ_RADIX_C +#define BN_MP_READ_SIGNED_BIN_C +#define BN_MP_READ_UNSIGNED_BIN_C +#define BN_MP_REDUCE_C +#define BN_MP_REDUCE_2K_C +#define BN_MP_REDUCE_2K_L_C +#define BN_MP_REDUCE_2K_SETUP_C +#define BN_MP_REDUCE_2K_SETUP_L_C +#define BN_MP_REDUCE_IS_2K_C +#define BN_MP_REDUCE_IS_2K_L_C +#define BN_MP_REDUCE_SETUP_C +#define BN_MP_RSHD_C +#define BN_MP_SET_C +#define BN_MP_SET_INT_C +#define BN_MP_SHRINK_C +#define BN_MP_SIGNED_BIN_SIZE_C +#define BN_MP_SQR_C +#define BN_MP_SQRMOD_C +#define BN_MP_SQRT_C +#define BN_MP_SUB_C +#define BN_MP_SUB_D_C +#define BN_MP_SUBMOD_C +#define BN_MP_TO_SIGNED_BIN_C +#define BN_MP_TO_SIGNED_BIN_N_C +#define BN_MP_TO_UNSIGNED_BIN_C +#define BN_MP_TO_UNSIGNED_BIN_N_C +#define BN_MP_TOOM_MUL_C +#define BN_MP_TOOM_SQR_C +#define BN_MP_TORADIX_C +#define BN_MP_TORADIX_N_C +#define BN_MP_UNSIGNED_BIN_SIZE_C +#define BN_MP_XOR_C +#define BN_MP_ZERO_C +#define BN_PRIME_TAB_C +#define BN_REVERSE_C +#define BN_S_MP_ADD_C +#define BN_S_MP_EXPTMOD_C +#define BN_S_MP_MUL_DIGS_C +#define BN_S_MP_MUL_HIGH_DIGS_C +#define BN_S_MP_SQR_C +#define BN_S_MP_SUB_C +#define BNCORE_C +#endif + +#if defined(BN_ERROR_C) + #define BN_MP_ERROR_TO_STRING_C +#endif + +#if defined(BN_FAST_MP_INVMOD_C) + #define BN_MP_ISEVEN_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_COPY_C + #define BN_MP_MOD_C + #define BN_MP_SET_C + #define BN_MP_DIV_2_C + #define BN_MP_ISODD_C + #define BN_MP_SUB_C + #define BN_MP_CMP_C + #define BN_MP_ISZERO_C + #define BN_MP_CMP_D_C + #define BN_MP_ADD_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C) + #define BN_MP_GROW_C + #define BN_MP_RSHD_C + #define BN_MP_CLAMP_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_FAST_S_MP_MUL_DIGS_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_FAST_S_MP_SQR_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_2EXPT_C) + #define BN_MP_ZERO_C + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_ABS_C) + #define BN_MP_COPY_C +#endif + +#if defined(BN_MP_ADD_C) + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_ADD_D_C) + #define BN_MP_GROW_C + #define BN_MP_SUB_D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_ADDMOD_C) + #define BN_MP_INIT_C + #define BN_MP_ADD_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_AND_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_CLAMP_C) +#endif + +#if defined(BN_MP_CLEAR_C) +#endif + +#if defined(BN_MP_CLEAR_MULTI_C) + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_CMP_C) + #define BN_MP_CMP_MAG_C +#endif + +#if defined(BN_MP_CMP_D_C) +#endif + +#if defined(BN_MP_CMP_MAG_C) +#endif + +#if defined(BN_MP_CNT_LSB_C) + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_COPY_C) + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_COUNT_BITS_C) +#endif + +#if defined(BN_MP_DIV_C) + #define BN_MP_ISZERO_C + #define BN_MP_CMP_MAG_C + #define BN_MP_COPY_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_SET_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_ABS_C + #define BN_MP_MUL_2D_C + #define BN_MP_CMP_C + #define BN_MP_SUB_C + #define BN_MP_ADD_C + #define BN_MP_DIV_2D_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_INIT_C + #define BN_MP_INIT_COPY_C + #define BN_MP_LSHD_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_D_C + #define BN_MP_CLAMP_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DIV_2_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_DIV_2D_C) + #define BN_MP_COPY_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_C + #define BN_MP_MOD_2D_C + #define BN_MP_CLEAR_C + #define BN_MP_RSHD_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_DIV_3_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DIV_D_C) + #define BN_MP_ISZERO_C + #define BN_MP_COPY_C + #define BN_MP_DIV_2D_C + #define BN_MP_DIV_3_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DR_IS_MODULUS_C) +#endif + +#if defined(BN_MP_DR_REDUCE_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_DR_SETUP_C) +#endif + +#if defined(BN_MP_EXCH_C) +#endif + +#if defined(BN_MP_EXPT_D_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_SET_C + #define BN_MP_SQR_C + #define BN_MP_CLEAR_C + #define BN_MP_MUL_C +#endif + +#if defined(BN_MP_EXPTMOD_C) + #define BN_MP_INIT_C + #define BN_MP_INVMOD_C + #define BN_MP_CLEAR_C + #define BN_MP_ABS_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_REDUCE_IS_2K_L_C + #define BN_S_MP_EXPTMOD_C + #define BN_MP_DR_IS_MODULUS_C + #define BN_MP_REDUCE_IS_2K_C + #define BN_MP_ISODD_C + #define BN_MP_EXPTMOD_FAST_C + #define BN_MP_EXPTMOD_BASE_2 +#endif + +#if defined(BN_MP_EXPTMOD_FAST_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C + #define BN_MP_MONTGOMERY_SETUP_C + #define BN_FAST_MP_MONTGOMERY_REDUCE_C + #define BN_MP_MONTGOMERY_REDUCE_C + #define BN_MP_DR_SETUP_C + #define BN_MP_DR_REDUCE_C + #define BN_MP_REDUCE_2K_SETUP_C + #define BN_MP_REDUCE_2K_C + #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C + #define BN_MP_MULMOD_C + #define BN_MP_SET_C + #define BN_MP_MOD_C + #define BN_MP_COPY_C + #define BN_MP_SQR_C + #define BN_MP_MUL_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_EXTEUCLID_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_SET_C + #define BN_MP_COPY_C + #define BN_MP_ISZERO_C + #define BN_MP_DIV_C + #define BN_MP_MUL_C + #define BN_MP_SUB_C + #define BN_MP_NEG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_FREAD_C) + #define BN_MP_ZERO_C + #define BN_MP_S_RMAP_C + #define BN_MP_MUL_D_C + #define BN_MP_ADD_D_C + #define BN_MP_CMP_D_C +#endif + +#if defined(BN_MP_FWRITE_C) + #define BN_MP_RADIX_SIZE_C + #define BN_MP_TORADIX_C +#endif + +#if defined(BN_MP_GCD_C) + #define BN_MP_ISZERO_C + #define BN_MP_ABS_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_S_MP_SUB_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_GET_INT_C) +#endif + +#if defined(BN_MP_GROW_C) +#endif + +#if defined(BN_MP_INIT_C) +#endif + +#if defined(BN_MP_INIT_COPY_C) + #define BN_MP_COPY_C +#endif + +#if defined(BN_MP_INIT_MULTI_C) + #define BN_MP_ERR_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_INIT_SET_C) + #define BN_MP_INIT_C + #define BN_MP_SET_C +#endif + +#if defined(BN_MP_INIT_SET_INT_C) + #define BN_MP_INIT_C + #define BN_MP_SET_INT_C +#endif + +#if defined(BN_MP_INIT_SIZE_C) + #define BN_MP_INIT_C +#endif + +#if defined(BN_MP_INVMOD_C) + #define BN_MP_ISZERO_C + #define BN_MP_ISODD_C + #define BN_FAST_MP_INVMOD_C + #define BN_MP_INVMOD_SLOW_C +#endif + +#if defined(BN_MP_INVMOD_SLOW_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_C + #define BN_MP_COPY_C + #define BN_MP_ISEVEN_C + #define BN_MP_SET_C + #define BN_MP_DIV_2_C + #define BN_MP_ISODD_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_CMP_C + #define BN_MP_CMP_D_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_IS_SQUARE_C) + #define BN_MP_MOD_D_C + #define BN_MP_INIT_SET_INT_C + #define BN_MP_MOD_C + #define BN_MP_GET_INT_C + #define BN_MP_SQRT_C + #define BN_MP_SQR_C + #define BN_MP_CMP_MAG_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_JACOBI_C) + #define BN_MP_CMP_D_C + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_MOD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_KARATSUBA_MUL_C) + #define BN_MP_MUL_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_SUB_C + #define BN_MP_ADD_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_KARATSUBA_SQR_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_SQR_C + #define BN_MP_SUB_C + #define BN_S_MP_ADD_C + #define BN_MP_LSHD_C + #define BN_MP_ADD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_LCM_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_GCD_C + #define BN_MP_CMP_MAG_C + #define BN_MP_DIV_C + #define BN_MP_MUL_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_LSHD_C) + #define BN_MP_GROW_C + #define BN_MP_RSHD_C +#endif + +#if defined(BN_MP_MOD_C) + #define BN_MP_INIT_C + #define BN_MP_DIV_C + #define BN_MP_CLEAR_C + #define BN_MP_ADD_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_MOD_2D_C) + #define BN_MP_ZERO_C + #define BN_MP_COPY_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MOD_D_C) + #define BN_MP_DIV_D_C +#endif + +#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_2EXPT_C + #define BN_MP_SET_C + #define BN_MP_MUL_2_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_MONTGOMERY_REDUCE_C) + #define BN_FAST_MP_MONTGOMERY_REDUCE_C + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C + #define BN_MP_RSHD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_MONTGOMERY_SETUP_C) +#endif + +#if defined(BN_MP_MUL_C) + #define BN_MP_TOOM_MUL_C + #define BN_MP_KARATSUBA_MUL_C + #define BN_FAST_S_MP_MUL_DIGS_C + #define BN_S_MP_MUL_C + #define BN_S_MP_MUL_DIGS_C +#endif + +#if defined(BN_MP_MUL_2_C) + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_MUL_2D_C) + #define BN_MP_COPY_C + #define BN_MP_GROW_C + #define BN_MP_LSHD_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MUL_D_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MULMOD_C) + #define BN_MP_INIT_C + #define BN_MP_MUL_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_N_ROOT_C) + #define BN_MP_INIT_C + #define BN_MP_SET_C + #define BN_MP_COPY_C + #define BN_MP_EXPT_D_C + #define BN_MP_MUL_C + #define BN_MP_SUB_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_C + #define BN_MP_CMP_C + #define BN_MP_SUB_D_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_NEG_C) + #define BN_MP_COPY_C + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_OR_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_FERMAT_C) + #define BN_MP_CMP_D_C + #define BN_MP_INIT_C + #define BN_MP_EXPTMOD_C + #define BN_MP_CMP_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_IS_DIVISIBLE_C) + #define BN_MP_MOD_D_C +#endif + +#if defined(BN_MP_PRIME_IS_PRIME_C) + #define BN_MP_CMP_D_C + #define BN_MP_PRIME_IS_DIVISIBLE_C + #define BN_MP_INIT_C + #define BN_MP_SET_C + #define BN_MP_PRIME_MILLER_RABIN_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_MILLER_RABIN_C) + #define BN_MP_CMP_D_C + #define BN_MP_INIT_COPY_C + #define BN_MP_SUB_D_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_EXPTMOD_C + #define BN_MP_CMP_C + #define BN_MP_SQRMOD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_NEXT_PRIME_C) + #define BN_MP_CMP_D_C + #define BN_MP_SET_C + #define BN_MP_SUB_D_C + #define BN_MP_ISEVEN_C + #define BN_MP_MOD_D_C + #define BN_MP_INIT_C + #define BN_MP_ADD_D_C + #define BN_MP_PRIME_MILLER_RABIN_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C) +#endif + +#if defined(BN_MP_PRIME_RANDOM_EX_C) + #define BN_MP_READ_UNSIGNED_BIN_C + #define BN_MP_PRIME_IS_PRIME_C + #define BN_MP_SUB_D_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_D_C +#endif + +#if defined(BN_MP_RADIX_SIZE_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_COPY_C + #define BN_MP_ISZERO_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_RADIX_SMAP_C) + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_RAND_C) + #define BN_MP_ZERO_C + #define BN_MP_ADD_D_C + #define BN_MP_LSHD_C +#endif + +#if defined(BN_MP_READ_RADIX_C) + #define BN_MP_ZERO_C + #define BN_MP_S_RMAP_C + #define BN_MP_RADIX_SMAP_C + #define BN_MP_MUL_D_C + #define BN_MP_ADD_D_C + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_READ_SIGNED_BIN_C) + #define BN_MP_READ_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_READ_UNSIGNED_BIN_C) + #define BN_MP_GROW_C + #define BN_MP_ZERO_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_REDUCE_C) + #define BN_MP_REDUCE_SETUP_C + #define BN_MP_INIT_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_C + #define BN_S_MP_MUL_HIGH_DIGS_C + #define BN_FAST_S_MP_MUL_HIGH_DIGS_C + #define BN_MP_MOD_2D_C + #define BN_S_MP_MUL_DIGS_C + #define BN_MP_SUB_C + #define BN_MP_CMP_D_C + #define BN_MP_SET_C + #define BN_MP_LSHD_C + #define BN_MP_ADD_C + #define BN_MP_CMP_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_2K_C) + #define BN_MP_INIT_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_DIV_2D_C + #define BN_MP_MUL_D_C + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_2K_L_C) + #define BN_MP_INIT_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_DIV_2D_C + #define BN_MP_MUL_C + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_2K_SETUP_C) + #define BN_MP_INIT_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_2EXPT_C + #define BN_MP_CLEAR_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_REDUCE_2K_SETUP_L_C) + #define BN_MP_INIT_C + #define BN_MP_2EXPT_C + #define BN_MP_COUNT_BITS_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_IS_2K_C) + #define BN_MP_REDUCE_2K_C + #define BN_MP_COUNT_BITS_C +#endif + +#if defined(BN_MP_REDUCE_IS_2K_L_C) +#endif + +#if defined(BN_MP_REDUCE_SETUP_C) + #define BN_MP_2EXPT_C + #define BN_MP_DIV_C +#endif + +#if defined(BN_MP_RSHD_C) + #define BN_MP_ZERO_C +#endif + +#if defined(BN_MP_SET_C) + #define BN_MP_ZERO_C +#endif + +#if defined(BN_MP_SET_INT_C) + #define BN_MP_ZERO_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_SHRINK_C) +#endif + +#if defined(BN_MP_SIGNED_BIN_SIZE_C) + #define BN_MP_UNSIGNED_BIN_SIZE_C +#endif + +#if defined(BN_MP_SQR_C) + #define BN_MP_TOOM_SQR_C + #define BN_MP_KARATSUBA_SQR_C + #define BN_FAST_S_MP_SQR_C + #define BN_S_MP_SQR_C +#endif + +#if defined(BN_MP_SQRMOD_C) + #define BN_MP_INIT_C + #define BN_MP_SQR_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_SQRT_C) + #define BN_MP_N_ROOT_C + #define BN_MP_ISZERO_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_DIV_C + #define BN_MP_ADD_C + #define BN_MP_DIV_2_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_SUB_C) + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_SUB_D_C) + #define BN_MP_GROW_C + #define BN_MP_ADD_D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_SUBMOD_C) + #define BN_MP_INIT_C + #define BN_MP_SUB_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_TO_SIGNED_BIN_C) + #define BN_MP_TO_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_TO_SIGNED_BIN_N_C) + #define BN_MP_SIGNED_BIN_SIZE_C + #define BN_MP_TO_SIGNED_BIN_C +#endif + +#if defined(BN_MP_TO_UNSIGNED_BIN_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_ISZERO_C + #define BN_MP_DIV_2D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_TO_UNSIGNED_BIN_N_C) + #define BN_MP_UNSIGNED_BIN_SIZE_C + #define BN_MP_TO_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_TOOM_MUL_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_2D_C + #define BN_MP_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2D_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_3_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_TOOM_SQR_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_2D_C + #define BN_MP_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_SQR_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2D_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_3_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_TORADIX_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_TORADIX_N_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_UNSIGNED_BIN_SIZE_C) + #define BN_MP_COUNT_BITS_C +#endif + +#if defined(BN_MP_XOR_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_ZERO_C) +#endif + +#if defined(BN_PRIME_TAB_C) +#endif + +#if defined(BN_REVERSE_C) +#endif + +#if defined(BN_S_MP_ADD_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_S_MP_EXPTMOD_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C + #define BN_MP_REDUCE_SETUP_C + #define BN_MP_REDUCE_C + #define BN_MP_REDUCE_2K_SETUP_L_C + #define BN_MP_REDUCE_2K_L_C + #define BN_MP_MOD_C + #define BN_MP_COPY_C + #define BN_MP_SQR_C + #define BN_MP_MUL_C + #define BN_MP_SET_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_S_MP_MUL_DIGS_C) + #define BN_FAST_S_MP_MUL_DIGS_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_MUL_HIGH_DIGS_C) + #define BN_FAST_S_MP_MUL_HIGH_DIGS_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_SQR_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_SUB_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BNCORE_C) +#endif + +#ifdef LTM3 +#define LTM_LAST +#endif +#include "mpi_superclass.h" +#include "mpi_class.h" +#else +#define LTM_LAST +#endif + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/mpi_superclass.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/mpi_superclass.h new file mode 100644 index 0000000..7347268 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/mpi_superclass.h @@ -0,0 +1,96 @@ +/* mpi_superclass.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +/* super class file for PK algos */ + +/* default ... include all MPI */ +#define LTM_ALL + +/* RSA only (does not support DH/DSA/ECC) */ +/* #define SC_RSA_1 */ + +/* For reference.... On an Athlon64 optimizing for speed... + + LTM's mpi.o with all functions [striped] is 142KiB in size. + +*/ + +/* Works for RSA only, mpi.o is 68KiB */ +#ifdef SC_RSA_1 + #define BN_MP_SHRINK_C + #define BN_MP_LCM_C + #define BN_MP_PRIME_RANDOM_EX_C + #define BN_MP_INVMOD_C + #define BN_MP_GCD_C + #define BN_MP_MOD_C + #define BN_MP_MULMOD_C + #define BN_MP_ADDMOD_C + #define BN_MP_EXPTMOD_C + #define BN_MP_SET_INT_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_UNSIGNED_BIN_SIZE_C + #define BN_MP_TO_UNSIGNED_BIN_C + #define BN_MP_MOD_D_C + #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C + #define BN_REVERSE_C + #define BN_PRIME_TAB_C + + /* other modifiers */ + #define BN_MP_DIV_SMALL /* Slower division, not critical */ + + /* here we are on the last pass so we turn things off. The functions classes are still there + * but we remove them specifically from the build. This also invokes tweaks in functions + * like removing support for even moduli, etc... + */ +#ifdef LTM_LAST + #undef BN_MP_TOOM_MUL_C + #undef BN_MP_TOOM_SQR_C + #undef BN_MP_KARATSUBA_MUL_C + #undef BN_MP_KARATSUBA_SQR_C + #undef BN_MP_REDUCE_C + #undef BN_MP_REDUCE_SETUP_C + #undef BN_MP_DR_IS_MODULUS_C + #undef BN_MP_DR_SETUP_C + #undef BN_MP_DR_REDUCE_C + #undef BN_MP_REDUCE_IS_2K_C + #undef BN_MP_REDUCE_2K_SETUP_C + #undef BN_MP_REDUCE_2K_C + #undef BN_S_MP_EXPTMOD_C + #undef BN_MP_DIV_3_C + #undef BN_S_MP_MUL_HIGH_DIGS_C + #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C + #undef BN_FAST_MP_INVMOD_C + + /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold + * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines] + * which means roughly speaking you can handle up to 2536-bit RSA keys with these defined without + * trouble. + */ + #undef BN_S_MP_MUL_DIGS_C + #undef BN_S_MP_SQR_C + #undef BN_MP_MONTGOMERY_REDUCE_C +#endif + +#endif + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/pkcs11.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/pkcs11.h new file mode 100644 index 0000000..0e5e7b2 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/pkcs11.h @@ -0,0 +1,537 @@ +/* pkcs11.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef _PKCS11_H_ +#define _PKCS11_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NULL_PTR +#define NULL_PTR 0 +#endif +#define CK_TRUE 1 +#define CK_FALSE 0 + + +#define CK_INVALID_HANDLE 0UL + +#define CKN_SURRENDER 0UL + +#define CKF_TOKEN_PRESENT 0x00000001UL +#define CKF_REMOVABLE_DEVICE 0x00000002UL +#define CKF_HW_SLOT 0x00000004UL + +#define CKF_HW 0x00000001UL +#define CKF_ENCRYPT 0x00000100UL +#define CKF_DECRYPT 0x00000200UL +#define CKF_DIGEST 0x00000400UL +#define CKF_SIGN 0x00000800UL +#define CKF_SIGN_RECOVER 0x00001000UL +#define CKF_VERIFY 0x00002000UL +#define CKF_VERIFY_RECOVER 0x00004000UL +#define CKF_GENERATE 0x00008000UL +#define CKF_GENERATE_KEY_PAIR 0x00010000UL +#define CKF_WRAP 0x00020000UL +#define CKF_UNWRAP 0x00040000UL +#define CKF_DERIVE 0x00080000UL +#define CKF_EC_F_P 0x00100000UL +#define CKF_EC_F_2M 0x00200000UL +#define CKF_EC_ECPARAMETERS 0x00400000UL +#define CKF_EC_NAMEDCURVE 0x00800000UL +#define CKF_EC_UNCOMPRESS 0x01000000UL +#define CKF_EC_COMPRESS 0x02000000UL + +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001UL +#define CKF_OS_LOCKING_OK 0x00000002UL + +#define CKU_SO 0UL +#define CKU_USER 1UL +#define CKU_CONTEXT_SPECIFIC 2UL + +#define CKF_RW_SESSION 0x00000002UL +#define CKF_SERIAL_SESSION 0x00000004UL + +#define CKO_PUBLIC_KEY 0x00000002UL +#define CKO_PRIVATE_KEY 0x00000003UL +#define CKO_SECRET_KEY 0x00000004UL + +#define CKK_RSA 0x00000000UL +#define CKK_DH 0x00000002UL +#define CKK_EC 0x00000003UL +#define CKK_GENERIC_SECRET 0x00000010UL +#define CKK_AES 0x0000001FUL +#define CKK_MD5_HMAC 0x00000027UL +#define CKK_SHA_1_HMAC 0x00000028UL +#define CKK_SHA256_HMAC 0x0000002bUL +#define CKK_SHA384_HMAC 0x0000002cUL +#define CKK_SHA512_HMAC 0x0000002dUL +#define CKK_SHA224_HMAC 0x0000002eUL + +#define CKA_CLASS 0x00000000UL +#define CKA_TOKEN 0x00000001UL +#define CKA_PRIVATE 0x00000002UL +#define CKA_LABEL 0x00000003UL +#define CKA_VALUE 0x00000011UL +#define CKA_OBJECT_ID 0x00000012UL +#define CKA_OWNER 0x00000084UL +#define CKA_TRUSTED 0x00000086UL +#define CKA_KEY_TYPE 0x00000100UL +#define CKA_ID 0x00000102UL +#define CKA_SENSITIVE 0x00000103UL +#define CKA_ENCRYPT 0x00000104UL +#define CKA_DECRYPT 0x00000105UL +#define CKA_WRAP 0x00000106UL +#define CKA_UNWRAP 0x00000107UL +#define CKA_SIGN 0x00000108UL +#define CKA_SIGN_RECOVER 0x00000109UL +#define CKA_VERIFY 0x0000010AUL +#define CKA_VERIFY_RECOVER 0x0000010BUL +#define CKA_DERIVE 0x0000010CUL +#define CKA_MODULUS 0x00000120UL +#define CKA_MODULUS_BITS 0x00000121UL +#define CKA_PUBLIC_EXPONENT 0x00000122UL +#define CKA_PRIVATE_EXPONENT 0x00000123UL +#define CKA_PRIME_1 0x00000124UL +#define CKA_PRIME_2 0x00000125UL +#define CKA_EXPONENT_1 0x00000126UL +#define CKA_EXPONENT_2 0x00000127UL +#define CKA_COEFFICIENT 0x00000128UL +#define CKA_PUBLIC_KEY_INFO 0x00000129UL +#define CKA_PRIME 0x00000130UL +#define CKA_BASE 0x00000132UL +#define CKA_PRIME_BITS 0x00000133UL +#define CKA_VALUE_BITS 0x00000160UL +#define CKA_VALUE_LEN 0x00000161UL +#define CKA_EXTRACTABLE 0x00000162UL +#define CKA_LOCAL 0x00000163UL +#define CKA_NEVER_EXTRACTABLE 0x00000164UL +#define CKA_ALWAYS_SENSITIVE 0x00000165UL +#define CKA_KEY_GEN_MECHANISM 0x00000166UL +#define CKA_MODIFIABLE 0x00000170UL +#define CKA_COPYABLE 0x00000171UL +#define CKA_DESTROYABLE 0x00000172UL +#define CKA_EC_PARAMS 0x00000180UL +#define CKA_EC_POINT 0x00000181UL +#define CKA_ALWAYS_AUTHENTICATE 0x00000202UL +#define CKA_HW_FEATURE_TYPE 0x00000300UL +#define CKA_RESET_ON_INIT 0x00000301UL +#define CKA_HAS_RESET 0x00000302UL + +#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000UL +#define CKM_RSA_X_509 0x00000003UL +#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020UL +#define CKM_DH_PKCS_DERIVE 0x00000021UL +#define CKM_MD5_HMAC 0x00000211UL +#define CKM_SHA_1_HMAC 0x00000221UL +#define CKM_SHA256_HMAC 0x00000251UL +#define CKM_SHA224_HMAC 0x00000256UL +#define CKM_SHA384_HMAC 0x00000261UL +#define CKM_SHA512_HMAC 0x00000271UL +#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350UL +#define CKM_EC_KEY_PAIR_GEN 0x00001040UL +#define CKM_ECDSA 0x00001041UL +#define CKM_ECDH1_DERIVE 0x00001050UL +#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051UL +#define CKM_AES_KEY_GEN 0x00001080UL +#define CKM_AES_CBC 0x00001082UL +#define CKM_AES_GCM 0x00001087UL + +#define CKR_OK 0x00000000UL +#define CKR_MECHANISM_INVALID 0x00000070UL +#define CKR_SIGNATURE_INVALID 0x000000C0UL + +#define CKD_NULL 0x00000001UL + + +typedef unsigned char CK_BYTE; +typedef CK_BYTE CK_CHAR; +typedef CK_BYTE CK_UTF8CHAR; +typedef CK_BYTE CK_BBOOL; +typedef unsigned long int CK_ULONG; +typedef long int CK_LONG; +typedef CK_ULONG CK_FLAGS; +typedef CK_BYTE* CK_BYTE_PTR; +typedef CK_CHAR* CK_CHAR_PTR; +typedef CK_UTF8CHAR* CK_UTF8CHAR_PTR; +typedef CK_ULONG* CK_ULONG_PTR; +typedef void* CK_VOID_PTR; +typedef CK_VOID_PTR* CK_VOID_PTR_PTR; + + +typedef CK_ULONG CK_RV; + + +typedef struct CK_VERSION { + CK_BYTE major; + CK_BYTE minor; +} CK_VERSION; +typedef CK_VERSION* CK_VERSION_PTR; + + +/* Info Types */ +typedef struct CK_INFO { + CK_VERSION cryptokiVersion; + CK_UTF8CHAR manufacturerID[32]; + CK_FLAGS flags; + CK_UTF8CHAR libraryDescription[32]; + CK_VERSION libraryVersion; +} CK_INFO; +typedef CK_INFO* CK_INFO_PTR; + + +/* Slot Types */ +typedef CK_ULONG CK_SLOT_ID; +typedef CK_SLOT_ID* CK_SLOT_ID_PTR; + +typedef struct CK_SLOT_INFO { + CK_UTF8CHAR slotDescription[64]; + CK_UTF8CHAR manufacturerID[32]; + CK_FLAGS flags; + + CK_VERSION hardwareVersion; + CK_VERSION firmwareVersion; +} CK_SLOT_INFO; +typedef CK_SLOT_INFO* CK_SLOT_INFO_PTR; + + +/* Token Types */ +typedef struct CK_TOKEN_INFO { + CK_UTF8CHAR label[32]; + CK_UTF8CHAR manufacturerID[32]; + CK_UTF8CHAR model[16]; + CK_CHAR serialNumber[16]; + CK_FLAGS flags; + CK_ULONG ulMaxSessionCount; + CK_ULONG ulSessionCount; + CK_ULONG ulMaxRwSessionCount; + CK_ULONG ulRwSessionCount; + CK_ULONG ulMaxPinLen; + CK_ULONG ulMinPinLen; + CK_ULONG ulTotalPublicMemory; + CK_ULONG ulFreePublicMemory; + CK_ULONG ulTotalPrivateMemory; + CK_ULONG ulFreePrivateMemory; + CK_VERSION hardwareVersion; + CK_VERSION firmwareVersion; + CK_CHAR utcTime[16]; +} CK_TOKEN_INFO; +typedef CK_TOKEN_INFO* CK_TOKEN_INFO_PTR; + + +/* Session Types */ +typedef CK_ULONG CK_SESSION_HANDLE; +typedef CK_SESSION_HANDLE* CK_SESSION_HANDLE_PTR; + +typedef CK_ULONG CK_USER_TYPE; + +typedef CK_ULONG CK_STATE; + +typedef struct CK_SESSION_INFO { + CK_SLOT_ID slotID; + CK_STATE state; + CK_FLAGS flags; + CK_ULONG ulDeviceError; +} CK_SESSION_INFO; +typedef CK_SESSION_INFO* CK_SESSION_INFO_PTR; + + +/* Object Types */ +typedef CK_ULONG CK_OBJECT_HANDLE; +typedef CK_OBJECT_HANDLE* CK_OBJECT_HANDLE_PTR; + +typedef CK_ULONG CK_OBJECT_CLASS; +typedef CK_OBJECT_CLASS* CK_OBJECT_CLASS_PTR; + +typedef CK_ULONG CK_KEY_TYPE; + +typedef CK_ULONG CK_ATTRIBUTE_TYPE; + +typedef struct CK_ATTRIBUTE { + CK_ATTRIBUTE_TYPE type; + CK_VOID_PTR pValue; + CK_ULONG ulValueLen; +} CK_ATTRIBUTE; +typedef CK_ATTRIBUTE* CK_ATTRIBUTE_PTR; + + +/* Mechanism Types */ +typedef CK_ULONG CK_MECHANISM_TYPE; +typedef CK_MECHANISM_TYPE* CK_MECHANISM_TYPE_PTR; + +typedef struct CK_MECHANISM { + CK_MECHANISM_TYPE mechanism; + CK_VOID_PTR pParameter; + CK_ULONG ulParameterLen; +} CK_MECHANISM; +typedef CK_MECHANISM* CK_MECHANISM_PTR; + +typedef struct CK_MECHANISM_INFO { + CK_ULONG ulMinKeySize; + CK_ULONG ulMaxKeySize; + CK_FLAGS flags; +} CK_MECHANISM_INFO; +typedef CK_MECHANISM_INFO * CK_MECHANISM_INFO_PTR; + + +typedef CK_ULONG CK_NOTIFICATION; + +typedef CK_RV (*CK_NOTIFY)(CK_SESSION_HANDLE hSession, CK_NOTIFICATION event, + CK_VOID_PTR pApplication); + + +/* Threading types. */ +typedef CK_RV (*CK_CREATEMUTEX)(CK_VOID_PTR_PTR ppMutex); +typedef CK_RV (*CK_DESTROYMUTEX)(CK_VOID_PTR pMutex); +typedef CK_RV (*CK_LOCKMUTEX)(CK_VOID_PTR pMutex); +typedef CK_RV (*CK_UNLOCKMUTEX)(CK_VOID_PTR pMutex); + +typedef struct CK_C_INITIALIZE_ARGS { + CK_CREATEMUTEX CreateMutex; + CK_DESTROYMUTEX DestroyMutex; + CK_LOCKMUTEX LockMutex; + CK_UNLOCKMUTEX UnlockMutex; + CK_FLAGS flags; + CK_VOID_PTR pReserved; +} CK_C_INITIALIZE_ARGS; +typedef CK_C_INITIALIZE_ARGS* CK_C_INITIALIZE_ARGS_PTR; + + +/* Cryptographic algorithm types. */ +typedef CK_ULONG CK_EC_KDF_TYPE; + +typedef struct CK_ECDH1_DERIVE_PARAMS { + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE_PTR pSharedData; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; +} CK_ECDH1_DERIVE_PARAMS; +typedef CK_ECDH1_DERIVE_PARAMS* CK_ECDH1_DERIVE_PARAMS_PTR; + + +typedef struct CK_GCM_PARAMS { + CK_BYTE_PTR pIv; + CK_ULONG ulIvLen; + CK_ULONG ulIvBits; + CK_BYTE_PTR pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulTagBits; +} CK_GCM_PARAMS; +typedef CK_GCM_PARAMS* CK_GCM_PARAMS_PTR; + +/* Function list types. */ +typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST; +typedef CK_FUNCTION_LIST* CK_FUNCTION_LIST_PTR; +typedef CK_FUNCTION_LIST_PTR* CK_FUNCTION_LIST_PTR_PTR; + +typedef CK_RV (*CK_C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR ppFunctionList); + +struct CK_FUNCTION_LIST { + CK_VERSION version; + + CK_RV (*C_Initialize)(CK_VOID_PTR pInitArgs); + CK_RV (*C_Finalize)(CK_VOID_PTR pReserved); + CK_RV (*C_GetInfo)(CK_INFO_PTR pInfo); + CK_RV (*C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR ppFunctionList); + CK_RV (*C_GetSlotList)(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, + CK_ULONG_PTR pulCount); + CK_RV (*C_GetSlotInfo)(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo); + CK_RV (*C_GetTokenInfo)(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo); + CK_RV (*C_GetMechanismList)(CK_SLOT_ID slotID, + CK_MECHANISM_TYPE_PTR pMechanismList, + CK_ULONG_PTR pulCount); + CK_RV (*C_GetMechanismInfo)(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, + CK_MECHANISM_INFO_PTR pInfo); + CK_RV (*C_InitToken)(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, + CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pLabel); + CK_RV (*C_InitPIN)(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, + CK_ULONG ulPinLen); + CK_RV (*C_SetPIN)(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, + CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, + CK_ULONG ulNewLen); + CK_RV (*C_OpenSession)(CK_SLOT_ID slotID, CK_FLAGS flags, + CK_VOID_PTR pApplication, CK_NOTIFY Notify, + CK_SESSION_HANDLE_PTR phSession); + CK_RV (*C_CloseSession)(CK_SESSION_HANDLE hSession); + CK_RV (*C_CloseAllSessions)(CK_SLOT_ID slotID); + CK_RV (*C_GetSessionInfo)(CK_SESSION_HANDLE hSession, + CK_SESSION_INFO_PTR pInfo); + CK_RV (*C_GetOperationState)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pOperationState, + CK_ULONG_PTR pulOperationStateLen); + CK_RV (*C_SetOperationState)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pOperationState, + CK_ULONG ulOperationStateLen, + CK_OBJECT_HANDLE hEncryptionKey, + CK_OBJECT_HANDLE hAuthenticationKey); + CK_RV (*C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, + CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen); + CK_RV (*C_Logout)(CK_SESSION_HANDLE hSession); + CK_RV (*C_CreateObject)(CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phObject); + CK_RV (*C_CopyObject)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phNewObject); + CK_RV (*C_DestroyObject)(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject); + CK_RV (*C_GetObjectSize)(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize); + CK_RV (*C_GetAttributeValue)(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount); + CK_RV (*C_SetAttributeValue)(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount); + CK_RV (*C_FindObjectsInit)(CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount); + CK_RV (*C_FindObjects)(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE_PTR phObject, + CK_ULONG ulMaxObjectCount, + CK_ULONG_PTR pulObjectCount); + CK_RV (*C_FindObjectsFinal)(CK_SESSION_HANDLE hSession); + CK_RV (*C_EncryptInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); + CK_RV (*C_Encrypt)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, + CK_ULONG_PTR pulEncryptedDataLen); + CK_RV (*C_EncryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen); + CK_RV (*C_EncryptFinal)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pLastEncryptedPart, + CK_ULONG_PTR pulLastEncryptedPartLen); + CK_RV (*C_DecryptInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); + CK_RV (*C_Decrypt)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, + CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, + CK_ULONG_PTR pulDataLen); + CK_RV (*C_DecryptUpdate)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, + CK_ULONG_PTR pulPartLen); + CK_RV (*C_DecryptFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, + CK_ULONG_PTR pulLastPartLen); + CK_RV (*C_DigestInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism); + CK_RV (*C_Digest)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, + CK_ULONG_PTR pulDigestLen); + CK_RV (*C_DigestUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen); + CK_RV (*C_DigestKey)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey); + CK_RV (*C_DigestFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, + CK_ULONG_PTR pulDigestLen); + CK_RV (*C_SignInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_Sign)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen); + CK_RV (*C_SignUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen); + CK_RV (*C_SignFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen); + CK_RV (*C_SignRecoverInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_SignRecover)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen); + CK_RV (*C_VerifyInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); + CK_RV (*C_Verify)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen); + CK_RV (*C_VerifyUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen); + CK_RV (*C_VerifyFinal)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen); + CK_RV (*C_VerifyRecoverInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_VerifyRecover)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, + CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen); + CK_RV (*C_DigestEncryptUpdate)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, CK_ULONG ulPartLen, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen); + CK_RV (*C_DecryptDigestUpdate)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, + CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen); + CK_RV (*C_SignEncryptUpdate)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, CK_ULONG ulPartLen, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen); + CK_RV (*C_DecryptVerifyUpdate)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, + CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen); + CK_RV (*C_GenerateKey)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phKey); + CK_RV (*C_GenerateKeyPair)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pPublicKeyTemplate, + CK_ULONG ulPublicKeyAttributeCount, + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, + CK_ULONG ulPrivateKeyAttributeCount, + CK_OBJECT_HANDLE_PTR phPublicKey, + CK_OBJECT_HANDLE_PTR phPrivateKey); + CK_RV (*C_WrapKey)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, + CK_BYTE_PTR pWrappedKey, + CK_ULONG_PTR pulWrappedKeyLen); + CK_RV (*C_UnwrapKey)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hUnwrappingKey, + CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey); + CK_RV (*C_DeriveKey)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hBaseKey, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey); + CK_RV (*C_SeedRandom)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, + CK_ULONG ulSeedLen); + CK_RV (*C_GenerateRandom)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR RandomData, CK_ULONG ulRandomLen); + CK_RV (*C_GetFunctionStatus)(CK_SESSION_HANDLE hSession); + CK_RV (*C_CancelFunction)(CK_SESSION_HANDLE hSession); + CK_RV (*C_WaitForSlotEvent)(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, + CK_VOID_PTR pRserved); + +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _PKCS11_H_ */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/pkcs12.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/pkcs12.h new file mode 100644 index 0000000..da9d4f0 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/pkcs12.h @@ -0,0 +1,72 @@ +/* pkcs12.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLF_CRYPT_PKCS12_H +#define WOLF_CRYPT_PKCS12_H + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef WOLFSSL_TYPES_DEFINED /* do not redeclare from ssl.h */ + typedef struct WC_PKCS12 WC_PKCS12; +#endif + +typedef struct WC_DerCertList { /* dereferenced in ssl.c */ + byte* buffer; + word32 bufferSz; + struct WC_DerCertList* next; +} WC_DerCertList; + +/* default values for creating PKCS12 */ +enum { + WC_PKCS12_ITT_DEFAULT = 2048, + WC_PKCS12_VERSION_DEFAULT = 3, + WC_PKCS12_MAC_DEFAULT = 1, +}; + +WOLFSSL_API WC_PKCS12* wc_PKCS12_new(void); +WOLFSSL_API void wc_PKCS12_free(WC_PKCS12* pkcs12); +WOLFSSL_API int wc_d2i_PKCS12(const byte* der, word32 derSz, WC_PKCS12* pkcs12); +WOLFSSL_API int wc_i2d_PKCS12(WC_PKCS12* pkcs12, byte** der, int* derSz); +WOLFSSL_API int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, + byte** pkey, word32* pkeySz, byte** cert, word32* certSz, + WC_DerCertList** ca); +WOLFSSL_API WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, + char* name, byte* key, word32 keySz, byte* cert, word32 certSz, + WC_DerCertList* ca, int nidKey, int nidCert, int iter, int macIter, + int keyType, void* heap); + + +WOLFSSL_LOCAL int wc_PKCS12_SetHeap(WC_PKCS12* pkcs12, void* heap); +WOLFSSL_LOCAL void* wc_PKCS12_GetHeap(WC_PKCS12* pkcs12); + +WOLFSSL_LOCAL void wc_FreeCertList(WC_DerCertList* list, void* heap); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLF_CRYPT_PKCS12_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/pkcs7.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/pkcs7.h new file mode 100644 index 0000000..6d327d4 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/pkcs7.h @@ -0,0 +1,500 @@ +/* pkcs7.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/pkcs7.h +*/ + +#ifndef WOLF_CRYPT_PKCS7_H +#define WOLF_CRYPT_PKCS7_H + +#include + +#ifdef HAVE_PKCS7 + +#ifndef NO_ASN + #include +#endif +#include +#include +#ifndef NO_AES + #include +#endif +#ifndef NO_DES3 + #include +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +/* Max number of certificates that PKCS7 structure can parse */ +#ifndef MAX_PKCS7_CERTS + #define MAX_PKCS7_CERTS 4 +#endif + +#ifndef MAX_ORI_TYPE_SZ + #define MAX_ORI_TYPE_SZ MAX_OID_SZ +#endif +#ifndef MAX_ORI_VALUE_SZ + #define MAX_ORI_VALUE_SZ 512 +#endif + +#ifndef MAX_SIGNED_ATTRIBS_SZ + #define MAX_SIGNED_ATTRIBS_SZ 7 +#endif + +#ifndef MAX_AUTH_ATTRIBS_SZ + #define MAX_AUTH_ATTRIBS_SZ 7 +#endif + +#ifndef MAX_UNAUTH_ATTRIBS_SZ + #define MAX_UNAUTH_ATTRIBS_SZ 7 +#endif + +/* PKCS#7 content types, ref RFC 2315 (Section 14) */ +enum PKCS7_TYPES { + PKCS7_MSG = 650, /* 1.2.840.113549.1.7 */ + DATA = 651, /* 1.2.840.113549.1.7.1 */ + SIGNED_DATA = 652, /* 1.2.840.113549.1.7.2 */ + ENVELOPED_DATA = 653, /* 1.2.840.113549.1.7.3 */ + SIGNED_AND_ENVELOPED_DATA = 654, /* 1.2.840.113549.1.7.4 */ + DIGESTED_DATA = 655, /* 1.2.840.113549.1.7.5 */ + ENCRYPTED_DATA = 656, /* 1.2.840.113549.1.7.6 */ +#if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA) + COMPRESSED_DATA = 678, /* 1.2.840.113549.1.9.16.1.9, RFC 3274 */ +#endif + FIRMWARE_PKG_DATA = 685, /* 1.2.840.113549.1.9.16.1.16, RFC 4108 */ + AUTH_ENVELOPED_DATA = 692 /* 1.2.840.113549.1.9.16.1.23, RFC 5083 */ +}; + +enum PKCS7_STATE { + WC_PKCS7_START = 0, + + /* decode encrypted */ + WC_PKCS7_STAGE2, + WC_PKCS7_STAGE3, + WC_PKCS7_STAGE4, + WC_PKCS7_STAGE5, + WC_PKCS7_STAGE6, + + WC_PKCS7_VERIFY_STAGE2, + WC_PKCS7_VERIFY_STAGE3, + WC_PKCS7_VERIFY_STAGE4, + WC_PKCS7_VERIFY_STAGE5, + WC_PKCS7_VERIFY_STAGE6, + + /* parse info set */ + WC_PKCS7_INFOSET_START, + WC_PKCS7_INFOSET_BER, + WC_PKCS7_INFOSET_STAGE1, + WC_PKCS7_INFOSET_STAGE2, + WC_PKCS7_INFOSET_END, + + /* decode enveloped data */ + WC_PKCS7_ENV_2, + WC_PKCS7_ENV_3, + WC_PKCS7_ENV_4, + WC_PKCS7_ENV_5, + + /* decode auth enveloped */ + WC_PKCS7_AUTHENV_2, + WC_PKCS7_AUTHENV_3, + WC_PKCS7_AUTHENV_4, + WC_PKCS7_AUTHENV_5, + WC_PKCS7_AUTHENV_6, + WC_PKCS7_AUTHENV_ATRB, + WC_PKCS7_AUTHENV_ATRBEND, + WC_PKCS7_AUTHENV_7, + + /* decryption state types */ + WC_PKCS7_DECRYPT_KTRI, + WC_PKCS7_DECRYPT_KTRI_2, + WC_PKCS7_DECRYPT_KTRI_3, + + + WC_PKCS7_DECRYPT_KARI, + WC_PKCS7_DECRYPT_KEKRI, + WC_PKCS7_DECRYPT_PWRI, + WC_PKCS7_DECRYPT_ORI, + + WC_PKCS7_DECRYPT_DONE, + +}; + +enum Pkcs7_Misc { + PKCS7_NONCE_SZ = 16, + MAX_ENCRYPTED_KEY_SZ = 512, /* max enc. key size, RSA <= 4096 */ + MAX_CONTENT_KEY_LEN = 32, /* highest current cipher is AES-256-CBC */ + MAX_CONTENT_IV_SIZE = 16, /* highest current is AES128 */ +#ifndef NO_AES + MAX_CONTENT_BLOCK_LEN = AES_BLOCK_SIZE, +#else + MAX_CONTENT_BLOCK_LEN = DES_BLOCK_SIZE, +#endif + MAX_RECIP_SZ = MAX_VERSION_SZ + + MAX_SEQ_SZ + ASN_NAME_MAX + MAX_SN_SZ + + MAX_SEQ_SZ + MAX_ALGO_SZ + 1 + MAX_ENCRYPTED_KEY_SZ, +#if (defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \ + (HAVE_FIPS_VERSION >= 2)) || defined(HAVE_SELFTEST) + /* In the event of fips cert 3389 or CAVP selftest build, these enums are + * not in aes.h for use with pkcs7 so enumerate it here outside the fips + * boundary */ + GCM_NONCE_MID_SZ = 12, /* The usual default nonce size for AES-GCM. */ + CCM_NONCE_MIN_SZ = 7, +#endif +}; + +enum Cms_Options { + CMS_SKID = 1, + CMS_ISSUER_AND_SERIAL_NUMBER = 2, +}; +#define DEGENERATE_SID 3 + +/* CMS/PKCS#7 RecipientInfo types, RFC 5652, Section 6.2 */ +enum Pkcs7_RecipientInfo_Types { + PKCS7_KTRI = 0, + PKCS7_KARI = 1, + PKCS7_KEKRI = 2, + PKCS7_PWRI = 3, + PKCS7_ORI = 4 +}; + +typedef struct PKCS7Attrib { + const byte* oid; + word32 oidSz; + const byte* value; + word32 valueSz; +} PKCS7Attrib; + + +typedef struct PKCS7DecodedAttrib { + struct PKCS7DecodedAttrib* next; + byte* oid; + word32 oidSz; + byte* value; + word32 valueSz; +} PKCS7DecodedAttrib; + +typedef struct PKCS7State PKCS7State; +typedef struct Pkcs7Cert Pkcs7Cert; +typedef struct Pkcs7EncodedRecip Pkcs7EncodedRecip; +typedef struct PKCS7 PKCS7; +typedef struct PKCS7 PKCS7_SIGNED; +typedef struct PKCS7SignerInfo PKCS7SignerInfo; + +/* OtherRecipientInfo decrypt callback prototype */ +typedef int (*CallbackOriDecrypt)(PKCS7* pkcs7, byte* oriType, word32 oriTypeSz, + byte* oriValue, word32 oriValueSz, + byte* decryptedKey, word32* decryptedKeySz, + void* ctx); +typedef int (*CallbackOriEncrypt)(PKCS7* pkcs7, byte* cek, word32 cekSz, + byte* oriType, word32* oriTypeSz, + byte* oriValue, word32* oriValueSz, + void* ctx); +typedef int (*CallbackDecryptContent)(PKCS7* pkcs7, int encryptOID, + byte* iv, int ivSz, byte* aad, word32 aadSz, + byte* authTag, word32 authTagSz, byte* in, + int inSz, byte* out, void* ctx); +typedef int (*CallbackWrapCEK)(PKCS7* pkcs7, byte* cek, word32 cekSz, + byte* keyId, word32 keyIdSz, + byte* originKey, word32 originKeySz, + byte* out, word32 outSz, + int keyWrapAlgo, int type, int dir); + +#if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA) +/* RSA sign raw digest callback, user builds DigestInfo */ +typedef int (*CallbackRsaSignRawDigest)(PKCS7* pkcs7, byte* digest, + word32 digestSz, byte* out, word32 outSz, + byte* privateKey, word32 privateKeySz, + int devId, int hashOID); +#endif + +/* Public Structure Warning: + * Existing members must not be changed to maintain backwards compatibility! + */ +struct PKCS7 { + WC_RNG* rng; + PKCS7Attrib* signedAttribs; + byte* content; /* inner content, not owner */ + byte* contentDynamic; /* content if constructed OCTET_STRING */ + byte* singleCert; /* recipient cert, DER, not owner */ + const byte* issuer; /* issuer name of singleCert */ + byte* privateKey; /* private key, DER, not owner */ + void* heap; /* heap hint for dynamic memory */ +#ifdef ASN_BER_TO_DER + byte* der; /* DER encoded version of message */ + word32 derSz; +#endif + byte* cert[MAX_PKCS7_CERTS]; + + /* Encrypted-data Content Type */ + byte* encryptionKey; /* block cipher encryption key */ + PKCS7Attrib* unprotectedAttribs; /* optional */ + PKCS7DecodedAttrib* decodedAttrib; /* linked list of decoded attribs */ + + /* Enveloped-data optional ukm, not owner */ + byte* ukm; + word32 ukmSz; + + word32 encryptionKeySz; /* size of key buffer, bytes */ + word32 unprotectedAttribsSz; + word32 contentSz; /* content size */ + word32 singleCertSz; /* size of recipient cert buffer, bytes */ + word32 issuerSz; /* length of issuer name */ + word32 issuerSnSz; /* length of serial number */ + + word32 publicKeySz; + word32 publicKeyOID; /* key OID (RSAk, ECDSAk, etc) */ + word32 privateKeySz; /* size of private key buffer, bytes */ + word32 signedAttribsSz; + int contentOID; /* PKCS#7 content type OID sum */ + int hashOID; + int encryptOID; /* key encryption algorithm OID */ + int keyWrapOID; /* key wrap algorithm OID */ + int keyAgreeOID; /* key agreement algorithm OID */ + int devId; /* device ID for HW based private key */ + byte issuerHash[KEYID_SIZE]; /* hash of all alt Names */ + byte issuerSn[MAX_SN_SZ]; /* singleCert's serial number */ + byte publicKey[MAX_RSA_INT_SZ + MAX_RSA_E_SZ]; /* MAX RSA key size (m + e)*/ + word32 certSz[MAX_PKCS7_CERTS]; + + /* flags - up to 16-bits */ + word16 isDynamic:1; + word16 noDegenerate:1; /* allow degenerate case in verify function */ + word16 detached:1; /* generate detached SignedData signature bundles */ + + byte contentType[MAX_OID_SZ]; /* custom contentType byte array */ + word32 contentTypeSz; /* size of contentType, bytes */ + + int sidType; /* SignerIdentifier type to use, of type + Pkcs7_SignerIdentifier_Types, default to + SID_ISSUER_AND_SERIAL_NUMBER */ + byte issuerSubjKeyId[KEYID_SIZE]; /* SubjectKeyIdentifier of singleCert */ + Pkcs7Cert* certList; /* certificates list for SignedData set */ + Pkcs7EncodedRecip* recipList; /* recipients list */ + byte* cek; /* content encryption key, random, dynamic */ + word32 cekSz; /* size of cek, bytes */ + byte* pass; /* password, for PWRI decryption */ + word32 passSz; /* size of pass, bytes */ + int kekEncryptOID; /* KEK encryption algorithm OID */ + + CallbackOriEncrypt oriEncryptCb; /* ORI encrypt callback */ + CallbackOriDecrypt oriDecryptCb; /* ORI decrypt callback */ + void* oriEncryptCtx; /* ORI encrypt user context ptr */ + void* oriDecryptCtx; /* ORI decrypt user context ptr */ + + PKCS7Attrib* authAttribs; /* authenticated attribs */ + word32 authAttribsSz; + PKCS7Attrib* unauthAttribs; /* unauthenticated attribs */ + word32 unauthAttribsSz; + +#ifndef NO_PKCS7_STREAM + PKCS7State* stream; +#endif + word32 state; + + word16 skipDefaultSignedAttribs:1; /* skip adding default signed attribs */ + + byte version; /* 1 for RFC 2315 and 3 for RFC 4108 */ + PKCS7SignerInfo* signerInfo; + CallbackDecryptContent decryptionCb; + CallbackWrapCEK wrapCEKCb; + void* decryptionCtx; + + byte* signature; + byte* plainDigest; + byte* pkcs7Digest; + word32 signatureSz; + word32 plainDigestSz; + word32 pkcs7DigestSz; + +#if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA) + CallbackRsaSignRawDigest rsaSignRawDigestCb; +#endif + /* !! NEW DATA MEMBERS MUST BE ADDED AT END !! */ +}; + +WOLFSSL_API PKCS7* wc_PKCS7_New(void* heap, int devId); +WOLFSSL_API int wc_PKCS7_Init(PKCS7* pkcs7, void* heap, int devId); +WOLFSSL_API int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* der, word32 derSz); +WOLFSSL_API int wc_PKCS7_AddCertificate(PKCS7* pkcs7, byte* der, word32 derSz); +WOLFSSL_API void wc_PKCS7_Free(PKCS7* pkcs7); + +WOLFSSL_API int wc_PKCS7_GetAttributeValue(PKCS7* pkcs7, const byte* oid, + word32 oidSz, byte* out, word32* outSz); + +WOLFSSL_API int wc_PKCS7_SetSignerIdentifierType(PKCS7* pkcs7, int type); +WOLFSSL_API int wc_PKCS7_SetContentType(PKCS7* pkcs7, byte* contentType, + word32 sz); +WOLFSSL_API int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz); +WOLFSSL_API int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz, + word32 blockSz); + +/* CMS/PKCS#7 Data */ +WOLFSSL_API int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output, + word32 outputSz); + +/* CMS/PKCS#7 SignedData */ +WOLFSSL_API int wc_PKCS7_SetDetached(PKCS7* pkcs7, word16 flag); +WOLFSSL_API int wc_PKCS7_NoDefaultSignedAttribs(PKCS7* pkcs7); +WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, + byte* output, word32 outputSz); +WOLFSSL_API int wc_PKCS7_EncodeSignedData_ex(PKCS7* pkcs7, const byte* hashBuf, + word32 hashSz, byte* outputHead, + word32* outputHeadSz, + byte* outputFoot, + word32* outputFootSz); +WOLFSSL_API void wc_PKCS7_AllowDegenerate(PKCS7* pkcs7, word16 flag); +WOLFSSL_API int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, + byte* pkiMsg, word32 pkiMsgSz); +WOLFSSL_API int wc_PKCS7_VerifySignedData_ex(PKCS7* pkcs7, const byte* hashBuf, + word32 hashSz, byte* pkiMsgHead, + word32 pkiMsgHeadSz, byte* pkiMsgFoot, + word32 pkiMsgFootSz); + +WOLFSSL_API int wc_PKCS7_GetSignerSID(PKCS7* pkcs7, byte* out, word32* outSz); + +/* CMS single-shot API for Signed FirmwarePkgData */ +WOLFSSL_API int wc_PKCS7_EncodeSignedFPD(PKCS7* pkcs7, byte* privateKey, + word32 privateKeySz, int signOID, + int hashOID, byte* content, + word32 contentSz, + PKCS7Attrib* signedAttribs, + word32 signedAttribsSz, byte* output, + word32 outputSz); +#ifndef NO_PKCS7_ENCRYPTED_DATA +/* CMS single-shot API for Signed Encrypted FirmwarePkgData */ +WOLFSSL_API int wc_PKCS7_EncodeSignedEncryptedFPD(PKCS7* pkcs7, + byte* encryptKey, word32 encryptKeySz, + byte* privateKey, word32 privateKeySz, + int encryptOID, int signOID, + int hashOID, byte* content, + word32 contentSz, + PKCS7Attrib* unprotectedAttribs, + word32 unprotectedAttribsSz, + PKCS7Attrib* signedAttribs, + word32 signedAttribsSz, + byte* output, word32 outputSz); +#endif /* NO_PKCS7_ENCRYPTED_DATA */ +#if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA) +/* CMS single-shot API for Signed Compressed FirmwarePkgData */ +WOLFSSL_API int wc_PKCS7_EncodeSignedCompressedFPD(PKCS7* pkcs7, + byte* privateKey, word32 privateKeySz, + int signOID, int hashOID, + byte* content, word32 contentSz, + PKCS7Attrib* signedAttribs, + word32 signedAttribsSz, byte* output, + word32 outputSz); + +#ifndef NO_PKCS7_ENCRYPTED_DATA +/* CMS single-shot API for Signed Encrypted Compressed FirmwarePkgData */ +WOLFSSL_API int wc_PKCS7_EncodeSignedEncryptedCompressedFPD(PKCS7* pkcs7, + byte* encryptKey, word32 encryptKeySz, + byte* privateKey, word32 privateKeySz, + int encryptOID, int signOID, + int hashOID, byte* content, + word32 contentSz, + PKCS7Attrib* unprotectedAttribs, + word32 unprotectedAttribsSz, + PKCS7Attrib* signedAttribs, + word32 signedAttribsSz, + byte* output, word32 outputSz); +#endif /* !NO_PKCS7_ENCRYPTED_DATA */ +#endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */ + +/* EnvelopedData and AuthEnvelopedData RecipientInfo functions */ +WOLFSSL_API int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, + word32 certSz, int options); +WOLFSSL_API int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, + word32 certSz, int keyWrapOID, + int keyAgreeOID, byte* ukm, + word32 ukmSz, int options); + +WOLFSSL_API int wc_PKCS7_SetKey(PKCS7* pkcs7, byte* key, word32 keySz); +WOLFSSL_API int wc_PKCS7_AddRecipient_KEKRI(PKCS7* pkcs7, int keyWrapOID, + byte* kek, word32 kekSz, + byte* keyID, word32 keyIdSz, + void* timePtr, byte* otherOID, + word32 otherOIDSz, byte* other, + word32 otherSz, int options); + +WOLFSSL_API int wc_PKCS7_SetPassword(PKCS7* pkcs7, byte* passwd, word32 pLen); +WOLFSSL_API int wc_PKCS7_AddRecipient_PWRI(PKCS7* pkcs7, byte* passwd, + word32 pLen, byte* salt, + word32 saltSz, int kdfOID, + int prfOID, int iterations, + int kekEncryptOID, int options); +WOLFSSL_API int wc_PKCS7_SetOriEncryptCtx(PKCS7* pkcs7, void* ctx); +WOLFSSL_API int wc_PKCS7_SetOriDecryptCtx(PKCS7* pkcs7, void* ctx); +WOLFSSL_API int wc_PKCS7_SetOriDecryptCb(PKCS7* pkcs7, CallbackOriDecrypt cb); +WOLFSSL_API int wc_PKCS7_AddRecipient_ORI(PKCS7* pkcs7, CallbackOriEncrypt cb, + int options); +WOLFSSL_API int wc_PKCS7_SetWrapCEKCb(PKCS7* pkcs7, + CallbackWrapCEK wrapCEKCb); + +#if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA) +WOLFSSL_API int wc_PKCS7_SetRsaSignRawDigestCb(PKCS7* pkcs7, + CallbackRsaSignRawDigest cb); +#endif + +/* CMS/PKCS#7 EnvelopedData */ +WOLFSSL_API int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, + byte* output, word32 outputSz); +WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, + word32 pkiMsgSz, byte* output, + word32 outputSz); + +/* CMS/PKCS#7 AuthEnvelopedData */ +WOLFSSL_API int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, + byte* output, word32 outputSz); +WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, + word32 pkiMsgSz, byte* output, + word32 outputSz); + +/* CMS/PKCS#7 EncryptedData */ +#ifndef NO_PKCS7_ENCRYPTED_DATA +WOLFSSL_API int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, + byte* output, word32 outputSz); +WOLFSSL_API int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* pkiMsg, + word32 pkiMsgSz, byte* output, + word32 outputSz); +WOLFSSL_API int wc_PKCS7_SetDecodeEncryptedCb(PKCS7* pkcs7, + CallbackDecryptContent decryptionCb); +WOLFSSL_API int wc_PKCS7_SetDecodeEncryptedCtx(PKCS7* pkcs7, void* ctx); +#endif /* NO_PKCS7_ENCRYPTED_DATA */ + +/* CMS/PKCS#7 CompressedData */ +#if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA) +WOLFSSL_API int wc_PKCS7_EncodeCompressedData(PKCS7* pkcs7, byte* output, + word32 outputSz); +WOLFSSL_API int wc_PKCS7_DecodeCompressedData(PKCS7* pkcs7, byte* pkiMsg, + word32 pkiMsgSz, byte* output, + word32 outputSz); +#endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_PKCS7 */ +#endif /* WOLF_CRYPT_PKCS7_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/poly1305.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/poly1305.h new file mode 100644 index 0000000..0f81ca0 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/poly1305.h @@ -0,0 +1,127 @@ +/* poly1305.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/poly1305.h +*/ + +#ifndef WOLF_CRYPT_POLY1305_H +#define WOLF_CRYPT_POLY1305_H + +#include + +#ifdef HAVE_POLY1305 + +#ifdef __cplusplus + extern "C" { +#endif + +/* auto detect between 32bit / 64bit */ +#if defined(__SIZEOF_INT128__) && defined(__LP64__) +#define WC_HAS_SIZEOF_INT128_64BIT +#endif + +#if defined(_MSC_VER) && defined(_M_X64) +#define WC_HAS_MSVC_64BIT +#endif + +#if (defined(__GNUC__) && defined(__LP64__) && \ + ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)))) +#define WC_HAS_GCC_4_4_64BIT +#endif + +#ifdef USE_INTEL_SPEEDUP +#elif (defined(WC_HAS_SIZEOF_INT128_64BIT) || defined(WC_HAS_MSVC_64BIT) || \ + defined(WC_HAS_GCC_4_4_64BIT)) +#define POLY130564 +#else +#define POLY130532 +#endif + +enum { + POLY1305 = 7, + POLY1305_BLOCK_SIZE = 16, + POLY1305_DIGEST_SIZE = 16, +}; + +#define WC_POLY1305_PAD_SZ 16 +#define WC_POLY1305_MAC_SZ 16 + +/* Poly1305 state */ +typedef struct Poly1305 { +#ifdef USE_INTEL_SPEEDUP + word64 r[3]; + word64 h[3]; + word64 pad[2]; + word64 hh[20]; + word32 r1[8]; + word32 r2[8]; + word32 r3[8]; + word32 r4[8]; + word64 hm[16]; + unsigned char buffer[8*POLY1305_BLOCK_SIZE]; + size_t leftover; + unsigned char finished; + unsigned char started; +#else +#if defined(WOLFSSL_ARMASM) && defined(__aarch64__) + ALIGN128 word32 r[5]; + ALIGN128 word32 r_2[5]; // r^2 + ALIGN128 word32 r_4[5]; // r^4 + ALIGN128 word32 h[5]; + word32 pad[4]; + word64 leftover; +#else +#if defined(POLY130564) + word64 r[3]; + word64 h[3]; + word64 pad[2]; +#else + word32 r[5]; + word32 h[5]; + word32 pad[4]; +#endif + size_t leftover; +#endif /* WOLFSSL_ARMASM */ + unsigned char buffer[POLY1305_BLOCK_SIZE]; + unsigned char finished; +#endif +} Poly1305; + +/* does init */ + +WOLFSSL_API int wc_Poly1305SetKey(Poly1305* poly1305, const byte* key, + word32 kySz); +WOLFSSL_API int wc_Poly1305Update(Poly1305* poly1305, const byte*, word32); +WOLFSSL_API int wc_Poly1305Final(Poly1305* poly1305, byte* tag); +WOLFSSL_API int wc_Poly1305_MAC(Poly1305* ctx, byte* additional, word32 addSz, + byte* input, word32 sz, byte* tag, word32 tagSz); + +void poly1305_block(Poly1305* ctx, const unsigned char *m); +void poly1305_blocks(Poly1305* ctx, const unsigned char *m, + size_t bytes); +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_POLY1305 */ +#endif /* WOLF_CRYPT_POLY1305_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h new file mode 100644 index 0000000..433066a --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h @@ -0,0 +1,152 @@ +/* esp32-crypt.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ +#ifndef __ESP32_CRYPT_H__ + +#define __ESP32_CRYPT_H__ + +#include "esp_idf_version.h" +#include "esp_types.h" +#include "esp_log.h" + +#ifdef WOLFSSL_ESP32WROOM32_CRYPT_DEBUG +#undef LOG_LOCAL_LEVEL +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG +#else +#undef LOG_LOCAL_LEVEL +#define LOG_LOCAL_LEVEL ESP_LOG_ERROR +#endif + +#include +#include "soc/dport_reg.h" +#include "soc/hwcrypto_reg.h" +#include "soc/cpu.h" +#include "driver/periph_ctrl.h" +#if ESP_IDF_VERSION_MAJOR >= 4 && ESP_IDF_VERSION_MINOR >= 1 +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +int esp_CryptHwMutexInit(wolfSSL_Mutex* mutex); +int esp_CryptHwMutexLock(wolfSSL_Mutex* mutex, TickType_t xBloxkTime); +int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex); + +#ifndef NO_AES + +#if ESP_IDF_VERSION_MAJOR >= 4 && ESP_IDF_VERSION_MINOR >= 1 +#include "esp32/rom/aes.h" +#else +#include "rom/aes.h" +#endif + +typedef enum tagES32_AES_PROCESS { + ESP32_AES_LOCKHW = 1, + ESP32_AES_UPDATEKEY_ENCRYPT = 2, + ESP32_AES_UPDATEKEY_DECRYPT = 3, + ESP32_AES_UNLOCKHW = 4 +} ESP32_AESPROCESS; + +struct Aes; +int wc_esp32AesCbcEncrypt(struct Aes* aes, byte* out, const byte* in, word32 sz); +int wc_esp32AesCbcDecrypt(struct Aes* aes, byte* out, const byte* in, word32 sz); +int wc_esp32AesEncrypt(struct Aes *aes, const byte* in, byte* out); +int wc_esp32AesDecrypt(struct Aes *aes, const byte* in, byte* out); + +#endif + +#ifdef WOLFSSL_ESP32WROOM32_CRYPT_DEBUG + +void wc_esp32TimerStart(); +uint64_t wc_esp32elapsedTime(); + +#endif /* WOLFSSL_ESP32WROOM32_CRYPT_DEBUG */ + +#if (!defined(NO_SHA) || !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || \ + defined(WOLFSSL_SHA512)) && \ + !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) + +/* RAW hash function APIs are not implemented with esp32 hardware acceleration*/ +#define WOLFSSL_NO_HASH_RAW +#if ESP_IDF_VERSION_MAJOR >= 4 && ESP_IDF_VERSION_MINOR >= 1 +#include "esp32/rom/sha.h" +#else +#include "rom/sha.h" +#endif + +typedef enum { + ESP32_SHA_INIT = 0, + ESP32_SHA_HW = 1, + ESP32_SHA_SW = 2, +} ESP32_DOSHA; + +typedef struct { + byte isfirstblock; + /* 0 , 1 hard, 2 soft */ + byte mode; + /* sha_type */ + enum SHA_TYPE sha_type; +} WC_ESP32SHA; + +int esp_sha_try_hw_lock(WC_ESP32SHA* ctx); +void esp_sha_hw_unlock( void ); + +struct wc_Sha; +int esp_sha_digest_process(struct wc_Sha* sha, byte bockprocess); +int esp_sha_process(struct wc_Sha* sha, const byte* data); + +#ifndef NO_SHA256 + struct wc_Sha256; + int esp_sha256_digest_process(struct wc_Sha256* sha, byte bockprocess); + int esp_sha256_process(struct wc_Sha256* sha, const byte* data); +#endif + +#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384) + struct wc_Sha512; + int esp_sha512_process(struct wc_Sha512* sha); + int esp_sha512_digest_process(struct wc_Sha512* sha, byte blockproc); +#endif + +#endif /* NO_SHA && */ + +#if !defined(NO_RSA) || defined(HAVE_ECC) + +#ifndef ESP_RSA_TIMEOUT + #define ESP_RSA_TIMEOUT 0xFFFFF +#endif + +struct fp_int; +int esp_mp_mul(struct fp_int* X, struct fp_int* Y, struct fp_int* Z); +int esp_mp_exptmod(struct fp_int* G, struct fp_int* X, word32 Xbits, struct fp_int* P, + struct fp_int* Y); +int esp_mp_mulmod(struct fp_int* X, struct fp_int* Y, struct fp_int* M, + struct fp_int* Z); + +#endif /* NO_RSA || HAVE_ECC*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP32_CRYPT_H__ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h new file mode 100644 index 0000000..7b60681 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h @@ -0,0 +1,153 @@ +/* renesas-tsip-crypt.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ +#ifndef __RENESAS_TSIP_CRYPT_H__ +#define __RENESAS_TSIP_CRYPT_H__ + +#if defined(WOLFSSL_RENESAS_TSIP_IAREWRX) + #include "r_bsp/mcu/all/r_rx_compiler.h" + #include "r_bsp/platform.h" +#else + #include "platform.h" +#endif + +#include "r_tsip_rx_if.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + tsip_Key_SESSION = 1, + tsip_Key_AES128 = 2, + tsip_Key_AES256 = 3, + tsip_Key_RSA1024 = 4, + tsip_Key_RSA2048 = 5, + tsip_Key_tls_Rsa2048 = 6, + UNKNOW = -1, +} wolfssl_TSIP_KEY_IV; + +enum { + l_TLS_RSA_WITH_AES_128_CBC_SHA = 0x2F, + l_TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x3c, + l_TLS_RSA_WITH_AES_256_CBC_SHA = 0x35, + l_TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x3d, +}; + +typedef struct +{ + uint8_t *encrypted_session_key; + uint8_t *iv; + uint8_t *encrypted_user_tls_key; + tsip_tls_ca_certification_public_key_index_t user_rsa2048_tls_pubindex; +} tsip_key_data; + +struct WOLFSSL; + +int tsip_Open( ); +void tsip_Close( ); +int tsip_hw_lock(); +void tsip_hw_unlock( void ); +int tsip_usable(const struct WOLFSSL *ssl); +void tsip_inform_sflash_signedcacert(const byte *ps_flash, + const byte *psigned_ca_cert, word32 len); +void tsip_inform_cert_sign(const byte *sign); +/* set / get key */ +void tsip_inform_user_keys(byte *encrypted_session_key, byte *iv, + byte *encrypted_user_tls_key); + +byte tsip_rootCAverified( ); +byte tsip_checkCA(word32 cmIdx); +int tsip_tls_RootCertVerify(const byte *cert , word32 cert_len, + word32 key_n_start, word32 key_n_len, + word32 key_e_start, word32 key_e_len, + word32 cm_row); +int tsip_tls_CertVerify(const byte *cert, word32 certSz, + const byte *signature, word32 sigSz, + word32 key_n_start, word32 key_n_len, + word32 key_e_start, word32 key_e_len, + byte *tsip_encRsaKeyIdx); +void tsip_inform_key_position(const word32 key_n_start, const word32 key_n_len, + const word32 key_e_start, const word32 key_e_len); +int tsip_generatePremasterSecret(byte *premaster, word32 preSz); +int tsip_generateEncryptPreMasterSecret(struct WOLFSSL *ssl, byte *out, + word32 *outSz); +int tsip_generateMasterSecret(const byte *pre, const byte *cr,const byte *sr, + byte *ms); +int tsip_generateSeesionKey(struct WOLFSSL *ssl); +int tsip_Sha256Hmac(const struct WOLFSSL *ssl, const byte *myInner, + word32 innerSz, const byte *in, word32 sz, byte *digest, + word32 verify); +int tsip_Sha1Hmac(const struct WOLFSSL *ssl, const byte *myInner, + word32 innerSz, const byte *in, word32 sz, byte *digest, + word32 verify); + +#if (!defined(NO_SHA) || !defined(NO_SHA256)) && \ + !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH) + +typedef enum { + TSIP_SHA1 = 0, + TSIP_SHA256 = 1, +} TSIP_SHA_TYPE; + +typedef struct { + byte* msg; + void* heap; + word32 used; + word32 len; + word32 sha_type; +} wolfssl_TSIP_Hash; + +/* RAW hash function APIs are not implemented with TSIP */ +#define WOLFSSL_NO_HASH_RAW + +typedef wolfssl_TSIP_Hash wc_Sha; + +#if !defined(NO_SHA256) + typedef wolfssl_TSIP_Hash wc_Sha256; +#endif + +#endif /* NO_SHA */ + +#if defined(WOLFSSL_RENESAS_TSIP_TLS_AES_CRYPT) +typedef struct { + tsip_aes_key_index_t tsip_keyIdx; + word32 keySize; +} TSIP_AES_CTX; + + struct Aes; + int wc_tsip_AesCbcEncrypt(struct Aes* aes, byte* out, const byte* in, + word32 sz); + int wc_tsip_AesCbcDecrypt(struct Aes* aes, byte* out, const byte* in, + word32 sz); + +#endif /* WOLFSSL_RENESAS_TSIP_TLS_AES */ + +#if defined(WOLFSSL_RENESAS_TSIP_CRYPT_DEBUG) +byte *ret2err(word32 ret); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __RENESAS_TSIP_CRYPT_H__ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/af_alg/afalg_hash.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/af_alg/afalg_hash.h new file mode 100644 index 0000000..7919451 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/af_alg/afalg_hash.h @@ -0,0 +1,50 @@ +/* afalg_hash.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLF_CRYPT_AFALG_HASH_H +#define WOLF_CRYPT_AFALG_HASH_H + +#include + +#undef WOLFSSL_NO_HASH_RAW +#define WOLFSSL_NO_HASH_RAW + +typedef struct { + byte* msg; + void* heap; + word32 used; + word32 len; + int alFd; + int rdFd; +} wolfssl_AFALG_Hash; + + + +#if !defined(NO_SHA256) && defined(WOLFSSL_AFALG_HASH) + typedef wolfssl_AFALG_Hash wc_Sha256; +#endif +#if defined(WOLFSSL_SHA3) && defined(WOLFSSL_AFALG_XILINX_SHA3) + typedef wolfssl_AFALG_Hash wc_Sha3; +#endif + +#endif /* WOLF_CRYPT_AFALG_HASH_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/af_alg/wc_afalg.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/af_alg/wc_afalg.h new file mode 100644 index 0000000..2e45556 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/af_alg/wc_afalg.h @@ -0,0 +1,53 @@ +/* wc_afalg.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLFSSL_AFALG_H +#define WOLFSSL_AFALG_H + +#include + +#include +#include +#include + +#define WC_SOCK_NOTSET -1 + +/* In some cases these flags are not set in AF_ALG header files. + * Documentation provided at kernel.org/doc/html/v4.16/crypto/userspace-if.html + * suggests using these values if not set */ +#ifndef AF_ALG + #define AF_ALG 38 +#endif +#ifndef SOL_ALG + #define SOL_ALG 279 +#endif + +WOLFSSL_LOCAL void wc_Afalg_SockAddr(struct sockaddr_alg* in, const char* type, const char* name); +WOLFSSL_LOCAL int wc_Afalg_Accept(struct sockaddr_alg* in, int inSz, int sock); +WOLFSSL_LOCAL int wc_Afalg_Socket(void); +WOLFSSL_LOCAL int wc_Afalg_CreateRead(int sock, const char* type, const char* name); +WOLFSSL_LOCAL int wc_Afalg_SetIv(struct cmsghdr* cmsg, byte* iv, word32 ivSz); +WOLFSSL_LOCAL int wc_Afalg_SetOp(struct cmsghdr* cmsg, int dir); +WOLFSSL_LOCAL int wc_Afalg_SetAad(struct cmsghdr* cmsg, word32 sz); + +#endif /* WOLFSSL_AFALG_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/arm/cryptoCell.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/arm/cryptoCell.h new file mode 100644 index 0000000..a1bd031 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/arm/cryptoCell.h @@ -0,0 +1,117 @@ +/* cryptoCell.h + * + * Copyright (C) 2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef WOLFSSL_CRYPTOCELL_H +#define WOLFSSL_CRYPTOCELL_H + +#if defined(WOLFSSL_CRYPTOCELL) +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "sns_silib.h" + +#ifndef NO_SHA256 + #include "crys_hash.h" + #include "crys_hash_error.h" + /* largest possible input data on CC310 DMA. */ + #define CC310_MAX_LENGTH_DMA (0xFFFF) +#endif + +#ifndef NO_AES + #include "ssi_aes.h" + + typedef struct aes_context_t { + SaSiAesUserContext_t user_ctx; /* CC310 AES User context */ + SaSiAesUserKeyData_t key; /* CC310 AES key structure */ + SaSiAesEncryptMode_t mode; /* encrypt or decrypt */ + } aes_context_t; + #define CC310_MAX_LENGTH_DMA_AES (0xFFF0) +#endif /* NO_AES */ + +#if !defined(WC_NO_RNG) + #if defined(WOLFSSL_nRF5x_SDK_15_2) + +/* To fix warning. MIN/MAX are defined in tfm.h and Nordic (re)defines them */ + #undef MIN + #undef MAX +/* includes to use RNG on the nRF52 */ + #include "nrf_drv_rng.h" + #include "nrf_assert.h" + #endif + + /*RNG Global variables*/ + extern CRYS_RND_State_t wc_rndState; + extern CRYS_RND_WorkBuff_t wc_rndWorkBuff; + extern SaSiRndGenerateVectWorkFunc_t wc_rndGenVectFunc; + int cc310_random_generate(byte* output, word32 size); +#endif + +#ifndef NO_RSA + #include "crys_rsa_types.h" + #include "crys_rnd.h" + #include "crys_rsa_schemes.h" + #include "crys_rsa_kg.h" + #include "crys_rsa_build.h" + + typedef struct rsa_context_t { + CRYS_RSAUserPrivKey_t privKey; + CRYS_RSAUserPubKey_t pubKey; + } rsa_context_t; +CRYS_RSA_HASH_OpMode_t cc310_hashModeRSA(enum wc_HashType hash_type); +#endif + +#ifdef HAVE_ECC + #include "crys_ecpki_kg.h" + #include "crys_ecpki_dh.h" + #include "crys_ecpki_build.h" + #include "crys_ecpki_domain.h" + #include "crys_ecpki_ecdsa.h" + + typedef struct ecc_context_t { + CRYS_ECPKI_UserPrivKey_t privKey; + CRYS_ECPKI_UserPublKey_t pubKey; + } ecc_context_t; + +CRYS_ECPKI_DomainID_t cc310_mapCurve(int curve_id); +CRYS_ECPKI_HASH_OpMode_t cc310_hashModeECC(int hash_size); +#endif /* HAVE_ECC */ + +#if !defined(NO_CRYPT_BENCHMARK) && defined(WOLFSSL_nRF5x_SDK_15_2) + /* includes to use Real-time counter (RTC) on nRF52840 */ + #include "nrf_gpio.h" + #include "nrf_drv_rtc.h" + #include "nrf_drv_clock.h" + #include "boards.h" + #include + #include +#endif /* NO_CRYPT_BENCHMARK && WOLFSSL_nRF5x_SDK_15_2*/ + +int cc310_Init(void); +void cc310_Free(void); + +#ifdef __cplusplus +} +#endif +#endif /* WOLFSSL_CRYPTOCELL */ +#endif /* WOLFSSL_CRYPTOCELL_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/atmel/atmel.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/atmel/atmel.h new file mode 100644 index 0000000..6413647 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/atmel/atmel.h @@ -0,0 +1,134 @@ +/* atmel.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef _ATECC508_H_ +#define _ATECC508_H_ + +#include + +#include +#include + +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC_PKCB) + #undef SHA_BLOCK_SIZE + #define SHA_BLOCK_SIZE SHA_BLOCK_SIZE_REMAP + #include + #undef SHA_BLOCK_SIZE +#endif + +/* ATECC508A only supports ECC P-256 */ +#define ATECC_KEY_SIZE (32) +#define ATECC_PUBKEY_SIZE (ATECC_KEY_SIZE*2) /* X and Y */ +#define ATECC_SIG_SIZE (ATECC_KEY_SIZE*2) /* R and S */ +#ifndef ATECC_MAX_SLOT +#define ATECC_MAX_SLOT (0x8) /* Only use 0-7 */ +#endif +#define ATECC_INVALID_SLOT (0xFF) + +/* Device Key for signing */ +#ifndef ATECC_SLOT_AUTH_PRIV +#define ATECC_SLOT_AUTH_PRIV (0x0) +#endif +/* Ephemeral key */ +#ifndef ATECC_SLOT_ECDHE_PRIV +#define ATECC_SLOT_ECDHE_PRIV (0x2) +#endif +/* Symmetric encryption key */ +#ifndef ATECC_SLOT_I2C_ENC +#define ATECC_SLOT_I2C_ENC (0x04) +#endif +/* Parent encryption key */ +#ifndef ATECC_SLOT_ENC_PARENT +#define ATECC_SLOT_ENC_PARENT (0x7) +#endif + +/* ATECC_KEY_SIZE required for ecc.h */ +#include + +struct WOLFSSL; +struct WOLFSSL_CTX; +struct WOLFSSL_X509_STORE_CTX; +struct ecc_key; + +/* Atmel port functions */ +int atmel_init(void); +void atmel_finish(void); +int atmel_get_random_number(uint32_t count, uint8_t* rand_out); +#ifndef ATMEL_GET_RANDOM_BLOCK_DEFINED + int atmel_get_random_block(unsigned char* output, unsigned int sz); + #define ATMEL_GET_RANDOM_BLOCK_DEFINED +#endif +long atmel_get_curr_time_and_date(long* tm); + +#ifdef WOLFSSL_ATECC508A + +enum atmelSlotType { + ATMEL_SLOT_ANY, + ATMEL_SLOT_ENCKEY, + ATMEL_SLOT_DEVICE, + ATMEL_SLOT_ECDHE, + ATMEL_SLOT_ECDHE_ENC, +}; + +int atmel_ecc_alloc(int slotType); +void atmel_ecc_free(int slotId); + +typedef int (*atmel_slot_alloc_cb)(int); +typedef void (*atmel_slot_dealloc_cb)(int); +int atmel_set_slot_allocator(atmel_slot_alloc_cb alloc, + atmel_slot_dealloc_cb dealloc); + +int atmel_ecc_translate_err(int status); +int atmel_get_rev_info(word32* revision); +void atmel_show_rev_info(void); + +/* The macro ATECC_GET_ENC_KEY can be set to override the default + encryption key with your own at build-time */ +#ifndef ATECC_GET_ENC_KEY + #define ATECC_GET_ENC_KEY(enckey, keysize) atmel_get_enc_key_default((enckey), (keysize)) +#endif +int atmel_get_enc_key_default(byte* enckey, word16 keysize); +int atmel_ecc_create_pms(int slotId, const uint8_t* peerKey, uint8_t* pms); +int atmel_ecc_create_key(int slotId, byte* peerKey); +int atmel_ecc_sign(int slotId, const byte* message, byte* signature); +int atmel_ecc_verify(const byte* message, const byte* signature, + const byte* pubkey, int* verified); + +#endif /* WOLFSSL_ATECC508A */ + +#ifdef HAVE_PK_CALLBACKS + int atcatls_create_key_cb(struct WOLFSSL* ssl, struct ecc_key* key, unsigned int keySz, + int ecc_curve, void* ctx); + int atcatls_create_pms_cb(struct WOLFSSL* ssl, struct ecc_key* otherKey, + unsigned char* pubKeyDer, word32* pubKeySz, + unsigned char* out, word32* outlen, + int side, void* ctx); + int atcatls_sign_certificate_cb(struct WOLFSSL* ssl, const byte* in, unsigned int inSz, + byte* out, word32* outSz, const byte* key, unsigned int keySz, void* ctx); + int atcatls_verify_signature_cb(struct WOLFSSL* ssl, const byte* sig, unsigned int sigSz, + const byte* hash, unsigned int hashSz, const byte* key, unsigned int keySz, + int* result, void* ctx); + + int atcatls_set_callbacks(struct WOLFSSL_CTX* ctx); + int atcatls_set_callback_ctx(struct WOLFSSL* ssl, void* user_ctx); +#endif + +#endif /* _ATECC508_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/caam/caam_driver.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/caam/caam_driver.h new file mode 100644 index 0000000..5e49312 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/caam/caam_driver.h @@ -0,0 +1,187 @@ +/* caam_driver.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef CAAM_DRIVER_H +#define CAAM_DRIVER_H + +#define CAAM_BASE 0xf2100000 + +#define CAAM_PAGE 0xf0100000 +#define CAAM_PAGE_MAX 6 + +/****************************************************************************** + Basic Descriptors + ****************************************************************************/ + +/* descriptor commands */ +#define CAAM_KEY 0x00000000 +#define CAAM_LOAD 0x10000000 +#define CAAM_LOAD_CTX 0x10200000 +#define CAAM_IMM 0x00800000 +#define CAAM_FIFO_L 0x20000000 +#define CAAM_FIFO_S 0x60000000 +#define CAAM_FIFO_S_SKEY 0x60260000 +#define CAAM_STORE 0x50000000 +#define CAAM_STORE_CTX 0x50200000 +#define CAAM_MOVE 0x78000000 +#define CAAM_OP 0x80000000 +#define CAAM_SIG 0x90000000 +#define CAAM_JUMP 0xA0000000 +#define CAAM_SEQI 0xF0000000/* SEQ in */ +#define CAAM_SEQO 0xF8000000/* SEQ out */ +#define CAAM_HEAD 0xB0800000 +#define CAAM_NWB 0x00200000 + +#define CAAM_BLOB_ENCAP 0x07000000 +#define CAAM_BLOB_DECAP 0x06000000 +#define CAAM_OPID_BLOB 0x000D0000 + +/* algorithms modes and types */ +#define CAAM_CLASS1 0x02000000/* i.e. AES */ +#define CAAM_CLASS2 0x04000000/* i.e. hash algos */ + +#define CAAM_ENC 0x00000001 +#define CAAM_DEC 0x00000000 +#define CAAM_ALG_INIT 0x00000004 +#define CAAM_ALG_INITF 0x0000000C +#define CAAM_ALG_UPDATE 0x00000000 +#define CAAM_ALG_FINAL 0x00000008 + + /* AES 10h */ +#define CAAM_AESCTR 0x00100000 +#define CAAM_AESCBC 0x00100100 +#define CAAM_AESECB 0x00100200 +#define CAAM_AESCFB 0x00100300 +#define CAAM_AESOFB 0x00100400 +#define CAAM_CMAC 0x00100600 +#define CAAM_AESCCM 0x00100800 + + /* HASH 40h */ +#define CAAM_MD5 0x00400000 +#define CAAM_SHA 0x00410000 +#define CAAM_SHA224 0x00420000 +#define CAAM_SHA256 0x00430000 +#define CAAM_SHA384 0x00440000 +#define CAAM_SHA512 0x00450000 + + /* HMAC 40h + 10 AAI */ +#define CAAM_HMAC_MD5 0x00400010 +#define CAAM_HMAC_SHA 0x00410010 +#define CAAM_HMAC_SHA224 0x00420010 +#define CAAM_HMAC_SHA256 0x00430010 +#define CAAM_HMAC_SHA384 0x00440010 +#define CAAM_HMAC_SHA512 0x00450010 + +#define CAAM_MD5_CTXSZ (16 + 8) +#define CAAM_SHA_CTXSZ (20 + 8) +#define CAAM_SHA224_CTXSZ (32 + 8) +#define CAAM_SHA256_CTXSZ (32 + 8) +#define CAAM_SHA384_CTXSZ (64 + 8) +#define CAAM_SHA512_CTXSZ (64 + 8) + + /* RNG 50h */ +#define CAAM_RNG 0x00500000 + + /* Used to get raw entropy from TRNG */ +#define CAAM_ENTROPY 0x00500001 + +#define FIFOL_TYPE_MSG 0x00100000 +#define FIFOL_TYPE_AAD 0x00300000 +#define FIFOL_TYPE_FC1 0x00010000 +#define FIFOL_TYPE_LC1 0x00020000 +#define FIFOL_TYPE_LC2 0x00040000 + +#define FIFOS_TYPE_MSG 0x00300000 + +/* continue bit set if more output is expected */ +#define CAAM_FIFOS_CONT 0x00800000 + +#define CAAM_PAGE_SZ 4096 + +/* RNG Registers */ +#define CAAM_RTMCTL CAAM_BASE + 0X0600 +#define CAAM_RTSDCTL CAAM_BASE + 0X0610 +#define CAAM_RTFRQMIN CAAM_BASE + 0X0618 +#define CAAM_RTFRQMAX CAAM_BASE + 0X061C +#define CAAM_RDSTA CAAM_BASE + 0X06C0 +#define CAAM_RTSTATUS CAAM_BASE + 0x063C + +/* each of the following 11 RTENT registers are an offset of 4 from RTENT0 */ +#define CAAM_RTENT0 CAAM_BASE + 0x0640 +#define CAAM_RTENT11 CAAM_BASE + 0x066C /* Max RTENT register */ + +/* RNG Masks/Values */ +#ifndef CAAM_ENT_DLY + #define CAAM_ENT_DLY 1200 /* @TODO lower value may gain performance */ +#endif +#define CAAM_PRGM 0x00010000 /* Set RTMCTL to program state */ +#define CAAM_TRNG 0x00000020 /* Set TRNG access */ +#define CAAM_CTLERR 0x00001000 +#define CAAM_ENTVAL 0x00000400 /* checking RTMCTL for entropy ready */ + +/* Input Job Ring Registers */ +#define CAAM_IRBAR0 CAAM_BASE + 0x1004 +#define CAAM_IRSR0 CAAM_BASE + 0x100C +#define CAAM_IRJAR0 CAAM_BASE + 0x101C + +/* Ouput Job Ring Registers */ +#define CAAM_ORBAR0 CAAM_BASE + 0x1024 +#define CAAM_ORSR0 CAAM_BASE + 0x102C +#define CAAM_ORJAR0 CAAM_BASE + 0x103C + + +/* Status Registers */ +#define CAAM_STATUS CAAM_BASE + 0x0FD4 +#define CAAM_VERSION_MS CAAM_BASE + 0x0FE8 +#define CAAM_VERSION_LS CAAM_BASE + 0x0FEC +#define CAMM_SUPPORT_MS CAAM_BASE + 0x0FF0 +#define CAMM_SUPPORT_LS CAAM_BASE + 0x0FF4 + + +#define CAAM_C1DSR_LS CAAM_BASE + 0x8014 +#define CAAM_C1MR CAAM_BASE + 0x8004 + + +/* output FIFO is 16 entries deep and each entry has a two 4 byte registers */ +#define CAAM_FIFOO_MS CAAM_BASE + 0x87F0 +#define CAAM_FIFOO_LS CAAM_BASE + 0x87F4 + +/* input FIFO is 16 entries deep with each entry having two 4 byte registers + All data writin to it from IP bus should be in big endian format */ +#define CAAM_FIFOI_LS CAAM_BASE + 0x87E0 + +/* offset of 4 with range 0 .. 13 */ +#define CAAM_CTX1 CAAM_BASE + 0x8100 +#define CAAM_CTRIV CAAM_CTX1 + 8 /* AES-CTR iv is in 2 and 3 */ +#define CAAM_CBCIV CAAM_CTX1 /* AES-CBC iv is in 1 and 2 */ + + +/* instantiate RNG and create JDKEK, TDKEK, and TDSK key */ +static unsigned int wc_rng_start[] = { + CAAM_HEAD | 0x00000006, + CAAM_OP | CAAM_CLASS1 | CAAM_RNG | 0x00000004, /* Instantiate RNG handle 0 with TRNG */ + CAAM_JUMP | 0x02000001, /* wait for Class1 RNG and jump to next cmd */ + CAAM_LOAD | 0x00880004, /* Load to clear written register */ + 0x00000001, /* reset done interupt */ + CAAM_OP | CAAM_CLASS1 | CAAM_RNG | 0x00001000 /* Generate secure keys */ +}; + +#endif /* CAAM_DRIVER_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/caam/wolfcaam.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/caam/wolfcaam.h new file mode 100644 index 0000000..3329b68 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/caam/wolfcaam.h @@ -0,0 +1,63 @@ +/* wolfcaam.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef WOLF_CRYPT_CAAM_INIT_H +#define WOLF_CRYPT_CAAM_INIT_H + +#include + +#if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) + +#include + +#if defined(__INTEGRITY) || defined(INTEGRITY) + #include +#endif + +WOLFSSL_LOCAL int wc_caamInit(void); +WOLFSSL_LOCAL int wc_caamFree(void); +WOLFSSL_LOCAL int wc_caamInitRng(void); +WOLFSSL_LOCAL int wc_caamFreeRng(void); + +WOLFSSL_LOCAL word32 wc_caamReadRegister(word32 reg); +WOLFSSL_LOCAL void wc_caamWriteRegister(word32 reg, word32 value); +WOLFSSL_LOCAL int wc_caamAddAndWait(Buffer* buf, word32 arg[4], word32 type); + +WOLFSSL_API int wc_caamSetResource(IODevice ioDev); + +WOLFSSL_API int wc_caamOpenBlob(byte* data, word32 dataSz, byte* out, + word32* outSz); +WOLFSSL_API int wc_caamCreateBlob(byte* data, word32 dataSz, byte* out, + word32* outSz); + +/* additional size that is added by CAAM when creating a blob */ +#define WC_CAAM_BLOB_SZ 48 + +#ifndef WC_CAAM_READ + #define WC_CAAM_READ(reg) wc_caamReadRegister((reg)) +#endif +#ifndef WC_CAAM_WRITE + #define WC_CAAM_WRITE(reg, x) wc_caamWriteRegister((reg), (x)) +#endif + +#endif /* WOLFSSL_IMX6_CAAM */ + +#endif /* WOLF_CRYPT_CAAM_INIT_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h new file mode 100644 index 0000000..ddc451b --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h @@ -0,0 +1,88 @@ +/* wolfcaam_sha.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef WOLF_CRYPT_CAAM_SHA_H +#define WOLF_CRYPT_CAAM_SHA_H + +#include + +#ifdef WOLFSSL_IMX6_CAAM + +#include + +#define WOLFSSL_NO_HASH_RAW + +#ifndef WC_CAAM_CTXLEN +/* last 8 bytes of context is for length */ +#define WC_CAAM_CTXLEN 8 +#endif + +#ifndef WC_CAAM_HASH_BLOCK +/* define sha structures and also get the max possible digest. Start with SHA + digest size */ +#define WC_CAAM_HASH_BLOCK 64 +#endif + +#ifndef WC_CAAM_MAX_DIGEST +#define WC_CAAM_MAX_DIGEST 20 +#ifdef WOLFSSL_SHA224 + #undef WC_CAAM_MAX_DIGEST + #define WC_CAAM_MAX_DIGEST 32 +#endif + +#ifndef NO_SHA256 + #undef WC_CAAM_MAX_DIGEST + #define WC_CAAM_MAX_DIGEST 32 +#endif + +#ifdef WOLFSSL_SHA384 + #undef WC_CAAM_MAX_DIGEST + #define WC_CAAM_MAX_DIGEST 64 +#endif + +#ifdef WOLFSSL_SHA512 + #undef WC_CAAM_MAX_DIGEST + #define WC_CAAM_MAX_DIGEST 64 +#endif +#endif /* WC_CAAM_MAX_DIGEST */ + + +typedef struct wc_Sha { + word32 ctx[(WC_CAAM_MAX_DIGEST + WC_CAAM_CTXLEN) / sizeof(word32)]; + word32 buffLen; /* in bytes */ + word32 buffer[WC_CAAM_HASH_BLOCK / sizeof(word32)]; +} wc_Sha; + +#ifndef NO_MD5 + typedef struct wc_Sha wc_Md5; +#endif + +#ifndef NO_SHA256 + typedef struct wc_Sha wc_Sha256; +#endif + +#ifdef WOLFSSL_SHA512 + typedef struct wc_Sha wc_Sha512; +#endif + +#endif /* WOLFSSL_IMX6_CAAM */ + +#endif /* WOLF_CRYPT_CAAM_SHA_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h new file mode 100644 index 0000000..e69de29 diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h new file mode 100644 index 0000000..8e28477 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h @@ -0,0 +1,31 @@ +/* cavium_octeon_sync.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _CAVIUM_OCTEON_SYNC_H_ +#define _CAVIUM_OCTEON_SYNC_H_ + +#ifdef HAVE_CAVIUM_OCTEON_SYNC + +WOLFSSL_API int wc_CryptoCb_InitOcteon(void); +WOLFSSL_API void wc_CryptoCb_CleanupOcteon(int* id); + +#endif /* HAVE_CAVIUM_OCTEON_SYNC */ +#endif /* _CAVIUM_OCTEON_SYNC_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h new file mode 100644 index 0000000..6639af0 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h @@ -0,0 +1,53 @@ +/* wc_devcrypto.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLFSSL_DEVCRYPTO_H +#define WOLFSSL_DEVCRYPTO_H + +#include + +#ifdef WOLFSSL_DEVCRYPTO + +#include +#include +#include +#include + +typedef struct WC_CRYPTODEV { + int cfd; + struct session_op sess; +} WC_CRYPTODEV; + +WOLFSSL_LOCAL int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz); +WOLFSSL_LOCAL void wc_DevCryptoFree(WC_CRYPTODEV* ctx); +WOLFSSL_LOCAL void wc_SetupCrypt(struct crypt_op* crt, WC_CRYPTODEV* dev, + byte* src, int srcSz, byte* dst, byte* dig, int flag); +WOLFSSL_LOCAL void wc_SetupCryptSym(struct crypt_op* crt, WC_CRYPTODEV* dev, + byte* src, word32 srcSz, byte* dst, byte* iv, int flag); +WOLFSSL_LOCAL void wc_SetupCryptAead(struct crypt_auth_op* crt, WC_CRYPTODEV* dev, + byte* src, word32 srcSz, byte* dst, byte* iv, word32 ivSz, int flag, + byte* authIn, word32 authInSz, byte* authTag, word32 authTagSz); + +#endif /* WOLFSSL_DEVCRYPTO */ +#endif /* WOLFSSL_DEVCRYPTO_H */ + + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/intel/quickassist.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/intel/quickassist.h new file mode 100644 index 0000000..e69de29 diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/intel/quickassist_mem.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/intel/quickassist_mem.h new file mode 100644 index 0000000..e69de29 diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/intel/quickassist_sync.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/intel/quickassist_sync.h new file mode 100644 index 0000000..ff87b2a --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/intel/quickassist_sync.h @@ -0,0 +1,53 @@ +/* quickassist_sync.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _INTEL_QUICKASSIST_SYNC_H_ +#define _INTEL_QUICKASSIST_SYNC_H_ + +#ifdef HAVE_INTEL_QA_SYNC + +WOLFSSL_API int wc_CryptoCb_InitIntelQa(void); +WOLFSSL_API void wc_CryptoCb_CleanupIntelQa(int* id); + +WOLFSSL_API void* wc_CryptoCb_IntelQaMalloc(size_t size, + void* heap, int type +#ifdef WOLFSSL_DEBUG_MEMORY + , const char* func, unsigned int line +#endif +); + +WOLFSSL_API void wc_CryptoCb_IntelQaFree(void *ptr, + void* heap, int type +#ifdef WOLFSSL_DEBUG_MEMORY + , const char* func, unsigned int line +#endif +); + +WOLFSSL_API void* wc_CryptoCb_IntelQaRealloc(void *ptr, + size_t size, void* heap, int type +#ifdef WOLFSSL_DEBUG_MEMORY + , const char* func, unsigned int line +#endif +); + +#endif /* HAVE_INTEL_QA_SYNC */ + +#endif /* _INTEL_QUICKASSIST_SYNC_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/nrf51.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/nrf51.h new file mode 100644 index 0000000..d8fe3bd --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/nrf51.h @@ -0,0 +1,44 @@ +/* nrf51.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLFSSL_NRF51_PORT_H +#define WOLFSSL_NRF51_PORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Public Functions */ +int nrf51_random_generate(byte* output, word32 sz); + +int nrf51_aes_set_key(const byte* key); +int nrf51_aes_encrypt(const byte* in, const byte* key, word32 rounds, byte* out); + +double current_time(int reset); + +#ifdef __cplusplus +} +#endif + +#endif /* WOLFSSL_NRF51_PORT_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/nxp/ksdk_port.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/nxp/ksdk_port.h new file mode 100644 index 0000000..001ec67 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/nxp/ksdk_port.h @@ -0,0 +1,93 @@ +/* ksdk_port.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef _KSDK_PORT_H_ +#define _KSDK_PORT_H_ + +#include +#ifdef USE_FAST_MATH + #include +#elif defined WOLFSSL_SP_MATH + #include +#else + #include +#endif +#include +#include +#include + + +/* API to init required hardware */ +int ksdk_port_init(void); + +/* software algorithm, by wolfcrypt */ +#if defined(FREESCALE_LTC_TFM) + int wolfcrypt_mp_mul(mp_int *A, mp_int *B, mp_int *C); + int wolfcrypt_mp_mod(mp_int *a, mp_int *b, mp_int *c); + int wolfcrypt_mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + int wolfcrypt_mp_mod(mp_int *a, mp_int *b, mp_int *c); + int wolfcrypt_mp_invmod(mp_int *a, mp_int *b, mp_int *c); + int wolfcrypt_mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y); + + /* Exported mp_mulmod function */ + int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +#endif /* FREESCALE_LTC_TFM */ + +#if defined(FREESCALE_LTC_ECC) + #include "fsl_ltc.h" + + typedef enum _fsl_ltc_ecc_coordinate_system + { + kLTC_Weierstrass = 0U, /*< Point coordinates on an elliptic curve in Weierstrass form */ + kLTC_Curve25519 = 1U, /*< Point coordinates on an Curve25519 elliptic curve in Montgomery form */ + kLTC_Ed25519 = 2U, /*< Point coordinates on an Ed25519 elliptic curve in twisted Edwards form */ + } fsl_ltc_ecc_coordinate_system_t; + + int wc_ecc_point_add(ecc_point *mG, ecc_point *mQ, ecc_point *mR, mp_int *m); + + #ifdef HAVE_CURVE25519 + int wc_curve25519(ECPoint *q, byte *n, const ECPoint *p, fsl_ltc_ecc_coordinate_system_t type); + const ECPoint *wc_curve25519_GetBasePoint(void); + status_t LTC_PKHA_Curve25519ToWeierstrass(const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut); + status_t LTC_PKHA_WeierstrassToCurve25519(const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut); + status_t LTC_PKHA_Curve25519ComputeY(ltc_pkha_ecc_point_t *ltcPoint); + #endif + + #ifdef HAVE_ED25519 + status_t LTC_PKHA_Ed25519ToWeierstrass(const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut); + status_t LTC_PKHA_WeierstrassToEd25519(const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut); + status_t LTC_PKHA_Ed25519_PointMul(const ltc_pkha_ecc_point_t *ltcPointIn, + const uint8_t *N, + size_t sizeN, + ltc_pkha_ecc_point_t *ltcPointOut, + fsl_ltc_ecc_coordinate_system_t typeOut); + const ltc_pkha_ecc_point_t *LTC_PKHA_Ed25519_BasePoint(void); + status_t LTC_PKHA_Ed25519_PointDecompress(const uint8_t *pubkey, size_t pubKeySize, ltc_pkha_ecc_point_t *ltcPointOut); + status_t LTC_PKHA_sc_reduce(uint8_t *a); + status_t LTC_PKHA_sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b, const uint8_t *c); + status_t LTC_PKHA_SignatureForVerify(uint8_t *rcheck, const unsigned char *a, const unsigned char *b, ed25519_key *key); + status_t LTC_PKHA_Ed25519_Compress(const ltc_pkha_ecc_point_t *ltcPointIn, uint8_t *p); + #endif + +#endif /* FREESCALE_LTC_ECC */ + +#endif /* _KSDK_PORT_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h new file mode 100644 index 0000000..fd481e2 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h @@ -0,0 +1,224 @@ +/* pic32mz-crypt.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef PIC32MZ_CRYPT_H +#define PIC32MZ_CRYPT_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include + +#ifdef WOLFSSL_MICROCHIP_PIC32MZ + +#ifndef MICROCHIP_PIC32 + #define MICROCHIP_PIC32 +#endif + +/* If algos aren't enabled then turn off */ +#ifdef WOLFSSL_PIC32MZ_HASH + #if defined(NO_MD5) && defined(NO_SHA) && defined(NO_SHA256) + #undef WOLFSSL_PIC32MZ_HASH + #endif +#endif + +#ifdef WOLFSSL_PIC32MZ_CRYPT + #if defined(NO_AES) && defined(NO_DES3) + #undef WOLFSSL_PIC32MZ_CRYPT + #endif +#endif + +/* Enables support for large hashing */ +/* requires exclusive access to crypto hardware done at application layer */ +#define WOLFSSL_PIC32MZ_LARGE_HASH + +#include +#include +#include + + +/* PIC32 Crypto Structures */ +typedef struct saCtrl { + unsigned int CRYPTOALGO : 4; + unsigned int MULTITASK : 3; + unsigned int KEYSIZE : 2; + unsigned int ENCTYPE : 1; + unsigned int ALGO : 7; + unsigned int : 3; + unsigned int FLAGS : 1; + unsigned int FB : 1; + unsigned int LOADIV : 1; + unsigned int LNC : 1; + unsigned int IRFLAG : 1; + unsigned int ICVONLY : 1; + unsigned int OR_EN : 1; + unsigned int NO_RX : 1; + unsigned int : 1; + unsigned int VERIFY : 1; + unsigned int : 2; +} saCtrl; + +typedef struct securityAssociation { + saCtrl SA_CTRL; + unsigned int SA_AUTHKEY[8]; + unsigned int SA_ENCKEY[8]; + unsigned int SA_AUTHIV[8]; + unsigned int SA_ENCIV[4]; +} securityAssociation; + +typedef struct bdCtrl { + unsigned int BUFLEN : 16; + unsigned int CBD_INT_EN : 1; + unsigned int PKT_INT_EN : 1; + unsigned int LIFM : 1; + unsigned int LAST_BD : 1; + unsigned int CRDMA_EN : 1; + unsigned int UPD_RES : 1; + unsigned int SA_FETCH_EN : 1; + unsigned int SEC_CODE : 8; + volatile unsigned int DESC_EN : 1; +} bdCtrl; + +typedef struct bufferDescriptor { + bdCtrl BD_CTRL; + unsigned int SA_ADDR; + unsigned int SRCADDR; + unsigned int DSTADDR; + unsigned int NXTPTR; + unsigned int UPDPTR; + unsigned int MSGLEN; + unsigned int ENCOFF; +} bufferDescriptor; + + +/* Cache Updates Struct */ +typedef struct hashUpdCache { + unsigned char* buf; + unsigned int bufLen; + unsigned int updLen; + int isCopy; +#ifdef WOLFSSL_PIC32MZ_LARGE_HASH + unsigned int finalLen; +#endif +} hashUpdCache; + + +/* Direction */ +#define PIC32_ENCRYPTION 0b1 +#define PIC32_DECRYPTION 0b0 + +/* Algorithm */ +#define PIC32_ALGO_HMAC1 0b01000000 +#define PIC32_ALGO_SHA256 0b00100000 +#define PIC32_ALGO_SHA1 0b00010000 +#define PIC32_ALGO_MD5 0b00001000 + +#define PIC32_ALGO_AES 0b00000100 +#define PIC32_ALGO_TDES 0b00000010 +#define PIC32_ALGO_DES 0b00000001 + +/* Crypto Algo */ +/* AES */ +#define PIC32_CRYPTOALGO_AES_GCM 0b1110 +#define PIC32_CRYPTOALGO_RCTR 0b1101 +#define PIC32_CRYPTOALGO_RCBC_MAC 0b1100 +#define PIC32_CRYPTOALGO_ROFB 0b1011 +#define PIC32_CRYPTOALGO_RCFB 0b1010 +#define PIC32_CRYPTOALGO_RCBC 0b1001 +#define PIC32_CRYPTOALGO_RECB 0b1000 +/* Triple-DES */ +#define PIC32_CRYPTOALGO_TOFB 0b0111 +#define PIC32_CRYPTOALGO_TCFB 0b0110 +#define PIC32_CRYPTOALGO_TCBC 0b0101 +#define PIC32_CRYPTOALGO_TECB 0b0100 +/* DES */ +#define PIC32_CRYPTOALGO_OFB 0b0011 +#define PIC32_CRYPTOALGO_CFB 0b0010 +#define PIC32_CRYPTOALGO_CBC 0b0001 +#define PIC32_CRYPTOALGO_ECB 0b0000 + +/* Key Size */ +#define PIC32_KEYSIZE_256 0b10 +#define PIC32_KEYSIZE_192 0b01 +#define PIC32_KEYSIZE_128 0b00 + +/* PIC32 Minimum Buffer/Block Sizes */ +#define PIC32_BLOCKSIZE_HASH 64 +#define PIC32_BLOCKSIZE_HMAC PIC32_BLOCKSIZE_HASH +#define PIC32_BLOCKSIZE_MD5 PIC32_BLOCKSIZE_HASH +#define PIC32_BLOCKSIZE_SHA1 PIC32_BLOCKSIZE_HASH +#define PIC32_BLOCKSIZE_SHA256 PIC32_BLOCKSIZE_HASH +#define PIC32_BLOCKSIZE_AES 16 +#define PIC32_BLOCKSIZE_TDES 24 +#define PIC32_BLOCKSIZE_DES 8 + +#define PIC32_DIGEST_SIZE 32 + + +/* Helper Macros */ +#define PIC32MZ_IF_RAM(addr) (KVA_TO_PA(addr) < 0x1D000000) + +/* If EF part then Crypto engine supports swapping output bytes */ +#define PIC32_NO_OUT_SWAP ((__PIC32_FEATURE_SET0 == 'E') && \ + (__PIC32_FEATURE_SET1 == 'C')) + + +#ifndef NO_AES +int wc_Pic32AesCrypt(word32 *key, int keyLen, word32 *iv, int ivLen, + byte* out, const byte* in, word32 sz, + int dir, int algo, int cryptoalgo); +#endif +#ifndef NO_DES3 +int wc_Pic32DesCrypt(word32 *key, int keyLen, word32 *iv, int ivLen, + byte* out, const byte* in, word32 sz, + int dir, int algo, int cryptoalgo); +#endif + +#ifdef WOLFSSL_PIC32MZ_HASH +#define WOLFSSL_NO_HASH_RAW + +int wc_Pic32Hash(const byte* in, int inLen, word32* out, int outLen, int algo); +int wc_Pic32HashCopy(hashUpdCache* src, hashUpdCache* dst); + +#ifndef NO_MD5 +struct wc_Md5; +void wc_Md5Pic32Free(struct wc_Md5* md5); +#endif +#ifndef NO_SHA +struct wc_Sha; +void wc_ShaPic32Free(struct wc_Sha* sha); +#endif + +#ifndef NO_SHA256 +struct wc_Sha256; +void wc_Sha256Pic32Free(struct wc_Sha256* sha256); +#endif +#endif /* WOLFSSL_PIC32MZ_HASH */ + +#endif /* WOLFSSL_MICROCHIP_PIC32MZ */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* PIC32MZ_CRYPT_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/st/stm32.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/st/stm32.h new file mode 100644 index 0000000..849f2fd --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/st/stm32.h @@ -0,0 +1,142 @@ +/* stm32.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef _WOLFPORT_STM32_H_ +#define _WOLFPORT_STM32_H_ + +/* Generic STM32 Hashing and Crypto Functions */ +/* Supports CubeMX HAL or Standard Peripheral Library */ + +#include +#include + +#if defined(WOLFSSL_STM32_PKA) + #include +#endif + +#ifdef STM32_HASH + +#define WOLFSSL_NO_HASH_RAW + +#ifdef HASH_DIGEST + /* The HASH_DIGEST register indicates SHA224/SHA256 support */ + #define STM32_HASH_SHA2 + #define HASH_CR_SIZE 54 + #define HASH_MAX_DIGEST 32 +#else + #define HASH_CR_SIZE 50 + #define HASH_MAX_DIGEST 20 +#endif + +/* Handle hash differences between CubeMX and StdPeriLib */ +#if !defined(HASH_ALGOMODE_HASH) && defined(HASH_AlgoMode_HASH) + #define HASH_ALGOMODE_HASH HASH_AlgoMode_HASH +#endif +#if !defined(HASH_DATATYPE_8B) && defined(HASH_DataType_8b) + #define HASH_DATATYPE_8B HASH_DataType_8b +#endif + +#ifndef STM32_HASH_TIMEOUT + #define STM32_HASH_TIMEOUT 0xFFFF +#endif + + +/* STM32 register size in bytes */ +#define STM32_HASH_REG_SIZE 4 + +/* STM32 Hash Context */ +typedef struct { + /* Context switching registers */ + uint32_t HASH_IMR; + uint32_t HASH_STR; + uint32_t HASH_CR; + uint32_t HASH_CSR[HASH_CR_SIZE]; + + /* Hash state / buffers */ + word32 buffer[STM32_HASH_REG_SIZE / sizeof(word32)]; /* partial word buffer */ + word32 buffLen; /* partial word remain */ + word32 loLen; /* total update bytes + (only lsb 6-bits is used for nbr valid bytes in last word) */ +} STM32_HASH_Context; + + +/* API's */ +void wc_Stm32_Hash_Init(STM32_HASH_Context* stmCtx); +int wc_Stm32_Hash_Update(STM32_HASH_Context* stmCtx, word32 algo, + const byte* data, int len); +int wc_Stm32_Hash_Final(STM32_HASH_Context* stmCtx, word32 algo, + byte* hash, int digestSize); + +#endif /* STM32_HASH */ + + +#ifdef STM32_CRYPTO + +#ifndef NO_AES + #if !defined(STM32_CRYPTO_AES_GCM) && (defined(WOLFSSL_STM32F4) || \ + defined(WOLFSSL_STM32F7) || defined(WOLFSSL_STM32L4)) + /* Hardware supports AES GCM acceleration */ + #define STM32_CRYPTO_AES_GCM + #endif + + #ifdef WOLFSSL_STM32L4 + #define STM32_CRYPTO_AES_ONLY /* crypto engine only supports AES */ + #define CRYP AES + #endif + + /* Detect newer CubeMX crypto HAL (HAL_CRYP_Encrypt / HAL_CRYP_Decrypt) */ + #if !defined(STM32_HAL_V2) && \ + defined(WOLFSSL_STM32F7) && defined(CRYP_AES_GCM) + #define STM32_HAL_V2 + #endif + + /* The datatype for STM32 CubeMX HAL Crypt calls */ + #ifdef STM32_HAL_V2 + #define STM_CRYPT_TYPE uint32_t + #else + #define STM_CRYPT_TYPE uint8_t + #endif + + /* CRYPT_AES_GCM starts the IV with 2 */ + #define STM32_GCM_IV_START 2 + + struct Aes; + #ifdef WOLFSSL_STM32_CUBEMX + int wc_Stm32_Aes_Init(struct Aes* aes, CRYP_HandleTypeDef* hcryp); + #else /* STD_PERI_LIB */ + int wc_Stm32_Aes_Init(struct Aes* aes, CRYP_InitTypeDef* cryptInit, + CRYP_KeyInitTypeDef* keyInit); + #endif /* WOLFSSL_STM32_CUBEMX */ +#endif /* !NO_AES */ + +#endif /* STM32_CRYPTO */ + +#ifdef WOLFSSL_STM32_PKA +int stm32_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, + word32 hashlen, int* res, ecc_key* key); + +int stm32_ecc_sign_hash_ex(const byte* hash, word32 hashlen, WC_RNG* rng, + ecc_key* key, mp_int *r, mp_int *s); + +#endif + + +#endif /* _WOLFPORT_STM32_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/st/stsafe.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/st/stsafe.h new file mode 100644 index 0000000..e7c451d --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/st/stsafe.h @@ -0,0 +1,94 @@ +/* stsafe.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef _WOLFPORT_STSAFE_H_ +#define _WOLFPORT_STSAFE_H_ + +#include +#include +#include +#include + +#ifdef WOLFSSL_STSAFEA100 + +/* The wolf STSAFE interface layer */ +/* Please contact wolfSSL for the STSAFE port files */ +#include "stsafe_interface.h" + +#ifndef STSAFE_MAX_KEY_LEN + #define STSAFE_MAX_KEY_LEN ((uint32_t)48) /* for up to 384-bit keys */ +#endif +#ifndef STSAFE_MAX_PUBKEY_RAW_LEN + #define STSAFE_MAX_PUBKEY_RAW_LEN ((uint32_t)STSAFE_MAX_KEY_LEN * 2) /* x/y */ +#endif +#ifndef STSAFE_MAX_SIG_LEN + #define STSAFE_MAX_SIG_LEN ((uint32_t)STSAFE_MAX_KEY_LEN * 2) /* r/s */ +#endif + +WOLFSSL_API int SSL_STSAFE_LoadDeviceCertificate(byte** pRawCertificate, + word32* pRawCertificateLen); + +#ifdef HAVE_PK_CALLBACKS +WOLFSSL_API int SSL_STSAFE_CreateKeyCb(WOLFSSL* ssl, ecc_key* key, word32 keySz, + int ecc_curve, void* ctx); +WOLFSSL_API int SSL_STSAFE_VerifyPeerCertCb(WOLFSSL* ssl, + const unsigned char* sig, unsigned int sigSz, + const unsigned char* hash, unsigned int hashSz, + const unsigned char* keyDer, unsigned int keySz, + int* result, void* ctx); +WOLFSSL_API int SSL_STSAFE_SignCertificateCb(WOLFSSL* ssl, + const byte* in, word32 inSz, + byte* out, word32* outSz, + const byte* key, word32 keySz, void* ctx); +WOLFSSL_API int SSL_STSAFE_SharedSecretCb(WOLFSSL* ssl, + ecc_key* otherKey, + unsigned char* pubKeyDer, unsigned int* pubKeySz, + unsigned char* out, unsigned int* outlen, + int side, void* ctx); + +/* Helper API's for setting up callbacks */ +WOLFSSL_API int SSL_STSAFE_SetupPkCallbacks(WOLFSSL_CTX* ctx); +WOLFSSL_API int SSL_STSAFE_SetupPkCallbackCtx(WOLFSSL* ssl, void* user_ctx); +#endif /* HAVE_PK_CALLBACKS */ + + +#ifdef WOLF_CRYPTO_CB + +#include + +/* Device ID that's unique and valid (not INVALID_DEVID -2) */ +#define WOLF_STSAFE_DEVID 0x53545341; /* STSA */ + +typedef struct wolfSTSAFE_CryptoCb_Ctx { +#ifdef HAVE_ECC + ecc_key wolfEccKey; +#endif + int devId; +} wolfSTSAFE_CryptoCb_Ctx; + +WOLFSSL_API int wolfSSL_STSAFE_CryptoDevCb(int devId, wc_CryptoInfo* info, + void* ctx); + +#endif /* WOLF_CRYPTO_CB */ + +#endif /* WOLFSSL_STSAFEA100 */ + +#endif /* _WOLFPORT_STSAFE_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/ti/ti-ccm.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/ti/ti-ccm.h new file mode 100644 index 0000000..656f3e8 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/ti/ti-ccm.h @@ -0,0 +1,47 @@ +/* port/ti/ti_ccm.c + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLF_CRYPT_TI_CCM_H +#define WOLF_CRYPT_TI_CCM_H + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if defined(WOLFSSL_TI_CRYPT) || defined(WOLFSSL_TI_HASH) + +int wolfSSL_TI_CCMInit(void) ; + +#ifndef SINGLE_THREADED +void wolfSSL_TI_lockCCM(void) ; +void wolfSSL_TI_unlockCCM(void) ; +#else +#define wolfSSL_TI_lockCCM() +#define wolfSSL_TI_unlockCCM() +#endif + +#endif + +#endif + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/ti/ti-hash.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/ti/ti-hash.h new file mode 100644 index 0000000..214541a --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/ti/ti-hash.h @@ -0,0 +1,63 @@ +/* port/ti/ti-hash.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLF_CRYPT_TI_HASH_H +#define WOLF_CRYPT_TI_HASH_H + +#include + +#ifndef WOLFSSL_TI_INITBUFF + #define WOLFSSL_TI_INITBUFF 64 +#endif + +#ifndef WOLFSSL_MAX_HASH_SIZE + #define WOLFSSL_MAX_HASH_SIZE 64 +#endif + +#define WOLFSSL_NO_HASH_RAW + +typedef struct { + byte *msg; + word32 used; + word32 len; + byte hash[WOLFSSL_MAX_HASH_SIZE]; +} wolfssl_TI_Hash; + + +#ifndef TI_HASH_TEST + +#if !defined(NO_MD5) + typedef wolfssl_TI_Hash wc_Md5; +#endif +#if !defined(NO_SHA) + typedef wolfssl_TI_Hash wc_Sha; +#endif +#if !defined(NO_SHA256) + typedef wolfssl_TI_Hash wc_Sha256; +#endif +#if defined(WOLFSSL_SHA224) + typedef wolfssl_TI_Hash wc_Sha224; +#endif + +#endif /* !TI_HASH_TEST */ + +#endif /* WOLF_CRYPT_TI_HASH_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/xilinx/xil-sha3.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/xilinx/xil-sha3.h new file mode 100644 index 0000000..0de69bb --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/port/xilinx/xil-sha3.h @@ -0,0 +1,45 @@ +/* xil-sha3.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLF_XIL_CRYPT_SHA3_H +#define WOLF_XIL_CRYPT_SHA3_H + +#ifdef WOLFSSL_SHA3 +#include "xsecure_sha.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Sha3 digest */ +typedef struct Sha3 { + XSecure_Sha3 hw; + XCsuDma dma; +} wc_Sha3; + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_SHA3 */ +#endif /* WOLF_XIL_CRYPT_SHA3_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/pwdbased.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/pwdbased.h new file mode 100644 index 0000000..7d79e3b --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/pwdbased.h @@ -0,0 +1,77 @@ +/* pwdbased.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/pwdbased.h +*/ + +#ifndef WOLF_CRYPT_PWDBASED_H +#define WOLF_CRYPT_PWDBASED_H + +#include + +#ifndef NO_PWDBASED + + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * hashType renamed to typeH to avoid shadowing global declaration here: + * wolfssl/wolfcrypt/asn.h line 173 in enum Oid_Types + */ +WOLFSSL_API int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen, + const byte* passwd, int passwdLen, + const byte* salt, int saltLen, int iterations, + int hashType, void* heap); +WOLFSSL_API int wc_PBKDF1(byte* output, const byte* passwd, int pLen, + const byte* salt, int sLen, int iterations, int kLen, + int typeH); +WOLFSSL_API int wc_PBKDF2_ex(byte* output, const byte* passwd, int pLen, + const byte* salt, int sLen, int iterations, int kLen, + int typeH, void* heap, int devId); +WOLFSSL_API int wc_PBKDF2(byte* output, const byte* passwd, int pLen, + const byte* salt, int sLen, int iterations, int kLen, + int typeH); +WOLFSSL_API int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int pLen, + const byte* salt, int sLen, int iterations, + int kLen, int typeH, int purpose); +WOLFSSL_API int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd,int passLen, + const byte* salt, int saltLen, int iterations, int kLen, + int hashType, int id, void* heap); + +#ifdef HAVE_SCRYPT +WOLFSSL_API int wc_scrypt(byte* output, const byte* passwd, int passLen, + const byte* salt, int saltLen, int cost, + int blockSize, int parallel, int dkLen); +WOLFSSL_API int wc_scrypt_ex(byte* output, const byte* passwd, int passLen, + const byte* salt, int saltLen, word32 iterations, + int blockSize, int parallel, int dkLen); +#endif + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* NO_PWDBASED */ +#endif /* WOLF_CRYPT_PWDBASED_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/rabbit.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/rabbit.h new file mode 100644 index 0000000..0064c45 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/rabbit.h @@ -0,0 +1,73 @@ +/* rabbit.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/rabbit.h +*/ + + +#ifndef WOLF_CRYPT_RABBIT_H +#define WOLF_CRYPT_RABBIT_H + +#include + +#ifndef NO_RABBIT + +#ifdef __cplusplus + extern "C" { +#endif + + +enum { + RABBIT_ENC_TYPE = 5 /* cipher unique type */ +}; + + +/* Rabbit Context */ +typedef struct RabbitCtx { + word32 x[8]; + word32 c[8]; + word32 carry; +} RabbitCtx; + + +/* Rabbit stream cipher */ +typedef struct Rabbit { + RabbitCtx masterCtx; + RabbitCtx workCtx; +#ifdef XSTREAM_ALIGN + void* heap; /* heap hint, currently XMALLOC only used with aligning */ +#endif +} Rabbit; + + +WOLFSSL_API int wc_RabbitProcess(Rabbit*, byte*, const byte*, word32); +WOLFSSL_API int wc_RabbitSetKey(Rabbit*, const byte* key, const byte* iv); + +WOLFSSL_LOCAL int wc_Rabbit_SetHeap(Rabbit* ctx, void* heap); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* NO_RABBIT */ +#endif /* WOLF_CRYPT_RABBIT_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/random.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/random.h new file mode 100644 index 0000000..e6ecf19 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/random.h @@ -0,0 +1,250 @@ +/* random.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/random.h +*/ + + + +#ifndef WOLF_CRYPT_RANDOM_H +#define WOLF_CRYPT_RANDOM_H + +#include + +#if defined(HAVE_FIPS) && \ + defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) + #include +#endif /* HAVE_FIPS_VERSION >= 2 */ + +/* included for fips @wc_fips */ +#if defined(HAVE_FIPS) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) +#include +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + /* Maximum generate block length */ +#ifndef RNG_MAX_BLOCK_LEN + #ifdef HAVE_INTEL_QA + #define RNG_MAX_BLOCK_LEN (0xFFFFl) + #else + #define RNG_MAX_BLOCK_LEN (0x10000l) + #endif +#endif + +/* Size of the BRBG seed */ +#ifndef DRBG_SEED_LEN + #define DRBG_SEED_LEN (440/8) +#endif + + +#if !defined(CUSTOM_RAND_TYPE) + /* To maintain compatibility the default is byte */ + #define CUSTOM_RAND_TYPE byte +#endif + +/* make sure Hash DRBG is enabled, unless WC_NO_HASHDRBG is defined + or CUSTOM_RAND_GENERATE_BLOCK is defined */ +#if !defined(WC_NO_HASHDRBG) && !defined(CUSTOM_RAND_GENERATE_BLOCK) + #undef HAVE_HASHDRBG + #define HAVE_HASHDRBG + #ifndef WC_RESEED_INTERVAL + #define WC_RESEED_INTERVAL (1000000) + #endif +#endif + + +/* avoid redefinition of structs */ +#if !defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + +/* RNG supports the following sources (in order): + * 1. CUSTOM_RAND_GENERATE_BLOCK: Defines name of function as RNG source and + * bypasses the options below. + * 2. HAVE_INTEL_RDRAND: Uses the Intel RDRAND if supported by CPU. + * 3. HAVE_HASHDRBG (requires SHA256 enabled): Uses SHA256 based P-RNG + * seeded via wc_GenerateSeed. This is the default source. + */ + + /* Seed source can be overridden by defining one of these: + CUSTOM_RAND_GENERATE_SEED + CUSTOM_RAND_GENERATE_SEED_OS + CUSTOM_RAND_GENERATE */ + + +#if defined(CUSTOM_RAND_GENERATE_BLOCK) + /* To use define the following: + * #define CUSTOM_RAND_GENERATE_BLOCK myRngFunc + * extern int myRngFunc(byte* output, word32 sz); + */ +#elif defined(HAVE_HASHDRBG) + #ifdef NO_SHA256 + #error "Hash DRBG requires SHA-256." + #endif /* NO_SHA256 */ + #include +#elif defined(HAVE_WNR) + /* allow whitewood as direct RNG source using wc_GenerateSeed directly */ +#elif defined(HAVE_INTEL_RDRAND) + /* Intel RDRAND or RDSEED */ +#elif !defined(WC_NO_RNG) + #error No RNG source defined! +#endif + +#ifdef HAVE_WNR + #include +#endif + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif + + +#if defined(USE_WINDOWS_API) + #if defined(_WIN64) + typedef unsigned __int64 ProviderHandle; + /* type HCRYPTPROV, avoid #include */ + #else + typedef unsigned long ProviderHandle; + #endif +#endif + + +/* OS specific seeder */ +typedef struct OS_Seed { + #if defined(USE_WINDOWS_API) + ProviderHandle handle; + #else + int fd; + #endif + #if defined(WOLF_CRYPTO_CB) + int devId; + #endif +} OS_Seed; + + +#ifndef WC_RNG_TYPE_DEFINED /* guard on redeclaration */ + typedef struct WC_RNG WC_RNG; + #define WC_RNG_TYPE_DEFINED +#endif + +/* RNG context */ +struct WC_RNG { + OS_Seed seed; + void* heap; +#ifdef HAVE_HASHDRBG + /* Hash-based Deterministic Random Bit Generator */ + struct DRBG* drbg; +#if defined(WOLFSSL_NO_MALLOC) && !defined(WOLFSSL_STATIC_MEMORY) + #define DRBG_STRUCT_SZ ((sizeof(word32)*3) + (DRBG_SEED_LEN*2)) + #ifdef WOLFSSL_SMALL_STACK_CACHE + #define DRBG_STRUCT_SZ_SHA256 (sizeof(wc_Sha256)) + #else + #define DRBG_STRUCT_SZ_SHA256 0 + #endif + #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) + #define DRBG_STRUCT_SZ_ASYNC (sizeof(void*) + sizeof(int)) + #else + #define DRBG_STRUCT_SZ_ASYNC 0 + #endif + byte drbg_data[DRBG_STRUCT_SZ + DRBG_STRUCT_SZ_SHA256 + DRBG_STRUCT_SZ_ASYNC]; +#endif + byte status; +#endif +#ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV asyncDev; +#endif +#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) + int devId; +#endif +}; + +#endif /* NO FIPS or have FIPS v2*/ + +/* NO_OLD_RNGNAME removes RNG struct name to prevent possible type conflicts, + * can't be used with CTaoCrypt FIPS */ +#if !defined(NO_OLD_RNGNAME) && !defined(HAVE_FIPS) + #define RNG WC_RNG +#endif + + +WOLFSSL_LOCAL +int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz); + + +#ifdef HAVE_WNR + /* Whitewood netRandom client library */ + WOLFSSL_API int wc_InitNetRandom(const char*, wnr_hmac_key, int); + WOLFSSL_API int wc_FreeNetRandom(void); +#endif /* HAVE_WNR */ + + +WOLFSSL_ABI WOLFSSL_API WC_RNG* wc_rng_new(byte*, word32, void*); +WOLFSSL_ABI WOLFSSL_API void wc_rng_free(WC_RNG*); + + +#ifndef WC_NO_RNG +WOLFSSL_API int wc_InitRng(WC_RNG*); +WOLFSSL_API int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId); +WOLFSSL_API int wc_InitRngNonce(WC_RNG* rng, byte* nonce, word32 nonceSz); +WOLFSSL_API int wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz, + void* heap, int devId); +WOLFSSL_API int wc_RNG_GenerateBlock(WC_RNG*, byte*, word32 sz); +WOLFSSL_API int wc_RNG_GenerateByte(WC_RNG*, byte*); +WOLFSSL_API int wc_FreeRng(WC_RNG*); +#else +#include +#define wc_InitRng(rng) NOT_COMPILED_IN +#define wc_InitRng_ex(rng, h, d) NOT_COMPILED_IN +#define wc_InitRngNonce(rng, n, s) NOT_COMPILED_IN +#define wc_InitRngNonce_ex(rng, n, s, h, d) NOT_COMPILED_IN +#define wc_RNG_GenerateBlock(rng, b, s) NOT_COMPILED_IN +#define wc_RNG_GenerateByte(rng, b) NOT_COMPILED_IN +#define wc_FreeRng(rng) (void)NOT_COMPILED_IN +#endif + + + +#ifdef HAVE_HASHDRBG + WOLFSSL_LOCAL int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* entropy, + word32 entropySz); + WOLFSSL_API int wc_RNG_TestSeed(const byte* seed, word32 seedSz); + WOLFSSL_API int wc_RNG_HealthTest(int reseed, + const byte* entropyA, word32 entropyASz, + const byte* entropyB, word32 entropyBSz, + byte* output, word32 outputSz); + WOLFSSL_API int wc_RNG_HealthTest_ex(int reseed, + const byte* nonce, word32 nonceSz, + const byte* entropyA, word32 entropyASz, + const byte* entropyB, word32 entropyBSz, + byte* output, word32 outputSz, + void* heap, int devId); +#endif /* HAVE_HASHDRBG */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLF_CRYPT_RANDOM_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/ripemd.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/ripemd.h new file mode 100644 index 0000000..cc9f130 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/ripemd.h @@ -0,0 +1,67 @@ +/* ripemd.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/ripemd.h +*/ + +#ifndef WOLF_CRYPT_RIPEMD_H +#define WOLF_CRYPT_RIPEMD_H + +#include + +#ifdef WOLFSSL_RIPEMD + +#ifdef __cplusplus + extern "C" { +#endif + + +/* in bytes */ +enum { + RIPEMD = 3, /* hash type unique */ + RIPEMD_BLOCK_SIZE = 64, + RIPEMD_DIGEST_SIZE = 20, + RIPEMD_PAD_SIZE = 56 +}; + + +/* RipeMd 160 digest */ +typedef struct RipeMd { + word32 buffLen; /* in bytes */ + word32 loLen; /* length in bytes */ + word32 hiLen; /* length in bytes */ + word32 digest[RIPEMD_DIGEST_SIZE / sizeof(word32)]; + word32 buffer[RIPEMD_BLOCK_SIZE / sizeof(word32)]; +} RipeMd; + + +WOLFSSL_API int wc_InitRipeMd(RipeMd*); +WOLFSSL_API int wc_RipeMdUpdate(RipeMd*, const byte*, word32); +WOLFSSL_API int wc_RipeMdFinal(RipeMd*, byte*); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_RIPEMD */ +#endif /* WOLF_CRYPT_RIPEMD_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/rsa.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/rsa.h new file mode 100644 index 0000000..e1056e3 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/rsa.h @@ -0,0 +1,353 @@ +/* rsa.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/rsa.h +*/ + + +#ifndef WOLF_CRYPT_RSA_H +#define WOLF_CRYPT_RSA_H + +#include + +#ifndef NO_RSA + + +/* RSA default exponent */ +#ifndef WC_RSA_EXPONENT + #define WC_RSA_EXPONENT 65537L +#endif + +#if defined(WC_RSA_NONBLOCK) + /* enable support for fast math based non-blocking exptmod */ + /* this splits the RSA function into many smaller operations */ + #ifndef USE_FAST_MATH + #error RSA non-blocking mode only supported using fast math + #endif + #ifndef TFM_TIMING_RESISTANT + #error RSA non-blocking mode only supported with timing resistance enabled + #endif + + /* RSA bounds check is not supported with RSA non-blocking mode */ + #undef NO_RSA_BOUNDS_CHECK + #define NO_RSA_BOUNDS_CHECK +#endif + +/* allow for user to plug in own crypto */ +#if !defined(HAVE_FIPS) && (defined(HAVE_USER_RSA) || defined(HAVE_FAST_RSA)) + #include "user_rsa.h" +#else + +#if defined(HAVE_FIPS) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) +/* for fips @wc_fips */ +#include +#if defined(CYASSL_KEY_GEN) && !defined(WOLFSSL_KEY_GEN) + #define WOLFSSL_KEY_GEN +#endif +#else + #include + #include +#endif /* HAVE_FIPS && HAVE_FIPS_VERION 1 */ +#if defined(HAVE_FIPS) && \ + defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) +#include +#endif + +/* header file needed for OAEP padding */ +#include + +#ifdef WOLFSSL_XILINX_CRYPT +#include "xsecure_rsa.h" +#endif + +#if defined(WOLFSSL_CRYPTOCELL) + #include +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +enum { + RSA_MIN_SIZE = 512, + RSA_MAX_SIZE = 4096, +}; + +/* avoid redefinition of structs */ +#if !defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + +#ifdef WOLFSSL_ASYNC_CRYPT + #include + #include +#endif + +enum { + RSA_PUBLIC = 0, + RSA_PRIVATE = 1, + + RSA_TYPE_UNKNOWN = -1, + RSA_PUBLIC_ENCRYPT = 0, + RSA_PUBLIC_DECRYPT = 1, + RSA_PRIVATE_ENCRYPT = 2, + RSA_PRIVATE_DECRYPT = 3, + + RSA_BLOCK_TYPE_1 = 1, + RSA_BLOCK_TYPE_2 = 2, + + RSA_MIN_PAD_SZ = 11, /* separator + 0 + pad value + 8 pads */ + + RSA_PSS_PAD_SZ = 8, + RSA_PSS_SALT_MAX_SZ = 62, + +#ifdef OPENSSL_EXTRA + RSA_PKCS1_PADDING_SIZE = 11, + RSA_PKCS1_OAEP_PADDING_SIZE = 42, /* (2 * hashlen(SHA-1)) + 2 */ +#endif +#ifdef WC_RSA_PSS + RSA_PSS_PAD_TERM = 0xBC, +#endif + + RSA_PSS_SALT_LEN_DEFAULT = -1, +#ifdef WOLFSSL_PSS_SALT_LEN_DISCOVER + RSA_PSS_SALT_LEN_DISCOVER = -2, +#endif + +#ifdef HAVE_PKCS11 + RSA_MAX_ID_LEN = 32, +#endif +}; + +#ifdef WC_RSA_NONBLOCK +typedef struct RsaNb { + exptModNb_t exptmod; /* non-block expt_mod */ + mp_int tmp; +} RsaNb; +#endif + +/* RSA */ +struct RsaKey { + mp_int n, e; +#ifndef WOLFSSL_RSA_PUBLIC_ONLY + mp_int d, p, q; +#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM) + mp_int dP, dQ, u; +#endif +#endif + void* heap; /* for user memory overrides */ + byte* data; /* temp buffer for async RSA */ + int type; /* public or private */ + int state; + word32 dataLen; +#ifdef WC_RSA_BLINDING + WC_RNG* rng; /* for PrivateDecrypt blinding */ +#endif +#ifdef WOLF_CRYPTO_CB + int devId; +#endif +#ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV asyncDev; + CertSignCtx certSignCtx; /* context info for cert sign (MakeSignature) */ +#endif /* WOLFSSL_ASYNC_CRYPT */ +#ifdef WOLFSSL_XILINX_CRYPT + word32 pubExp; /* to keep values in scope they are here in struct */ + byte* mod; + XSecure_Rsa xRsa; +#endif +#ifdef HAVE_PKCS11 + byte id[RSA_MAX_ID_LEN]; + int idLen; +#endif +#if defined(WOLFSSL_ASYNC_CRYPT) || !defined(WOLFSSL_RSA_VERIFY_INLINE) + byte dataIsAlloc; +#endif +#ifdef WC_RSA_NONBLOCK + RsaNb* nb; +#endif +#ifdef WOLFSSL_AFALG_XILINX_RSA + int alFd; + int rdFd; +#endif +#if defined(WOLFSSL_CRYPTOCELL) + rsa_context_t ctx; +#endif +}; + +#ifndef WC_RSAKEY_TYPE_DEFINED + typedef struct RsaKey RsaKey; + #define WC_RSAKEY_TYPE_DEFINED +#endif + +#endif /*HAVE_FIPS */ + +WOLFSSL_API int wc_InitRsaKey(RsaKey* key, void* heap); +WOLFSSL_API int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId); +WOLFSSL_API int wc_FreeRsaKey(RsaKey* key); +#ifdef HAVE_PKCS11 +WOLFSSL_API int wc_InitRsaKey_Id(RsaKey* key, unsigned char* id, int len, + void* heap, int devId); +#endif +WOLFSSL_API int wc_CheckRsaKey(RsaKey* key); +#ifdef WOLFSSL_XILINX_CRYPT +WOLFSSL_LOCAL int wc_InitRsaHw(RsaKey* key); +#endif /* WOLFSSL_XILINX_CRYPT */ + +WOLFSSL_API int wc_RsaFunction(const byte* in, word32 inLen, byte* out, + word32* outLen, int type, RsaKey* key, WC_RNG* rng); + +WOLFSSL_API int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key, WC_RNG* rng); +WOLFSSL_API int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, + RsaKey* key); +WOLFSSL_API int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key); +WOLFSSL_API int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key, WC_RNG* rng); +WOLFSSL_API int wc_RsaPSS_Sign(const byte* in, word32 inLen, byte* out, + word32 outLen, enum wc_HashType hash, int mgf, + RsaKey* key, WC_RNG* rng); +WOLFSSL_API int wc_RsaPSS_Sign_ex(const byte* in, word32 inLen, byte* out, + word32 outLen, enum wc_HashType hash, + int mgf, int saltLen, RsaKey* key, + WC_RNG* rng); +WOLFSSL_API int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, + RsaKey* key); +WOLFSSL_API int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key); +WOLFSSL_API int wc_RsaPSS_VerifyInline(byte* in, word32 inLen, byte** out, + enum wc_HashType hash, int mgf, + RsaKey* key); +WOLFSSL_API int wc_RsaPSS_VerifyInline_ex(byte* in, word32 inLen, byte** out, + enum wc_HashType hash, int mgf, + int saltLen, RsaKey* key); +WOLFSSL_API int wc_RsaPSS_Verify(byte* in, word32 inLen, byte* out, + word32 outLen, enum wc_HashType hash, int mgf, + RsaKey* key); +WOLFSSL_API int wc_RsaPSS_Verify_ex(byte* in, word32 inLen, byte* out, + word32 outLen, enum wc_HashType hash, + int mgf, int saltLen, RsaKey* key); +WOLFSSL_API int wc_RsaPSS_CheckPadding(const byte* in, word32 inLen, byte* sig, + word32 sigSz, + enum wc_HashType hashType); +WOLFSSL_API int wc_RsaPSS_CheckPadding_ex(const byte* in, word32 inLen, + byte* sig, word32 sigSz, + enum wc_HashType hashType, + int saltLen, int bits); +WOLFSSL_API int wc_RsaPSS_VerifyCheckInline(byte* in, word32 inLen, byte** out, + const byte* digest, word32 digentLen, + enum wc_HashType hash, int mgf, + RsaKey* key); +WOLFSSL_API int wc_RsaPSS_VerifyCheck(byte* in, word32 inLen, + byte* out, word32 outLen, + const byte* digest, word32 digestLen, + enum wc_HashType hash, int mgf, + RsaKey* key); + +WOLFSSL_API int wc_RsaEncryptSize(RsaKey* key); + +#if !defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) +/* to avoid asn duplicate symbols @wc_fips */ +WOLFSSL_API int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, + RsaKey*, word32); +WOLFSSL_API int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, + RsaKey*, word32); +WOLFSSL_API int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, + const byte* e, word32 eSz, RsaKey* key); + WOLFSSL_API int wc_RsaKeyToDer(RsaKey*, byte* output, word32 inLen); + +#ifdef WC_RSA_BLINDING + WOLFSSL_API int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng); +#endif +#ifdef WC_RSA_NONBLOCK + WOLFSSL_API int wc_RsaSetNonBlock(RsaKey* key, RsaNb* nb); + #ifdef WC_RSA_NONBLOCK_TIME + WOLFSSL_API int wc_RsaSetNonBlockTime(RsaKey* key, word32 maxBlockUs, + word32 cpuMHz); + #endif +#endif + +/* + choice of padding added after fips, so not available when using fips RSA + */ + +/* Mask Generation Function Identifiers */ +#define WC_MGF1NONE 0 +#define WC_MGF1SHA1 26 +#define WC_MGF1SHA224 4 +#define WC_MGF1SHA256 1 +#define WC_MGF1SHA384 2 +#define WC_MGF1SHA512 3 + +/* Padding types */ +#define WC_RSA_PKCSV15_PAD 0 +#define WC_RSA_OAEP_PAD 1 +#define WC_RSA_PSS_PAD 2 +#define WC_RSA_NO_PAD 3 + +WOLFSSL_API int wc_RsaPublicEncrypt_ex(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key, WC_RNG* rng, int type, + enum wc_HashType hash, int mgf, byte* label, word32 lableSz); +WOLFSSL_API int wc_RsaPrivateDecrypt_ex(const byte* in, word32 inLen, + byte* out, word32 outLen, RsaKey* key, int type, + enum wc_HashType hash, int mgf, byte* label, word32 lableSz); +WOLFSSL_API int wc_RsaPrivateDecryptInline_ex(byte* in, word32 inLen, + byte** out, RsaKey* key, int type, enum wc_HashType hash, + int mgf, byte* label, word32 lableSz); +#if defined(WC_RSA_DIRECT) || defined(WC_RSA_NO_PADDING) +WOLFSSL_API int wc_RsaDirect(byte* in, word32 inLen, byte* out, word32* outSz, + RsaKey* key, int type, WC_RNG* rng); +#endif + +#endif /* HAVE_FIPS */ + +WOLFSSL_API int wc_RsaFlattenPublicKey(RsaKey*, byte*, word32*, byte*, + word32*); +WOLFSSL_API int wc_RsaExportKey(RsaKey* key, + byte* e, word32* eSz, + byte* n, word32* nSz, + byte* d, word32* dSz, + byte* p, word32* pSz, + byte* q, word32* qSz); + +WOLFSSL_API int wc_RsaKeyToPublicDer(RsaKey*, byte* output, word32 inLen); + + WOLFSSL_API int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng); + WOLFSSL_API int wc_CheckProbablePrime_ex(const byte* p, word32 pSz, + const byte* q, word32 qSz, + const byte* e, word32 eSz, + int nlen, int* isPrime, WC_RNG* rng); + WOLFSSL_API int wc_CheckProbablePrime(const byte* p, word32 pSz, + const byte* q, word32 qSz, + const byte* e, word32 eSz, + int nlen, int* isPrime); + +#endif /* HAVE_USER_RSA */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* NO_RSA */ +#endif /* WOLF_CRYPT_RSA_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/selftest.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/selftest.h new file mode 100644 index 0000000..3449364 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/selftest.h @@ -0,0 +1,48 @@ +/* selftest.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +#ifndef WOLFCRYPT_SELF_TEST_H +#define WOLFCRYPT_SELF_TEST_H + +#include + + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef HAVE_SELFTEST + /* Get wolfCrypt CAVP version */ + WOLFSSL_API const char* wolfCrypt_GetVersion_CAVP_selftest(void); + + /* wolfCrypt self test, runs CAVP KATs */ + WOLFSSL_API int wolfCrypt_SelfTest(void); +#endif + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFCRYPT_SELF_TEST_H */ + + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/settings.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/settings.h new file mode 100644 index 0000000..009923b --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/settings.h @@ -0,0 +1,2108 @@ +/* settings.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +/* Place OS specific preprocessor flags, defines, includes here, will be + included into every file because types.h includes it */ + + +#ifndef WOLF_CRYPT_SETTINGS_H +#define WOLF_CRYPT_SETTINGS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Uncomment next line if using IPHONE */ +/* #define IPHONE */ + +/* Uncomment next line if using ThreadX */ +/* #define THREADX */ + +/* Uncomment next line if using Micrium uC/OS-III */ +/* #define MICRIUM */ + +/* Uncomment next line if using Deos RTOS*/ +/* #define WOLFSSL_DEOS*/ + +/* Uncomment next line if using Mbed */ +/* #define MBED */ + +/* Uncomment next line if using Microchip PIC32 ethernet starter kit */ +/* #define MICROCHIP_PIC32 */ + +/* Uncomment next line if using Microchip TCP/IP stack, version 5 */ +/* #define MICROCHIP_TCPIP_V5 */ + +/* Uncomment next line if using Microchip TCP/IP stack, version 6 or later */ +/* #define MICROCHIP_TCPIP */ + +/* Uncomment next line if using PIC32MZ Crypto Engine */ +/* #define WOLFSSL_MICROCHIP_PIC32MZ */ + +/* Uncomment next line if using FreeRTOS */ +/* #define FREERTOS */ + +/* Uncomment next line if using FreeRTOS+ TCP */ +/* #define FREERTOS_TCP */ + +/* Uncomment next line if using FreeRTOS Windows Simulator */ +/* #define FREERTOS_WINSIM */ + +/* Uncomment next line if using RTIP */ +/* #define EBSNET */ + +/* Uncomment next line if using lwip */ +/* #define WOLFSSL_LWIP */ + +/* Uncomment next line if building wolfSSL for a game console */ +/* #define WOLFSSL_GAME_BUILD */ + +/* Uncomment next line if building wolfSSL for LSR */ +/* #define WOLFSSL_LSR */ + +/* Uncomment next line if building for Freescale Classic MQX version 5.0 */ +/* #define FREESCALE_MQX_5_0 */ + +/* Uncomment next line if building for Freescale Classic MQX version 4.0 */ +/* #define FREESCALE_MQX_4_0 */ + +/* Uncomment next line if building for Freescale Classic MQX/RTCS/MFS */ +/* #define FREESCALE_MQX */ + +/* Uncomment next line if building for Freescale KSDK MQX/RTCS/MFS */ +/* #define FREESCALE_KSDK_MQX */ + +/* Uncomment next line if building for Freescale KSDK Bare Metal */ +/* #define FREESCALE_KSDK_BM */ + +/* Uncomment next line if building for Freescale KSDK FreeRTOS, */ +/* (old name FREESCALE_FREE_RTOS) */ +/* #define FREESCALE_KSDK_FREERTOS */ + +/* Uncomment next line if using STM32F2 */ +/* #define WOLFSSL_STM32F2 */ + +/* Uncomment next line if using STM32F4 */ +/* #define WOLFSSL_STM32F4 */ + +/* Uncomment next line if using STM32FL */ +/* #define WOLFSSL_STM32FL */ + +/* Uncomment next line if using STM32F7 */ +/* #define WOLFSSL_STM32F7 */ + +/* Uncomment next line if using QL SEP settings */ +/* #define WOLFSSL_QL */ + +/* Uncomment next line if building for EROAD */ +/* #define WOLFSSL_EROAD */ + +/* Uncomment next line if building for IAR EWARM */ +/* #define WOLFSSL_IAR_ARM */ + +/* Uncomment next line if building for Rowley CrossWorks ARM */ +/* #define WOLFSSL_ROWLEY_ARM */ + +/* Uncomment next line if using TI-RTOS settings */ +/* #define WOLFSSL_TIRTOS */ + +/* Uncomment next line if building with PicoTCP */ +/* #define WOLFSSL_PICOTCP */ + +/* Uncomment next line if building for PicoTCP demo bundle */ +/* #define WOLFSSL_PICOTCP_DEMO */ + +/* Uncomment next line if building for uITRON4 */ +/* #define WOLFSSL_uITRON4 */ + +/* Uncomment next line if building for uT-Kernel */ +/* #define WOLFSSL_uTKERNEL2 */ + +/* Uncomment next line if using Max Strength build */ +/* #define WOLFSSL_MAX_STRENGTH */ + +/* Uncomment next line if building for VxWorks */ +/* #define WOLFSSL_VXWORKS */ + +/* Uncomment next line if building for Nordic nRF5x platofrm */ +/* #define WOLFSSL_NRF5x */ + +/* Uncomment next line to enable deprecated less secure static DH suites */ +/* #define WOLFSSL_STATIC_DH */ + +/* Uncomment next line to enable deprecated less secure static RSA suites */ +/* #define WOLFSSL_STATIC_RSA */ + +/* Uncomment next line if building for ARDUINO */ +/* Uncomment both lines if building for ARDUINO on INTEL_GALILEO */ +/* #define WOLFSSL_ARDUINO */ +/* #define INTEL_GALILEO */ + +/* Uncomment next line to enable asynchronous crypto WC_PENDING_E */ +/* #define WOLFSSL_ASYNC_CRYPT */ + +/* Uncomment next line if building for uTasker */ +/* #define WOLFSSL_UTASKER */ + +/* Uncomment next line if building for embOS */ +/* #define WOLFSSL_EMBOS */ + +/* Uncomment next line if building for RIOT-OS */ +/* #define WOLFSSL_RIOT_OS */ + +/* Uncomment next line if building for using XILINX hardened crypto */ +/* #define WOLFSSL_XILINX_CRYPT */ + +/* Uncomment next line if building for using XILINX */ +/* #define WOLFSSL_XILINX */ + +/* Uncomment next line if building for WICED Studio. */ +/* #define WOLFSSL_WICED */ + +/* Uncomment next line if building for Nucleus 1.2 */ +/* #define WOLFSSL_NUCLEUS_1_2 */ + +/* Uncomment next line if building for using Apache mynewt */ +/* #define WOLFSSL_APACHE_MYNEWT */ + +/* Uncomment next line if building for using ESP-IDF */ +/* #define WOLFSSL_ESPIDF */ + +/* Uncomment next line if using Espressif ESP32-WROOM-32 */ +/* #define WOLFSSL_ESPWROOM32 */ + +/* Uncomment next line if using Espressif ESP32-WROOM-32SE */ +/* #define WOLFSSL_ESPWROOM32SE */ + +/* Uncomment next line if using ARM CRYPTOCELL*/ +/* #define WOLFSSL_CRYPTOCELL */ + +/* Uncomment next line if using RENESAS TSIP */ +/* #define WOLFSSL_RENESAS_TSIP */ + +/* Uncomment next line if using RENESAS RX64N */ +/* #define WOLFSSL_RENESAS_RX65N */ + +#include + +#ifdef WOLFSSL_USER_SETTINGS + #include "user_settings.h" +#endif + + +/* make sure old RNG name is used with CTaoCrypt FIPS */ +#ifdef HAVE_FIPS + #if !defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2) + #define WC_RNG RNG + #else + #ifndef WOLFSSL_STM32L4 + #define RNG WC_RNG + #endif + #endif + /* blinding adds API not available yet in FIPS mode */ + #undef WC_RSA_BLINDING +#endif + + +#if defined(_WIN32) && !defined(_M_X64) && \ + defined(HAVE_AESGCM) && defined(WOLFSSL_AESNI) + +/* The _M_X64 macro is what's used in the headers for MSC to tell if it + * has the 64-bit versions of the 128-bit integers available. If one is + * building on 32-bit Windows with AES-NI, turn off the AES-GCMloop + * unrolling. */ + + #define AES_GCM_AESNI_NO_UNROLL +#endif + +#ifdef IPHONE + #define SIZEOF_LONG_LONG 8 +#endif + +#ifdef THREADX + #define SIZEOF_LONG_LONG 8 +#endif + +#ifdef HAVE_NETX + #ifdef NEED_THREADX_TYPES + #include + #endif + #include +#endif + +#if defined(WOLFSSL_ESPIDF) + #define FREERTOS + #define WOLFSSL_LWIP + #define NO_WRITEV + #define SIZEOF_LONG_LONG 8 + #define NO_WOLFSSL_DIR + #define WOLFSSL_NO_CURRDIR + + #define TFM_TIMING_RESISTANT + #define ECC_TIMING_RESISTANT + #define WC_RSA_BLINDING + +#if defined(WOLFSSL_ESPWROOM32) || defined(WOLFSSL_ESPWROOM32SE) + #ifndef NO_ESP32WROOM32_CRYPT + #define WOLFSSL_ESP32WROOM32_CRYPT + #if defined(ESP32_USE_RSA_PRIMITIVE) && \ + !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) + #define WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI + #define USE_FAST_MATH + #define WOLFSSL_SMALL_STACK + #endif + #endif +#endif +#endif /* WOLFSSL_ESPIDF */ + +#if defined(WOLFSSL_RENESAS_TSIP) + #define TSIP_TLS_HMAC_KEY_INDEX_WORDSIZE 64 + #define TSIP_TLS_MASTERSECRET_SIZE 80 /* 20 words */ + #define TSIP_TLS_ENCPUBKEY_SZ_BY_CERTVRFY 560 /* in byte */ + #if !defined(NO_RENESAS_TSIP_CRYPT) && defined(WOLFSSL_RENESAS_RX65N) + #define WOLFSSL_RENESAS_TSIP_CRYPT + #define WOLFSSL_RENESAS_TSIP_TLS + #define WOLFSSL_RENESAS_TSIP_TLS_AES_CRYPT + #endif +#endif + +#if defined(HAVE_LWIP_NATIVE) /* using LwIP native TCP socket */ + #define WOLFSSL_LWIP + #define NO_WRITEV + #define SINGLE_THREADED + #define WOLFSSL_USER_IO + #define NO_FILESYSTEM +#endif + +#if defined(WOLFSSL_CONTIKI) + #include + #define WOLFSSL_UIP + #define NO_WOLFSSL_MEMORY + #define NO_WRITEV + #define SINGLE_THREADED + #define WOLFSSL_USER_IO + #define NO_FILESYSTEM + #define CUSTOM_RAND_TYPE uint16_t + #define CUSTOM_RAND_GENERATE random_rand + static inline word32 LowResTimer(void) + { + return clock_seconds(); + } +#endif + +#if defined(WOLFSSL_IAR_ARM) || defined(WOLFSSL_ROWLEY_ARM) + #define NO_MAIN_DRIVER + #define SINGLE_THREADED + #if !defined(USE_CERT_BUFFERS_2048) && !defined(USE_CERT_BUFFERS_4096) + #define USE_CERT_BUFFERS_1024 + #endif + #define BENCH_EMBEDDED + #define NO_FILESYSTEM + #define NO_WRITEV + #define WOLFSSL_USER_IO + #define BENCH_EMBEDDED +#endif + +#ifdef MICROCHIP_PIC32 + /* #define WOLFSSL_MICROCHIP_PIC32MZ */ + #define SIZEOF_LONG_LONG 8 + #define SINGLE_THREADED + #define WOLFSSL_USER_IO + #define NO_WRITEV + #define NO_DEV_RANDOM + #define NO_FILESYSTEM + #define USE_FAST_MATH + #define TFM_TIMING_RESISTANT + #define WOLFSSL_HAVE_MIN + #define WOLFSSL_HAVE_MAX + #define NO_BIG_INT +#endif + +#ifdef WOLFSSL_MICROCHIP_PIC32MZ + #ifndef NO_PIC32MZ_CRYPT + #define WOLFSSL_PIC32MZ_CRYPT + #endif + #ifndef NO_PIC32MZ_RNG + #define WOLFSSL_PIC32MZ_RNG + #endif + #ifndef NO_PIC32MZ_HASH + #define WOLFSSL_PIC32MZ_HASH + #endif +#endif + +#ifdef MICROCHIP_TCPIP_V5 + /* include timer functions */ + #include "TCPIP Stack/TCPIP.h" +#endif + +#ifdef MICROCHIP_TCPIP + /* include timer, NTP functions */ + #ifdef MICROCHIP_MPLAB_HARMONY + #include "tcpip/tcpip.h" + #else + #include "system/system_services.h" + #include "tcpip/sntp.h" + #endif +#endif + +#ifdef MBED + #define WOLFSSL_USER_IO + #define NO_FILESYSTEM + #define NO_CERTS + #if !defined(USE_CERT_BUFFERS_2048) && !defined(USE_CERT_BUFFERS_4096) + #define USE_CERT_BUFFERS_1024 + #endif + #define NO_WRITEV + #define NO_DEV_RANDOM + #define NO_SHA512 + #define NO_DH + /* Allows use of DH with fixed points if uncommented and NO_DH is removed */ + /* WOLFSSL_DH_CONST */ + #define NO_DSA + #define NO_HC128 + #define HAVE_ECC + #define NO_SESSION_CACHE + #define WOLFSSL_CMSIS_RTOS +#endif + + +#ifdef WOLFSSL_EROAD + #define FREESCALE_MQX + #define FREESCALE_MMCAU + #define SINGLE_THREADED + #define NO_STDIO_FILESYSTEM + #define WOLFSSL_LEANPSK + #define HAVE_NULL_CIPHER + #define NO_OLD_TLS + #define NO_ASN + #define NO_BIG_INT + #define NO_RSA + #define NO_DSA + #define NO_DH + /* Allows use of DH with fixed points if uncommented and NO_DH is removed */ + /* WOLFSSL_DH_CONST */ + #define NO_CERTS + #define NO_PWDBASED + #define NO_DES3 + #define NO_MD4 + #define NO_RC4 + #define NO_MD5 + #define NO_SESSION_CACHE + #define NO_MAIN_DRIVER +#endif + +#ifdef WOLFSSL_PICOTCP + #ifndef errno + #define errno pico_err + #endif + #include "pico_defines.h" + #include "pico_stack.h" + #include "pico_constants.h" + #include "pico_protocol.h" + #define CUSTOM_RAND_GENERATE pico_rand +#endif + +#ifdef WOLFSSL_PICOTCP_DEMO + #define WOLFSSL_STM32 + #define USE_FAST_MATH + #define TFM_TIMING_RESISTANT + #define XMALLOC(s, h, type) PICO_ZALLOC((s)) + #define XFREE(p, h, type) PICO_FREE((p)) + #define SINGLE_THREADED + #define NO_WRITEV + #define WOLFSSL_USER_IO + #define NO_DEV_RANDOM + #define NO_FILESYSTEM +#endif + +#ifdef FREERTOS_WINSIM + #define FREERTOS + #define USE_WINDOWS_API +#endif + + +#ifdef WOLFSSL_VXWORKS + /* VxWorks simulator incorrectly detects building for i386 */ + #ifdef VXWORKS_SIM + #define TFM_NO_ASM + #endif + /* For VxWorks pthreads wrappers for mutexes uncomment the next line. */ + /* #define WOLFSSL_PTHREADS */ + #define WOLFSSL_HAVE_MIN + #define WOLFSSL_HAVE_MAX + #define USE_FAST_MATH + #define TFM_TIMING_RESISTANT + #define NO_MAIN_DRIVER + #define NO_DEV_RANDOM + #define NO_WRITEV +#endif + + +#ifdef WOLFSSL_ARDUINO + #define NO_WRITEV + #define NO_WOLFSSL_DIR + #define SINGLE_THREADED + #define NO_DEV_RANDOM + #ifndef INTEL_GALILEO /* Galileo has time.h compatibility */ + #define TIME_OVERRIDES + #ifndef XTIME + #error "Must define XTIME externally see porting guide" + #error "https://www.wolfssl.com/docs/porting-guide/" + #endif + #ifndef XGMTIME + #error "Must define XGMTIME externally see porting guide" + #error "https://www.wolfssl.com/docs/porting-guide/" + #endif + #endif + #define WOLFSSL_USER_IO + #define HAVE_ECC + #define NO_DH + #define NO_SESSION_CACHE +#endif + + +#ifdef WOLFSSL_UTASKER + /* uTasker configuration - used for fnRandom() */ + #include "config.h" + + #define SINGLE_THREADED + #define NO_WOLFSSL_DIR + #define WOLFSSL_HAVE_MIN + #define NO_WRITEV + + #define HAVE_ECC + #define ALT_ECC_SIZE + #define USE_FAST_MATH + #define TFM_TIMING_RESISTANT + #define ECC_TIMING_RESISTANT + + /* used in wolfCrypt test */ + #define NO_MAIN_DRIVER + #define USE_CERT_BUFFERS_2048 + + /* uTasker port uses RAW sockets, use I/O callbacks + * See wolfSSL uTasker example for sample callbacks */ + #define WOLFSSL_USER_IO + + /* uTasker filesystem not ported */ + #define NO_FILESYSTEM + + /* uTasker RNG is abstracted, calls HW RNG when available */ + #define CUSTOM_RAND_GENERATE fnRandom + #define CUSTOM_RAND_TYPE unsigned short + + /* user needs to define XTIME to function that provides + * seconds since Unix epoch */ + #ifndef XTIME + #error XTIME must be defined in wolfSSL settings.h + /* #define XTIME fnSecondsSinceEpoch */ + #endif + + /* use uTasker std library replacements where available */ + #define STRING_USER + #define XMEMCPY(d,s,l) uMemcpy((d),(s),(l)) + #define XMEMSET(b,c,l) uMemset((b),(c),(l)) + #define XMEMCMP(s1,s2,n) uMemcmp((s1),(s2),(n)) + #define XMEMMOVE(d,s,l) memmove((d),(s),(l)) + + #define XSTRLEN(s1) uStrlen((s1)) + #define XSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n)) + #define XSTRSTR(s1,s2) strstr((s1),(s2)) + #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) + #define XSTRNCMP(s1,s2,n) strncmp((s1),(s2),(n)) + #define XSTRNCAT(s1,s2,n) strncat((s1),(s2),(n)) + #define XSTRNCASECMP(s1,s2,n) _strnicmp((s1),(s2),(n)) + #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) \ + || defined(HAVE_ALPN) + #define XSTRTOK strtok_r + #endif +#endif + +#ifdef WOLFSSL_EMBOS + #define NO_FILESYSTEM /* Not ported at this time */ + #define USE_CERT_BUFFERS_2048 /* use when NO_FILESYSTEM */ + #define NO_MAIN_DRIVER + #define NO_RC4 + #define SINGLE_THREADED /* Not ported at this time */ +#endif + +#ifdef WOLFSSL_RIOT_OS + #define NO_WRITEV + #define TFM_NO_ASM + #define NO_FILESYSTEM + #define USE_CERT_BUFFERS_2048 + #if defined(WOLFSSL_GNRC) && !defined(WOLFSSL_DTLS) + #define WOLFSSL_DTLS + #endif +#endif + +#ifdef WOLFSSL_CHIBIOS + /* ChibiOS definitions. This file is distributed with chibiOS. */ + #include "wolfssl_chibios.h" +#endif + +#ifdef WOLFSSL_PB + /* PB is using older 1.2 version of Nucleus */ + #undef WOLFSSL_NUCLEUS + #define WOLFSSL_NUCLEUS_1_2 +#endif + +#ifdef WOLFSSL_NUCLEUS_1_2 + #define NO_WRITEV + #define NO_WOLFSSL_DIR + + #if !defined(NO_ASN_TIME) && !defined(USER_TIME) + #error User must define XTIME, see manual + #endif + + #if !defined(XMALLOC_OVERRIDE) && !defined(XMALLOC_USER) + extern void* nucleus_malloc(unsigned long size, void* heap, int type); + extern void* nucleus_realloc(void* ptr, unsigned long size, void* heap, + int type); + extern void nucleus_free(void* ptr, void* heap, int type); + + #define XMALLOC(s, h, type) nucleus_malloc((s), (h), (type)) + #define XREALLOC(p, n, h, t) nucleus_realloc((p), (n), (h), (t)) + #define XFREE(p, h, type) nucleus_free((p), (h), (type)) + #endif +#endif + +#ifdef WOLFSSL_NRF5x + #define SIZEOF_LONG 4 + #define SIZEOF_LONG_LONG 8 + #define NO_ASN_TIME + #define NO_DEV_RANDOM + #define NO_FILESYSTEM + #define NO_MAIN_DRIVER + #define NO_WRITEV + #define SINGLE_THREADED + #define USE_FAST_MATH + #define TFM_TIMING_RESISTANT + #define USE_WOLFSSL_MEMORY + #define WOLFSSL_NRF51 + #define WOLFSSL_USER_IO + #define NO_SESSION_CACHE +#endif + +/* Micrium will use Visual Studio for compilation but not the Win32 API */ +#if defined(_WIN32) && !defined(MICRIUM) && !defined(FREERTOS) && \ + !defined(FREERTOS_TCP) && !defined(EBSNET) && !defined(WOLFSSL_EROAD) && \ + !defined(WOLFSSL_UTASKER) && !defined(INTIME_RTOS) + #define USE_WINDOWS_API +#endif + +#if defined(WOLFSSL_uITRON4) + +#define XMALLOC_USER +#include +#define ITRON_POOL_SIZE 1024*20 +extern int uITRON4_minit(size_t poolsz) ; +extern void *uITRON4_malloc(size_t sz) ; +extern void *uITRON4_realloc(void *p, size_t sz) ; +extern void uITRON4_free(void *p) ; + +#define XMALLOC(sz, heap, type) uITRON4_malloc(sz) +#define XREALLOC(p, sz, heap, type) uITRON4_realloc(p, sz) +#define XFREE(p, heap, type) uITRON4_free(p) +#endif + +#if defined(WOLFSSL_uTKERNEL2) + #ifndef NO_TKERNEL_MEM_POOL + #define XMALLOC_OVERRIDE + int uTKernel_init_mpool(unsigned int sz); /* initializing malloc pool */ + void* uTKernel_malloc(unsigned int sz); + void* uTKernel_realloc(void *p, unsigned int sz); + void uTKernel_free(void *p); + #define XMALLOC(s, h, type) uTKernel_malloc((s)) + #define XREALLOC(p, n, h, t) uTKernel_realloc((p), (n)) + #define XFREE(p, h, type) uTKernel_free((p)) + #endif + + #ifndef NO_STDIO_FGETS_REMAP + #include + #include "tm/tmonitor.h" + + /* static char* gets(char *buff); */ + static char* fgets(char *buff, int sz, XFILE fp) { + char * p = buff; + *p = '\0'; + while (1) { + *p = tm_getchar(-1); + tm_putchar(*p); + if (*p == '\r') { + tm_putchar('\n'); + *p = '\0'; + break; + } + p++; + } + return buff; + } + #endif /* !NO_STDIO_FGETS_REMAP */ +#endif + + +#if defined(WOLFSSL_LEANPSK) && !defined(XMALLOC_USER) && \ + !defined(NO_WOLFSSL_MEMORY) + #include + #define XMALLOC(s, h, type) malloc((s)) + #define XFREE(p, h, type) free((p)) + #define XREALLOC(p, n, h, t) realloc((p), (n)) +#endif + +#if defined(XMALLOC_USER) && defined(SSN_BUILDING_LIBYASSL) + #undef XMALLOC + #define XMALLOC yaXMALLOC + #undef XFREE + #define XFREE yaXFREE + #undef XREALLOC + #define XREALLOC yaXREALLOC +#endif + + +#ifdef FREERTOS + #include "FreeRTOS.h" + + /* FreeRTOS pvPortRealloc() only in AVR32_UC3 port */ + #if !defined(XMALLOC_USER) && !defined(NO_WOLFSSL_MEMORY) && \ + !defined(WOLFSSL_STATIC_MEMORY) + #define XMALLOC(s, h, type) pvPortMalloc((s)) + #define XFREE(p, h, type) vPortFree((p)) + #endif + #if defined(HAVE_ED25519) || defined(WOLFSSL_ESPIDF) + #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n)) + #endif + #ifndef NO_WRITEV + #define NO_WRITEV + #endif + #ifndef HAVE_SHA512 + #ifndef NO_SHA512 + #define NO_SHA512 + #endif + #endif + #ifndef HAVE_DH + #ifndef NO_DH + #define NO_DH + #endif + #endif + #ifndef NO_DSA + #define NO_DSA + #endif + #ifndef NO_HC128 + #define NO_HC128 + #endif + + #ifndef SINGLE_THREADED + #include "semphr.h" + #endif +#endif + +#ifdef FREERTOS_TCP + #if !defined(NO_WOLFSSL_MEMORY) && !defined(XMALLOC_USER) && \ + !defined(WOLFSSL_STATIC_MEMORY) + #define XMALLOC(s, h, type) pvPortMalloc((s)) + #define XFREE(p, h, type) vPortFree((p)) + #endif + + #define WOLFSSL_GENSEED_FORTEST + + #define NO_WOLFSSL_DIR + #define NO_WRITEV + #define USE_FAST_MATH + #define TFM_TIMING_RESISTANT + #define NO_MAIN_DRIVER +#endif + +#ifdef WOLFSSL_TIRTOS + #define SIZEOF_LONG_LONG 8 + #define NO_WRITEV + #define NO_WOLFSSL_DIR + #define USE_FAST_MATH + #define TFM_TIMING_RESISTANT + #define ECC_TIMING_RESISTANT + #define WC_RSA_BLINDING + #define NO_DEV_RANDOM + #define NO_FILESYSTEM + #define USE_CERT_BUFFERS_2048 + #define NO_ERROR_STRINGS + /* Uncomment this setting if your toolchain does not offer time.h header */ + /* #define USER_TIME */ + #define HAVE_ECC + #define HAVE_ALPN + #define USE_WOLF_STRTOK /* use with HAVE_ALPN */ + #define HAVE_TLS_EXTENSIONS + #define HAVE_AESGCM + #ifdef WOLFSSL_TI_CRYPT + #define NO_GCM_ENCRYPT_EXTRA + #define NO_PUBLIC_GCM_SET_IV + #define NO_PUBLIC_CCM_SET_NONCE + #endif + #define HAVE_SUPPORTED_CURVES + #define ALT_ECC_SIZE + + #ifdef __IAR_SYSTEMS_ICC__ + #pragma diag_suppress=Pa089 + #elif !defined(__GNUC__) + /* Suppress the sslpro warning */ + #pragma diag_suppress=11 + #endif + + #include +#endif + +#ifdef EBSNET + #include "rtip.h" + + /* #define DEBUG_WOLFSSL */ + #define NO_WOLFSSL_DIR /* tbd */ + + #if (POLLOS) + #define SINGLE_THREADED + #endif + + #if (RTPLATFORM) + #if (!RTP_LITTLE_ENDIAN) + #define BIG_ENDIAN_ORDER + #endif + #else + #if (!KS_LITTLE_ENDIAN) + #define BIG_ENDIAN_ORDER + #endif + #endif + + #if (WINMSP3) + #undef SIZEOF_LONG + #define SIZEOF_LONG_LONG 8 + #else + #error settings.h - please implement SIZEOF_LONG and SIZEOF_LONG_LONG + #endif + + #define XMALLOC(s, h, type) ((void *)rtp_malloc((s), SSL_PRO_MALLOC)) + #define XFREE(p, h, type) (rtp_free(p)) + #define XREALLOC(p, n, h, t) (rtp_realloc((p), (n))) + + #if (WINMSP3) + #define XSTRNCASECMP(s1,s2,n) _strnicmp((s1),(s2),(n)) + #else + #sslpro: settings.h - please implement XSTRNCASECMP - needed for HAVE_ECC + #endif + + #define WOLFSSL_HAVE_MAX + #define WOLFSSL_HAVE_MIN + + #define USE_FAST_MATH + #define TFM_TIMING_RESISTANT + #define WC_RSA_BLINDING + #define ECC_TIMING_RESISTANT + + #define HAVE_ECC + +#endif /* EBSNET */ + +#ifdef WOLFSSL_GAME_BUILD + #define SIZEOF_LONG_LONG 8 + #if defined(__PPU) || defined(__XENON) + #define BIG_ENDIAN_ORDER + #endif +#endif + +#ifdef WOLFSSL_LSR + #define HAVE_WEBSERVER + #define SIZEOF_LONG_LONG 8 + #define WOLFSSL_LOW_MEMORY + #define NO_WRITEV + #define NO_SHA512 + #define NO_DH + /* Allows use of DH with fixed points if uncommented and NO_DH is removed */ + /* WOLFSSL_DH_CONST */ + #define NO_DSA + #define NO_HC128 + #define NO_DEV_RANDOM + #define NO_WOLFSSL_DIR + #define NO_RABBIT + #ifndef NO_FILESYSTEM + #define LSR_FS + #include "inc/hw_types.h" + #include "fs.h" + #endif + #define WOLFSSL_LWIP + #include /* for tcp errno */ + #define WOLFSSL_SAFERTOS + #if defined(__IAR_SYSTEMS_ICC__) + /* enum uses enum */ + #pragma diag_suppress=Pa089 + #endif +#endif + +#ifdef WOLFSSL_SAFERTOS + #ifndef SINGLE_THREADED + #include "SafeRTOS/semphr.h" + #endif + #ifndef WOLFSSL_NO_MALLOC + #include "SafeRTOS/heap.h" + #endif + #if !defined(XMALLOC_USER) && !defined(NO_WOLFSSL_MEMORY) && \ + !defined(WOLFSSL_STATIC_MEMORY) + #define XMALLOC(s, h, type) pvPortMalloc((s)) + #define XFREE(p, h, type) vPortFree((p)) + #endif + #if !defined(USE_FAST_MATH) || defined(HAVE_ED25519) + #define XREALLOC(p, n, h, t) pvPortRealloc((p), (n)) + #endif +#endif + +#ifdef WOLFSSL_LOW_MEMORY + #undef RSA_LOW_MEM + #define RSA_LOW_MEM + #undef WOLFSSL_SMALL_STACK + #define WOLFSSL_SMALL_STACK + #undef TFM_TIMING_RESISTANT + #define TFM_TIMING_RESISTANT +#endif + +#ifdef FREESCALE_MQX_5_0 + /* use normal Freescale MQX port, but with minor changes for 5.0 */ + #define FREESCALE_MQX +#endif + +#ifdef FREESCALE_MQX_4_0 + /* use normal Freescale MQX port, but with minor changes for 4.0 */ + #define FREESCALE_MQX +#endif + +#ifdef FREESCALE_MQX + #define FREESCALE_COMMON + #include "mqx.h" + #ifndef NO_FILESYSTEM + #include "mfs.h" + #if (defined(MQX_USE_IO_OLD) && MQX_USE_IO_OLD) || \ + defined(FREESCALE_MQX_5_0) + #include "fio.h" + #define NO_STDIO_FILESYSTEM + #else + #include "nio.h" + #endif + #endif + #ifndef SINGLE_THREADED + #include "mutex.h" + #endif + + #if !defined(XMALLOC_OVERRIDE) && !defined(XMALLOC_USER) + #define XMALLOC_OVERRIDE + #define XMALLOC(s, h, t) (void *)_mem_alloc_system((s)) + #define XFREE(p, h, t) {void* xp = (p); if ((xp)) _mem_free((xp));} + /* Note: MQX has no realloc, using fastmath above */ + #endif +#endif + +#ifdef FREESCALE_KSDK_MQX + #define FREESCALE_COMMON + #include + #ifndef NO_FILESYSTEM + #if (defined(MQX_USE_IO_OLD) && MQX_USE_IO_OLD) || \ + defined(FREESCALE_MQX_5_0) + #include + #else + #include + #include + #endif + #endif + #ifndef SINGLE_THREADED + #include + #endif + + #define XMALLOC(s, h, t) (void *)_mem_alloc_system((s)) + #define XFREE(p, h, t) {void* xp = (p); if ((xp)) _mem_free((xp));} + #define XREALLOC(p, n, h, t) _mem_realloc((p), (n)) /* since MQX 4.1.2 */ + + #define MQX_FILE_PTR FILE * + #define IO_SEEK_SET SEEK_SET + #define IO_SEEK_END SEEK_END +#endif /* FREESCALE_KSDK_MQX */ + +#if defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS) + #define NO_FILESYSTEM + #define WOLFSSL_CRYPT_HW_MUTEX 1 + + #if !defined(XMALLOC_USER) && !defined(NO_WOLFSSL_MEMORY) + #define XMALLOC(s, h, type) pvPortMalloc((s)) + #define XFREE(p, h, type) vPortFree((p)) + #endif + + //#define USER_TICKS + /* Allows use of DH with fixed points if uncommented and NO_DH is removed */ + /* WOLFSSL_DH_CONST */ + #define WOLFSSL_LWIP + #define FREERTOS_TCP + + #define FREESCALE_FREE_RTOS + #define FREERTOS_SOCKET_ERROR ( -1 ) + #define FREERTOS_EWOULDBLOCK ( -2 ) + #define FREERTOS_EINVAL ( -4 ) + #define FREERTOS_EADDRNOTAVAIL ( -5 ) + #define FREERTOS_EADDRINUSE ( -6 ) + #define FREERTOS_ENOBUFS ( -7 ) + #define FREERTOS_ENOPROTOOPT ( -8 ) +#endif /* FREESCALE_FREE_RTOS || FREESCALE_KSDK_FREERTOS */ + +#ifdef FREESCALE_KSDK_BM + #define FREESCALE_COMMON + #define WOLFSSL_USER_IO + #define SINGLE_THREADED + #define NO_FILESYSTEM + #ifndef TIME_OVERRIDES + #define USER_TICKS + #endif +#endif /* FREESCALE_KSDK_BM */ + +#ifdef FREESCALE_COMMON + #define SIZEOF_LONG_LONG 8 + + /* disable features */ + #undef NO_WRITEV + #define NO_WRITEV + #undef NO_DEV_RANDOM + #define NO_DEV_RANDOM + #undef NO_RABBIT + #define NO_RABBIT + #undef NO_WOLFSSL_DIR + #define NO_WOLFSSL_DIR + #undef NO_RC4 + #define NO_RC4 + + /* enable features */ + #undef USE_FAST_MATH + #define USE_FAST_MATH + + #define USE_CERT_BUFFERS_2048 + #define BENCH_EMBEDDED + + #define TFM_TIMING_RESISTANT + #define ECC_TIMING_RESISTANT + + #undef HAVE_ECC + #define HAVE_ECC + #ifndef NO_AES + #undef HAVE_AESCCM + #define HAVE_AESCCM + #undef HAVE_AESGCM + #define HAVE_AESGCM + #undef WOLFSSL_AES_COUNTER + #define WOLFSSL_AES_COUNTER + #undef WOLFSSL_AES_DIRECT + #define WOLFSSL_AES_DIRECT + #endif + + #ifdef FREESCALE_KSDK_1_3 + #include "fsl_device_registers.h" + #elif !defined(FREESCALE_MQX) + /* Classic MQX does not have fsl_common.h */ + #include "fsl_common.h" + #endif + + /* random seed */ + #define NO_OLD_RNGNAME + #if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0) + #define FREESCALE_KSDK_2_0_TRNG + #elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0) + #ifdef FREESCALE_KSDK_1_3 + #include "fsl_rnga_driver.h" + #define FREESCALE_RNGA + #define RNGA_INSTANCE (0) + #else + #define FREESCALE_KSDK_2_0_RNGA + #endif + #elif !defined(FREESCALE_KSDK_BM) && !defined(FREESCALE_FREE_RTOS) && !defined(FREESCALE_KSDK_FREERTOS) + #define FREESCALE_RNGA + #define RNGA_INSTANCE (0) + /* defaulting to K70 RNGA, user should change if different */ + /* #define FREESCALE_K53_RNGB */ + #define FREESCALE_K70_RNGA + #endif + + /* HW crypto */ + /* automatic enable based on Kinetis feature */ + /* if case manual selection is required, for example for benchmarking purposes, + * just define FREESCALE_USE_MMCAU or FREESCALE_USE_LTC or none of these two macros (for software only) + * both can be enabled simultaneously as LTC has priority over MMCAU in source code. + */ + /* #define FSL_HW_CRYPTO_MANUAL_SELECTION */ + #ifndef FSL_HW_CRYPTO_MANUAL_SELECTION + #if defined(FSL_FEATURE_SOC_MMCAU_COUNT) && FSL_FEATURE_SOC_MMCAU_COUNT + #define FREESCALE_USE_MMCAU + #endif + + #if defined(FSL_FEATURE_SOC_LTC_COUNT) && FSL_FEATURE_SOC_LTC_COUNT + #define FREESCALE_USE_LTC + #endif + #else + /* #define FREESCALE_USE_MMCAU */ + /* #define FREESCALE_USE_LTC */ + #endif +#endif /* FREESCALE_COMMON */ + +/* Classic pre-KSDK mmCAU library */ +#ifdef FREESCALE_USE_MMCAU_CLASSIC + #define FREESCALE_USE_MMCAU + #define FREESCALE_MMCAU_CLASSIC + #define FREESCALE_MMCAU_CLASSIC_SHA +#endif + +/* KSDK mmCAU library */ +#ifdef FREESCALE_USE_MMCAU + /* AES and DES */ + #define FREESCALE_MMCAU + /* MD5, SHA-1 and SHA-256 */ + #define FREESCALE_MMCAU_SHA +#endif /* FREESCALE_USE_MMCAU */ + +#ifdef FREESCALE_USE_LTC + #if defined(FSL_FEATURE_SOC_LTC_COUNT) && FSL_FEATURE_SOC_LTC_COUNT + #define FREESCALE_LTC + #define LTC_BASE LTC0 + + #if defined(FSL_FEATURE_LTC_HAS_DES) && FSL_FEATURE_LTC_HAS_DES + #define FREESCALE_LTC_DES + #endif + + #if defined(FSL_FEATURE_LTC_HAS_GCM) && FSL_FEATURE_LTC_HAS_GCM + #define FREESCALE_LTC_AES_GCM + #endif + + #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + #define FREESCALE_LTC_SHA + #endif + + #if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA + #define FREESCALE_LTC_ECC + #define FREESCALE_LTC_TFM + + /* the LTC PKHA hardware limit is 2048 bits (256 bytes) for integer arithmetic. + the LTC_MAX_INT_BYTES defines the size of local variables that hold big integers. */ + #ifndef LTC_MAX_INT_BYTES + #define LTC_MAX_INT_BYTES (256) + #endif + + /* This FREESCALE_LTC_TFM_RSA_4096_ENABLE macro can be defined. + * In such a case both software and hardware algorithm + * for TFM is linked in. The decision for which algorithm is used is determined at runtime + * from size of inputs. If inputs and result can fit into LTC (see LTC_MAX_INT_BYTES) + * then we call hardware algorithm, otherwise we call software algorithm. + * + * Chinese reminder theorem is used to break RSA 4096 exponentiations (both public and private key) + * into several computations with 2048-bit modulus and exponents. + */ + /* #define FREESCALE_LTC_TFM_RSA_4096_ENABLE */ + + /* ECC-384, ECC-256, ECC-224 and ECC-192 have been enabled with LTC PKHA acceleration */ + #ifdef HAVE_ECC + #undef ECC_TIMING_RESISTANT + #define ECC_TIMING_RESISTANT + + /* the LTC PKHA hardware limit is 512 bits (64 bytes) for ECC. + the LTC_MAX_ECC_BITS defines the size of local variables that hold ECC parameters + and point coordinates */ + #ifndef LTC_MAX_ECC_BITS + #define LTC_MAX_ECC_BITS (384) + #endif + + /* Enable curves up to 384 bits */ + #if !defined(ECC_USER_CURVES) && !defined(HAVE_ALL_CURVES) + #define ECC_USER_CURVES + #define HAVE_ECC192 + #define HAVE_ECC224 + #undef NO_ECC256 + #define HAVE_ECC384 + #endif + #endif + #endif + #endif +#endif /* FREESCALE_USE_LTC */ + +#ifdef FREESCALE_LTC_TFM_RSA_4096_ENABLE + #undef USE_CERT_BUFFERS_4096 + #define USE_CERT_BUFFERS_4096 + #undef FP_MAX_BITS + #define FP_MAX_BITS (8192) + + #undef NO_DH + #define NO_DH + #undef NO_DSA + #define NO_DSA +#endif /* FREESCALE_LTC_TFM_RSA_4096_ENABLE */ + +/* if LTC has AES engine but doesn't have GCM, use software with LTC AES ECB mode */ +#if defined(FREESCALE_USE_LTC) && !defined(FREESCALE_LTC_AES_GCM) + #define GCM_TABLE +#endif + +#if defined(WOLFSSL_STM32F2) || defined(WOLFSSL_STM32F4) || \ + defined(WOLFSSL_STM32F7) || defined(WOLFSSL_STM32F1) || \ + defined(WOLFSSL_STM32L4) + + #define SIZEOF_LONG_LONG 8 + #ifndef CHAR_BIT + #define CHAR_BIT 8 + #endif + #define NO_DEV_RANDOM + #define NO_WOLFSSL_DIR + #undef NO_RABBIT + #define NO_RABBIT + #ifndef NO_STM32_RNG + #undef STM32_RNG + #define STM32_RNG + #ifdef WOLFSSL_STM32F427_RNG + #include "stm32f427xx.h" + #endif + #endif + #ifndef NO_STM32_CRYPTO + #undef STM32_CRYPTO + #define STM32_CRYPTO + + #ifdef WOLFSSL_STM32L4 + #define NO_AES_192 /* hardware does not support 192-bit */ + #endif + #endif + #ifndef NO_STM32_HASH + #undef STM32_HASH + #define STM32_HASH + #endif + #if !defined(__GNUC__) && !defined(__ICCARM__) + #define KEIL_INTRINSICS + #endif + #define NO_OLD_RNGNAME + #ifdef WOLFSSL_STM32_CUBEMX + #if defined(WOLFSSL_STM32F2) + #include "stm32f2xx_hal.h" + #elif defined(WOLFSSL_STM32L4) + #include "stm32l4xx_hal.h" + #elif defined(WOLFSSL_STM32F4) + #include "stm32f4xx_hal.h" + #elif defined(WOLFSSL_STM32F7) + #include "stm32f7xx_hal.h" + #elif defined(WOLFSSL_STM32F1) + #include "stm32f1xx_hal.h" + #endif + #if defined(WOLFSSL_CUBEMX_USE_LL) && defined(WOLFSSL_STM32L4) + #include "stm32l4xx_ll_rng.h" + #endif + + #ifndef STM32_HAL_TIMEOUT + #define STM32_HAL_TIMEOUT 0xFF + #endif + #else + #if defined(WOLFSSL_STM32F2) + #include "stm32f2xx.h" + #ifdef STM32_CRYPTO + #include "stm32f2xx_cryp.h" + #endif + #ifdef STM32_HASH + #include "stm32f2xx_hash.h" + #endif + #elif defined(WOLFSSL_STM32F4) + #include "stm32f4xx.h" + #ifdef STM32_CRYPTO + #include "stm32f4xx_cryp.h" + #endif + #ifdef STM32_HASH + #include "stm32f4xx_hash.h" + #endif + #elif defined(WOLFSSL_STM32L4) + #include "stm32l4xx.h" + #ifdef STM32_CRYPTO + #include "stm32l4xx_cryp.h" + #endif + #ifdef STM32_HASH + #include "stm32l4xx_hash.h" + #endif + #elif defined(WOLFSSL_STM32F7) + #include "stm32f7xx.h" + #elif defined(WOLFSSL_STM32F1) + #include "stm32f1xx.h" + #endif + #endif /* WOLFSSL_STM32_CUBEMX */ +#endif /* WOLFSSL_STM32F2 || WOLFSSL_STM32F4 || WOLFSSL_STM32L4 || WOLFSSL_STM32F7 */ +#ifdef WOLFSSL_DEOS + #include + #include + #include + #include + #include + #include + #include /* for rand_r: pseudo-random number generator */ + #include /* for snprintf */ + + /* use external memory XMALLOC, XFREE and XREALLOC functions */ + #define XMALLOC_USER + + /* disable fall-back case, malloc, realloc and free are unavailable */ + #define WOLFSSL_NO_MALLOC + + /* file sytem has not been ported since it is a seperate product. */ + + #define NO_FILESYSTEM + + #ifdef NO_FILESYSTEM + #define NO_WOLFSSL_DIR + #define NO_WRITEV + #endif + + #define USE_FAST_MATH + #define TFM_TIMING_RESISTANT + #define ECC_TIMING_RESISTANT + #define WC_RSA_BLINDING + + #define HAVE_ECC + #define ALT_ECC_SIZE + #define TFM_ECC192 + #define TFM_ECC224 + #define TFM_ECC256 + #define TFM_ECC384 + #define TFM_ECC521 + + #define HAVE_TLS_EXTENSIONS + #define HAVE_SUPPORTED_CURVES + #define HAVE_EXTENDED_MASTER + + #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + #define BIG_ENDIAN_ORDER + #else + #undef BIG_ENDIAN_ORDER + #define LITTLE_ENDIAN_ORDER + #endif +#endif /* WOLFSSL_DEOS*/ + +#ifdef MICRIUM + #include + #include + #include + #include + #include + #include + #include + + #define USE_FAST_MATH + #define TFM_TIMING_RESISTANT + #define ECC_TIMING_RESISTANT + #define WC_RSA_BLINDING + #define HAVE_HASHDRBG + + #define HAVE_ECC + #define ALT_ECC_SIZE + #define TFM_ECC192 + #define TFM_ECC224 + #define TFM_ECC256 + #define TFM_ECC384 + #define TFM_ECC521 + + #define NO_RC4 + #define HAVE_TLS_EXTENSIONS + #define HAVE_SUPPORTED_CURVES + #define HAVE_EXTENDED_MASTER + + #define NO_WOLFSSL_DIR + #define NO_WRITEV + + #ifndef CUSTOM_RAND_GENERATE + #define CUSTOM_RAND_TYPE RAND_NBR + #define CUSTOM_RAND_GENERATE Math_Rand + #endif + #define STRING_USER + #define XSTRLEN(pstr) ((CPU_SIZE_T)Str_Len((CPU_CHAR *)(pstr))) + #define XSTRNCPY(pstr_dest, pstr_src, len_max) \ + ((CPU_CHAR *)Str_Copy_N((CPU_CHAR *)(pstr_dest), \ + (CPU_CHAR *)(pstr_src), (CPU_SIZE_T)(len_max))) + #define XSTRNCMP(pstr_1, pstr_2, len_max) \ + ((CPU_INT16S)Str_Cmp_N((CPU_CHAR *)(pstr_1), \ + (CPU_CHAR *)(pstr_2), (CPU_SIZE_T)(len_max))) + #define XSTRNCASECMP(pstr_1, pstr_2, len_max) \ + ((CPU_INT16S)Str_CmpIgnoreCase_N((CPU_CHAR *)(pstr_1), \ + (CPU_CHAR *)(pstr_2), (CPU_SIZE_T)(len_max))) + #define XSTRSTR(pstr, pstr_srch) \ + ((CPU_CHAR *)Str_Str((CPU_CHAR *)(pstr), \ + (CPU_CHAR *)(pstr_srch))) + #define XSTRNSTR(pstr, pstr_srch, len_max) \ + ((CPU_CHAR *)Str_Str_N((CPU_CHAR *)(pstr), \ + (CPU_CHAR *)(pstr_srch),(CPU_SIZE_T)(len_max))) + #define XSTRNCAT(pstr_dest, pstr_cat, len_max) \ + ((CPU_CHAR *)Str_Cat_N((CPU_CHAR *)(pstr_dest), \ + (const CPU_CHAR *)(pstr_cat),(CPU_SIZE_T)(len_max))) + #define XMEMSET(pmem, data_val, size) \ + ((void)Mem_Set((void *)(pmem), \ + (CPU_INT08U) (data_val), \ + (CPU_SIZE_T)(size))) + #define XMEMCPY(pdest, psrc, size) ((void)Mem_Copy((void *)(pdest), \ + (void *)(psrc), (CPU_SIZE_T)(size))) + #define XMEMCMP(pmem_1, pmem_2, size) \ + (((CPU_BOOLEAN)Mem_Cmp((void *)(pmem_1), \ + (void *)(pmem_2), \ + (CPU_SIZE_T)(size))) ? DEF_NO : DEF_YES) + #define XMEMMOVE XMEMCPY + + #if (OS_CFG_MUTEX_EN == DEF_DISABLED) + #define SINGLE_THREADED + #endif + + #if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG) + #define BIG_ENDIAN_ORDER + #else + #undef BIG_ENDIAN_ORDER + #define LITTLE_ENDIAN_ORDER + #endif +#endif /* MICRIUM */ + +#ifdef WOLFSSL_MCF5441X + #define BIG_ENDIAN_ORDER + #ifndef SIZEOF_LONG + #define SIZEOF_LONG 4 + #endif + #ifndef SIZEOF_LONG_LONG + #define SIZEOF_LONG_LONG 8 + #endif +#endif + + #define OPENSSL_EXTRA + + +#ifdef WOLFSSL_QL + #ifndef WOLFSSL_SEP + #define WOLFSSL_SEP + #endif + #ifndef OPENSSL_EXTRA + #define OPENSSL_EXTRA + #endif + #ifndef SESSION_CERTS + #define SESSION_CERTS + #endif + #ifndef HAVE_AESCCM + #define HAVE_AESCCM + #endif + #ifndef ATOMIC_USER + #define ATOMIC_USER + #endif + #ifndef WOLFSSL_DER_LOAD + #define WOLFSSL_DER_LOAD + #endif + #ifndef KEEP_PEER_CERT + #define KEEP_PEER_CERT + #endif + #ifndef HAVE_ECC + #define HAVE_ECC + #endif + #ifndef SESSION_INDEX + #define SESSION_INDEX + #endif +#endif /* WOLFSSL_QL */ + + +#if defined(WOLFSSL_XILINX) + #define NO_WOLFSSL_DIR + #define NO_DEV_RANDOM + #define HAVE_AESGCM +#endif + +#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_AFALG_XILINX) + #if defined(WOLFSSL_ARMASM) + #error can not use both ARMv8 instructions and XILINX hardened crypto + #endif + #if defined(WOLFSSL_SHA3) + /* only SHA3-384 is supported */ + #undef WOLFSSL_NOSHA3_224 + #undef WOLFSSL_NOSHA3_256 + #undef WOLFSSL_NOSHA3_512 + #define WOLFSSL_NOSHA3_224 + #define WOLFSSL_NOSHA3_256 + #define WOLFSSL_NOSHA3_512 + #endif + #ifdef WOLFSSL_AFALG_XILINX_AES + #undef WOLFSSL_AES_DIRECT + #define WOLFSSL_AES_DIRECT + #endif +#endif /*(WOLFSSL_XILINX_CRYPT)*/ + +#if defined(WOLFSSL_APACHE_MYNEWT) + #include "os/os_malloc.h" + #if !defined(WOLFSSL_LWIP) + #include + #endif + + #if !defined(SIZEOF_LONG) + #define SIZEOF_LONG 4 + #endif + #if !defined(SIZEOF_LONG_LONG) + #define SIZEOF_LONG_LONG 8 + #endif + #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + #define BIG_ENDIAN_ORDER + #else + #undef BIG_ENDIAN_ORDER + #define LITTLE_ENDIAN_ORDER + #endif + #define NO_WRITEV + #define WOLFSSL_USER_IO + #define SINGLE_THREADED + #define NO_DEV_RANDOM + #define NO_DH + #define NO_WOLFSSL_DIR + #define NO_ERROR_STRINGS + #define HAVE_ECC + #define NO_SESSION_CACHE + #define NO_ERROR_STRINGS + #define XMALLOC_USER + #define XMALLOC(sz, heap, type) os_malloc(sz) + #define XREALLOC(p, sz, heap, type) os_realloc(p, sz) + #define XFREE(p, heap, type) os_free(p) + +#endif /*(WOLFSSL_APACHE_MYNEWT)*/ + +#ifdef WOLFSSL_ZEPHYR + #include + #include + #include + #include + + #define WOLFSSL_DH_CONST + #define WOLFSSL_HAVE_MIN + #define WOLFSSL_HAVE_MAX + #define NO_WRITEV + + #define USE_FLAT_BENCHMARK_H + #define USE_FLAT_TEST_H + #define EXIT_FAILURE 1 + #define MAIN_NO_ARGS + + void *z_realloc(void *ptr, size_t size); + #define realloc z_realloc + + #define CONFIG_NET_SOCKETS_POSIX_NAMES +#endif + +#ifdef WOLFSSL_IMX6 + #ifndef SIZEOF_LONG_LONG + #define SIZEOF_LONG_LONG 8 + #endif +#endif + +/* if defined turn on all CAAM support */ +#ifdef WOLFSSL_IMX6_CAAM + #undef WOLFSSL_IMX6_CAAM_RNG + #define WOLFSSL_IMX6_CAAM_RNG + + #undef WOLFSSL_IMX6_CAAM_BLOB + #define WOLFSSL_IMX6_CAAM_BLOB + +#if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_XTS) + /* large performance gain with HAVE_AES_ECB defined */ + #undef HAVE_AES_ECB + #define HAVE_AES_ECB +#endif +#endif + +#if !defined(XMALLOC_USER) && !defined(MICRIUM_MALLOC) && \ + !defined(WOLFSSL_LEANPSK) && !defined(NO_WOLFSSL_MEMORY) && \ + !defined(XMALLOC_OVERRIDE) + #define USE_WOLFSSL_MEMORY +#endif + + +#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) + #undef KEEP_PEER_CERT + #define KEEP_PEER_CERT +#endif + + +/* stream ciphers except arc4 need 32bit alignment, intel ok without */ +#ifndef XSTREAM_ALIGN + #if defined(__x86_64__) || defined(__ia64__) || defined(__i386__) + #define NO_XSTREAM_ALIGN + #else + #define XSTREAM_ALIGN + #endif +#endif + +/* write dup cannot be used with secure renegotiation because write dup + * make write side write only and read side read only */ +#if defined(HAVE_WRITE_DUP) && defined(HAVE_SECURE_RENEGOTIATION) + #error "WRITE DUP and SECURE RENEGOTIATION cannot both be on" +#endif + +#ifdef WOLFSSL_SGX + #ifdef _MSC_VER + #define NO_RC4 + #ifndef HAVE_FIPS + #define WOLFCRYPT_ONLY + #define NO_DES3 + #define NO_SHA + #define NO_MD5 + #else + #define TFM_TIMING_RESISTANT + #define NO_WOLFSSL_DIR + #define NO_WRITEV + #define NO_MAIN_DRIVER + #define WOLFSSL_LOG_PRINTF + #define WOLFSSL_DH_CONST + #endif + #else + #define HAVE_ECC + #define NO_WRITEV + #define NO_MAIN_DRIVER + #define USER_TICKS + #define WOLFSSL_LOG_PRINTF + #define WOLFSSL_DH_CONST + #endif /* _MSC_VER */ + #if !defined(HAVE_FIPS) && !defined(NO_RSA) + #define WC_RSA_BLINDING + #endif + + #define NO_FILESYSTEM + #define ECC_TIMING_RESISTANT + #define TFM_TIMING_RESISTANT + #define SINGLE_THREADED + #define NO_ASN_TIME /* can not use headers such as windows.h */ + #define HAVE_AESGCM + #define USE_CERT_BUFFERS_2048 + #define USE_FAST_MATH +#endif /* WOLFSSL_SGX */ + +/* FreeScale MMCAU hardware crypto has 4 byte alignment. + However, KSDK fsl_mmcau.h gives API with no alignment + requirements (4 byte alignment is managed internally by fsl_mmcau.c) */ +#ifdef FREESCALE_MMCAU + #ifdef FREESCALE_MMCAU_CLASSIC + #define WOLFSSL_MMCAU_ALIGNMENT 4 + #else + #define WOLFSSL_MMCAU_ALIGNMENT 0 + #endif +#endif + +/* if using hardware crypto and have alignment requirements, specify the + requirement here. The record header of SSL/TLS will prevent easy alignment. + This hint tries to help as much as possible. */ +#ifndef WOLFSSL_GENERAL_ALIGNMENT + #ifdef WOLFSSL_AESNI + #define WOLFSSL_GENERAL_ALIGNMENT 16 + #elif defined(XSTREAM_ALIGN) + #define WOLFSSL_GENERAL_ALIGNMENT 4 + #elif defined(FREESCALE_MMCAU) || defined(FREESCALE_MMCAU_CLASSIC) + #define WOLFSSL_GENERAL_ALIGNMENT WOLFSSL_MMCAU_ALIGNMENT + #else + #define WOLFSSL_GENERAL_ALIGNMENT 0 + #endif +#endif + +#if defined(WOLFSSL_GENERAL_ALIGNMENT) && (WOLFSSL_GENERAL_ALIGNMENT > 0) + #if defined(_MSC_VER) + #define XGEN_ALIGN __declspec(align(WOLFSSL_GENERAL_ALIGNMENT)) + #elif defined(__GNUC__) + #define XGEN_ALIGN __attribute__((aligned(WOLFSSL_GENERAL_ALIGNMENT))) + #else + #define XGEN_ALIGN + #endif +#else + #define XGEN_ALIGN +#endif + + +#ifdef __INTEL_COMPILER + #pragma warning(disable:2259) /* explicit casts to smaller sizes, disable */ +#endif + +/* user can specify what curves they want with ECC_USER_CURVES otherwise + * all curves are on by default for now */ +#ifndef ECC_USER_CURVES + #if !defined(WOLFSSL_SP_MATH) && !defined(HAVE_ALL_CURVES) + #define HAVE_ALL_CURVES + #endif +#endif + +/* ECC Configs */ +#ifdef HAVE_ECC + /* By default enable Sign, Verify, DHE, Key Import and Key Export unless explicitly disabled */ + #ifndef NO_ECC_SIGN + #undef HAVE_ECC_SIGN + #define HAVE_ECC_SIGN + #endif + #ifndef NO_ECC_VERIFY + #undef HAVE_ECC_VERIFY + #define HAVE_ECC_VERIFY + #endif + #ifndef NO_ECC_CHECK_KEY + #undef HAVE_ECC_CHECK_KEY + #define HAVE_ECC_CHECK_KEY + #endif + #ifndef NO_ECC_DHE + #undef HAVE_ECC_DHE + #define HAVE_ECC_DHE + #endif + #ifndef NO_ECC_KEY_IMPORT + #undef HAVE_ECC_KEY_IMPORT + #define HAVE_ECC_KEY_IMPORT + #endif + #ifndef NO_ECC_KEY_EXPORT + #undef HAVE_ECC_KEY_EXPORT + #define HAVE_ECC_KEY_EXPORT + #endif +#endif /* HAVE_ECC */ + +/* Curve255519 Configs */ +#ifdef HAVE_CURVE25519 + /* By default enable shared secret, key export and import */ + #ifndef NO_CURVE25519_SHARED_SECRET + #undef HAVE_CURVE25519_SHARED_SECRET + #define HAVE_CURVE25519_SHARED_SECRET + #endif + #ifndef NO_CURVE25519_KEY_EXPORT + #undef HAVE_CURVE25519_KEY_EXPORT + #define HAVE_CURVE25519_KEY_EXPORT + #endif + #ifndef NO_CURVE25519_KEY_IMPORT + #undef HAVE_CURVE25519_KEY_IMPORT + #define HAVE_CURVE25519_KEY_IMPORT + #endif +#endif /* HAVE_CURVE25519 */ + +/* Ed255519 Configs */ +#ifdef HAVE_ED25519 + /* By default enable sign, verify, key export and import */ + #ifndef NO_ED25519_SIGN + #undef HAVE_ED25519_SIGN + #define HAVE_ED25519_SIGN + #endif + #ifndef NO_ED25519_VERIFY + #undef HAVE_ED25519_VERIFY + #define HAVE_ED25519_VERIFY + #endif + #ifndef NO_ED25519_KEY_EXPORT + #undef HAVE_ED25519_KEY_EXPORT + #define HAVE_ED25519_KEY_EXPORT + #endif + #ifndef NO_ED25519_KEY_IMPORT + #undef HAVE_ED25519_KEY_IMPORT + #define HAVE_ED25519_KEY_IMPORT + #endif +#endif /* HAVE_ED25519 */ + +/* AES Config */ +#ifndef NO_AES + /* By default enable all AES key sizes, decryption and CBC */ + #ifndef AES_MAX_KEY_SIZE + #undef AES_MAX_KEY_SIZE + #define AES_MAX_KEY_SIZE 256 + #endif + + #ifndef NO_AES_128 + #undef WOLFSSL_AES_128 + #define WOLFSSL_AES_128 + #endif + #if !defined(NO_AES_192) && AES_MAX_KEY_SIZE >= 192 + #undef WOLFSSL_AES_192 + #define WOLFSSL_AES_192 + #endif + #if !defined(NO_AES_256) && AES_MAX_KEY_SIZE >= 256 + #undef WOLFSSL_AES_256 + #define WOLFSSL_AES_256 + #endif + #if !defined(WOLFSSL_AES_128) && defined(HAVE_ECC_ENCRYPT) + #warning HAVE_ECC_ENCRYPT uses AES 128 bit keys + #endif + + #ifndef NO_AES_DECRYPT + #undef HAVE_AES_DECRYPT + #define HAVE_AES_DECRYPT + #endif + #ifndef NO_AES_CBC + #undef HAVE_AES_CBC + #define HAVE_AES_CBC + #endif + #ifdef WOLFSSL_AES_XTS + /* AES-XTS makes calls to AES direct functions */ + #ifndef WOLFSSL_AES_DIRECT + #define WOLFSSL_AES_DIRECT + #endif + #endif + #ifdef WOLFSSL_AES_CFB + /* AES-CFB makes calls to AES direct functions */ + #ifndef WOLFSSL_AES_DIRECT + #define WOLFSSL_AES_DIRECT + #endif + #endif +#endif + +#if (defined(WOLFSSL_TLS13) && defined(WOLFSSL_NO_TLS12)) || \ + (!defined(HAVE_AES_CBC) && defined(NO_DES3) && defined(NO_RC4) && \ + !defined(HAVE_CAMELLIA) && !defined(HAVE_IDEA) && \ + !defined(HAVE_NULL_CIPHER) && !defined(HAVE_HC128)) + #define WOLFSSL_AEAD_ONLY +#endif + +#if !defined(NO_DH) && !defined(HAVE_FFDHE) + #if defined(HAVE_FFDHE_2048) || defined(HAVE_FFDHE_3072) || \ + defined(HAVE_FFDHE_4096) || defined(HAVE_FFDHE_6144) || \ + defined(HAVE_FFDHE_8192) + #define HAVE_FFDHE + #endif +#endif +#if defined(HAVE_FFDHE_8192) + #define MIN_FFDHE_FP_MAX_BITS 16384 +#elif defined(HAVE_FFDHE_6144) + #define MIN_FFDHE_FP_MAX_BITS 12288 +#elif defined(HAVE_FFDHE_4096) + #define MIN_FFDHE_FP_MAX_BITS 8192 +#elif defined(HAVE_FFDHE_3072) + #define MIN_FFDHE_FP_MAX_BITS 6144 +#elif defined(HAVE_FFDHE_2048) + #define MIN_FFDHE_FP_MAX_BITS 4096 +#else + #define MIN_FFDHE_FP_MAX_BITS 0 +#endif +#if defined(HAVE_FFDHE) && defined(FP_MAX_BITS) + #if MIN_FFDHE_FP_MAX_BITS > FP_MAX_BITS + #error "FFDHE parameters are too large for FP_MAX_BIT as set" + #endif +#endif + +/* if desktop type system and fastmath increase default max bits */ +#ifdef WOLFSSL_X86_64_BUILD + #if defined(USE_FAST_MATH) && !defined(FP_MAX_BITS) + #if MIN_FFDHE_FP_MAX_BITS <= 8192 + #define FP_MAX_BITS 8192 + #else + #define FP_MAX_BITS MIN_FFDHE_FP_MAX_BITS + #endif + #endif +#endif + +/* If using the max strength build, ensure OLD TLS is disabled. */ +#ifdef WOLFSSL_MAX_STRENGTH + #undef NO_OLD_TLS + #define NO_OLD_TLS +#endif + + +/* Default AES minimum auth tag sz, allow user to override */ +#ifndef WOLFSSL_MIN_AUTH_TAG_SZ + #define WOLFSSL_MIN_AUTH_TAG_SZ 12 +#endif + + +/* sniffer requires: + * static RSA cipher suites + * session stats and peak stats + */ +#ifdef WOLFSSL_SNIFFER + #ifndef WOLFSSL_STATIC_RSA + #define WOLFSSL_STATIC_RSA + #endif + #ifndef WOLFSSL_STATIC_DH + #define WOLFSSL_STATIC_DH + #endif + /* Allow option to be disabled. */ + #ifndef WOLFSSL_NO_SESSION_STATS + #ifndef WOLFSSL_SESSION_STATS + #define WOLFSSL_SESSION_STATS + #endif + #ifndef WOLFSSL_PEAK_SESSIONS + #define WOLFSSL_PEAK_SESSIONS + #endif + #endif +#endif + +/* Decode Public Key extras on by default, user can turn off with + * WOLFSSL_NO_DECODE_EXTRA */ +#ifndef WOLFSSL_NO_DECODE_EXTRA + #ifndef RSA_DECODE_EXTRA + #define RSA_DECODE_EXTRA + #endif + #ifndef ECC_DECODE_EXTRA + #define ECC_DECODE_EXTRA + #endif +#endif + +/* C Sharp wrapper defines */ +#ifdef HAVE_CSHARP + #ifndef WOLFSSL_DTLS + #define WOLFSSL_DTLS + #endif + #undef NO_PSK + #undef NO_SHA256 + #undef NO_DH +#endif + +/* Asynchronous Crypto */ +#ifdef WOLFSSL_ASYNC_CRYPT + /* Make sure wolf events are enabled */ + #undef HAVE_WOLF_EVENT + #define HAVE_WOLF_EVENT + + #ifdef WOLFSSL_ASYNC_CRYPT_TEST + #define WC_ASYNC_DEV_SIZE 168 + #else + #define WC_ASYNC_DEV_SIZE 336 + #endif + + #if !defined(HAVE_CAVIUM) && !defined(HAVE_INTEL_QA) && \ + !defined(WOLFSSL_ASYNC_CRYPT_TEST) + #error No async hardware defined with WOLFSSL_ASYNC_CRYPT! + #endif + + /* Enable ECC_CACHE_CURVE for ASYNC */ + #if !defined(ECC_CACHE_CURVE) + #define ECC_CACHE_CURVE + #endif +#endif /* WOLFSSL_ASYNC_CRYPT */ +#ifndef WC_ASYNC_DEV_SIZE + #define WC_ASYNC_DEV_SIZE 0 +#endif + +/* leantls checks */ +#ifdef WOLFSSL_LEANTLS + #ifndef HAVE_ECC + #error leantls build needs ECC + #endif +#endif /* WOLFSSL_LEANTLS*/ + +/* restriction with static memory */ +#ifdef WOLFSSL_STATIC_MEMORY + #if defined(HAVE_IO_POOL) || defined(XMALLOC_USER) || defined(NO_WOLFSSL_MEMORY) + #error static memory cannot be used with HAVE_IO_POOL, XMALLOC_USER or NO_WOLFSSL_MEMORY + #endif + #if !defined(USE_FAST_MATH) && !defined(NO_BIG_INT) + #error static memory requires fast math please define USE_FAST_MATH + #endif + #ifdef WOLFSSL_SMALL_STACK + #error static memory does not support small stack please undefine + #endif +#endif /* WOLFSSL_STATIC_MEMORY */ + +#ifdef HAVE_AES_KEYWRAP + #ifndef WOLFSSL_AES_DIRECT + #error AES key wrap requires AES direct please define WOLFSSL_AES_DIRECT + #endif +#endif + +#ifdef HAVE_PKCS7 + #if defined(NO_AES) && defined(NO_DES3) + #error PKCS7 needs either AES or 3DES enabled, please enable one + #endif + #ifndef HAVE_AES_KEYWRAP + #error PKCS7 requires AES key wrap please define HAVE_AES_KEYWRAP + #endif + #if defined(HAVE_ECC) && !defined(HAVE_X963_KDF) + #error PKCS7 requires X963 KDF please define HAVE_X963_KDF + #endif +#endif + +#ifndef NO_PKCS12 + #undef HAVE_PKCS12 + #define HAVE_PKCS12 +#endif + +#ifndef NO_PKCS8 + #undef HAVE_PKCS8 + #define HAVE_PKCS8 +#endif + +#if !defined(NO_PBKDF1) || defined(WOLFSSL_ENCRYPTED_KEYS) || defined(HAVE_PKCS8) || defined(HAVE_PKCS12) + #undef HAVE_PBKDF1 + #define HAVE_PBKDF1 +#endif + +#if !defined(NO_PBKDF2) || defined(HAVE_PKCS7) || defined(HAVE_SCRYPT) + #undef HAVE_PBKDF2 + #define HAVE_PBKDF2 +#endif + + +#if !defined(WOLFCRYPT_ONLY) && !defined(NO_OLD_TLS) && \ + (defined(NO_SHA) || defined(NO_MD5)) + #error old TLS requires MD5 and SHA +#endif + +/* for backwards compatibility */ +#if defined(TEST_IPV6) && !defined(WOLFSSL_IPV6) + #define WOLFSSL_IPV6 +#endif + + +/* Place any other flags or defines here */ + +#if defined(WOLFSSL_MYSQL_COMPATIBLE) && defined(_WIN32) \ + && defined(HAVE_GMTIME_R) + #undef HAVE_GMTIME_R /* don't trust macro with windows */ +#endif /* WOLFSSL_MYSQL_COMPATIBLE */ + +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) + #define SSL_OP_NO_COMPRESSION SSL_OP_NO_COMPRESSION + #define OPENSSL_NO_ENGINE + #define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT + #ifndef OPENSSL_EXTRA + #define OPENSSL_EXTRA + #endif + #ifndef HAVE_SESSION_TICKET + #define HAVE_SESSION_TICKET + #endif + #ifndef HAVE_OCSP + #define HAVE_OCSP + #endif + #ifndef KEEP_OUR_CERT + #define KEEP_OUR_CERT + #endif + #ifndef HAVE_SNI + #define HAVE_SNI + #endif +#endif + +#if defined(WOLFSSL_NGINX) + #define SSL_CTRL_SET_TLSEXT_HOSTNAME +#endif + + +/* both CURVE and ED small math should be enabled */ +#ifdef CURVED25519_SMALL + #define CURVE25519_SMALL + #define ED25519_SMALL +#endif + + +#ifndef WOLFSSL_ALERT_COUNT_MAX + #define WOLFSSL_ALERT_COUNT_MAX 5 +#endif + +/* warning for not using harden build options (default with ./configure) */ +#if 0 + #if (defined(USE_FAST_MATH) && !defined(TFM_TIMING_RESISTANT)) || \ + (defined(HAVE_ECC) && !defined(ECC_TIMING_RESISTANT)) || \ + (!defined(NO_RSA) && !defined(WC_RSA_BLINDING) && !defined(HAVE_FIPS) && \ + !defined(WC_NO_RNG)) + + #ifndef _MSC_VER + #warning "For timing resistance / side-channel attack prevention consider using harden options" + #else + #pragma message("Warning: For timing resistance / side-channel attack prevention consider using harden options") + #endif + #endif +#endif + +#if defined(NO_OLD_WC_NAMES) || defined(OPENSSL_EXTRA) + /* added to have compatibility with SHA256() */ + #if !defined(NO_OLD_SHA_NAMES) && !defined(HAVE_FIPS) + #define NO_OLD_SHA_NAMES + #endif +#endif + +/* switch for compatibility layer functionality. Has subparts i.e. BIO/X509 + * When opensslextra is enabled all subparts should be turned on. */ +#ifdef OPENSSL_EXTRA + #undef OPENSSL_EXTRA_X509_SMALL + #define OPENSSL_EXTRA_X509_SMALL +#endif /* OPENSSL_EXTRA */ + +/* support for converting DER to PEM */ +#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) || \ + defined(OPENSSL_EXTRA) + #undef WOLFSSL_DER_TO_PEM + #define WOLFSSL_DER_TO_PEM +#endif + +/* keep backwards compatibility enabling encrypted private key */ +#ifndef WOLFSSL_ENCRYPTED_KEYS + #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \ + defined(HAVE_WEBSERVER) + #define WOLFSSL_ENCRYPTED_KEYS + #endif +#endif + +/* support for disabling PEM to DER */ +#if !defined(WOLFSSL_NO_PEM) + #undef WOLFSSL_PEM_TO_DER + #define WOLFSSL_PEM_TO_DER +#endif + +/* Parts of the openssl compatibility layer require peer certs */ +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) + #undef KEEP_PEER_CERT + #define KEEP_PEER_CERT +#endif + +/* RAW hash function APIs are not implemented with ARMv8 hardware acceleration*/ +#ifdef WOLFSSL_ARMASM + #undef WOLFSSL_NO_HASH_RAW + #define WOLFSSL_NO_HASH_RAW +#endif + +#if !defined(WOLFSSL_SHA384) && !defined(WOLFSSL_SHA512) && defined(NO_AES) && \ + !defined(WOLFSSL_SHA3) + #undef WOLFSSL_NO_WORD64_OPS + #define WOLFSSL_NO_WORD64_OPS +#endif + +#if !defined(WOLFCRYPT_ONLY) && !defined(WOLFSSL_NO_TLS12) + #undef WOLFSSL_HAVE_PRF + #define WOLFSSL_HAVE_PRF +#endif + +#if defined(NO_AES) && defined(NO_DES3) && !defined(HAVE_CAMELLIA) && \ + !defined(WOLFSSL_HAVE_PRF) && defined(NO_PWDBASED) && !defined(HAVE_IDEA) + #undef WOLFSSL_NO_XOR_OPS + #define WOLFSSL_NO_XOR_OPS +#endif + +#if defined(NO_ASN) && defined(WOLFCRYPT_ONLY) + #undef WOLFSSL_NO_INT_ENCODE + #define WOLFSSL_NO_INT_ENCODE + #undef WOLFSSL_NO_INT_DECODE + #define WOLFSSL_NO_INT_DECODE +#endif + +#if defined(WOLFCRYPT_ONLY) && defined(WOLFSSL_RSA_VERIFY_ONLY) && \ + defined(WC_NO_RSA_OAEP) + #undef WOLFSSL_NO_CT_OPS + #define WOLFSSL_NO_CT_OPS +#endif + +#if defined(WOLFCRYPT_ONLY) && defined(NO_AES) && !defined(HAVE_CURVE25519) && \ + defined(WC_NO_RNG) && defined(WC_NO_RSA_OAEP) + #undef WOLFSSL_NO_CONST_CMP + #define WOLFSSL_NO_CONST_CMP +#endif + +#if defined(WOLFCRYPT_ONLY) && defined(NO_AES) && !defined(WOLFSSL_SHA384) && \ + !defined(WOLFSSL_SHA512) && defined(WC_NO_RNG) && \ + defined(WOLFSSL_SP_MATH) && defined(WOLFSSL_RSA_PUBLIC_ONLY) + #undef WOLFSSL_NO_FORCE_ZERO + #define WOLFSSL_NO_FORCE_ZERO +#endif + +/* Detect old cryptodev name */ +#if defined(WOLF_CRYPTO_DEV) && !defined(WOLF_CRYPTO_CB) + #define WOLF_CRYPTO_CB +#endif + +#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_NO_SIGALG) + #error TLS 1.3 requires the Signature Algorithms extension to be enabled +#endif + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sha.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sha.h new file mode 100644 index 0000000..e222654 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sha.h @@ -0,0 +1,178 @@ +/* sha.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/sha.h +*/ + + +#ifndef WOLF_CRYPT_SHA_H +#define WOLF_CRYPT_SHA_H + +#include + +#ifndef NO_SHA + +#if defined(HAVE_FIPS) && \ + defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) + #include +#endif /* HAVE_FIPS_VERSION >= 2 */ + +#if defined(HAVE_FIPS) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) +#define wc_Sha Sha +#define WC_SHA SHA +#define WC_SHA_BLOCK_SIZE SHA_BLOCK_SIZE +#define WC_SHA_DIGEST_SIZE SHA_DIGEST_SIZE +#define WC_SHA_PAD_SIZE SHA_PAD_SIZE + +/* for fips @wc_fips */ +#include +#endif + +#ifdef FREESCALE_LTC_SHA + #include "fsl_ltc.h" +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +/* avoid redefinition of structs */ +#if !defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + +#ifdef WOLFSSL_MICROCHIP_PIC32MZ + #include +#endif +#ifdef STM32_HASH + #include +#endif +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif +#ifdef WOLFSSL_ESP32WROOM32_CRYPT + #include +#endif + +#if !defined(NO_OLD_SHA_NAMES) + #define SHA WC_SHA +#endif + +#ifndef NO_OLD_WC_NAMES + #define Sha wc_Sha + #define SHA_BLOCK_SIZE WC_SHA_BLOCK_SIZE + #define SHA_DIGEST_SIZE WC_SHA_DIGEST_SIZE + #define SHA_PAD_SIZE WC_SHA_PAD_SIZE +#endif + +/* in bytes */ +enum { + WC_SHA = WC_HASH_TYPE_SHA, + WC_SHA_BLOCK_SIZE = 64, + WC_SHA_DIGEST_SIZE = 20, + WC_SHA_PAD_SIZE = 56 +}; + + +#if defined(WOLFSSL_TI_HASH) + #include "wolfssl/wolfcrypt/port/ti/ti-hash.h" + +#elif defined(WOLFSSL_IMX6_CAAM) + #include "wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h" +#elif defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \ + !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH) + #include "wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h" +#else + +/* Sha digest */ +struct wc_Sha { +#ifdef FREESCALE_LTC_SHA + ltc_hash_ctx_t ctx; +#elif defined(STM32_HASH) + STM32_HASH_Context stmCtx; +#else + word32 buffLen; /* in bytes */ + word32 loLen; /* length in bytes */ + word32 hiLen; /* length in bytes */ + word32 buffer[WC_SHA_BLOCK_SIZE / sizeof(word32)]; + #ifdef WOLFSSL_PIC32MZ_HASH + word32 digest[PIC32_DIGEST_SIZE / sizeof(word32)]; + #else + word32 digest[WC_SHA_DIGEST_SIZE / sizeof(word32)]; + #endif + void* heap; + #ifdef WOLFSSL_PIC32MZ_HASH + hashUpdCache cache; /* cache for updates */ + #endif + #ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV asyncDev; + #endif /* WOLFSSL_ASYNC_CRYPT */ + #ifdef WOLF_CRYPTO_CB + int devId; + void* devCtx; /* generic crypto callback context */ + #endif +#endif +#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ + !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) + WC_ESP32SHA ctx; +#endif +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + word32 flags; /* enum wc_HashFlags in hash.h */ +#endif +}; + +#ifndef WC_SHA_TYPE_DEFINED + typedef struct wc_Sha wc_Sha; + #define WC_SHA_TYPE_DEFINED +#endif + +#endif /* WOLFSSL_TI_HASH */ + + +#endif /* HAVE_FIPS */ + +WOLFSSL_API int wc_InitSha(wc_Sha*); +WOLFSSL_API int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId); +WOLFSSL_API int wc_ShaUpdate(wc_Sha*, const byte*, word32); +WOLFSSL_API int wc_ShaFinalRaw(wc_Sha*, byte*); +WOLFSSL_API int wc_ShaFinal(wc_Sha*, byte*); +WOLFSSL_API void wc_ShaFree(wc_Sha*); + +WOLFSSL_API int wc_ShaGetHash(wc_Sha*, byte*); +WOLFSSL_API int wc_ShaCopy(wc_Sha*, wc_Sha*); + +#ifdef WOLFSSL_PIC32MZ_HASH +WOLFSSL_API void wc_ShaSizeSet(wc_Sha* sha, word32 len); +#endif + +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + WOLFSSL_API int wc_ShaSetFlags(wc_Sha* sha, word32 flags); + WOLFSSL_API int wc_ShaGetFlags(wc_Sha* sha, word32* flags); +#endif + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* NO_SHA */ +#endif /* WOLF_CRYPT_SHA_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sha256.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sha256.h new file mode 100644 index 0000000..1d84a84 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sha256.h @@ -0,0 +1,255 @@ +/* sha256.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/sha256.h +*/ + + + +#ifndef WOLF_CRYPT_SHA256_H +#define WOLF_CRYPT_SHA256_H + +#include + +#ifndef NO_SHA256 + +#if defined(HAVE_FIPS) && \ + defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) + #include +#endif /* HAVE_FIPS_VERSION >= 2 */ + +#if defined(HAVE_FIPS) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) + #define wc_Sha256 Sha256 + #define WC_SHA256 SHA256 + #define WC_SHA256_BLOCK_SIZE SHA256_BLOCK_SIZE + #define WC_SHA256_DIGEST_SIZE SHA256_DIGEST_SIZE + #define WC_SHA256_PAD_SIZE SHA256_PAD_SIZE + + #ifdef WOLFSSL_SHA224 + #define wc_Sha224 Sha224 + #define WC_SHA224 SHA224 + #define WC_SHA224_BLOCK_SIZE SHA224_BLOCK_SIZE + #define WC_SHA224_DIGEST_SIZE SHA224_DIGEST_SIZE + #define WC_SHA224_PAD_SIZE SHA224_PAD_SIZE + #endif + + /* for fips @wc_fips */ + #include +#endif + +#ifdef FREESCALE_LTC_SHA + #include "fsl_ltc.h" +#endif + + +#ifdef __cplusplus + extern "C" { +#endif + +/* avoid redefinition of structs */ +#if !defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + +#ifdef WOLFSSL_MICROCHIP_PIC32MZ + #include +#endif +#ifdef STM32_HASH + #include +#endif +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif +#if defined(WOLFSSL_DEVCRYPTO) && defined(WOLFSSL_DEVCRYPTO_HASH) + #include +#endif +#if defined(WOLFSSL_ESP32WROOM32_CRYPT) + #include "wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h" +#endif +#if defined(WOLFSSL_CRYPTOCELL) + #include +#endif + +#if defined(_MSC_VER) + #define SHA256_NOINLINE __declspec(noinline) +#elif defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) + #define SHA256_NOINLINE __attribute__((noinline)) +#else + #define SHA256_NOINLINE +#endif + +#if !defined(NO_OLD_SHA_NAMES) + #define SHA256 WC_SHA256 +#endif + +#ifndef NO_OLD_WC_NAMES + #define Sha256 wc_Sha256 + #define SHA256_BLOCK_SIZE WC_SHA256_BLOCK_SIZE + #define SHA256_DIGEST_SIZE WC_SHA256_DIGEST_SIZE + #define SHA256_PAD_SIZE WC_SHA256_PAD_SIZE +#endif + +/* in bytes */ +enum { + WC_SHA256 = WC_HASH_TYPE_SHA256, + WC_SHA256_BLOCK_SIZE = 64, + WC_SHA256_DIGEST_SIZE = 32, + WC_SHA256_PAD_SIZE = 56 +}; + + +#ifdef WOLFSSL_TI_HASH + #include "wolfssl/wolfcrypt/port/ti/ti-hash.h" +#elif defined(WOLFSSL_IMX6_CAAM) + #include "wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h" +#elif defined(WOLFSSL_AFALG_HASH) + #include "wolfssl/wolfcrypt/port/af_alg/afalg_hash.h" +#elif defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \ + !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH) + #include "wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h" +#else + +/* wc_Sha256 digest */ +struct wc_Sha256 { +#ifdef FREESCALE_LTC_SHA + ltc_hash_ctx_t ctx; +#elif defined(STM32_HASH_SHA2) + STM32_HASH_Context stmCtx; +#else + /* alignment on digest and buffer speeds up ARMv8 crypto operations */ + ALIGN16 word32 digest[WC_SHA256_DIGEST_SIZE / sizeof(word32)]; + ALIGN16 word32 buffer[WC_SHA256_BLOCK_SIZE / sizeof(word32)]; + word32 buffLen; /* in bytes */ + word32 loLen; /* length in bytes */ + word32 hiLen; /* length in bytes */ + void* heap; +#ifdef WOLFSSL_PIC32MZ_HASH + hashUpdCache cache; /* cache for updates */ +#endif +#ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV asyncDev; +#endif /* WOLFSSL_ASYNC_CRYPT */ +#ifdef WOLFSSL_SMALL_STACK_CACHE + word32* W; +#endif +#ifdef WOLFSSL_DEVCRYPTO_HASH + WC_CRYPTODEV ctx; + byte* msg; + word32 used; + word32 len; +#endif +#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ + !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) + WC_ESP32SHA ctx; +#endif +#ifdef WOLFSSL_CRYPTOCELL + CRYS_HASHUserContext_t ctx; +#endif +#ifdef WOLF_CRYPTO_CB + int devId; + void* devCtx; /* generic crypto callback context */ +#endif +#endif +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + word32 flags; /* enum wc_HashFlags in hash.h */ +#endif +}; + +#ifndef WC_SHA256_TYPE_DEFINED + typedef struct wc_Sha256 wc_Sha256; + #define WC_SHA256_TYPE_DEFINED +#endif + +#endif + +#endif /* HAVE_FIPS */ + +WOLFSSL_API int wc_InitSha256(wc_Sha256*); +WOLFSSL_API int wc_InitSha256_ex(wc_Sha256*, void*, int); +WOLFSSL_API int wc_Sha256Update(wc_Sha256*, const byte*, word32); +WOLFSSL_API int wc_Sha256FinalRaw(wc_Sha256*, byte*); +WOLFSSL_API int wc_Sha256Final(wc_Sha256*, byte*); +WOLFSSL_API void wc_Sha256Free(wc_Sha256*); + +WOLFSSL_API int wc_Sha256GetHash(wc_Sha256*, byte*); +WOLFSSL_API int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst); + +#ifdef WOLFSSL_PIC32MZ_HASH +WOLFSSL_API void wc_Sha256SizeSet(wc_Sha256*, word32); +#endif + +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + WOLFSSL_API int wc_Sha256SetFlags(wc_Sha256* sha256, word32 flags); + WOLFSSL_API int wc_Sha256GetFlags(wc_Sha256* sha256, word32* flags); +#endif + +#ifdef WOLFSSL_SHA224 +/* avoid redefinition of structs */ +#if !defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + +#ifndef NO_OLD_WC_NAMES + #define Sha224 wc_Sha224 + #define SHA224 WC_SHA224 + #define SHA224_BLOCK_SIZE WC_SHA224_BLOCK_SIZE + #define SHA224_DIGEST_SIZE WC_SHA224_DIGEST_SIZE + #define SHA224_PAD_SIZE WC_SHA224_PAD_SIZE +#endif + +/* in bytes */ +enum { + WC_SHA224 = WC_HASH_TYPE_SHA224, + WC_SHA224_BLOCK_SIZE = WC_SHA256_BLOCK_SIZE, + WC_SHA224_DIGEST_SIZE = 28, + WC_SHA224_PAD_SIZE = WC_SHA256_PAD_SIZE +}; + + +#ifndef WC_SHA224_TYPE_DEFINED + typedef struct wc_Sha256 wc_Sha224; + #define WC_SHA224_TYPE_DEFINED +#endif +#endif /* HAVE_FIPS */ + +WOLFSSL_API int wc_InitSha224(wc_Sha224*); +WOLFSSL_API int wc_InitSha224_ex(wc_Sha224*, void*, int); +WOLFSSL_API int wc_Sha224Update(wc_Sha224*, const byte*, word32); +WOLFSSL_API int wc_Sha224Final(wc_Sha224*, byte*); +WOLFSSL_API void wc_Sha224Free(wc_Sha224*); + +WOLFSSL_API int wc_Sha224GetHash(wc_Sha224*, byte*); +WOLFSSL_API int wc_Sha224Copy(wc_Sha224* src, wc_Sha224* dst); + +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + WOLFSSL_API int wc_Sha224SetFlags(wc_Sha224* sha224, word32 flags); + WOLFSSL_API int wc_Sha224GetFlags(wc_Sha224* sha224, word32* flags); +#endif + +#endif /* WOLFSSL_SHA224 */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* NO_SHA256 */ +#endif /* WOLF_CRYPT_SHA256_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sha3.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sha3.h new file mode 100644 index 0000000..e3dff98 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sha3.h @@ -0,0 +1,157 @@ +/* sha3.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLF_CRYPT_SHA3_H +#define WOLF_CRYPT_SHA3_H + +#include + +#ifdef WOLFSSL_SHA3 + +#ifdef HAVE_FIPS + /* for fips @wc_fips */ + #include +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif + +/* in bytes */ +enum { + WC_SHA3_224 = WC_HASH_TYPE_SHA3_224, + WC_SHA3_224_DIGEST_SIZE = 28, + WC_SHA3_224_COUNT = 18, + + WC_SHA3_256 = WC_HASH_TYPE_SHA3_256, + WC_SHA3_256_DIGEST_SIZE = 32, + WC_SHA3_256_COUNT = 17, + + WC_SHA3_384 = WC_HASH_TYPE_SHA3_384, + WC_SHA3_384_DIGEST_SIZE = 48, + WC_SHA3_384_COUNT = 13, + + WC_SHA3_512 = WC_HASH_TYPE_SHA3_512, + WC_SHA3_512_DIGEST_SIZE = 64, + WC_SHA3_512_COUNT = 9, + +#ifndef HAVE_SELFTEST + /* These values are used for HMAC, not SHA-3 directly. + * They come from from FIPS PUB 202. */ + WC_SHA3_224_BLOCK_SIZE = 144, + WC_SHA3_256_BLOCK_SIZE = 136, + WC_SHA3_384_BLOCK_SIZE = 104, + WC_SHA3_512_BLOCK_SIZE = 72, +#endif +}; + +#ifndef NO_OLD_WC_NAMES + #define SHA3_224 WC_SHA3_224 + #define SHA3_224_DIGEST_SIZE WC_SHA3_224_DIGEST_SIZE + #define SHA3_256 WC_SHA3_256 + #define SHA3_256_DIGEST_SIZE WC_SHA3_256_DIGEST_SIZE + #define SHA3_384 WC_SHA3_384 + #define SHA3_384_DIGEST_SIZE WC_SHA3_384_DIGEST_SIZE + #define SHA3_512 WC_SHA3_512 + #define SHA3_512_DIGEST_SIZE WC_SHA3_512_DIGEST_SIZE + #define Sha3 wc_Sha3 +#endif + + + +#ifdef WOLFSSL_XILINX_CRYPT + #include "wolfssl/wolfcrypt/port/xilinx/xil-sha3.h" +#elif defined(WOLFSSL_AFALG_XILINX_SHA3) + #include +#else + +/* Sha3 digest */ +struct Sha3 { + /* State data that is processed for each block. */ + word64 s[25]; + /* Unprocessed message data. */ + byte t[200]; + /* Index into unprocessed data to place next message byte. */ + byte i; + + void* heap; + +#ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV asyncDev; +#endif /* WOLFSSL_ASYNC_CRYPT */ +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + word32 flags; /* enum wc_HashFlags in hash.h */ +#endif +}; + +#ifndef WC_SHA3_TYPE_DEFINED + typedef struct Sha3 wc_Sha3; + #define WC_SHA3_TYPE_DEFINED +#endif + +#endif + + +WOLFSSL_API int wc_InitSha3_224(wc_Sha3*, void*, int); +WOLFSSL_API int wc_Sha3_224_Update(wc_Sha3*, const byte*, word32); +WOLFSSL_API int wc_Sha3_224_Final(wc_Sha3*, byte*); +WOLFSSL_API void wc_Sha3_224_Free(wc_Sha3*); +WOLFSSL_API int wc_Sha3_224_GetHash(wc_Sha3*, byte*); +WOLFSSL_API int wc_Sha3_224_Copy(wc_Sha3* src, wc_Sha3* dst); + +WOLFSSL_API int wc_InitSha3_256(wc_Sha3*, void*, int); +WOLFSSL_API int wc_Sha3_256_Update(wc_Sha3*, const byte*, word32); +WOLFSSL_API int wc_Sha3_256_Final(wc_Sha3*, byte*); +WOLFSSL_API void wc_Sha3_256_Free(wc_Sha3*); +WOLFSSL_API int wc_Sha3_256_GetHash(wc_Sha3*, byte*); +WOLFSSL_API int wc_Sha3_256_Copy(wc_Sha3* src, wc_Sha3* dst); + +WOLFSSL_API int wc_InitSha3_384(wc_Sha3*, void*, int); +WOLFSSL_API int wc_Sha3_384_Update(wc_Sha3*, const byte*, word32); +WOLFSSL_API int wc_Sha3_384_Final(wc_Sha3*, byte*); +WOLFSSL_API void wc_Sha3_384_Free(wc_Sha3*); +WOLFSSL_API int wc_Sha3_384_GetHash(wc_Sha3*, byte*); +WOLFSSL_API int wc_Sha3_384_Copy(wc_Sha3* src, wc_Sha3* dst); + +WOLFSSL_API int wc_InitSha3_512(wc_Sha3*, void*, int); +WOLFSSL_API int wc_Sha3_512_Update(wc_Sha3*, const byte*, word32); +WOLFSSL_API int wc_Sha3_512_Final(wc_Sha3*, byte*); +WOLFSSL_API void wc_Sha3_512_Free(wc_Sha3*); +WOLFSSL_API int wc_Sha3_512_GetHash(wc_Sha3*, byte*); +WOLFSSL_API int wc_Sha3_512_Copy(wc_Sha3* src, wc_Sha3* dst); + +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + WOLFSSL_API int wc_Sha3_SetFlags(wc_Sha3* sha3, word32 flags); + WOLFSSL_API int wc_Sha3_GetFlags(wc_Sha3* sha3, word32* flags); +#endif + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_SHA3 */ +#endif /* WOLF_CRYPT_SHA3_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sha512.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sha512.h new file mode 100644 index 0000000..e80b567 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sha512.h @@ -0,0 +1,228 @@ +/* sha512.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/sha512.h +*/ + + +#ifndef WOLF_CRYPT_SHA512_H +#define WOLF_CRYPT_SHA512_H + +#include + +#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384) + +#if defined(HAVE_FIPS) && \ + defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) + #include +#endif /* HAVE_FIPS_VERSION >= 2 */ + +#if defined(HAVE_FIPS) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) + #ifdef WOLFSSL_SHA512 + #define wc_Sha512 Sha512 + #define WC_SHA512 SHA512 + #define WC_SHA512_BLOCK_SIZE SHA512_BLOCK_SIZE + #define WC_SHA512_DIGEST_SIZE SHA512_DIGEST_SIZE + #define WC_SHA512_PAD_SIZE SHA512_PAD_SIZE + #endif /* WOLFSSL_SHA512 */ + #ifdef WOLFSSL_SHA384 + #define wc_Sha384 Sha384 + #define WC_SHA384 SHA384 + #define WC_SHA384_BLOCK_SIZE SHA384_BLOCK_SIZE + #define WC_SHA384_DIGEST_SIZE SHA384_DIGEST_SIZE + #define WC_SHA384_PAD_SIZE SHA384_PAD_SIZE + #endif /* WOLFSSL_SHA384 */ + + #define CYASSL_SHA512 + #if defined(WOLFSSL_SHA384) + #define CYASSL_SHA384 + #endif + /* for fips @wc_fips */ + #include +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +/* avoid redefinition of structs */ +#if !defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif +#ifdef WOLFSSL_ESP32WROOM32_CRYPT + #include +#endif +#if defined(_MSC_VER) + #define SHA512_NOINLINE __declspec(noinline) +#elif defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) + #define SHA512_NOINLINE __attribute__((noinline)) +#else + #define SHA512_NOINLINE +#endif + +#ifdef WOLFSSL_SHA512 + +#if !defined(NO_OLD_SHA_NAMES) + #define SHA512 WC_SHA512 +#endif + +#if !defined(NO_OLD_WC_NAMES) + #define Sha512 wc_Sha512 + #define SHA512_BLOCK_SIZE WC_SHA512_BLOCK_SIZE + #define SHA512_DIGEST_SIZE WC_SHA512_DIGEST_SIZE + #define SHA512_PAD_SIZE WC_SHA512_PAD_SIZE +#endif + +#endif /* WOLFSSL_SHA512 */ + +/* in bytes */ +enum { +#ifdef WOLFSSL_SHA512 + WC_SHA512 = WC_HASH_TYPE_SHA512, +#endif + WC_SHA512_BLOCK_SIZE = 128, + WC_SHA512_DIGEST_SIZE = 64, + WC_SHA512_PAD_SIZE = 112 +}; + + +#ifdef WOLFSSL_IMX6_CAAM + #include "wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h" +#else +/* wc_Sha512 digest */ +struct wc_Sha512 { + word64 digest[WC_SHA512_DIGEST_SIZE / sizeof(word64)]; + word64 buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64)]; + word32 buffLen; /* in bytes */ + word64 loLen; /* length in bytes */ + word64 hiLen; /* length in bytes */ + void* heap; +#ifdef USE_INTEL_SPEEDUP + const byte* data; +#endif +#ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV asyncDev; +#endif /* WOLFSSL_ASYNC_CRYPT */ +#ifdef WOLFSSL_SMALL_STACK_CACHE + word64* W; +#endif +#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ + !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) + WC_ESP32SHA ctx; +#endif +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + word32 flags; /* enum wc_HashFlags in hash.h */ +#endif +}; + +#ifndef WC_SHA512_TYPE_DEFINED + typedef struct wc_Sha512 wc_Sha512; + #define WC_SHA512_TYPE_DEFINED +#endif +#endif + +#endif /* HAVE_FIPS */ + +#ifdef WOLFSSL_ARMASM +WOLFSSL_LOCAL void Transform_Sha512_Len(wc_Sha512* sha512, const byte* data, + word32 len); +#endif + +#ifdef WOLFSSL_SHA512 + +WOLFSSL_API int wc_InitSha512(wc_Sha512*); +WOLFSSL_API int wc_InitSha512_ex(wc_Sha512*, void*, int); +WOLFSSL_API int wc_Sha512Update(wc_Sha512*, const byte*, word32); +WOLFSSL_API int wc_Sha512FinalRaw(wc_Sha512*, byte*); +WOLFSSL_API int wc_Sha512Final(wc_Sha512*, byte*); +WOLFSSL_API void wc_Sha512Free(wc_Sha512*); + +WOLFSSL_API int wc_Sha512GetHash(wc_Sha512*, byte*); +WOLFSSL_API int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst); + +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + WOLFSSL_API int wc_Sha512SetFlags(wc_Sha512* sha512, word32 flags); + WOLFSSL_API int wc_Sha512GetFlags(wc_Sha512* sha512, word32* flags); +#endif + +#endif /* WOLFSSL_SHA512 */ + +#if defined(WOLFSSL_SHA384) + +/* avoid redefinition of structs */ +#if !defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + +#if !defined(NO_OLD_SHA_NAMES) + #define SHA384 WC_SHA384 +#endif + +#if !defined(NO_OLD_WC_NAMES) + #define Sha384 wc_Sha384 + #define SHA384_BLOCK_SIZE WC_SHA384_BLOCK_SIZE + #define SHA384_DIGEST_SIZE WC_SHA384_DIGEST_SIZE + #define SHA384_PAD_SIZE WC_SHA384_PAD_SIZE +#endif + +/* in bytes */ +enum { + WC_SHA384 = WC_HASH_TYPE_SHA384, + WC_SHA384_BLOCK_SIZE = WC_SHA512_BLOCK_SIZE, + WC_SHA384_DIGEST_SIZE = 48, + WC_SHA384_PAD_SIZE = WC_SHA512_PAD_SIZE +}; + + +#ifndef WC_SHA384_TYPE_DEFINED + typedef struct wc_Sha512 wc_Sha384; + #define WC_SHA384_TYPE_DEFINED +#endif +#endif /* HAVE_FIPS */ + +WOLFSSL_API int wc_InitSha384(wc_Sha384*); +WOLFSSL_API int wc_InitSha384_ex(wc_Sha384*, void*, int); +WOLFSSL_API int wc_Sha384Update(wc_Sha384*, const byte*, word32); +WOLFSSL_API int wc_Sha384FinalRaw(wc_Sha384*, byte*); +WOLFSSL_API int wc_Sha384Final(wc_Sha384*, byte*); +WOLFSSL_API void wc_Sha384Free(wc_Sha384*); + +WOLFSSL_API int wc_Sha384GetHash(wc_Sha384*, byte*); +WOLFSSL_API int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst); + +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + WOLFSSL_API int wc_Sha384SetFlags(wc_Sha384* sha384, word32 flags); + WOLFSSL_API int wc_Sha384GetFlags(wc_Sha384* sha384, word32* flags); +#endif + +#endif /* WOLFSSL_SHA384 */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */ +#endif /* WOLF_CRYPT_SHA512_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/signature.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/signature.h new file mode 100644 index 0000000..fe3b6a8 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/signature.h @@ -0,0 +1,87 @@ +/* signature.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/signature.h +*/ + + +#ifndef WOLF_CRYPT_SIGNATURE_H +#define WOLF_CRYPT_SIGNATURE_H + +#include +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +enum wc_SignatureType { + WC_SIGNATURE_TYPE_NONE = 0, + WC_SIGNATURE_TYPE_ECC = 1, + WC_SIGNATURE_TYPE_RSA = 2, + WC_SIGNATURE_TYPE_RSA_W_ENC = 3, /* Adds DER header via wc_EncodeSignature */ +}; + +WOLFSSL_API int wc_SignatureGetSize(enum wc_SignatureType sig_type, + const void* key, word32 key_len); + +WOLFSSL_API int wc_SignatureVerifyHash( + enum wc_HashType hash_type, enum wc_SignatureType sig_type, + const byte* hash_data, word32 hash_len, + const byte* sig, word32 sig_len, + const void* key, word32 key_len); + +WOLFSSL_API int wc_SignatureVerify( + enum wc_HashType hash_type, enum wc_SignatureType sig_type, + const byte* data, word32 data_len, + const byte* sig, word32 sig_len, + const void* key, word32 key_len); + +WOLFSSL_API int wc_SignatureGenerateHash( + enum wc_HashType hash_type, enum wc_SignatureType sig_type, + const byte* hash_data, word32 hash_len, + byte* sig, word32 *sig_len, + const void* key, word32 key_len, WC_RNG* rng); +WOLFSSL_API int wc_SignatureGenerateHash_ex( + enum wc_HashType hash_type, enum wc_SignatureType sig_type, + const byte* hash_data, word32 hash_len, + byte* sig, word32 *sig_len, + const void* key, word32 key_len, WC_RNG* rng, int verify); +WOLFSSL_API int wc_SignatureGenerate( + enum wc_HashType hash_type, enum wc_SignatureType sig_type, + const byte* data, word32 data_len, + byte* sig, word32 *sig_len, + const void* key, word32 key_len, + WC_RNG* rng); +WOLFSSL_API int wc_SignatureGenerate_ex( + enum wc_HashType hash_type, enum wc_SignatureType sig_type, + const byte* data, word32 data_len, + byte* sig, word32 *sig_len, + const void* key, word32 key_len, + WC_RNG* rng, int verify); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLF_CRYPT_SIGNATURE_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sp.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sp.h new file mode 100644 index 0000000..2e8fbe7 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sp.h @@ -0,0 +1,132 @@ +/* sp.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLF_CRYPT_SP_H +#define WOLF_CRYPT_SP_H + +#include + +#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \ + defined(WOLFSSL_HAVE_SP_ECC) + +#include + +#include +#include + +#include + +#if defined(_MSC_VER) + #define SP_NOINLINE __declspec(noinline) +#elif defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) || defined(__KEIL__) + #define SP_NOINLINE __attribute__((noinline)) +#else + #define SP_NOINLINE +#endif + + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef WOLFSSL_HAVE_SP_RSA + +WOLFSSL_LOCAL int sp_RsaPublic_2048(const byte* in, word32 inLen, + mp_int* em, mp_int* mm, byte* out, word32* outLen); +WOLFSSL_LOCAL int sp_RsaPrivate_2048(const byte* in, word32 inLen, + mp_int* dm, mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, + mp_int* mm, byte* out, word32* outLen); + +WOLFSSL_LOCAL int sp_RsaPublic_3072(const byte* in, word32 inLen, + mp_int* em, mp_int* mm, byte* out, word32* outLen); +WOLFSSL_LOCAL int sp_RsaPrivate_3072(const byte* in, word32 inLen, + mp_int* dm, mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, + mp_int* mm, byte* out, word32* outLen); + +WOLFSSL_LOCAL int sp_RsaPublic_4096(const byte* in, word32 inLen, + mp_int* em, mp_int* mm, byte* out, word32* outLen); +WOLFSSL_LOCAL int sp_RsaPrivate_4096(const byte* in, word32 inLen, + mp_int* dm, mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, + mp_int* mm, byte* out, word32* outLen); + +#endif /* WOLFSSL_HAVE_SP_RSA */ + +#if defined(WOLFSSL_HAVE_SP_DH) || defined(WOLFSSL_HAVE_SP_RSA) + +WOLFSSL_LOCAL int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, + mp_int* res); +WOLFSSL_LOCAL int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, + mp_int* res); +WOLFSSL_LOCAL int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, + mp_int* res); +WOLFSSL_LOCAL int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, + mp_int* res); +WOLFSSL_LOCAL int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, + mp_int* res); + +#endif + +#ifdef WOLFSSL_HAVE_SP_DH + +WOLFSSL_LOCAL int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, + mp_int* mod, byte* out, word32* outLen); +WOLFSSL_LOCAL int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, + mp_int* mod, byte* out, word32* outLen); +WOLFSSL_LOCAL int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, + mp_int* mod, byte* out, word32* outLen); + +#endif /* WOLFSSL_HAVE_SP_DH */ + +#ifdef WOLFSSL_HAVE_SP_ECC + +int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* rm, int map, + void* heap); +int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* rm, int map, void* heap); + +int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap); +int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, + word32* outlen, void* heap); +int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, + mp_int* rm, mp_int* sm, mp_int* km, void* heap); +int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, mp_int* pY, + mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap); +int sp_ecc_is_point_256(mp_int* pX, mp_int* pY); +int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap); +int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, + mp_int* qX, mp_int* qY, mp_int* qZ, + mp_int* rX, mp_int* rY, mp_int* rZ); +int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, + mp_int* rX, mp_int* rY, mp_int* rZ); +int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ); +int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym); + +#endif /*ifdef WOLFSSL_HAVE_SP_ECC */ + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */ + +#endif /* WOLF_CRYPT_SP_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sp_int.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sp_int.h new file mode 100644 index 0000000..c7388bd --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/sp_int.h @@ -0,0 +1,271 @@ +/* sp_int.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLF_CRYPT_SP_INT_H +#define WOLF_CRYPT_SP_INT_H + +#include +#include + +/* Make sure WOLFSSL_SP_ASM build option defined when requested */ +#if !defined(WOLFSSL_SP_ASM) && ( \ + defined(WOLFSSL_SP_X86_64_ASM) || defined(WOLFSSL_SP_ARM32_ASM) || \ + defined(WOLFSSL_SP_ARM64_ASM) || defined(WOLFSSL_SP_ARM_THUMB_ASM) || \ + defined(WOLFSSL_SP_ARM_CORTEX_M_ASM)) + #define WOLFSSL_SP_ASM +#endif + + +#ifdef WOLFSSL_SP_X86_64_ASM + #define SP_WORD_SIZE 64 + + #define HAVE_INTEL_AVX1 + #define HAVE_INTEL_AVX2 +#elif defined(WOLFSSL_SP_ARM64_ASM) + #define SP_WORD_SIZE 64 +#elif defined(WOLFSSL_SP_ARM32_ASM) + #define SP_WORD_SIZE 32 +#elif defined(WOLFSSL_SP_ARM_THUMB_ASM) + #define SP_WORD_SIZE 32 +#endif + +#ifndef SP_WORD_SIZE + #if defined(NO_64BIT) || !defined(HAVE___UINT128_T) + #define SP_WORD_SIZE 32 + #else + #define SP_WORD_SIZE 64 + #endif +#endif + +#ifndef WOLFSSL_SP_ASM + #if SP_WORD_SIZE == 32 + typedef int32_t sp_digit; + typedef uint32_t sp_int_digit; + typedef uint64_t sp_int_word; + #elif SP_WORD_SIZE == 64 + typedef int64_t sp_digit; + typedef uint64_t sp_int_digit; + #ifdef __SIZEOF_INT128__ + typedef __uint128_t uint128_t; + typedef __int128_t int128_t; + #else + typedef unsigned long uint128_t __attribute__ ((mode(TI))); + typedef long int128_t __attribute__ ((mode(TI))); + #endif + typedef uint128_t sp_int_word; + #else + #error Word size not defined + #endif +#else + #if SP_WORD_SIZE == 32 + typedef uint32_t sp_digit; + typedef uint32_t sp_int_digit; + typedef uint64_t sp_int_word; + #elif SP_WORD_SIZE == 64 + typedef uint64_t sp_digit; + typedef uint64_t sp_int_digit; + #ifdef __SIZEOF_INT128__ + typedef __uint128_t uint128_t; + typedef __int128_t int128_t; + #else + typedef unsigned long uint128_t __attribute__ ((mode(TI))); + typedef long int128_t __attribute__ ((mode(TI))); + #endif + typedef uint128_t sp_int_word; + #else + #error Word size not defined + #endif +#endif + +#ifdef WOLFSSL_SP_MATH +#include + +#if !defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_HAVE_SP_DH) + #if !defined(NO_PWDBASED) && defined(WOLFSSL_SHA512) + #define SP_INT_DIGITS ((512 + SP_WORD_SIZE) / SP_WORD_SIZE) + #else + #define SP_INT_DIGITS ((256 + SP_WORD_SIZE) / SP_WORD_SIZE) + #endif +#elif defined(WOLFSSL_SP_4096) + #if defined(WOLFSSL_HAVE_SP_DH) + #define SP_INT_DIGITS ((8192 + SP_WORD_SIZE) / SP_WORD_SIZE) + #else + #define SP_INT_DIGITS ((4096 + SP_WORD_SIZE) / SP_WORD_SIZE) + #endif +#elif !defined(WOLFSSL_SP_NO_3072) + #if defined(WOLFSSL_HAVE_SP_DH) + #define SP_INT_DIGITS ((6144 + SP_WORD_SIZE) / SP_WORD_SIZE) + #else + #define SP_INT_DIGITS ((3072 + SP_WORD_SIZE) / SP_WORD_SIZE) + #endif +#else + #if defined(WOLFSSL_HAVE_SP_DH) + #define SP_INT_DIGITS ((4096 + SP_WORD_SIZE) / SP_WORD_SIZE) + #else + #define SP_INT_DIGITS ((2048 + SP_WORD_SIZE) / SP_WORD_SIZE) + #endif +#endif + +#define sp_isodd(a) ((a)->used != 0 && ((a)->dp[0] & 1)) +#define sp_iseven(a) ((a)->used != 0 && ((a)->dp[0] & 1) == 0) +#define sp_iszero(a) ((a)->used == 0) +#define sp_isone(a) ((a)->used == 1 && (a)->dp[0] == 1) +#define sp_abs(a, b) sp_copy(a, b) + +#ifdef HAVE_WOLF_BIGINT + /* raw big integer */ + typedef struct WC_BIGINT { + byte* buf; + word32 len; + void* heap; + } WC_BIGINT; + #define WOLF_BIGINT_DEFINED +#endif + +typedef struct sp_int { + int used; + int size; + sp_int_digit dp[SP_INT_DIGITS]; +#ifdef HAVE_WOLF_BIGINT + struct WC_BIGINT raw; /* unsigned binary (big endian) */ +#endif +} sp_int; + +typedef sp_int mp_int; +typedef sp_digit mp_digit; + +#include + + +MP_API int sp_init(sp_int* a); +MP_API int sp_init_multi(sp_int* a, sp_int* b, sp_int* c, sp_int* d, + sp_int* e, sp_int* f); +MP_API void sp_clear(sp_int* a); +MP_API int sp_unsigned_bin_size(sp_int* a); +MP_API int sp_read_unsigned_bin(sp_int* a, const byte* in, int inSz); +MP_API int sp_read_radix(sp_int* a, const char* in, int radix); +MP_API int sp_cmp(sp_int* a, sp_int* b); +MP_API int sp_count_bits(sp_int* a); +MP_API int sp_leading_bit(sp_int* a); +MP_API int sp_to_unsigned_bin(sp_int* a, byte* out); +MP_API int sp_to_unsigned_bin_len(sp_int* a, byte* out, int outSz); +MP_API void sp_forcezero(sp_int* a); +MP_API int sp_copy(sp_int* a, sp_int* r); +MP_API int sp_set(sp_int* a, sp_int_digit d); +MP_API void sp_clamp(sp_int* a); +MP_API int sp_grow(sp_int* a, int l); +MP_API int sp_sub_d(sp_int* a, sp_int_digit d, sp_int* r); +MP_API int sp_cmp_d(sp_int* a, sp_int_digit d); +MP_API int sp_sub(sp_int* a, sp_int* b, sp_int* r); +MP_API int sp_mod(sp_int* a, sp_int* m, sp_int* r); +MP_API void sp_zero(sp_int* a); +MP_API int sp_add_d(sp_int* a, sp_int_digit d, sp_int* r); +MP_API int sp_lshd(sp_int* a, int s); +MP_API int sp_add(sp_int* a, sp_int* b, sp_int* r); +MP_API int sp_set_int(sp_int* a, unsigned long b); +MP_API int sp_tohex(sp_int* a, char* str); +MP_API int sp_2expt(sp_int* a, int e); +MP_API int sp_rand_prime(sp_int* r, int len, WC_RNG* rng, void* heap); +MP_API int sp_mul(sp_int* a, sp_int* b, sp_int* r); +MP_API int sp_mulmod(sp_int* a, sp_int* b, sp_int* m, sp_int* r); +MP_API int sp_gcd(sp_int* a, sp_int* b, sp_int* r); +MP_API int sp_invmod(sp_int* a, sp_int* m, sp_int* r); +MP_API int sp_lcm(sp_int* a, sp_int* b, sp_int* r); +MP_API int sp_exptmod(sp_int* b, sp_int* e, sp_int* m, sp_int* r); +MP_API int sp_prime_is_prime(mp_int* a, int t, int* result); +MP_API int sp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng); +MP_API int sp_exch(sp_int* a, sp_int* b); +MP_API int sp_get_digit_count(sp_int *a); +MP_API int sp_init_copy (sp_int * a, sp_int * b); +MP_API void sp_rshb(sp_int* a, int n, sp_int* r); + + +#define MP_OKAY 0 +#define MP_NO 0 +#define MP_YES 1 + +#define MP_RADIX_HEX 16 + +#define MP_GT 1 +#define MP_EQ 0 +#define MP_LT -1 + +#define MP_MEM -2 +#define MP_VAL -3 + +#define DIGIT_BIT SP_WORD_SIZE + +#define CheckFastMathSettings() 1 + +#define mp_free(a) + +#define mp_isodd sp_isodd +#define mp_iseven sp_iseven +#define mp_iszero sp_iszero +#define mp_isone sp_isone +#define mp_abs sp_abs + +#define mp_init sp_init +#define mp_init_multi sp_init_multi +#define mp_clear sp_clear +#define mp_read_unsigned_bin sp_read_unsigned_bin +#define mp_unsigned_bin_size sp_unsigned_bin_size +#define mp_read_radix sp_read_radix +#define mp_cmp sp_cmp +#define mp_count_bits sp_count_bits +#define mp_leading_bit sp_leading_bit +#define mp_to_unsigned_bin sp_to_unsigned_bin +#define mp_to_unsigned_bin_len sp_to_unsigned_bin_len +#define mp_forcezero sp_forcezero +#define mp_copy sp_copy +#define mp_set sp_set +#define mp_clamp sp_clamp +#define mp_grow sp_grow +#define mp_sub_d sp_sub_d +#define mp_cmp_d sp_cmp_d +#define mp_sub sp_sub +#define mp_mod sp_mod +#define mp_zero sp_zero +#define mp_add_d sp_add_d +#define mp_lshd sp_lshd +#define mp_add sp_add +#define mp_set_int sp_set_int +#define mp_tohex sp_tohex +#define mp_2expt sp_2expt +#define mp_rand_prime sp_rand_prime +#define mp_mul sp_mul +#define mp_mulmod sp_mulmod +#define mp_gcd sp_gcd +#define mp_invmod sp_invmod +#define mp_lcm sp_lcm +#define mp_exptmod sp_exptmod +#define mp_prime_is_prime sp_prime_is_prime +#define mp_prime_is_prime_ex sp_prime_is_prime_ex +#define mp_exch sp_exch +#define get_digit_count sp_get_digit_count +#define mp_init_copy sp_init_copy +#define mp_rshb(A,x) sp_rshb(A,x,A) + +#endif + +#endif /* WOLF_CRYPT_SP_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/srp.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/srp.h new file mode 100644 index 0000000..85db198 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/srp.h @@ -0,0 +1,311 @@ +/* srp.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/srp.h +*/ + +#ifdef WOLFCRYPT_HAVE_SRP + +#ifndef WOLFCRYPT_SRP_H +#define WOLFCRYPT_SRP_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/* Select the largest available hash for the buffer size. */ +#if defined(WOLFSSL_SHA512) + #define SRP_MAX_DIGEST_SIZE WC_SHA512_DIGEST_SIZE +#elif defined(WOLFSSL_SHA384) + #define SRP_MAX_DIGEST_SIZE WC_SHA384_DIGEST_SIZE +#elif !defined(NO_SHA256) + #define SRP_MAX_DIGEST_SIZE WC_SHA256_DIGEST_SIZE +#elif !defined(NO_SHA) + #define SRP_MAX_DIGEST_SIZE WC_SHA_DIGEST_SIZE +#else + #error "You have to have some kind of SHA hash if you want to use SRP." +#endif + +/* Set the minimum number of bits acceptable in an SRP modulus */ +#define SRP_MODULUS_MIN_BITS 512 + +/* Set the minimum number of bits acceptable for private keys (RFC 5054) */ +#define SRP_PRIVATE_KEY_MIN_BITS 256 + +/* salt size for SRP password */ +#define SRP_SALT_SIZE 16 + +/** + * SRP side, client or server. + */ +typedef enum { + SRP_CLIENT_SIDE = 0, + SRP_SERVER_SIDE = 1, +} SrpSide; + +/** + * SRP hash type, SHA[1|256|384|512]. + */ +typedef enum { + SRP_TYPE_SHA = 1, + SRP_TYPE_SHA256 = 2, + SRP_TYPE_SHA384 = 3, + SRP_TYPE_SHA512 = 4, +} SrpType; + + +/** + * SRP hash struct. + */ +typedef struct { + byte type; + union { + #ifndef NO_SHA + wc_Sha sha; + #endif + #ifndef NO_SHA256 + wc_Sha256 sha256; + #endif + #ifdef WOLFSSL_SHA384 + wc_Sha384 sha384; + #endif + #ifdef WOLFSSL_SHA512 + wc_Sha512 sha512; + #endif + } data; +} SrpHash; + +typedef struct Srp { + SrpSide side; /**< Client or Server, @see SrpSide. */ + SrpType type; /**< Hash type, @see SrpType. */ + byte* user; /**< Username, login. */ + word32 userSz; /**< Username length. */ + byte* salt; /**< Small salt. */ + word32 saltSz; /**< Salt length. */ + mp_int N; /**< Modulus. N = 2q+1, [q, N] are primes.*/ + mp_int g; /**< Generator. A generator modulo N. */ + byte k[SRP_MAX_DIGEST_SIZE]; /**< Multiplier parameter. k = H(N, g) */ + mp_int auth; /**< Client: x = H(salt + H(user:pswd)) */ + /**< Server: v = g ^ x % N */ + mp_int priv; /**< Private ephemeral value. */ + SrpHash client_proof; /**< Client proof. Sent to the Server. */ + SrpHash server_proof; /**< Server proof. Sent to the Client. */ + byte* key; /**< Session key. */ + word32 keySz; /**< Session key length. */ + int (*keyGenFunc_cb) (struct Srp* srp, byte* secret, word32 size); + /**< Function responsible for generating the session key. */ + /**< It MUST use XMALLOC with type DYNAMIC_TYPE_SRP to allocate the */ + /**< key buffer for this structure and set keySz to the buffer size. */ + /**< The default function used by this implementation is a modified */ + /**< version of t_mgf1 that uses the proper hash function according */ + /**< to srp->type. */ + void* heap; /**< heap hint pointer */ +} Srp; + +/** + * Initializes the Srp struct for usage. + * + * @param[out] srp the Srp structure to be initialized. + * @param[in] type the hash type to be used. + * @param[in] side the side of the communication. + * + * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h + */ +WOLFSSL_API int wc_SrpInit(Srp* srp, SrpType type, SrpSide side); + +/** + * Releases the Srp struct resources after usage. + * + * @param[in,out] srp the Srp structure to be terminated. + */ +WOLFSSL_API void wc_SrpTerm(Srp* srp); + +/** + * Sets the username. + * + * This function MUST be called after wc_SrpInit. + * + * @param[in,out] srp the Srp structure. + * @param[in] username the buffer containing the username. + * @param[in] size the username size in bytes + * + * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h + */ +WOLFSSL_API int wc_SrpSetUsername(Srp* srp, const byte* username, word32 size); + + +/** + * Sets the srp parameters based on the username. + * + * This function MUST be called after wc_SrpSetUsername. + * + * @param[in,out] srp the Srp structure. + * @param[in] N the Modulus. N = 2q+1, [q, N] are primes. + * @param[in] nSz the N size in bytes. + * @param[in] g the Generator modulo N. + * @param[in] gSz the g size in bytes + * @param[in] salt a small random salt. Specific for each username. + * @param[in] saltSz the salt size in bytes + * + * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h + */ +WOLFSSL_API int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz, + const byte* g, word32 gSz, + const byte* salt, word32 saltSz); + +/** + * Sets the password. + * + * Setting the password does not persists the clear password data in the + * srp structure. The client calculates x = H(salt + H(user:pswd)) and stores + * it in the auth field. + * + * This function MUST be called after wc_SrpSetParams and is CLIENT SIDE ONLY. + * + * @param[in,out] srp the Srp structure. + * @param[in] password the buffer containing the password. + * @param[in] size the password size in bytes. + * + * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h + */ +WOLFSSL_API int wc_SrpSetPassword(Srp* srp, const byte* password, word32 size); + +/** + * Sets the verifier. + * + * This function MUST be called after wc_SrpSetParams and is SERVER SIDE ONLY. + * + * @param[in,out] srp the Srp structure. + * @param[in] verifier the buffer containing the verifier. + * @param[in] size the verifier size in bytes. + * + * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h + */ +WOLFSSL_API int wc_SrpSetVerifier(Srp* srp, const byte* verifier, word32 size); + +/** + * Gets the verifier. + * + * The client calculates the verifier with v = g ^ x % N. + * This function MAY be called after wc_SrpSetPassword and is CLIENT SIDE ONLY. + * + * @param[in,out] srp the Srp structure. + * @param[out] verifier the buffer to write the verifier. + * @param[in,out] size the buffer size in bytes. Will be updated with the + * verifier size. + * + * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h + */ +WOLFSSL_API int wc_SrpGetVerifier(Srp* srp, byte* verifier, word32* size); + +/** + * Sets the private ephemeral value. + * + * The private ephemeral value is known as: + * a at the client side. a = random() + * b at the server side. b = random() + * This function is handy for unit test cases or if the developer wants to use + * an external random source to set the ephemeral value. + * This function MAY be called before wc_SrpGetPublic. + * + * @param[in,out] srp the Srp structure. + * @param[in] priv the ephemeral value. + * @param[in] size the private size in bytes. + * + * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h + */ +WOLFSSL_API int wc_SrpSetPrivate(Srp* srp, const byte* priv, word32 size); + +/** + * Gets the public ephemeral value. + * + * The public ephemeral value is known as: + * A at the client side. A = g ^ a % N + * B at the server side. B = (k * v + (g ˆ b % N)) % N + * This function MUST be called after wc_SrpSetPassword or wc_SrpSetVerifier. + * + * @param[in,out] srp the Srp structure. + * @param[out] pub the buffer to write the public ephemeral value. + * @param[in,out] size the the buffer size in bytes. Will be updated with + * the ephemeral value size. + * + * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h + */ +WOLFSSL_API int wc_SrpGetPublic(Srp* srp, byte* pub, word32* size); + + +/** + * Computes the session key. + * + * The key can be accessed at srp->key after success. + * + * @param[in,out] srp the Srp structure. + * @param[in] clientPubKey the client's public ephemeral value. + * @param[in] clientPubKeySz the client's public ephemeral value size. + * @param[in] serverPubKey the server's public ephemeral value. + * @param[in] serverPubKeySz the server's public ephemeral value size. + * + * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h + */ +WOLFSSL_API int wc_SrpComputeKey(Srp* srp, + byte* clientPubKey, word32 clientPubKeySz, + byte* serverPubKey, word32 serverPubKeySz); + +/** + * Gets the proof. + * + * This function MUST be called after wc_SrpComputeKey. + * + * @param[in,out] srp the Srp structure. + * @param[out] proof the buffer to write the proof. + * @param[in,out] size the buffer size in bytes. Will be updated with the + * proof size. + * + * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h + */ +WOLFSSL_API int wc_SrpGetProof(Srp* srp, byte* proof, word32* size); + +/** + * Verifies the peers proof. + * + * This function MUST be called before wc_SrpGetSessionKey. + * + * @param[in,out] srp the Srp structure. + * @param[in] proof the peers proof. + * @param[in] size the proof size in bytes. + * + * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h + */ +WOLFSSL_API int wc_SrpVerifyPeersProof(Srp* srp, byte* proof, word32 size); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFCRYPT_SRP_H */ +#endif /* WOLFCRYPT_HAVE_SRP */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/tfm.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/tfm.h new file mode 100644 index 0000000..170280c --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/tfm.h @@ -0,0 +1,826 @@ +/* tfm.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +/* + * Based on public domain TomsFastMath 0.10 by Tom St Denis, tomstdenis@iahu.ca, + * http://math.libtomcrypt.com + */ + + +/** + * Edited by Moises Guimaraes (moises.guimaraes@phoebus.com.br) + * to fit CyaSSL's needs. + */ + +/*! + \file wolfssl/wolfcrypt/tfm.h +*/ + +#ifndef WOLF_CRYPT_TFM_H +#define WOLF_CRYPT_TFM_H + +#include +#ifndef CHAR_BIT + #include +#endif + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef WOLFSSL_NO_ASM + #undef TFM_NO_ASM + #define TFM_NO_ASM +#endif + +#ifdef NO_64BIT + #undef NO_TFM_64BIT + #define NO_TFM_64BIT +#endif + +#ifndef NO_TFM_64BIT +/* autodetect x86-64 and make sure we are using 64-bit digits with x86-64 asm */ +#if defined(__x86_64__) + #if defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM) + #error x86-64 detected, x86-32/SSE2/ARM optimizations are not valid! + #endif + #if !defined(TFM_X86_64) && !defined(TFM_NO_ASM) + #define TFM_X86_64 + #endif +#endif +#if defined(TFM_X86_64) + #if !defined(FP_64BIT) + #define FP_64BIT + #endif +#endif +/* use 64-bit digit even if not using asm on x86_64 */ +#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_TFM_64BIT */ + +/* try to detect x86-32 */ +#if defined(__i386__) && !defined(TFM_SSE2) + #if defined(TFM_X86_64) || defined(TFM_ARM) + #error x86-32 detected, x86-64/ARM optimizations are not valid! + #endif + #if !defined(TFM_X86) && !defined(TFM_NO_ASM) + #define TFM_X86 + #endif +#endif + +/* make sure we're 32-bit for x86-32/sse/arm/ppc32 */ +#if (defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM) || defined(TFM_PPC32)) && defined(FP_64BIT) + #warning x86-32, SSE2 and ARM, PPC32 optimizations require 32-bit digits (undefining) + #undef FP_64BIT +#endif + +/* multi asms? */ +#ifdef TFM_X86 + #define TFM_ASM +#endif +#ifdef TFM_X86_64 + #ifdef TFM_ASM + #error TFM_ASM already defined! + #endif + #define TFM_ASM +#endif +#ifdef TFM_SSE2 + #ifdef TFM_ASM + #error TFM_ASM already defined! + #endif + #define TFM_ASM +#endif +#ifdef TFM_ARM + #ifdef TFM_ASM + #error TFM_ASM already defined! + #endif + #define TFM_ASM +#endif +#ifdef TFM_PPC32 + #ifdef TFM_ASM + #error TFM_ASM already defined! + #endif + #define TFM_ASM +#endif +#ifdef TFM_PPC64 + #ifdef TFM_ASM + #error TFM_ASM already defined! + #endif + #define TFM_ASM +#endif +#ifdef TFM_AVR32 + #ifdef TFM_ASM + #error TFM_ASM already defined! + #endif + #define TFM_ASM +#endif + +/* we want no asm? */ +#ifdef TFM_NO_ASM + #undef TFM_X86 + #undef TFM_X86_64 + #undef TFM_SSE2 + #undef TFM_ARM + #undef TFM_PPC32 + #undef TFM_PPC64 + #undef TFM_AVR32 + #undef TFM_ASM +#endif + +/* ECC helpers */ +#ifdef TFM_ECC192 + #ifdef FP_64BIT + #define TFM_MUL3 + #define TFM_SQR3 + #else + #define TFM_MUL6 + #define TFM_SQR6 + #endif +#endif + +#ifdef TFM_ECC224 + #ifdef FP_64BIT + #define TFM_MUL4 + #define TFM_SQR4 + #else + #define TFM_MUL7 + #define TFM_SQR7 + #endif +#endif + +#ifdef TFM_ECC256 + #ifdef FP_64BIT + #define TFM_MUL4 + #define TFM_SQR4 + #else + #define TFM_MUL8 + #define TFM_SQR8 + #endif +#endif + +#ifdef TFM_ECC384 + #ifdef FP_64BIT + #define TFM_MUL6 + #define TFM_SQR6 + #else + #define TFM_MUL12 + #define TFM_SQR12 + #endif +#endif + +#ifdef TFM_ECC521 + #ifdef FP_64BIT + #define TFM_MUL9 + #define TFM_SQR9 + #else + #define TFM_MUL17 + #define TFM_SQR17 + #endif +#endif + + +/* allow user to define on fp_digit, fp_word types */ +#ifndef WOLFSSL_BIGINT_TYPES + +/* some default configurations. + */ +#if defined(WC_16BIT_CPU) + typedef unsigned int fp_digit; + #define SIZEOF_FP_DIGIT 2 + typedef unsigned long fp_word; +#elif defined(FP_64BIT) + /* for GCC only on supported platforms */ + typedef unsigned long long fp_digit; /* 64bit, 128 uses mode(TI) below */ + #define SIZEOF_FP_DIGIT 8 + typedef unsigned long fp_word __attribute__ ((mode(TI))); +#else + + #ifndef NO_TFM_64BIT + #if defined(_MSC_VER) || defined(__BORLANDC__) + typedef unsigned __int64 ulong64; + #else + typedef unsigned long long ulong64; + #endif + typedef unsigned int fp_digit; + #define SIZEOF_FP_DIGIT 4 + typedef ulong64 fp_word; + #define FP_32BIT + #else + /* some procs like coldfire prefer not to place multiply into 64bit type + even though it exists */ + typedef unsigned short fp_digit; + #define SIZEOF_FP_DIGIT 2 + typedef unsigned int fp_word; + #endif +#endif + +#endif /* WOLFSSL_BIGINT_TYPES */ + + +/* # of digits this is */ +#define DIGIT_BIT ((CHAR_BIT) * SIZEOF_FP_DIGIT) + +/* Max size of any number in bits. Basically the largest size you will be + * multiplying should be half [or smaller] of FP_MAX_SIZE-four_digit + * + * It defaults to 4096-bits [allowing multiplications up to 2048x2048 bits ] + */ + + +#ifndef FP_MAX_BITS + #define FP_MAX_BITS 4096 +#endif +#define FP_MAX_SIZE (FP_MAX_BITS+(8*DIGIT_BIT)) + +/* will this lib work? */ +#if (CHAR_BIT & 7) + #error CHAR_BIT must be a multiple of eight. +#endif +#if FP_MAX_BITS % CHAR_BIT + #error FP_MAX_BITS must be a multiple of CHAR_BIT +#endif + +#define FP_MASK (fp_digit)(-1) +#define FP_DIGIT_MAX FP_MASK +#define FP_SIZE (FP_MAX_SIZE/DIGIT_BIT) + +#define FP_MAX_PRIME_SIZE (FP_MAX_BITS/(2*CHAR_BIT)) +/* In terms of FP_MAX_BITS, it is double the size possible for a number + * to allow for multiplication, divide that 2 out. Also divide by CHAR_BIT + * to convert from bits to bytes. (Note, FP_PRIME_SIZE is the number of + * values in the canned prime number list.) */ + +/* signs */ +#define FP_ZPOS 0 +#define FP_NEG 1 + +/* return codes */ +#define FP_OKAY 0 +#define FP_VAL -1 +#define FP_MEM -2 +#define FP_NOT_INF -3 +#define FP_WOULDBLOCK -4 + +/* equalities */ +#define FP_LT -1 /* less than */ +#define FP_EQ 0 /* equal to */ +#define FP_GT 1 /* greater than */ + +/* replies */ +#define FP_YES 1 /* yes response */ +#define FP_NO 0 /* no response */ + +#ifdef HAVE_WOLF_BIGINT + /* raw big integer */ + typedef struct WC_BIGINT { + byte* buf; + word32 len; + void* heap; + } WC_BIGINT; + #define WOLF_BIGINT_DEFINED +#endif + +/* a FP type */ +typedef struct fp_int { + int used; + int sign; +#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT) + int size; +#endif + fp_digit dp[FP_SIZE]; + +#ifdef HAVE_WOLF_BIGINT + struct WC_BIGINT raw; /* unsigned binary (big endian) */ +#endif +} fp_int; + +/* Types */ +typedef fp_digit mp_digit; +typedef fp_word mp_word; +typedef fp_int mp_int; + + +/* wolf big int and common functions */ +#include + + +/* externally define this symbol to ignore the default settings, useful for changing the build from the make process */ +#ifndef TFM_ALREADY_SET + +/* do we want the large set of small multiplications ? + Enable these if you are going to be doing a lot of small (<= 16 digit) multiplications say in ECC + Or if you're on a 64-bit machine doing RSA as a 1024-bit integer == 16 digits ;-) + */ +/* need to refactor the function */ +/*#define TFM_SMALL_SET */ + +/* do we want huge code + Enable these if you are doing 20, 24, 28, 32, 48, 64 digit multiplications (useful for RSA) + Less important on 64-bit machines as 32 digits == 2048 bits + */ +#if 0 +#define TFM_MUL3 +#define TFM_MUL4 +#define TFM_MUL6 +#define TFM_MUL7 +#define TFM_MUL8 +#define TFM_MUL9 +#define TFM_MUL12 +#define TFM_MUL17 +#endif +#ifdef TFM_HUGE_SET +#define TFM_MUL20 +#define TFM_MUL24 +#define TFM_MUL28 +#define TFM_MUL32 +#if (FP_MAX_BITS >= 6144) && defined(FP_64BIT) + #define TFM_MUL48 +#endif +#if (FP_MAX_BITS >= 8192) && defined(FP_64BIT) + #define TFM_MUL64 +#endif +#endif + +#if 0 +#define TFM_SQR3 +#define TFM_SQR4 +#define TFM_SQR6 +#define TFM_SQR7 +#define TFM_SQR8 +#define TFM_SQR9 +#define TFM_SQR12 +#define TFM_SQR17 +#endif +#ifdef TFM_HUGE_SET +#define TFM_SQR20 +#define TFM_SQR24 +#define TFM_SQR28 +#define TFM_SQR32 +#define TFM_SQR48 +#define TFM_SQR64 +#endif + +/* Optional math checks (enable WOLFSSL_DEBUG_MATH to print info) */ +/* #define TFM_CHECK */ + +/* Is the target a P4 Prescott + */ +/* #define TFM_PRESCOTT */ + +/* Do we want timing resistant fp_exptmod() ? + * This makes it slower but also timing invariant with respect to the exponent + */ +/* #define TFM_TIMING_RESISTANT */ + +#endif /* TFM_ALREADY_SET */ + +/* functions */ + +/* returns a TFM ident string useful for debugging... */ +/*const char *fp_ident(void);*/ + +/* initialize [or zero] an fp int */ +void fp_init(fp_int *a); +MP_API void fp_zero(fp_int *a); +MP_API void fp_clear(fp_int *a); /* uses ForceZero to clear sensitive memory */ +MP_API void fp_forcezero (fp_int * a); +MP_API void fp_free(fp_int* a); + +/* zero/even/odd ? */ +#define fp_iszero(a) (((a)->used == 0) ? FP_YES : FP_NO) +#define fp_isone(a) \ + ((((a)->used == 1) && ((a)->dp[0] == 1)) ? FP_YES : FP_NO) +#define fp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? FP_YES : FP_NO) +#define fp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? FP_YES : FP_NO) +#define fp_isneg(a) (((a)->sign != 0) ? FP_YES : FP_NO) + +/* set to a small digit */ +void fp_set(fp_int *a, fp_digit b); +void fp_set_int(fp_int *a, unsigned long b); + +/* check if a bit is set */ +int fp_is_bit_set(fp_int *a, fp_digit b); +/* set the b bit to 1 */ +int fp_set_bit (fp_int * a, fp_digit b); + +/* copy from a to b */ +void fp_copy(fp_int *a, fp_int *b); +void fp_init_copy(fp_int *a, fp_int *b); + +/* clamp digits */ +#define fp_clamp(a) { while ((a)->used && (a)->dp[(a)->used-1] == 0) --((a)->used); (a)->sign = (a)->used ? (a)->sign : FP_ZPOS; } +#define mp_clamp(a) fp_clamp(a) +#define mp_grow(a,s) MP_OKAY + +/* negate and absolute */ +#define fp_neg(a, b) { fp_copy(a, b); (b)->sign ^= 1; fp_clamp(b); } +#define fp_abs(a, b) { fp_copy(a, b); (b)->sign = 0; } + +/* right shift x digits */ +void fp_rshd(fp_int *a, int x); + +/* right shift x bits */ +void fp_rshb(fp_int *a, int x); + +/* left shift x digits */ +void fp_lshd(fp_int *a, int x); + +/* signed comparison */ +int fp_cmp(fp_int *a, fp_int *b); + +/* unsigned comparison */ +int fp_cmp_mag(fp_int *a, fp_int *b); + +/* power of 2 operations */ +void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d); +void fp_mod_2d(fp_int *a, int b, fp_int *c); +void fp_mul_2d(fp_int *a, int b, fp_int *c); +void fp_2expt (fp_int *a, int b); +void fp_mul_2(fp_int *a, fp_int *c); +void fp_div_2(fp_int *a, fp_int *c); + +/* Counts the number of lsbs which are zero before the first zero bit */ +int fp_cnt_lsb(fp_int *a); + +/* c = a + b */ +void fp_add(fp_int *a, fp_int *b, fp_int *c); + +/* c = a - b */ +void fp_sub(fp_int *a, fp_int *b, fp_int *c); + +/* c = a * b */ +int fp_mul(fp_int *a, fp_int *b, fp_int *c); + +/* b = a*a */ +int fp_sqr(fp_int *a, fp_int *b); + +/* a/b => cb + d == a */ +int fp_div(fp_int *a, fp_int *b, fp_int *c, fp_int *d); + +/* c = a mod b, 0 <= c < b */ +int fp_mod(fp_int *a, fp_int *b, fp_int *c); + +/* compare against a single digit */ +int fp_cmp_d(fp_int *a, fp_digit b); + +/* c = a + b */ +void fp_add_d(fp_int *a, fp_digit b, fp_int *c); + +/* c = a - b */ +int fp_sub_d(fp_int *a, fp_digit b, fp_int *c); + +/* c = a * b */ +void fp_mul_d(fp_int *a, fp_digit b, fp_int *c); + +/* a/b => cb + d == a */ +/*int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d);*/ + +/* c = a mod b, 0 <= c < b */ +/*int fp_mod_d(fp_int *a, fp_digit b, fp_digit *c);*/ + +/* ---> number theory <--- */ +/* d = a + b (mod c) */ +/*int fp_addmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);*/ + +/* d = a - b (mod c) */ +/*int fp_submod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);*/ + +/* d = a * b (mod c) */ +int fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); + +/* d = a - b (mod c) */ +int fp_submod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); + +/* d = a + b (mod c) */ +int fp_addmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); + +/* c = a * a (mod b) */ +int fp_sqrmod(fp_int *a, fp_int *b, fp_int *c); + +/* c = 1/a (mod b) */ +int fp_invmod(fp_int *a, fp_int *b, fp_int *c); + +/* c = (a, b) */ +/*int fp_gcd(fp_int *a, fp_int *b, fp_int *c);*/ + +/* c = [a, b] */ +/*int fp_lcm(fp_int *a, fp_int *b, fp_int *c);*/ + +/* setups the montgomery reduction */ +int fp_montgomery_setup(fp_int *a, fp_digit *mp); + +/* computes a = B**n mod b without division or multiplication useful for + * normalizing numbers in a Montgomery system. + */ +void fp_montgomery_calc_normalization(fp_int *a, fp_int *b); + +/* computes x/R == x (mod N) via Montgomery Reduction */ +int fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp); + +/* d = a**b (mod c) */ +int fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); +int fp_exptmod_ex(fp_int *a, fp_int *b, int minDigits, fp_int *c, fp_int *d); + +#ifdef WC_RSA_NONBLOCK + +enum tfmExptModNbState { + TFM_EXPTMOD_NB_INIT = 0, + TFM_EXPTMOD_NB_MONT, + TFM_EXPTMOD_NB_MONT_RED, + TFM_EXPTMOD_NB_MONT_MUL, + TFM_EXPTMOD_NB_MONT_MOD, + TFM_EXPTMOD_NB_MONT_MODCHK, + TFM_EXPTMOD_NB_NEXT, + TFM_EXPTMOD_NB_MUL, + TFM_EXPTMOD_NB_MUL_RED, + TFM_EXPTMOD_NB_SQR, + TFM_EXPTMOD_NB_SQR_RED, + TFM_EXPTMOD_NB_RED, + TFM_EXPTMOD_NB_COUNT /* last item for total state count only */ +}; + +typedef struct { +#ifndef WC_NO_CACHE_RESISTANT + fp_int R[3]; +#else + fp_int R[2]; +#endif + fp_digit buf; + fp_digit mp; + int bitcnt; + int digidx; + int y; + int state; /* tfmExptModNbState */ +#ifdef WC_RSA_NONBLOCK_TIME + word32 maxBlockInst; /* maximum instructions to block */ + word32 totalInst; /* tracks total instructions */ +#endif +} exptModNb_t; + +#ifdef WC_RSA_NONBLOCK_TIME +enum { + TFM_EXPTMOD_NB_STOP = 0, /* stop and return FP_WOULDBLOCK */ + TFM_EXPTMOD_NB_CONTINUE = 1, /* keep blocking */ +}; +#endif + +/* non-blocking version of timing resistant fp_exptmod function */ +/* supports cache resistance */ +int fp_exptmod_nb(exptModNb_t* nb, fp_int* G, fp_int* X, fp_int* P, fp_int* Y); + +#endif /* WC_RSA_NONBLOCK */ + +/* primality stuff */ + +/* perform a Miller-Rabin test of a to the base b and store result in "result" */ +/*void fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result);*/ + +#define FP_PRIME_SIZE 256 +/* 256 trial divisions + 8 Miller-Rabins, returns FP_YES if probable prime */ +/*int fp_isprime(fp_int *a);*/ +/* extended version of fp_isprime, do 't' Miller-Rabins instead of only 8 */ +/*int fp_isprime_ex(fp_int *a, int t, int* result);*/ + +/* Primality generation flags */ +/*#define TFM_PRIME_BBS 0x0001 */ /* BBS style prime */ +/*#define TFM_PRIME_SAFE 0x0002 */ /* Safe prime (p-1)/2 == prime */ +/*#define TFM_PRIME_2MSB_OFF 0x0004 */ /* force 2nd MSB to 0 */ +/*#define TFM_PRIME_2MSB_ON 0x0008 */ /* force 2nd MSB to 1 */ + +/* callback for fp_prime_random, should fill dst with random bytes and return how many read [up to len] */ +/*typedef int tfm_prime_callback(unsigned char *dst, int len, void *dat);*/ + +/*#define fp_prime_random(a, t, size, bbs, cb, dat) fp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?TFM_PRIME_BBS:0, cb, dat)*/ + +/*int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback cb, void *dat);*/ + +/* radix conversions */ +int fp_count_bits(fp_int *a); +int fp_leading_bit(fp_int *a); + +int fp_unsigned_bin_size(fp_int *a); +void fp_read_unsigned_bin(fp_int *a, const unsigned char *b, int c); +int fp_to_unsigned_bin(fp_int *a, unsigned char *b); +int fp_to_unsigned_bin_len(fp_int *a, unsigned char *b, int c); +int fp_to_unsigned_bin_at_pos(int x, fp_int *t, unsigned char *b); + +/*int fp_signed_bin_size(fp_int *a);*/ +/*void fp_read_signed_bin(fp_int *a, const unsigned char *b, int c);*/ +/*void fp_to_signed_bin(fp_int *a, unsigned char *b);*/ + +/*int fp_read_radix(fp_int *a, char *str, int radix);*/ +/*int fp_toradix(fp_int *a, char *str, int radix);*/ +/*int fp_toradix_n(fp_int * a, char *str, int radix, int maxlen);*/ + + +/* VARIOUS LOW LEVEL STUFFS */ +void s_fp_add(fp_int *a, fp_int *b, fp_int *c); +void s_fp_sub(fp_int *a, fp_int *b, fp_int *c); +void fp_reverse(unsigned char *s, int len); + +int fp_mul_comba(fp_int *a, fp_int *b, fp_int *c); + +int fp_mul_comba_small(fp_int *a, fp_int *b, fp_int *c); +int fp_mul_comba3(fp_int *a, fp_int *b, fp_int *c); +int fp_mul_comba4(fp_int *a, fp_int *b, fp_int *c); +int fp_mul_comba6(fp_int *a, fp_int *b, fp_int *c); +int fp_mul_comba7(fp_int *a, fp_int *b, fp_int *c); +int fp_mul_comba8(fp_int *a, fp_int *b, fp_int *c); +int fp_mul_comba9(fp_int *a, fp_int *b, fp_int *c); +int fp_mul_comba12(fp_int *a, fp_int *b, fp_int *c); +int fp_mul_comba17(fp_int *a, fp_int *b, fp_int *c); +int fp_mul_comba20(fp_int *a, fp_int *b, fp_int *c); +int fp_mul_comba24(fp_int *a, fp_int *b, fp_int *c); +int fp_mul_comba28(fp_int *a, fp_int *b, fp_int *c); +int fp_mul_comba32(fp_int *a, fp_int *b, fp_int *c); +int fp_mul_comba48(fp_int *a, fp_int *b, fp_int *c); +int fp_mul_comba64(fp_int *a, fp_int *b, fp_int *c); +int fp_sqr_comba(fp_int *a, fp_int *b); +int fp_sqr_comba_small(fp_int *a, fp_int *b); +int fp_sqr_comba3(fp_int *a, fp_int *b); +int fp_sqr_comba4(fp_int *a, fp_int *b); +int fp_sqr_comba6(fp_int *a, fp_int *b); +int fp_sqr_comba7(fp_int *a, fp_int *b); +int fp_sqr_comba8(fp_int *a, fp_int *b); +int fp_sqr_comba9(fp_int *a, fp_int *b); +int fp_sqr_comba12(fp_int *a, fp_int *b); +int fp_sqr_comba17(fp_int *a, fp_int *b); +int fp_sqr_comba20(fp_int *a, fp_int *b); +int fp_sqr_comba24(fp_int *a, fp_int *b); +int fp_sqr_comba28(fp_int *a, fp_int *b); +int fp_sqr_comba32(fp_int *a, fp_int *b); +int fp_sqr_comba48(fp_int *a, fp_int *b); +int fp_sqr_comba64(fp_int *a, fp_int *b); + + +/** + * Used by wolfSSL + */ + +/* Constants */ +#define MP_LT FP_LT /* less than */ +#define MP_EQ FP_EQ /* equal to */ +#define MP_GT FP_GT /* greater than */ +#define MP_VAL FP_VAL /* invalid */ +#define MP_MEM FP_MEM /* memory error */ +#define MP_NOT_INF FP_NOT_INF /* point not at infinity */ +#define MP_OKAY FP_OKAY /* ok result */ +#define MP_NO FP_NO /* yes/no result */ +#define MP_YES FP_YES /* yes/no result */ +#define MP_ZPOS FP_ZPOS +#define MP_NEG FP_NEG +#define MP_MASK FP_MASK + +/* Prototypes */ +#define mp_zero(a) fp_zero(a) +#define mp_isone(a) fp_isone(a) +#define mp_iseven(a) fp_iseven(a) +#define mp_isneg(a) fp_isneg(a) + +#define MP_RADIX_BIN 2 +#define MP_RADIX_OCT 8 +#define MP_RADIX_DEC 10 +#define MP_RADIX_HEX 16 +#define MP_RADIX_MAX 64 + +#define mp_tobinary(M, S) mp_toradix((M), (S), MP_RADIX_BIN) +#define mp_tooctal(M, S) mp_toradix((M), (S), MP_RADIX_OCT) +#define mp_todecimal(M, S) mp_toradix((M), (S), MP_RADIX_DEC) +#define mp_tohex(M, S) mp_toradix((M), (S), MP_RADIX_HEX) + +MP_API int mp_init (mp_int * a); +MP_API void mp_clear (mp_int * a); +MP_API void mp_free (mp_int * a); +MP_API void mp_forcezero (mp_int * a); +MP_API int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e, + mp_int* f); + +MP_API int mp_add (mp_int * a, mp_int * b, mp_int * c); +MP_API int mp_sub (mp_int * a, mp_int * b, mp_int * c); +MP_API int mp_add_d (mp_int * a, mp_digit b, mp_int * c); + +MP_API int mp_mul (mp_int * a, mp_int * b, mp_int * c); +MP_API int mp_mul_d (mp_int * a, mp_digit b, mp_int * c); +MP_API int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d); +MP_API int mp_submod (mp_int* a, mp_int* b, mp_int* c, mp_int* d); +MP_API int mp_addmod (mp_int* a, mp_int* b, mp_int* c, mp_int* d); +MP_API int mp_mod(mp_int *a, mp_int *b, mp_int *c); +MP_API int mp_invmod(mp_int *a, mp_int *b, mp_int *c); +MP_API int mp_exptmod (mp_int * g, mp_int * x, mp_int * p, mp_int * y); +MP_API int mp_exptmod_ex (mp_int * g, mp_int * x, int minDigits, mp_int * p, + mp_int * y); +MP_API int mp_mul_2d(mp_int *a, int b, mp_int *c); +MP_API int mp_2expt(mp_int* a, int b); + +MP_API int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d); + +MP_API int mp_cmp(mp_int *a, mp_int *b); +MP_API int mp_cmp_d(mp_int *a, mp_digit b); + +MP_API int mp_unsigned_bin_size(mp_int * a); +MP_API int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c); +MP_API int mp_to_unsigned_bin_at_pos(int x, mp_int *t, unsigned char *b); +MP_API int mp_to_unsigned_bin (mp_int * a, unsigned char *b); +MP_API int mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c); + +MP_API int mp_sub_d(fp_int *a, fp_digit b, fp_int *c); +MP_API int mp_copy(fp_int* a, fp_int* b); +MP_API int mp_isodd(mp_int* a); +MP_API int mp_iszero(mp_int* a); +MP_API int mp_count_bits(mp_int *a); +MP_API int mp_leading_bit(mp_int *a); +MP_API int mp_set_int(mp_int *a, unsigned long b); +MP_API int mp_is_bit_set (mp_int * a, mp_digit b); +MP_API int mp_set_bit (mp_int * a, mp_digit b); +MP_API void mp_rshb(mp_int *a, int x); +MP_API void mp_rshd(mp_int *a, int x); +MP_API int mp_toradix (mp_int *a, char *str, int radix); +MP_API int mp_radix_size (mp_int * a, int radix, int *size); + +#ifdef WOLFSSL_DEBUG_MATH + MP_API void mp_dump(const char* desc, mp_int* a, byte verbose); +#else + #define mp_dump(desc, a, verbose) +#endif + +#if !defined(NO_DSA) || defined(HAVE_ECC) + MP_API int mp_read_radix(mp_int* a, const char* str, int radix); +#endif + +#ifdef HAVE_ECC + MP_API int mp_sqr(fp_int *a, fp_int *b); + MP_API int mp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp); + MP_API int mp_montgomery_setup(fp_int *a, fp_digit *rho); + MP_API int mp_div_2(fp_int * a, fp_int * b); + MP_API int mp_init_copy(fp_int * a, fp_int * b); +#endif + +#if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DSA) || \ + defined(WOLFSSL_KEY_GEN) + MP_API int mp_set(fp_int *a, fp_digit b); +#endif + +#if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || !defined(NO_RSA) || \ + !defined(NO_DSA) || !defined(NO_DH) + MP_API int mp_sqrmod(mp_int* a, mp_int* b, mp_int* c); + MP_API int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); +#endif + +#if !defined(NO_DH) || !defined(NO_DSA) || !defined(NO_RSA) || defined(WOLFSSL_KEY_GEN) +MP_API int mp_prime_is_prime(mp_int* a, int t, int* result); +MP_API int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng); +#endif /* !NO_DH || !NO_DSA || !NO_RSA || WOLFSSL_KEY_GEN */ +#ifdef WOLFSSL_KEY_GEN +MP_API int mp_gcd(fp_int *a, fp_int *b, fp_int *c); +MP_API int mp_lcm(fp_int *a, fp_int *b, fp_int *c); +MP_API int mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap); +MP_API int mp_exch(mp_int *a, mp_int *b); +#endif /* WOLFSSL_KEY_GEN */ + +MP_API int mp_cnt_lsb(fp_int *a); +MP_API int mp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d); +MP_API int mp_mod_d(fp_int* a, fp_digit b, fp_digit* c); +MP_API int mp_lshd (mp_int * a, int b); +MP_API int mp_abs(mp_int* a, mp_int* b); + +WOLFSSL_API word32 CheckRunTimeFastMath(void); + +/* If user uses RSA, DH, DSA, or ECC math lib directly then fast math FP_SIZE + must match, return 1 if a match otherwise 0 */ +#define CheckFastMathSettings() (FP_SIZE == CheckRunTimeFastMath()) + + +#ifdef __cplusplus + } +#endif + +#endif /* WOLF_CRYPT_TFM_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/types.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/types.h new file mode 100644 index 0000000..e803515 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/types.h @@ -0,0 +1,914 @@ +/* types.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/types.h +*/ + +#ifndef WOLF_CRYPT_TYPES_H +#define WOLF_CRYPT_TYPES_H + + #include + #include + + #ifdef __cplusplus + extern "C" { + #endif + + + #define WOLFSSL_ABI + /* Tag for all the APIs that are a part of the fixed ABI. */ + + + #if defined(WORDS_BIGENDIAN) + #define BIG_ENDIAN_ORDER + #endif + + #ifndef BIG_ENDIAN_ORDER + #define LITTLE_ENDIAN_ORDER + #endif + + #ifndef WOLFSSL_TYPES + #ifndef byte + typedef unsigned char byte; + #endif + #ifdef WC_16BIT_CPU + typedef unsigned int word16; + typedef unsigned long word32; + #else + typedef unsigned short word16; + typedef unsigned int word32; + #endif + typedef byte word24[3]; + #endif + + + /* try to set SIZEOF_LONG or LONG_LONG if user didn't */ + #if !defined(_MSC_VER) && !defined(__BCPLUSPLUS__) && !defined(__EMSCRIPTEN__) + #if !defined(SIZEOF_LONG_LONG) && !defined(SIZEOF_LONG) + #if (defined(__alpha__) || defined(__ia64__) || \ + defined(_ARCH_PPC64) || defined(__mips64) || \ + defined(__x86_64__) || \ + ((defined(sun) || defined(__sun)) && \ + (defined(LP64) || defined(_LP64)))) + /* long should be 64bit */ + #define SIZEOF_LONG 8 + #elif defined(__i386__) || defined(__CORTEX_M3__) + /* long long should be 64bit */ + #define SIZEOF_LONG_LONG 8 + #endif + #endif + #endif + + #if defined(_MSC_VER) || defined(__BCPLUSPLUS__) + #define WORD64_AVAILABLE + #define W64LIT(x) x##ui64 + typedef unsigned __int64 word64; + #elif defined(__EMSCRIPTEN__) + #define WORD64_AVAILABLE + #define W64LIT(x) x##ull + typedef unsigned long long word64; + #elif defined(SIZEOF_LONG) && SIZEOF_LONG == 8 + #define WORD64_AVAILABLE + #define W64LIT(x) x##LL + typedef unsigned long word64; + #elif defined(SIZEOF_LONG_LONG) && SIZEOF_LONG_LONG == 8 + #define WORD64_AVAILABLE + #define W64LIT(x) x##LL + typedef unsigned long long word64; + #elif defined(__SIZEOF_LONG_LONG__) && __SIZEOF_LONG_LONG__ == 8 + #define WORD64_AVAILABLE + #define W64LIT(x) x##LL + typedef unsigned long long word64; + #endif + +#if !defined(NO_64BIT) && defined(WORD64_AVAILABLE) && !defined(WC_16BIT_CPU) + /* These platforms have 64-bit CPU registers. */ + #if (defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || \ + defined(__mips64) || defined(__x86_64__) || defined(_M_X64)) || \ + defined(__aarch64__) || defined(__sparc64__) || \ + (defined(__riscv_xlen) && (__riscv_xlen == 64)) + typedef word64 wolfssl_word; + #define WC_64BIT_CPU + #elif (defined(sun) || defined(__sun)) && \ + (defined(LP64) || defined(_LP64)) + /* LP64 with GNU GCC compiler is reserved for when long int is 64 bits + * and int uses 32 bits. When using Solaris Studio sparc and __sparc are + * available for 32 bit detection but __sparc64__ could be missed. This + * uses LP64 for checking 64 bit CPU arch. */ + typedef word64 wolfssl_word; + #define WC_64BIT_CPU + #else + typedef word32 wolfssl_word; + #ifdef WORD64_AVAILABLE + #define WOLFCRYPT_SLOW_WORD64 + #endif + #endif + +#elif defined(WC_16BIT_CPU) + #undef WORD64_AVAILABLE + typedef word16 wolfssl_word; + #define MP_16BIT /* for mp_int, mp_word needs to be twice as big as + mp_digit, no 64 bit type so make mp_digit 16 bit */ + +#else + #undef WORD64_AVAILABLE + typedef word32 wolfssl_word; + #define MP_16BIT /* for mp_int, mp_word needs to be twice as big as + mp_digit, no 64 bit type so make mp_digit 16 bit */ +#endif + + enum { + WOLFSSL_WORD_SIZE = sizeof(wolfssl_word), + WOLFSSL_BIT_SIZE = 8, + WOLFSSL_WORD_BITS = WOLFSSL_WORD_SIZE * WOLFSSL_BIT_SIZE + }; + + #define WOLFSSL_MAX_16BIT 0xffffU + + /* use inlining if compiler allows */ + #ifndef WC_INLINE + #ifndef NO_INLINE + #ifdef _MSC_VER + #define WC_INLINE __inline + #elif defined(__GNUC__) + #ifdef WOLFSSL_VXWORKS + #define WC_INLINE __inline__ + #else + #define WC_INLINE inline + #endif + #elif defined(__IAR_SYSTEMS_ICC__) + #define WC_INLINE inline + #elif defined(THREADX) + #define WC_INLINE _Inline + #elif defined(__ghc__) + #ifndef __cplusplus + #define WC_INLINE __inline + #else + #define WC_INLINE inline + #endif + #else + #define WC_INLINE + #endif + #else + #define WC_INLINE + #endif + #endif + + #if defined(HAVE_FIPS) || defined(HAVE_SELFTEST) + #define INLINE WC_INLINE + #endif + + + /* set up rotate style */ + #if (defined(_MSC_VER) || defined(__BCPLUSPLUS__)) && \ + !defined(WOLFSSL_SGX) && !defined(INTIME_RTOS) + #define INTEL_INTRINSICS + #define FAST_ROTATE + #elif defined(__MWERKS__) && TARGET_CPU_PPC + #define PPC_INTRINSICS + #define FAST_ROTATE + #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + /* GCC does peephole optimizations which should result in using rotate + instructions */ + #define FAST_ROTATE + #endif + + + /* set up thread local storage if available */ + #ifdef HAVE_THREAD_LS + #if defined(_MSC_VER) + #define THREAD_LS_T __declspec(thread) + /* Thread local storage only in FreeRTOS v8.2.1 and higher */ + #elif defined(FREERTOS) || defined(FREERTOS_TCP) || \ + defined(WOLFSSL_ZEPHYR) + #define THREAD_LS_T + #else + #define THREAD_LS_T __thread + #endif + #else + #define THREAD_LS_T + #endif + + /* GCC 7 has new switch() fall-through detection */ + /* default to FALL_THROUGH stub */ + #ifndef FALL_THROUGH + #define FALL_THROUGH + + #if defined(__GNUC__) + #if ((__GNUC__ > 7) || ((__GNUC__ == 7) && (__GNUC_MINOR__ >= 1))) + #undef FALL_THROUGH + #define FALL_THROUGH __attribute__ ((fallthrough)); + #endif + #endif + #endif /* FALL_THROUGH */ + + /* Micrium will use Visual Studio for compilation but not the Win32 API */ + #if defined(_WIN32) && !defined(MICRIUM) && !defined(FREERTOS) && \ + !defined(FREERTOS_TCP) && !defined(EBSNET) && \ + !defined(WOLFSSL_UTASKER) && !defined(INTIME_RTOS) + #define USE_WINDOWS_API + #endif + + + /* idea to add global alloc override by Moises Guimaraes */ + /* default to libc stuff */ + /* XREALLOC is used once in normal math lib, not in fast math lib */ + /* XFREE on some embedded systems doesn't like free(0) so test */ + #if defined(HAVE_IO_POOL) + WOLFSSL_API void* XMALLOC(size_t n, void* heap, int type); + WOLFSSL_API void* XREALLOC(void *p, size_t n, void* heap, int type); + WOLFSSL_API void XFREE(void *p, void* heap, int type); + #elif (defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_INTEL_QA)) || \ + defined(HAVE_INTEL_QA_SYNC) + #ifndef HAVE_INTEL_QA_SYNC + #include + #undef USE_WOLFSSL_MEMORY + #ifdef WOLFSSL_DEBUG_MEMORY + #define XMALLOC(s, h, t) IntelQaMalloc((s), (h), (t), __func__, __LINE__) + #define XFREE(p, h, t) IntelQaFree((p), (h), (t), __func__, __LINE__) + #define XREALLOC(p, n, h, t) IntelQaRealloc((p), (n), (h), (t), __func__, __LINE__) + #else + #define XMALLOC(s, h, t) IntelQaMalloc((s), (h), (t)) + #define XFREE(p, h, t) IntelQaFree((p), (h), (t)) + #define XREALLOC(p, n, h, t) IntelQaRealloc((p), (n), (h), (t)) + #endif /* WOLFSSL_DEBUG_MEMORY */ + #else + #include + #undef USE_WOLFSSL_MEMORY + #ifdef WOLFSSL_DEBUG_MEMORY + #define XMALLOC(s, h, t) wc_CryptoCb_IntelQaMalloc((s), (h), (t), __func__, __LINE__) + #define XFREE(p, h, t) wc_CryptoCb_IntelQaFree((p), (h), (t), __func__, __LINE__) + #define XREALLOC(p, n, h, t) wc_CryptoCb_IntelQaRealloc((p), (n), (h), (t), __func__, __LINE__) + #else + #define XMALLOC(s, h, t) wc_CryptoCb_IntelQaMalloc((s), (h), (t)) + #define XFREE(p, h, t) wc_CryptoCb_IntelQaFree((p), (h), (t)) + #define XREALLOC(p, n, h, t) wc_CryptoCb_IntelQaRealloc((p), (n), (h), (t)) + #endif /* WOLFSSL_DEBUG_MEMORY */ + #endif + #elif defined(XMALLOC_USER) + /* prototypes for user heap override functions */ + #include /* for size_t */ + extern void *XMALLOC(size_t n, void* heap, int type); + extern void *XREALLOC(void *p, size_t n, void* heap, int type); + extern void XFREE(void *p, void* heap, int type); + #elif defined(WOLFSSL_MEMORY_LOG) + #define XMALLOC(n, h, t) xmalloc(n, h, t, __func__, __FILE__, __LINE__) + #define XREALLOC(p, n, h, t) xrealloc(p, n, h, t, __func__, __FILE__, __LINE__) + #define XFREE(p, h, t) xfree(p, h, t, __func__, __FILE__, __LINE__) + + /* prototypes for user heap override functions */ + #include /* for size_t */ + #include + WOLFSSL_API void *xmalloc(size_t n, void* heap, int type, + const char* func, const char* file, unsigned int line); + WOLFSSL_API void *xrealloc(void *p, size_t n, void* heap, int type, + const char* func, const char* file, unsigned int line); + WOLFSSL_API void xfree(void *p, void* heap, int type, const char* func, + const char* file, unsigned int line); + #elif defined(XMALLOC_OVERRIDE) + /* override the XMALLOC, XFREE and XREALLOC macros */ + #elif defined(WOLFSSL_TELIT_M2MB) + /* Telit M2MB SDK requires use m2mb_os API's, not std malloc/free */ + /* Use of malloc/free will cause CPU reboot */ + #define XMALLOC(s, h, t) ((void)h, (void)t, m2mb_os_malloc((s))) + #define XFREE(p, h, t) {void* xp = (p); if((xp)) m2mb_os_free((xp));} + #define XREALLOC(p, n, h, t) m2mb_os_realloc((p), (n)) + + #elif defined(NO_WOLFSSL_MEMORY) + #ifdef WOLFSSL_NO_MALLOC + /* this platform does not support heap use */ + #ifdef WOLFSSL_MALLOC_CHECK + #include + static inline void* malloc_check(size_t sz) { + printf("wolfSSL_malloc failed"); + return NULL; + }; + #define XMALLOC(s, h, t) malloc_check((s)) + #define XFREE(p, h, t) + #define XREALLOC(p, n, h, t) (NULL) + #else + #define XMALLOC(s, h, t) (NULL) + #define XFREE(p, h, t) + #define XREALLOC(p, n, h, t) (NULL) + #endif + #else + /* just use plain C stdlib stuff if desired */ + #include + #define XMALLOC(s, h, t) malloc((s)) + #define XFREE(p, h, t) {void* xp = (p); if((xp)) free((xp));} + #define XREALLOC(p, n, h, t) realloc((p), (n)) + #endif + #elif !defined(MICRIUM_MALLOC) && !defined(EBSNET) \ + && !defined(WOLFSSL_SAFERTOS) && !defined(FREESCALE_MQX) \ + && !defined(FREESCALE_KSDK_MQX) && !defined(FREESCALE_FREE_RTOS) \ + && !defined(WOLFSSL_LEANPSK) && !defined(WOLFSSL_uITRON4) + /* default C runtime, can install different routines at runtime via cbs */ + #include + #ifdef WOLFSSL_STATIC_MEMORY + #ifdef WOLFSSL_DEBUG_MEMORY + #define XMALLOC(s, h, t) wolfSSL_Malloc((s), (h), (t), __func__, __LINE__) + #define XFREE(p, h, t) {void* xp = (p); if((xp)) wolfSSL_Free((xp), (h), (t), __func__, __LINE__);} + #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n), (h), (t), __func__, __LINE__) + #else + #define XMALLOC(s, h, t) wolfSSL_Malloc((s), (h), (t)) + #define XFREE(p, h, t) {void* xp = (p); if((xp)) wolfSSL_Free((xp), (h), (t));} + #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n), (h), (t)) + #endif /* WOLFSSL_DEBUG_MEMORY */ + #elif !defined(FREERTOS) && !defined(FREERTOS_TCP) + #ifdef WOLFSSL_DEBUG_MEMORY + #define XMALLOC(s, h, t) ((void)h, (void)t, wolfSSL_Malloc((s), __func__, __LINE__)) + #define XFREE(p, h, t) {void* xp = (p); if((xp)) wolfSSL_Free((xp), __func__, __LINE__);} + #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n), __func__, __LINE__) + #else + #define XMALLOC(s, h, t) ((void)h, (void)t, wolfSSL_Malloc((s))) + #define XFREE(p, h, t) {void* xp = (p); if((xp)) wolfSSL_Free((xp));} + #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n)) + #endif /* WOLFSSL_DEBUG_MEMORY */ + #endif /* WOLFSSL_STATIC_MEMORY */ + #endif + + /* declare/free variable handling for async */ + #ifdef WOLFSSL_ASYNC_CRYPT + #define DECLARE_VAR(VAR_NAME, VAR_TYPE, VAR_SIZE, HEAP) \ + VAR_TYPE* VAR_NAME = (VAR_TYPE*)XMALLOC(sizeof(VAR_TYPE) * VAR_SIZE, (HEAP), DYNAMIC_TYPE_WOLF_BIGINT); + #define DECLARE_VAR_INIT(VAR_NAME, VAR_TYPE, VAR_SIZE, INIT_VALUE, HEAP) \ + VAR_TYPE* VAR_NAME = ({ \ + VAR_TYPE* ptr = (VAR_TYPE*)XMALLOC(sizeof(VAR_TYPE) * VAR_SIZE, (HEAP), DYNAMIC_TYPE_WOLF_BIGINT); \ + if (ptr && INIT_VALUE) { \ + XMEMCPY(ptr, INIT_VALUE, sizeof(VAR_TYPE) * VAR_SIZE); \ + } \ + ptr; \ + }) + #define DECLARE_ARRAY(VAR_NAME, VAR_TYPE, VAR_ITEMS, VAR_SIZE, HEAP) \ + VAR_TYPE* VAR_NAME[VAR_ITEMS]; \ + int idx##VAR_NAME; \ + for (idx##VAR_NAME=0; idx##VAR_NAME + #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) + #define XMEMSET(b,c,l) memset((b),(c),(l)) + #define XMEMCMP(s1,s2,n) memcmp((s1),(s2),(n)) + #define XMEMMOVE(d,s,l) memmove((d),(s),(l)) + + #define XSTRLEN(s1) strlen((s1)) + #define XSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n)) + /* strstr, strncmp, and strncat only used by wolfSSL proper, + * not required for wolfCrypt only */ + #define XSTRSTR(s1,s2) strstr((s1),(s2)) + #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) + #define XSTRNCMP(s1,s2,n) strncmp((s1),(s2),(n)) + #define XSTRNCAT(s1,s2,n) strncat((s1),(s2),(n)) + + #ifdef USE_WOLF_STRSEP + #define XSTRSEP(s1,d) wc_strsep((s1),(d)) + #else + #define XSTRSEP(s1,d) strsep((s1),(d)) + #endif + + #ifndef XSTRNCASECMP + #if defined(MICROCHIP_PIC32) || defined(WOLFSSL_TIRTOS) || \ + defined(WOLFSSL_ZEPHYR) + /* XC32 does not support strncasecmp, so use case sensitive one */ + #define XSTRNCASECMP(s1,s2,n) strncmp((s1),(s2),(n)) + #elif defined(USE_WINDOWS_API) || defined(FREERTOS_TCP_WINSIM) + #define XSTRNCASECMP(s1,s2,n) _strnicmp((s1),(s2),(n)) + #else + #if defined(HAVE_STRINGS_H) && defined(WOLF_C99) && \ + !defined(WOLFSSL_SGX) + #include + #endif + #if defined(WOLFSSL_DEOS) + #define XSTRNCASECMP(s1,s2,n) strnicmp((s1),(s2),(n)) + #else + #define XSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n)) + #endif + #endif + #endif /* !XSTRNCASECMP */ + + /* snprintf is used in asn.c for GetTimeString, PKCS7 test, and when + debugging is turned on */ + #ifndef USE_WINDOWS_API + #ifndef XSNPRINTF + #if defined(NO_FILESYSTEM) && (defined(OPENSSL_EXTRA) || \ + defined(HAVE_PKCS7)) && !defined(NO_STDIO_FILESYSTEM) + /* case where stdio is not included else where but is needed + for snprintf */ + #include + #endif + #define XSNPRINTF snprintf + #endif + #else + #if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) + #if defined(_MSC_VER) && (_MSC_VER >= 1900) + /* Beginning with the UCRT in Visual Studio 2015 and + Windows 10, snprintf is no longer identical to + _snprintf. The snprintf function behavior is now + C99 standard compliant. */ + #define XSNPRINTF snprintf + #else + /* 4996 warning to use MS extensions e.g., _sprintf_s + instead of _snprintf */ + #pragma warning(disable: 4996) + static WC_INLINE + int xsnprintf(char *buffer, size_t bufsize, + const char *format, ...) { + va_list ap; + int ret; + + if ((int)bufsize <= 0) return -1; + va_start(ap, format); + ret = vsnprintf(buffer, bufsize, format, ap); + if (ret >= (int)bufsize) + ret = -1; + va_end(ap); + return ret; + } + #define XSNPRINTF xsnprintf + #endif /* (_MSC_VER >= 1900) */ + #endif /* _MSC_VER || __CYGWIN__ || __MINGW32__ */ + #endif /* USE_WINDOWS_API */ + + #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) \ + || defined(HAVE_ALPN) + /* use only Thread Safe version of strtok */ + #if defined(USE_WOLF_STRTOK) + #define XSTRTOK(s1,d,ptr) wc_strtok((s1),(d),(ptr)) + #elif defined(USE_WINDOWS_API) || defined(INTIME_RTOS) + #define XSTRTOK(s1,d,ptr) strtok_s((s1),(d),(ptr)) + #else + #define XSTRTOK(s1,d,ptr) strtok_r((s1),(d),(ptr)) + #endif + #endif + + #if defined(WOLFSSL_CERT_EXT) || defined(HAVE_OCSP) || \ + defined(HAVE_CRL_IO) || defined(HAVE_HTTP_CLIENT) || \ + !defined(NO_CRYPT_BENCHMARK) + + #ifndef XATOI /* if custom XATOI is not already defined */ + #include + #define XATOI(s) atoi((s)) + #endif + #endif + #endif + + #ifdef USE_WOLF_STRTOK + WOLFSSL_API char* wc_strtok(char *str, const char *delim, char **nextp); + #endif + #ifdef USE_WOLF_STRSEP + WOLFSSL_API char* wc_strsep(char **stringp, const char *delim); + #endif + + #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \ + !defined(NO_STDIO_FILESYSTEM) + #ifndef XGETENV + #include + #define XGETENV getenv + #endif + #endif /* OPENSSL_EXTRA */ + + #ifndef CTYPE_USER + #include + #if defined(HAVE_ECC) || defined(HAVE_OCSP) || \ + defined(WOLFSSL_KEY_GEN) || !defined(NO_DSA) + #define XTOUPPER(c) toupper((c)) + #define XISALPHA(c) isalpha((c)) + #endif + /* needed by wolfSSL_check_domain_name() */ + #define XTOLOWER(c) tolower((c)) + #endif + + + /* memory allocation types for user hints */ + enum { + DYNAMIC_TYPE_CA = 1, + DYNAMIC_TYPE_CERT = 2, + DYNAMIC_TYPE_KEY = 3, + DYNAMIC_TYPE_FILE = 4, + DYNAMIC_TYPE_SUBJECT_CN = 5, + DYNAMIC_TYPE_PUBLIC_KEY = 6, + DYNAMIC_TYPE_SIGNER = 7, + DYNAMIC_TYPE_NONE = 8, + DYNAMIC_TYPE_BIGINT = 9, + DYNAMIC_TYPE_RSA = 10, + DYNAMIC_TYPE_METHOD = 11, + DYNAMIC_TYPE_OUT_BUFFER = 12, + DYNAMIC_TYPE_IN_BUFFER = 13, + DYNAMIC_TYPE_INFO = 14, + DYNAMIC_TYPE_DH = 15, + DYNAMIC_TYPE_DOMAIN = 16, + DYNAMIC_TYPE_SSL = 17, + DYNAMIC_TYPE_CTX = 18, + DYNAMIC_TYPE_WRITEV = 19, + DYNAMIC_TYPE_OPENSSL = 20, + DYNAMIC_TYPE_DSA = 21, + DYNAMIC_TYPE_CRL = 22, + DYNAMIC_TYPE_REVOKED = 23, + DYNAMIC_TYPE_CRL_ENTRY = 24, + DYNAMIC_TYPE_CERT_MANAGER = 25, + DYNAMIC_TYPE_CRL_MONITOR = 26, + DYNAMIC_TYPE_OCSP_STATUS = 27, + DYNAMIC_TYPE_OCSP_ENTRY = 28, + DYNAMIC_TYPE_ALTNAME = 29, + DYNAMIC_TYPE_SUITES = 30, + DYNAMIC_TYPE_CIPHER = 31, + DYNAMIC_TYPE_RNG = 32, + DYNAMIC_TYPE_ARRAYS = 33, + DYNAMIC_TYPE_DTLS_POOL = 34, + DYNAMIC_TYPE_SOCKADDR = 35, + DYNAMIC_TYPE_LIBZ = 36, + DYNAMIC_TYPE_ECC = 37, + DYNAMIC_TYPE_TMP_BUFFER = 38, + DYNAMIC_TYPE_DTLS_MSG = 39, + DYNAMIC_TYPE_X509 = 40, + DYNAMIC_TYPE_TLSX = 41, + DYNAMIC_TYPE_OCSP = 42, + DYNAMIC_TYPE_SIGNATURE = 43, + DYNAMIC_TYPE_HASHES = 44, + DYNAMIC_TYPE_SRP = 45, + DYNAMIC_TYPE_COOKIE_PWD = 46, + DYNAMIC_TYPE_USER_CRYPTO = 47, + DYNAMIC_TYPE_OCSP_REQUEST = 48, + DYNAMIC_TYPE_X509_EXT = 49, + DYNAMIC_TYPE_X509_STORE = 50, + DYNAMIC_TYPE_X509_CTX = 51, + DYNAMIC_TYPE_URL = 52, + DYNAMIC_TYPE_DTLS_FRAG = 53, + DYNAMIC_TYPE_DTLS_BUFFER = 54, + DYNAMIC_TYPE_SESSION_TICK = 55, + DYNAMIC_TYPE_PKCS = 56, + DYNAMIC_TYPE_MUTEX = 57, + DYNAMIC_TYPE_PKCS7 = 58, + DYNAMIC_TYPE_AES_BUFFER = 59, + DYNAMIC_TYPE_WOLF_BIGINT = 60, + DYNAMIC_TYPE_ASN1 = 61, + DYNAMIC_TYPE_LOG = 62, + DYNAMIC_TYPE_WRITEDUP = 63, + DYNAMIC_TYPE_PRIVATE_KEY = 64, + DYNAMIC_TYPE_HMAC = 65, + DYNAMIC_TYPE_ASYNC = 66, + DYNAMIC_TYPE_ASYNC_NUMA = 67, + DYNAMIC_TYPE_ASYNC_NUMA64 = 68, + DYNAMIC_TYPE_CURVE25519 = 69, + DYNAMIC_TYPE_ED25519 = 70, + DYNAMIC_TYPE_SECRET = 71, + DYNAMIC_TYPE_DIGEST = 72, + DYNAMIC_TYPE_RSA_BUFFER = 73, + DYNAMIC_TYPE_DCERT = 74, + DYNAMIC_TYPE_STRING = 75, + DYNAMIC_TYPE_PEM = 76, + DYNAMIC_TYPE_DER = 77, + DYNAMIC_TYPE_CERT_EXT = 78, + DYNAMIC_TYPE_ALPN = 79, + DYNAMIC_TYPE_ENCRYPTEDINFO= 80, + DYNAMIC_TYPE_DIRCTX = 81, + DYNAMIC_TYPE_HASHCTX = 82, + DYNAMIC_TYPE_SEED = 83, + DYNAMIC_TYPE_SYMMETRIC_KEY= 84, + DYNAMIC_TYPE_ECC_BUFFER = 85, + DYNAMIC_TYPE_QSH = 86, + DYNAMIC_TYPE_SALT = 87, + DYNAMIC_TYPE_HASH_TMP = 88, + DYNAMIC_TYPE_BLOB = 89, + DYNAMIC_TYPE_NAME_ENTRY = 90, + DYNAMIC_TYPE_SNIFFER_SERVER = 1000, + DYNAMIC_TYPE_SNIFFER_SESSION = 1001, + DYNAMIC_TYPE_SNIFFER_PB = 1002, + DYNAMIC_TYPE_SNIFFER_PB_BUFFER = 1003, + DYNAMIC_TYPE_SNIFFER_TICKET_ID = 1004, + DYNAMIC_TYPE_SNIFFER_NAMED_KEY = 1005, + }; + + /* max error buffer string size */ + #ifndef WOLFSSL_MAX_ERROR_SZ + #define WOLFSSL_MAX_ERROR_SZ 80 + #endif + + /* stack protection */ + enum { + MIN_STACK_BUFFER = 8 + }; + + + /* Algorithm Types */ + enum wc_AlgoType { + WC_ALGO_TYPE_NONE = 0, + WC_ALGO_TYPE_HASH = 1, + WC_ALGO_TYPE_CIPHER = 2, + WC_ALGO_TYPE_PK = 3, + WC_ALGO_TYPE_RNG = 4, + WC_ALGO_TYPE_SEED = 5, + WC_ALGO_TYPE_HMAC = 6, + + WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_HMAC + }; + + /* hash types */ + enum wc_HashType { + #if defined(HAVE_SELFTEST) || defined(HAVE_FIPS) + /* In selftest build, WC_* types are not mapped to WC_HASH_TYPE types. + * Values here are based on old selftest hmac.h enum, with additions. + * These values are fixed for backwards FIPS compatibility */ + WC_HASH_TYPE_NONE = 15, + WC_HASH_TYPE_MD2 = 16, + WC_HASH_TYPE_MD4 = 17, + WC_HASH_TYPE_MD5 = 0, + WC_HASH_TYPE_SHA = 1, /* SHA-1 (not old SHA-0) */ + WC_HASH_TYPE_SHA224 = 8, + WC_HASH_TYPE_SHA256 = 2, + WC_HASH_TYPE_SHA384 = 5, + WC_HASH_TYPE_SHA512 = 4, + WC_HASH_TYPE_MD5_SHA = 18, + WC_HASH_TYPE_SHA3_224 = 10, + WC_HASH_TYPE_SHA3_256 = 11, + WC_HASH_TYPE_SHA3_384 = 12, + WC_HASH_TYPE_SHA3_512 = 13, + WC_HASH_TYPE_BLAKE2B = 14, + WC_HASH_TYPE_BLAKE2S = 19, + + WC_HASH_TYPE_MAX = WC_HASH_TYPE_BLAKE2S + #else + WC_HASH_TYPE_NONE = 0, + WC_HASH_TYPE_MD2 = 1, + WC_HASH_TYPE_MD4 = 2, + WC_HASH_TYPE_MD5 = 3, + WC_HASH_TYPE_SHA = 4, /* SHA-1 (not old SHA-0) */ + WC_HASH_TYPE_SHA224 = 5, + WC_HASH_TYPE_SHA256 = 6, + WC_HASH_TYPE_SHA384 = 7, + WC_HASH_TYPE_SHA512 = 8, + WC_HASH_TYPE_MD5_SHA = 9, + WC_HASH_TYPE_SHA3_224 = 10, + WC_HASH_TYPE_SHA3_256 = 11, + WC_HASH_TYPE_SHA3_384 = 12, + WC_HASH_TYPE_SHA3_512 = 13, + WC_HASH_TYPE_BLAKE2B = 14, + WC_HASH_TYPE_BLAKE2S = 15, + + WC_HASH_TYPE_MAX = WC_HASH_TYPE_BLAKE2S + #endif /* HAVE_SELFTEST */ + }; + + /* cipher types */ + enum wc_CipherType { + WC_CIPHER_NONE = 0, + WC_CIPHER_AES = 1, + WC_CIPHER_AES_CBC = 2, + WC_CIPHER_AES_GCM = 3, + WC_CIPHER_AES_CTR = 4, + WC_CIPHER_AES_XTS = 5, + WC_CIPHER_AES_CFB = 6, + WC_CIPHER_DES3 = 7, + WC_CIPHER_DES = 8, + WC_CIPHER_CHACHA = 9, + WC_CIPHER_HC128 = 10, + WC_CIPHER_IDEA = 11, + + WC_CIPHER_MAX = WC_CIPHER_HC128 + }; + + /* PK=public key (asymmetric) based algorithms */ + enum wc_PkType { + WC_PK_TYPE_NONE = 0, + WC_PK_TYPE_RSA = 1, + WC_PK_TYPE_DH = 2, + WC_PK_TYPE_ECDH = 3, + WC_PK_TYPE_ECDSA_SIGN = 4, + WC_PK_TYPE_ECDSA_VERIFY = 5, + WC_PK_TYPE_ED25519 = 6, + WC_PK_TYPE_CURVE25519 = 7, + WC_PK_TYPE_RSA_KEYGEN = 8, + WC_PK_TYPE_EC_KEYGEN = 9, + + WC_PK_TYPE_MAX = WC_PK_TYPE_EC_KEYGEN + }; + + + /* settings detection for compile vs runtime math incompatibilities */ + enum { + #if !defined(USE_FAST_MATH) && !defined(SIZEOF_LONG) && !defined(SIZEOF_LONG_LONG) + CTC_SETTINGS = 0x0 + #elif !defined(USE_FAST_MATH) && defined(SIZEOF_LONG) && (SIZEOF_LONG == 8) + CTC_SETTINGS = 0x1 + #elif !defined(USE_FAST_MATH) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8) + CTC_SETTINGS = 0x2 + #elif !defined(USE_FAST_MATH) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 4) + CTC_SETTINGS = 0x4 + #elif defined(USE_FAST_MATH) && !defined(SIZEOF_LONG) && !defined(SIZEOF_LONG_LONG) + CTC_SETTINGS = 0x8 + #elif defined(USE_FAST_MATH) && defined(SIZEOF_LONG) && (SIZEOF_LONG == 8) + CTC_SETTINGS = 0x10 + #elif defined(USE_FAST_MATH) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8) + CTC_SETTINGS = 0x20 + #elif defined(USE_FAST_MATH) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 4) + CTC_SETTINGS = 0x40 + #else + #error "bad math long / long long settings" + #endif + }; + + + WOLFSSL_API word32 CheckRunTimeSettings(void); + + /* If user uses RSA, DH, DSA, or ECC math lib directly then fast math and long + types need to match at compile time and run time, CheckCtcSettings will + return 1 if a match otherwise 0 */ + #define CheckCtcSettings() (CTC_SETTINGS == CheckRunTimeSettings()) + + /* invalid device id */ + #define INVALID_DEVID -2 + + + /* AESNI requires alignment and ARMASM gains some performance from it + * Xilinx RSA operations require alignment */ + #if defined(WOLFSSL_AESNI) || defined(WOLFSSL_ARMASM) || \ + defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_AFALG_XILINX) + #if !defined(ALIGN16) + #if defined(__IAR_SYSTEMS_ICC__) || 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 + #endif + #endif /* !ALIGN16 */ + + #if !defined (ALIGN32) + #if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) + #define ALIGN32 __attribute__ ( (aligned (32))) + #elif defined(_MSC_VER) + /* disable align warning, we want alignment ! */ + #pragma warning(disable: 4324) + #define ALIGN32 __declspec (align (32)) + #else + #define ALIGN32 + #endif + #endif /* !ALIGN32 */ + + #if !defined(ALIGN64) + #if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) + #define ALIGN64 __attribute__ ( (aligned (64))) + #elif defined(_MSC_VER) + /* disable align warning, we want alignment ! */ + #pragma warning(disable: 4324) + #define ALIGN64 __declspec (align (64)) + #else + #define ALIGN64 + #endif + #endif /* !ALIGN64 */ + + #if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) + #define ALIGN128 __attribute__ ( (aligned (128))) + #elif defined(_MSC_VER) + /* disable align warning, we want alignment ! */ + #pragma warning(disable: 4324) + #define ALIGN128 __declspec (align (128)) + #else + #define ALIGN128 + #endif + + #if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) + #define ALIGN256 __attribute__ ( (aligned (256))) + #elif defined(_MSC_VER) + /* disable align warning, we want alignment ! */ + #pragma warning(disable: 4324) + #define ALIGN256 __declspec (align (256)) + #else + #define ALIGN256 + #endif + + #else + #ifndef ALIGN16 + #define ALIGN16 + #endif + #ifndef ALIGN32 + #define ALIGN32 + #endif + #ifndef ALIGN64 + #define ALIGN64 + #endif + #ifndef ALIGN128 + #define ALIGN128 + #endif + #ifndef ALIGN256 + #define ALIGN256 + #endif + #endif /* WOLFSSL_AESNI || WOLFSSL_ARMASM */ + + + #ifndef TRUE + #define TRUE 1 + #endif + #ifndef FALSE + #define FALSE 0 + #endif + + + #if defined(HAVE_STACK_SIZE) + #define EXIT_TEST(ret) return (void*)((size_t)(ret)) + #else + #define EXIT_TEST(ret) return ret + #endif + + + #if (defined(__IAR_SYSTEMS_ICC__) && (__IAR_SYSTEMS_ICC__ > 8)) || \ + defined(__GNUC__) + #define WOLFSSL_PACK __attribute__ ((packed)) + #else + #define WOLFSSL_PACK + #endif + + #ifndef __GNUC_PREREQ + #if defined(__GNUC__) && defined(__GNUC_MINOR__) + #define __GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) + #else + #define __GNUC_PREREQ(maj, min) (0) /* not GNUC */ + #endif + #endif + + #if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) + #define WC_NORETURN __attribute__((noreturn)) + #else + #define WC_NORETURN + #endif + + #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \ + defined(WOLFSSL_DEBUG_MATH) || defined(DEBUG_WOLFSSL) || \ + defined(WOLFSSL_PUBLIC_MP) || defined(OPENSSL_EXTRA) || \ + (defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)) + #undef WC_MP_TO_RADIX + #define WC_MP_TO_RADIX + #endif + + #ifdef __cplusplus + } /* extern "C" */ + #endif + +#endif /* WOLF_CRYPT_TYPES_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/user_settings.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/user_settings.h new file mode 100644 index 0000000..ca59ff6 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/user_settings.h @@ -0,0 +1,90 @@ +#ifndef _WIN_USER_SETTINGS_H_ +#define _WIN_USER_SETTINGS_H_ + +/* Verify this is Windows */ +#ifndef _WIN32 +#error This user_settings.h header is only designed for Windows +#endif + +/* Configurations */ +#if defined(HAVE_FIPS) + /* FIPS */ + #define OPENSSL_EXTRA + #define HAVE_THREAD_LS + #define WOLFSSL_KEY_GEN + #define HAVE_AESGCM + #define HAVE_HASHDRBG + #define WOLFSSL_SHA384 + #define WOLFSSL_SHA512 + #define NO_PSK + #define NO_HC128 + #define NO_RC4 + #define NO_RABBIT + #define NO_DSA + #define NO_MD4 + #define WOLFSSL_CERT_GEN + #define WOLFSSL_KEY_GEN + + #if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) + #define WOLFSSL_SHA224 + #define WOLFSSL_SHA3 + #define WC_RSA_PSS + #define WC_RSA_NO_PADDING + #define HAVE_ECC + #define ECC_SHAMIR + #define HAVE_ECC_CDH + #define ECC_TIMING_RESISTANT + #define TFM_TIMING_RESISTANT + #define WOLFSSL_AES_COUNTER + #define WOLFSSL_AES_DIRECT + #define HAVE_AES_ECB + #define HAVE_AESCCM + #define WOLFSSL_CMAC + #define HAVE_HKDF + #define WOLFSSL_VALIDATE_ECC_IMPORT + #define WOLFSSL_VALIDATE_FFC_IMPORT + #define HAVE_FFDHE_Q + #define WOLFSSL_AESNI + #define HAVE_INTEL_RDSEED + #define FORCE_FAILURE_RDSEED + #define WOLFSSL_CERT_GEN + #define WOLFSSL_KEY_GEN + #endif /* FIPS v2 */ +#else + /* Enables blinding mode, to prevent timing attacks */ + #define WC_RSA_BLINDING + + #if defined(WOLFSSL_LIB) + /* The lib */ + #define OPENSSL_EXTRA + #define WOLFSSL_RIPEMD + #define WOLFSSL_SHA512 + #define NO_PSK + #define HAVE_EXTENDED_MASTER + #define WOLFSSL_SNIFFER + #define HAVE_TLS_EXTENSIONS + #define HAVE_SECURE_RENEGOTIATION + #define WOLFSSL_CERT_GEN + #define WOLFSSL_KEY_GEN + + #define HAVE_AESGCM + #define WOLFSSL_SHA384 + #define WOLFSSL_SHA512 + + #define HAVE_SUPPORTED_CURVES + #define HAVE_TLS_EXTENSIONS + + #define HAVE_ECC + #define ECC_SHAMIR + #define ECC_TIMING_RESISTANT + #else + /* The servers and clients */ + #define OPENSSL_EXTRA + #define NO_PSK + #define WOLFSSL_CERT_GEN + #define WOLFSSL_KEY_GEN + #endif +#endif /* HAVE_FIPS */ + +#endif /* _WIN_USER_SETTINGS_H_ */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/visibility.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/visibility.h new file mode 100644 index 0000000..07ba2f1 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/visibility.h @@ -0,0 +1,79 @@ +/* visibility.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +/* Visibility control macros */ + +#ifndef WOLF_CRYPT_VISIBILITY_H +#define WOLF_CRYPT_VISIBILITY_H + + +/* for compatibility and so that fips is using same name of macro @wc_fips */ +/* The following visibility wrappers are for old FIPS. New FIPS should use + * the same as a non-FIPS build. */ +#if defined(HAVE_FIPS) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) + #include + #define WOLFSSL_API CYASSL_API + #define WOLFSSL_LOCAL CYASSL_LOCAL +#else + +/* WOLFSSL_API is used for the public API symbols. + It either imports or exports (or does nothing for static builds) + + WOLFSSL_LOCAL is used for non-API symbols (private). +*/ + +#if defined(BUILDING_WOLFSSL) + #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) + #if defined(WOLFSSL_DLL) + #define WOLFSSL_API __declspec(dllexport) + #else + #define WOLFSSL_API + #endif + #define WOLFSSL_LOCAL + #elif defined(HAVE_VISIBILITY) && HAVE_VISIBILITY + #define WOLFSSL_API __attribute__ ((visibility("default"))) + #define WOLFSSL_LOCAL __attribute__ ((visibility("hidden"))) + #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) + #define WOLFSSL_API __global + #define WOLFSSL_LOCAL __hidden + #else + #define WOLFSSL_API + #define WOLFSSL_LOCAL + #endif /* HAVE_VISIBILITY */ +#else /* BUILDING_WOLFSSL */ + #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) + #if defined(WOLFSSL_DLL) + #define WOLFSSL_API __declspec(dllimport) + #else + #define WOLFSSL_API + #endif + #define WOLFSSL_LOCAL + #else + #define WOLFSSL_API + #define WOLFSSL_LOCAL + #endif +#endif /* BUILDING_WOLFSSL */ + +#endif /* HAVE_FIPS */ +#endif /* WOLF_CRYPT_VISIBILITY_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wc_encrypt.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wc_encrypt.h new file mode 100644 index 0000000..d1f1fb7 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wc_encrypt.h @@ -0,0 +1,101 @@ +/* wc_encrypt.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/wc_encrypt.h +*/ + + +#ifndef WOLF_CRYPT_ENCRYPT_H +#define WOLF_CRYPT_ENCRYPT_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/* determine max cipher key size */ +#ifndef NO_AES + #define WC_MAX_SYM_KEY_SIZE (AES_MAX_KEY_SIZE/8) +#elif defined(HAVE_CHACHA) + #define WC_MAX_SYM_KEY_SIZE CHACHA_MAX_KEY_SZ +#elif !defined(NO_DES3) + #define WC_MAX_SYM_KEY_SIZE DES3_KEY_SIZE +#elif !defined(NO_RC4) + #define WC_MAX_SYM_KEY_SIZE RC4_KEY_SIZE +#else + #define WC_MAX_SYM_KEY_SIZE 32 +#endif + + +#if !defined(NO_AES) && defined(HAVE_AES_CBC) +WOLFSSL_API int wc_AesCbcEncryptWithKey(byte* out, const byte* in, word32 inSz, + const byte* key, word32 keySz, + const byte* iv); +WOLFSSL_API int wc_AesCbcDecryptWithKey(byte* out, const byte* in, word32 inSz, + const byte* key, word32 keySz, + const byte* iv); +#endif /* !NO_AES */ + + +#ifndef NO_DES3 +WOLFSSL_API int wc_Des_CbcDecryptWithKey(byte* out, + const byte* in, word32 sz, + const byte* key, const byte* iv); +WOLFSSL_API int wc_Des_CbcEncryptWithKey(byte* out, + const byte* in, word32 sz, + const byte* key, const byte* iv); +WOLFSSL_API int wc_Des3_CbcEncryptWithKey(byte* out, + const byte* in, word32 sz, + const byte* key, const byte* iv); +WOLFSSL_API int wc_Des3_CbcDecryptWithKey(byte* out, + const byte* in, word32 sz, + const byte* key, const byte* iv); +#endif /* !NO_DES3 */ + + + + +#ifdef WOLFSSL_ENCRYPTED_KEYS + struct EncryptedInfo; + WOLFSSL_API int wc_BufferKeyDecrypt(struct EncryptedInfo* info, byte* der, word32 derSz, + const byte* password, int passwordSz, int hashType); + WOLFSSL_API int wc_BufferKeyEncrypt(struct EncryptedInfo* info, byte* der, word32 derSz, + const byte* password, int passwordSz, int hashType); +#endif /* WOLFSSL_ENCRYPTED_KEYS */ + +#ifndef NO_PWDBASED + WOLFSSL_LOCAL int wc_CryptKey(const char* password, int passwordSz, + byte* salt, int saltSz, int iterations, int id, byte* input, int length, + int version, byte* cbcIv, int enc); +#endif + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLF_CRYPT_ENCRYPT_H */ + diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wc_pkcs11.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wc_pkcs11.h new file mode 100644 index 0000000..614f65d --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wc_pkcs11.h @@ -0,0 +1,94 @@ +/* wc_pkcs11.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef _WOLFPKCS11_H_ +#define _WOLFPKCS11_H_ + +#include + +#ifdef HAVE_PKCS11 + +#ifndef WOLF_CRYPTO_CB + #error PKCS11 support requires ./configure --enable-cryptocb or WOLF_CRYPTO_CB to be defined +#endif + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef struct Pkcs11Dev { + void* dlHandle; /* Handle to library */ + CK_FUNCTION_LIST* func; /* Array of functions */ + void* heap; +} Pkcs11Dev; + +typedef struct Pkcs11Token { + CK_FUNCTION_LIST* func; /* Table of PKCS#11 function from lib */ + CK_SLOT_ID slotId; /* Id of slot to use */ + CK_SESSION_HANDLE handle; /* Handle to active session */ + CK_UTF8CHAR_PTR userPin; /* User's PIN to login with */ + CK_ULONG userPinSz; /* Size of user's PIN in bytes */ +} Pkcs11Token; + +typedef struct Pkcs11Session { + CK_FUNCTION_LIST* func; /* Table of PKCS#11 function from lib */ + CK_SLOT_ID slotId; /* Id of slot to use */ + CK_SESSION_HANDLE handle; /* Handle to active session */ +} Pkcs11Session; + +/* Types of keys that can be stored. */ +enum Pkcs11KeyType { + PKCS11_KEY_TYPE_AES_GCM, + PKCS11_KEY_TYPE_AES_CBC, + PKCS11_KEY_TYPE_HMAC, + PKCS11_KEY_TYPE_RSA, + PKCS11_KEY_TYPE_EC, +}; + + +WOLFSSL_API int wc_Pkcs11_Initialize(Pkcs11Dev* dev, const char* library, + void* heap); +WOLFSSL_API void wc_Pkcs11_Finalize(Pkcs11Dev* dev); + +WOLFSSL_API int wc_Pkcs11Token_Init(Pkcs11Token* token, Pkcs11Dev* dev, + int slotId, const char* tokenName, const unsigned char *userPin, + int userPinSz); +WOLFSSL_API void wc_Pkcs11Token_Final(Pkcs11Token* token); +WOLFSSL_API int wc_Pkcs11Token_Open(Pkcs11Token* token, int readWrite); +WOLFSSL_API void wc_Pkcs11Token_Close(Pkcs11Token* token); + +WOLFSSL_API int wc_Pkcs11StoreKey(Pkcs11Token* token, int type, int clear, + void* key); + +WOLFSSL_API int wc_Pkcs11_CryptoDevCb(int devId, wc_CryptoInfo* info, + void* ctx); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_PKCS11 */ + +#endif /* _WOLFPKCS11_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wc_port.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wc_port.h new file mode 100644 index 0000000..024bfd3 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wc_port.h @@ -0,0 +1,762 @@ +/* wc_port.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/wc_port.h +*/ + +#ifndef WOLF_CRYPT_PORT_H +#define WOLF_CRYPT_PORT_H + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/* Detect if compiler supports C99. "NO_WOLF_C99" can be defined in + * user_settings.h to disable checking for C99 support. */ +#if !defined(WOLF_C99) && defined(__STDC_VERSION__) && \ + !defined(WOLFSSL_ARDUINO) && !defined(NO_WOLF_C99) + #if __STDC_VERSION__ >= 199901L + #define WOLF_C99 + #endif +#endif + + +/* GENERIC INCLUDE SECTION */ +#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) + #include + #if (defined(MQX_USE_IO_OLD) && MQX_USE_IO_OLD) || \ + defined(FREESCALE_MQX_5_0) + #include + #else + #include + #endif +#endif + + +/* THREADING/MUTEX SECTION */ +#ifdef USE_WINDOWS_API + #ifdef WOLFSSL_GAME_BUILD + #include "system/xtl.h" + #else + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + #ifndef WOLFSSL_SGX + #if defined(_WIN32_WCE) || defined(WIN32_LEAN_AND_MEAN) + /* On WinCE winsock2.h must be included before windows.h */ + #include + #endif + #include + #endif /* WOLFSSL_SGX */ + #endif +#elif defined(THREADX) + #ifndef SINGLE_THREADED + #ifdef NEED_THREADX_TYPES + #include + #endif + #include + #endif +#elif defined(WOLFSSL_DEOS) + #include "mutexapi.h" +#elif defined(MICRIUM) + /* do nothing, just don't pick Unix */ +#elif defined(FREERTOS) || defined(FREERTOS_TCP) || defined(WOLFSSL_SAFERTOS) + /* do nothing */ +#elif defined(EBSNET) + /* do nothing */ +#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) + /* do nothing */ +#elif defined(FREESCALE_FREE_RTOS) + #include "fsl_os_abstraction.h" +#elif defined(WOLFSSL_VXWORKS) + #include +#elif defined(WOLFSSL_uITRON4) + #include "stddef.h" + #include "kernel.h" +#elif defined(WOLFSSL_uTKERNEL2) + #include "tk/tkernel.h" +#elif defined(WOLFSSL_CMSIS_RTOS) + #include "cmsis_os.h" +#elif defined(WOLFSSL_CMSIS_RTOSv2) + #include "cmsis_os2.h" +#elif defined(WOLFSSL_MDK_ARM) + #if defined(WOLFSSL_MDK5) + #include "cmsis_os.h" + #else + #include + #endif +#elif defined(WOLFSSL_CMSIS_RTOS) + #include "cmsis_os.h" +#elif defined(WOLFSSL_TIRTOS) + #include + #include +#elif defined(WOLFSSL_FROSTED) + #include +#elif defined(INTIME_RTOS) + #include + #include +#elif defined(WOLFSSL_NUCLEUS_1_2) + /* NU_DEBUG needed struct access in nucleus_realloc */ + #define NU_DEBUG + #include "plus/nucleus.h" + #include "nucleus.h" +#elif defined(WOLFSSL_APACHE_MYNEWT) + /* do nothing */ +#elif defined(WOLFSSL_ZEPHYR) + #ifndef SINGLE_THREADED + #include + #endif +#elif defined(WOLFSSL_TELIT_M2MB) + + /* Telit SDK uses C++ compile option (--cpp), which causes link issue + to API's if wrapped in extern "C" */ + #ifdef __cplusplus + } /* extern "C" */ + #endif + + #include "m2mb_types.h" + #include "m2mb_os_types.h" + #include "m2mb_os_api.h" + #include "m2mb_os.h" + #include "m2mb_os_mtx.h" + #ifndef NO_ASN_TIME + #include "m2mb_rtc.h" + #endif + #ifndef NO_FILESYSTEM + #include "m2mb_fs_posix.h" + #endif + + #undef kB /* eliminate conflict in asn.h */ + + #ifdef __cplusplus + extern "C" { + #endif + +#else + #ifndef SINGLE_THREADED + #define WOLFSSL_PTHREADS + #include + #endif + #if (defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)) && \ + !defined(NO_FILESYSTEM) + #include /* for close of BIO */ + #endif +#endif + +/* For FIPS keep the function names the same */ +#ifdef HAVE_FIPS +#define wc_InitMutex InitMutex +#define wc_FreeMutex FreeMutex +#define wc_LockMutex LockMutex +#define wc_UnLockMutex UnLockMutex +#endif /* HAVE_FIPS */ + +#ifdef SINGLE_THREADED + typedef int wolfSSL_Mutex; +#else /* MULTI_THREADED */ + /* FREERTOS comes first to enable use of FreeRTOS Windows simulator only */ + #if defined(FREERTOS) + typedef xSemaphoreHandle wolfSSL_Mutex; + #elif defined(FREERTOS_TCP) + #include "FreeRTOS.h" + #include "semphr.h" + typedef SemaphoreHandle_t wolfSSL_Mutex; + #elif defined(WOLFSSL_SAFERTOS) + typedef struct wolfSSL_Mutex { + signed char mutexBuffer[portQUEUE_OVERHEAD_BYTES]; + xSemaphoreHandle mutex; + } wolfSSL_Mutex; + #elif defined(USE_WINDOWS_API) + typedef CRITICAL_SECTION wolfSSL_Mutex; + #elif defined(WOLFSSL_PTHREADS) + typedef pthread_mutex_t wolfSSL_Mutex; + #elif defined(THREADX) + typedef TX_MUTEX wolfSSL_Mutex; + #elif defined(WOLFSSL_DEOS) + typedef mutex_handle_t wolfSSL_Mutex; + #elif defined(MICRIUM) + typedef OS_MUTEX wolfSSL_Mutex; + #elif defined(EBSNET) + typedef RTP_MUTEX wolfSSL_Mutex; + #elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) + typedef MUTEX_STRUCT wolfSSL_Mutex; + #elif defined(FREESCALE_FREE_RTOS) + typedef mutex_t wolfSSL_Mutex; + #elif defined(WOLFSSL_VXWORKS) + typedef SEM_ID wolfSSL_Mutex; + #elif defined(WOLFSSL_uITRON4) + typedef struct wolfSSL_Mutex { + T_CSEM sem ; + ID id ; + } wolfSSL_Mutex; + #elif defined(WOLFSSL_uTKERNEL2) + typedef struct wolfSSL_Mutex { + T_CSEM sem ; + ID id ; + } wolfSSL_Mutex; + #elif defined(WOLFSSL_MDK_ARM) + #if defined(WOLFSSL_CMSIS_RTOS) + typedef osMutexId wolfSSL_Mutex; + #else + typedef OS_MUT wolfSSL_Mutex; + #endif + #elif defined(WOLFSSL_CMSIS_RTOS) + typedef osMutexId wolfSSL_Mutex; + #elif defined(WOLFSSL_CMSIS_RTOSv2) + typedef osMutexId_t wolfSSL_Mutex; + #elif defined(WOLFSSL_TIRTOS) + typedef ti_sysbios_knl_Semaphore_Handle wolfSSL_Mutex; + #elif defined(WOLFSSL_FROSTED) + typedef mutex_t * wolfSSL_Mutex; + #elif defined(INTIME_RTOS) + typedef RTHANDLE wolfSSL_Mutex; + #elif defined(WOLFSSL_NUCLEUS_1_2) + typedef NU_SEMAPHORE wolfSSL_Mutex; + #elif defined(WOLFSSL_ZEPHYR) + typedef struct k_mutex wolfSSL_Mutex; + #elif defined(WOLFSSL_TELIT_M2MB) + typedef M2MB_OS_MTX_HANDLE wolfSSL_Mutex; + #else + #error Need a mutex type in multithreaded mode + #endif /* USE_WINDOWS_API */ +#endif /* SINGLE_THREADED */ + +/* Enable crypt HW mutex for Freescale MMCAU, PIC32MZ or STM32 */ +#if defined(FREESCALE_MMCAU) || defined(WOLFSSL_MICROCHIP_PIC32MZ) || \ + defined(STM32_CRYPTO) + #ifndef WOLFSSL_CRYPT_HW_MUTEX + #define WOLFSSL_CRYPT_HW_MUTEX 1 + #endif +#endif /* FREESCALE_MMCAU */ + +#ifndef WOLFSSL_CRYPT_HW_MUTEX + #define WOLFSSL_CRYPT_HW_MUTEX 0 +#endif + +#if WOLFSSL_CRYPT_HW_MUTEX + /* wolfSSL_CryptHwMutexInit is called on first wolfSSL_CryptHwMutexLock, + however it's recommended to call this directly on Hw init to avoid possible + race condition where two calls to wolfSSL_CryptHwMutexLock are made at + the same time. */ + int wolfSSL_CryptHwMutexInit(void); + int wolfSSL_CryptHwMutexLock(void); + int wolfSSL_CryptHwMutexUnLock(void); +#else + /* Define stubs, since HW mutex is disabled */ + #define wolfSSL_CryptHwMutexInit() 0 /* Success */ + #define wolfSSL_CryptHwMutexLock() 0 /* Success */ + #define wolfSSL_CryptHwMutexUnLock() (void)0 /* Success */ +#endif /* WOLFSSL_CRYPT_HW_MUTEX */ + +/* Mutex functions */ +WOLFSSL_API int wc_InitMutex(wolfSSL_Mutex*); +WOLFSSL_API wolfSSL_Mutex* wc_InitAndAllocMutex(void); +WOLFSSL_API int wc_FreeMutex(wolfSSL_Mutex*); +WOLFSSL_API int wc_LockMutex(wolfSSL_Mutex*); +WOLFSSL_API int wc_UnLockMutex(wolfSSL_Mutex*); +#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) +/* dynamically set which mutex to use. unlock / lock is controlled by flag */ +typedef void (mutex_cb)(int flag, int type, const char* file, int line); + +WOLFSSL_API int wc_LockMutex_ex(int flag, int type, const char* file, int line); +WOLFSSL_API int wc_SetMutexCb(mutex_cb* cb); +#endif + +/* main crypto initialization function */ +WOLFSSL_API int wolfCrypt_Init(void); +WOLFSSL_API int wolfCrypt_Cleanup(void); + + +/* FILESYSTEM SECTION */ +/* filesystem abstraction layer, used by ssl.c */ +#ifndef NO_FILESYSTEM + +#if defined(EBSNET) + #include "vfapi.h" + #include "vfile.h" + + int ebsnet_fseek(int a, long b, int c); /* Not prototyped in vfile.h per + * EBSnet feedback */ + + #define XFILE int + #define XFOPEN(NAME, MODE) vf_open((const char *)NAME, VO_RDONLY, 0); + #define XFSEEK ebsnet_fseek + #define XFTELL vf_tell + #define XREWIND vf_rewind + #define XFREAD(BUF, SZ, AMT, FD) vf_read(FD, BUF, SZ*AMT) + #define XFWRITE(BUF, SZ, AMT, FD) vf_write(FD, BUF, SZ*AMT) + #define XFCLOSE vf_close + #define XSEEK_END VSEEK_END + #define XBADFILE -1 + #define XFGETS(b,s,f) -2 /* Not ported yet */ +#elif defined(LSR_FS) + #include + #define XFILE struct fs_file* + #define XFOPEN(NAME, MODE) fs_open((char*)NAME); + #define XFSEEK(F, O, W) (void)F + #define XFTELL(F) (F)->len + #define XREWIND(F) (void)F + #define XFREAD(BUF, SZ, AMT, F) fs_read(F, (char*)BUF, SZ*AMT) + #define XFWRITE(BUF, SZ, AMT, F) fs_write(F, (char*)BUF, SZ*AMT) + #define XFCLOSE fs_close + #define XSEEK_END 0 + #define XBADFILE NULL + #define XFGETS(b,s,f) -2 /* Not ported yet */ +#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) + #define XFILE MQX_FILE_PTR + #define XFOPEN fopen + #define XFSEEK fseek + #define XFTELL ftell + #define XREWIND(F) fseek(F, 0, IO_SEEK_SET) + #define XFREAD fread + #define XFWRITE fwrite + #define XFCLOSE fclose + #define XSEEK_END IO_SEEK_END + #define XBADFILE NULL + #define XFGETS fgets +#elif defined(WOLFSSL_DEOS) + #define NO_FILESYSTEM + #warning "TODO - DDC-I Certifiable Fast File System for Deos is not integrated" + //#define XFILE bfd * + +#elif defined(MICRIUM) + #include + #define XFILE FS_FILE* + #define XFOPEN fs_fopen + #define XFSEEK fs_fseek + #define XFTELL fs_ftell + #define XREWIND fs_rewind + #define XFREAD fs_fread + #define XFWRITE fs_fwrite + #define XFCLOSE fs_fclose + #define XSEEK_END FS_SEEK_END + #define XBADFILE NULL + #define XFGETS(b,s,f) -2 /* Not ported yet */ +#elif defined(WOLFSSL_NUCLEUS_1_2) + #include "fal/inc/fal.h" + #define XFILE FILE* + #define XFOPEN fopen + #define XFSEEK fseek + #define XFTELL ftell + #define XREWIND rewind + #define XFREAD fread + #define XFWRITE fwrite + #define XFCLOSE fclose + #define XSEEK_END PSEEK_END + #define XBADFILE NULL +#elif defined(WOLFSSL_APACHE_MYNEWT) + #include + #define XFILE struct fs_file* + + #define XFOPEN mynewt_fopen + #define XFSEEK mynewt_fseek + #define XFTELL mynewt_ftell + #define XREWIND mynewt_rewind + #define XFREAD mynewt_fread + #define XFWRITE mynewt_fwrite + #define XFCLOSE mynewt_fclose + #define XSEEK_END 2 + #define XBADFILE NULL + #define XFGETS(b,s,f) -2 /* Not ported yet */ +#elif defined(WOLFSSL_ZEPHYR) + #include + + #define XFILE struct fs_file_t* + #define STAT struct fs_dirent + + XFILE z_fs_open(const char* filename, const char* perm); + int z_fs_close(XFILE file); + + #define XFOPEN z_fs_open + #define XFCLOSE z_fs_close + #define XFSEEK fs_seek + #define XFTELL fs_tell + #define XFREWIND fs_rewind + #define XREWIND(F) fs_seek(F, 0, FS_SEEK_SET) + #define XFREAD(P,S,N,F) fs_read(F, P, S*N) + #define XFWRITE(P,S,N,F) fs_write(F, P, S*N) + #define XSEEK_END FS_SEEK_END + #define XBADFILE NULL + #define XFGETS(b,s,f) -2 /* Not ported yet */ + +#elif defined(WOLFSSL_TELIT_M2MB) + #define XFILE INT32 + #define XFOPEN(NAME, MODE) m2mb_fs_open((NAME), 0, (MODE)) + #define XFSEEK(F, O, W) m2mb_fs_lseek((F), (O), (W)) + #define XFTELL(F) m2mb_fs_lseek((F), 0, M2MB_SEEK_END) + #define XREWIND(F) (void)F + #define XFREAD(BUF, SZ, AMT, F) m2mb_fs_read((F), (BUF), (SZ)*(AMT)) + #define XFWRITE(BUF, SZ, AMT, F) m2mb_fs_write((F), (BUF), (SZ)*(AMT)) + #define XFCLOSE m2mb_fs_close + #define XSEEK_END M2MB_SEEK_END + #define XBADFILE -1 + #define XFGETS(b,s,f) -2 /* Not ported yet */ + +#elif defined(WOLFSSL_USER_FILESYSTEM) + /* To be defined in user_settings.h */ +#else + /* stdio, default case */ + #include + #define XFILE FILE* + #if defined(WOLFSSL_MDK_ARM) + extern FILE * wolfSSL_fopen(const char *name, const char *mode) ; + #define XFOPEN wolfSSL_fopen + #else + #define XFOPEN fopen + #endif + #define XFSEEK fseek + #define XFTELL ftell + #define XREWIND rewind + #define XFREAD fread + #define XFWRITE fwrite + #define XFCLOSE fclose + #define XSEEK_END SEEK_END + #define XBADFILE NULL + #define XFGETS fgets + + #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR)\ + && !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2) + #include + #include + #include + #endif +#endif + + #ifndef MAX_FILENAME_SZ + #define MAX_FILENAME_SZ 256 /* max file name length */ + #endif + #ifndef MAX_PATH + #define MAX_PATH 256 + #endif + +#if !defined(NO_WOLFSSL_DIR) && !defined(WOLFSSL_NUCLEUS) && \ + !defined(WOLFSSL_NUCLEUS_1_2) + typedef struct ReadDirCtx { + #ifdef USE_WINDOWS_API + WIN32_FIND_DATAA FindFileData; + HANDLE hFind; + #elif defined(WOLFSSL_ZEPHYR) + struct fs_dirent entry; + struct fs_dir_t dir; + struct fs_dirent s; + struct fs_dir_t* dirp; + + #elif defined(WOLFSSL_TELIT_M2MB) + M2MB_DIR_T* dir; + struct M2MB_DIRENT* entry; + struct M2MB_STAT s; + #else + struct dirent* entry; + DIR* dir; + struct stat s; + #endif + char name[MAX_FILENAME_SZ]; + } ReadDirCtx; + + #define WC_READDIR_NOFILE -1 + + WOLFSSL_API int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name); + WOLFSSL_API int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name); + WOLFSSL_API void wc_ReadDirClose(ReadDirCtx* ctx); +#endif /* !NO_WOLFSSL_DIR */ + +#endif /* !NO_FILESYSTEM */ + + +/* MIN/MAX MACRO SECTION */ +/* Windows API defines its own min() macro. */ +#if defined(USE_WINDOWS_API) + #if defined(min) || defined(WOLFSSL_MYSQL_COMPATIBLE) + #define WOLFSSL_HAVE_MIN + #endif /* min */ + #if defined(max) || defined(WOLFSSL_MYSQL_COMPATIBLE) + #define WOLFSSL_HAVE_MAX + #endif /* max */ +#endif /* USE_WINDOWS_API */ + + +/* TIME SECTION */ +/* Time functions */ +#ifndef NO_ASN_TIME +#if defined(USER_TIME) + /* Use our gmtime and time_t/struct tm types. + Only needs seconds since EPOCH using XTIME function. + time_t XTIME(time_t * timer) {} + */ + #define WOLFSSL_GMTIME + #ifndef HAVE_TM_TYPE + #define USE_WOLF_TM + #endif + #ifndef HAVE_TIME_T_TYPE + #define USE_WOLF_TIME_T + #endif + +#elif defined(TIME_OVERRIDES) + /* Override XTIME() and XGMTIME() functionality. + Requires user to provide these functions: + time_t XTIME(time_t * timer) {} + struct tm* XGMTIME(const time_t* timer, struct tm* tmp) {} + */ + #ifndef HAVE_TIME_T_TYPE + #define USE_WOLF_TIME_T + #endif + #ifndef HAVE_TM_TYPE + #define USE_WOLF_TM + #endif + #define NEED_TMP_TIME + +#elif defined(WOLFSSL_XILINX) && defined(FREERTOS) + #define USER_TIME + #include + +#elif defined(HAVE_RTP_SYS) + #include "os.h" /* dc_rtc_api needs */ + #include "dc_rtc_api.h" /* to get current time */ + + /* uses parital structures */ + #define XTIME(tl) (0) + #define XGMTIME(c, t) rtpsys_gmtime((c)) + +#elif defined(WOLFSSL_DEOS) + #define XTIME(t1) deos_time((t1)) + #define WOLFSSL_GMTIME + #define USE_WOLF_TM + #define USE_WOLF_TIME_T + +#elif defined(MICRIUM) + #include + #include + #define XTIME(t1) micrium_time((t1)) + #define WOLFSSL_GMTIME + +#elif defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP) + #include + #define XTIME(t1) pic32_time((t1)) + #define XGMTIME(c, t) gmtime((c)) + +#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) + #ifdef FREESCALE_MQX_4_0 + #include + extern time_t mqx_time(time_t* timer); + #else + #define HAVE_GMTIME_R + #endif + #define XTIME(t1) mqx_time((t1)) + +#elif defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS) + #include + #ifndef XTIME + /*extern time_t ksdk_time(time_t* timer);*/ + #define XTIME(t1) ksdk_time((t1)) + #endif + #define XGMTIME(c, t) gmtime((c)) + +#elif defined(WOLFSSL_ATMEL) && defined(WOLFSSL_ATMEL_TIME) + #define XTIME(t1) atmel_get_curr_time_and_date((t1)) + #define WOLFSSL_GMTIME + #define USE_WOLF_TM + #define USE_WOLF_TIME_T + +#elif defined(WOLFSSL_WICED) + #include + time_t wiced_pseudo_unix_epoch_time(time_t * timer); + #define XTIME(t1) wiced_pseudo_unix_epoch_time((t1)) + #define HAVE_GMTIME_R + +#elif defined(IDIRECT_DEV_TIME) + /*Gets the timestamp from cloak software owned by VT iDirect + in place of time() from */ + #include + #define XTIME(t1) idirect_time((t1)) + #define XGMTIME(c, t) gmtime((c)) + +#elif defined(_WIN32_WCE) + #include + #define XTIME(t1) windows_time((t1)) + #define WOLFSSL_GMTIME + +#elif defined(WOLFSSL_APACHE_MYNEWT) + #include "os/os_time.h" + #define XTIME(t1) mynewt_time((t1)) + #define WOLFSSL_GMTIME + #define USE_WOLF_TM + #define USE_WOLF_TIME_T + +#elif defined(WOLFSSL_ZEPHYR) + #ifndef _POSIX_C_SOURCE + #include + #else + #include + #endif + + typedef signed int time_t; + + time_t z_time(time_t *timer); + + #define XTIME(tl) z_time((tl)) + #define XGMTIME(c, t) gmtime((c)) + #define WOLFSSL_GMTIME + + #define USE_WOLF_TM + +#elif defined(WOLFSSL_TELIT_M2MB) + typedef long time_t; + extern time_t m2mb_xtime(time_t * timer); + #define XTIME(tl) m2mb_xtime((tl)) + #ifdef WOLFSSL_TLS13 + extern time_t m2mb_xtime_ms(time_t * timer); + #define XTIME_MS(tl) m2mb_xtime_ms((tl)) + #endif + #ifndef NO_CRYPT_BENCHMARK + extern double m2mb_xtime_bench(int reset); + #define WOLFSSL_CURRTIME_REMAP m2mb_xtime_bench + #endif + #define XGMTIME(c, t) gmtime((c)) + #define WOLFSSL_GMTIME + #define USE_WOLF_TM + +#else + /* default */ + /* uses complete facility */ + #include + #if defined(HAVE_SYS_TIME_H) + #include + #endif + + /* PowerPC time_t is int */ + #ifdef __PPC__ + #define TIME_T_NOT_64BIT + #endif +#endif + +#ifdef SIZEOF_TIME_T + /* check if size of time_t from autoconf is less than 8 bytes (64bits) */ + #if SIZEOF_TIME_T < 8 + #undef TIME_T_NOT_64BIT + #define TIME_T_NOT_64BIT + #endif +#endif +#ifdef TIME_T_NOT_LONG + /* one old reference to TIME_T_NOT_LONG in GCC-ARM example README + * this keeps support for the old macro name */ + #undef TIME_T_NOT_64BIT + #define TIME_T_NOT_64BIT +#endif + +/* Map default time functions */ +#if !defined(XTIME) && !defined(TIME_OVERRIDES) && !defined(USER_TIME) + #ifdef TEST_BEFORE_DATE + #define XTIME(tl) (946681200UL) /* Jan 1, 2000 */ + #else + #define XTIME(tl) time((tl)) + #endif +#endif +#if !defined(XGMTIME) && !defined(TIME_OVERRIDES) + #if defined(WOLFSSL_GMTIME) || !defined(HAVE_GMTIME_R) || defined(WOLF_C99) + #define XGMTIME(c, t) gmtime((c)) + #else + #define XGMTIME(c, t) gmtime_r((c), (t)) + #define NEED_TMP_TIME + #endif +#endif +#if !defined(XVALIDATE_DATE) && !defined(HAVE_VALIDATE_DATE) + #define USE_WOLF_VALIDDATE + #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t)) +#endif + +/* wolf struct tm and time_t */ +#if defined(USE_WOLF_TM) + struct tm { + int tm_sec; /* seconds after the minute [0-60] */ + int tm_min; /* minutes after the hour [0-59] */ + int tm_hour; /* hours since midnight [0-23] */ + int tm_mday; /* day of the month [1-31] */ + int tm_mon; /* months since January [0-11] */ + int tm_year; /* years since 1900 */ + int tm_wday; /* days since Sunday [0-6] */ + int tm_yday; /* days since January 1 [0-365] */ + int tm_isdst; /* Daylight Savings Time flag */ + long tm_gmtoff; /* offset from CUT in seconds */ + char *tm_zone; /* timezone abbreviation */ + }; +#endif /* USE_WOLF_TM */ +#if defined(USE_WOLF_TIME_T) + typedef long time_t; +#endif +#if defined(USE_WOLF_SUSECONDS_T) + typedef long suseconds_t; +#endif +#if defined(USE_WOLF_TIMEVAL_T) + struct timeval + { + time_t tv_sec; + suseconds_t tv_usec; + }; +#endif + + /* forward declarations */ +#if defined(USER_TIME) + struct tm* gmtime(const time_t* timer); + extern time_t XTIME(time_t * timer); + + #ifdef STACK_TRAP + /* for stack trap tracking, don't call os gmtime on OS X/linux, + uses a lot of stack spce */ + extern time_t time(time_t * timer); + #define XTIME(tl) time((tl)) + #endif /* STACK_TRAP */ + +#elif defined(TIME_OVERRIDES) + extern time_t XTIME(time_t * timer); + extern struct tm* XGMTIME(const time_t* timer, struct tm* tmp); +#elif defined(WOLFSSL_GMTIME) + struct tm* gmtime(const time_t* timer); +#endif +#endif /* NO_ASN_TIME */ + + +#ifndef WOLFSSL_LEANPSK + char* mystrnstr(const char* s1, const char* s2, unsigned int n); +#endif + +#ifndef FILE_BUFFER_SIZE + #define FILE_BUFFER_SIZE 1024 /* default static file buffer size for input, + will use dynamic buffer if not big enough */ +#endif + +#ifdef HAVE_CAVIUM_OCTEON_SYNC + /* By default, the OCTEON's global variables are all thread local. This + * tag allows them to be shared between threads. */ + #include "cvmx-platform.h" + #define WOLFSSL_GLOBAL CVMX_SHARED +#else + #define WOLFSSL_GLOBAL +#endif + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLF_CRYPT_PORT_H */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wolfevent.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wolfevent.h new file mode 100644 index 0000000..0f8c08c --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wolfevent.h @@ -0,0 +1,120 @@ +/* wolfevent.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef _WOLF_EVENT_H_ +#define _WOLF_EVENT_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef SINGLE_THREADED + #include +#endif + +typedef struct WOLF_EVENT WOLF_EVENT; +typedef unsigned short WOLF_EVENT_FLAG; + +typedef enum WOLF_EVENT_TYPE { + WOLF_EVENT_TYPE_NONE, +#ifdef WOLFSSL_ASYNC_CRYPT + WOLF_EVENT_TYPE_ASYNC_WOLFSSL, /* context is WOLFSSL* */ + WOLF_EVENT_TYPE_ASYNC_WOLFCRYPT, /* context is WC_ASYNC_DEV */ + WOLF_EVENT_TYPE_ASYNC_FIRST = WOLF_EVENT_TYPE_ASYNC_WOLFSSL, + WOLF_EVENT_TYPE_ASYNC_LAST = WOLF_EVENT_TYPE_ASYNC_WOLFCRYPT, +#endif /* WOLFSSL_ASYNC_CRYPT */ +} WOLF_EVENT_TYPE; + +typedef enum WOLF_EVENT_STATE { + WOLF_EVENT_STATE_READY, + WOLF_EVENT_STATE_PENDING, + WOLF_EVENT_STATE_DONE, +} WOLF_EVENT_STATE; + +struct WOLF_EVENT { + /* double linked list */ + WOLF_EVENT* next; + WOLF_EVENT* prev; + + void* context; + union { + void* ptr; +#ifdef WOLFSSL_ASYNC_CRYPT + struct WC_ASYNC_DEV* async; +#endif + } dev; +#ifdef HAVE_CAVIUM + word64 reqId; + #ifdef WOLFSSL_NITROX_DEBUG + word32 pendCount; + #endif +#endif +#ifndef WC_NO_ASYNC_THREADING + pthread_t threadId; +#endif + int ret; /* Async return code */ + unsigned int flags; + WOLF_EVENT_TYPE type; + WOLF_EVENT_STATE state; +}; + +enum WOLF_POLL_FLAGS { + WOLF_POLL_FLAG_CHECK_HW = 0x01, +}; + +typedef struct { + WOLF_EVENT* head; /* head of queue */ + WOLF_EVENT* tail; /* tail of queue */ +#ifndef SINGLE_THREADED + wolfSSL_Mutex lock; /* queue lock */ +#endif + int count; +} WOLF_EVENT_QUEUE; + + +#ifdef HAVE_WOLF_EVENT + +/* Event */ +WOLFSSL_API int wolfEvent_Init(WOLF_EVENT* event, WOLF_EVENT_TYPE type, void* context); +WOLFSSL_API int wolfEvent_Poll(WOLF_EVENT* event, WOLF_EVENT_FLAG flags); + +/* Event Queue */ +WOLFSSL_API int wolfEventQueue_Init(WOLF_EVENT_QUEUE* queue); +WOLFSSL_API int wolfEventQueue_Push(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event); +WOLFSSL_API int wolfEventQueue_Pop(WOLF_EVENT_QUEUE* queue, WOLF_EVENT** event); +WOLFSSL_API int wolfEventQueue_Poll(WOLF_EVENT_QUEUE* queue, void* context_filter, + WOLF_EVENT** events, int maxEvents, WOLF_EVENT_FLAG flags, int* eventCount); +WOLFSSL_API int wolfEventQueue_Count(WOLF_EVENT_QUEUE* queue); +WOLFSSL_API void wolfEventQueue_Free(WOLF_EVENT_QUEUE* queue); + +/* the queue mutex must be locked prior to calling these */ +WOLFSSL_API int wolfEventQueue_Add(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event); +WOLFSSL_API int wolfEventQueue_Remove(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event); + + +#endif /* HAVE_WOLF_EVENT */ + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* _WOLF_EVENT_H_ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wolfmath.h b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wolfmath.h new file mode 100644 index 0000000..1db3223 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfcrypt/wolfmath.h @@ -0,0 +1,96 @@ +/* wolfmath.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef __WOLFMATH_H__ +#define __WOLFMATH_H__ + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef WOLFSSL_PUBLIC_MP + #define MP_API WOLFSSL_API +#else + #define MP_API WOLFSSL_LOCAL +#endif + +#ifndef MIN + #define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +#ifndef MAX + #define MAX(x,y) ((x)>(y)?(x):(y)) +#endif + +/* timing resistance array */ +#if !defined(WC_NO_CACHE_RESISTANT) && \ + ((defined(HAVE_ECC) && defined(ECC_TIMING_RESISTANT)) || \ + (defined(USE_FAST_MATH) && defined(TFM_TIMING_RESISTANT))) + + extern const wolfssl_word wc_off_on_addr[2]; +#endif + + +/* common math functions */ +MP_API int get_digit_count(mp_int* a); +MP_API mp_digit get_digit(mp_int* a, int n); +MP_API int get_rand_digit(WC_RNG* rng, mp_digit* d); + +WOLFSSL_API int mp_rand(mp_int* a, int digits, WC_RNG* rng); + +enum { + /* format type */ + WC_TYPE_HEX_STR = 1, + WC_TYPE_UNSIGNED_BIN = 2, +}; + +WOLFSSL_API int wc_export_int(mp_int* mp, byte* buf, word32* len, + word32 keySz, int encType); + +#ifdef HAVE_WOLF_BIGINT + #if !defined(WOLF_BIGINT_DEFINED) + /* raw big integer */ + typedef struct WC_BIGINT { + byte* buf; + word32 len; + void* heap; + } WC_BIGINT; + #define WOLF_BIGINT_DEFINED + #endif + + WOLFSSL_LOCAL void wc_bigint_init(WC_BIGINT* a); + WOLFSSL_LOCAL int wc_bigint_alloc(WC_BIGINT* a, word32 sz); + WOLFSSL_LOCAL int wc_bigint_from_unsigned_bin(WC_BIGINT* a, const byte* in, word32 inlen); + WOLFSSL_LOCAL int wc_bigint_to_unsigned_bin(WC_BIGINT* a, byte* out, word32* outlen); + WOLFSSL_LOCAL void wc_bigint_zero(WC_BIGINT* a); + WOLFSSL_LOCAL void wc_bigint_free(WC_BIGINT* a); + + WOLFSSL_LOCAL int wc_mp_to_bigint(mp_int* src, WC_BIGINT* dst); + WOLFSSL_LOCAL int wc_mp_to_bigint_sz(mp_int* src, WC_BIGINT* dst, word32 sz); + WOLFSSL_LOCAL int wc_bigint_to_mp(WC_BIGINT* src, mp_int* dst); +#endif /* HAVE_WOLF_BIGINT */ + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* __WOLFMATH_H__ */ diff --git a/wolfssl_hlavickove_subory/wolfssl/wolfio.h b/wolfssl_hlavickove_subory/wolfssl/wolfio.h new file mode 100644 index 0000000..7db5d06 --- /dev/null +++ b/wolfssl_hlavickove_subory/wolfssl/wolfio.h @@ -0,0 +1,582 @@ +/* io.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfio.h +*/ + +#ifndef WOLFSSL_IO_H +#define WOLFSSL_IO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Micrium uses NetSock I/O callbacks in wolfio.c */ +#if !defined(WOLFSSL_USER_IO) + /* OCSP and CRL_IO require HTTP client */ + #if defined(HAVE_OCSP) || defined(HAVE_CRL_IO) + #ifndef HAVE_HTTP_CLIENT + #define HAVE_HTTP_CLIENT + #endif + #endif +#endif + +#if !defined(WOLFSSL_USER_IO) + /* Micrium uses NetSock I/O callbacks in wolfio.c */ + #if !defined(USE_WOLFSSL_IO) && !defined(MICRIUM) && \ + !defined(WOLFSSL_CONTIKI) && !defined(WOLFSSL_NO_SOCK) + #define USE_WOLFSSL_IO + #endif +#endif + + +#if defined(USE_WOLFSSL_IO) || defined(HAVE_HTTP_CLIENT) + +#ifdef HAVE_LIBZ + #include "zlib.h" +#endif + +#ifndef USE_WINDOWS_API + #if defined(WOLFSSL_LWIP) && !defined(WOLFSSL_APACHE_MYNEWT) + /* lwIP needs to be configured to use sockets API in this mode */ + /* LWIP_SOCKET 1 in lwip/opt.h or in build */ + #include "lwip/sockets.h" + #ifndef LWIP_PROVIDE_ERRNO + #include + #define LWIP_PROVIDE_ERRNO 1 + #endif + #elif defined(FREESCALE_MQX) + #include + #include + #elif defined(FREESCALE_KSDK_MQX) + #include + #elif (defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)) + #include "rl_net.h" + #include "errno.h" + #elif defined(WOLFSSL_CMSIS_RTOS) + #include "cmsis_os.h" + #elif defined(WOLFSSL_CMSIS_RTOSv2) + #include "cmsis_os2.h" + #elif defined(WOLFSSL_TIRTOS) + #include + #elif defined(FREERTOS_TCP) + #include "FreeRTOS_Sockets.h" + #elif defined(WOLFSSL_IAR_ARM) + /* nothing */ + #elif defined(WOLFSSL_VXWORKS) + #include + #include + #elif defined(WOLFSSL_NUCLEUS_1_2) + #include + #include + #elif defined(WOLFSSL_ATMEL) + #include "socket/include/socket.h" + #elif defined(INTIME_RTOS) + #undef MIN + #undef MAX + #include + #include + #include + #include + #include + #include + /* defines these, to avoid conflict, do undef */ + #undef SOCKADDR + #undef SOCKADDR_IN + #elif defined(WOLFSSL_PRCONNECT_PRO) + #include + #include + #include + #include + #include + #include + #include + #elif defined(WOLFSSL_SGX) + #include + #elif defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP) + #include + #elif defined(WOLFSSL_DEOS) + #include + #include + #include + #elif defined(WOLFSSL_ZEPHYR) + #include + #elif !defined(WOLFSSL_NO_SOCK) + #include + #include + #ifndef EBSNET + #include + #endif + #include + #define XFCNTL(fd, flag, block) fcntl((fd), (flag), (block)) + + #if defined(HAVE_RTP_SYS) + #include + #elif defined(EBSNET) + #include "rtipapi.h" /* errno */ + #include "socket.h" + #elif !defined(DEVKITPRO) && !defined(WOLFSSL_PICOTCP) \ + && !defined(WOLFSSL_CONTIKI) && !defined(WOLFSSL_WICED) \ + && !defined(WOLFSSL_GNRC) && !defined(WOLFSSL_RIOT_OS) + #include + #include + #include + #include + #ifdef __PPU + #include + #else + #include + #endif + #endif + #endif +#endif /* USE_WINDOWS_API */ + +#ifdef __sun + #include +#endif + +#ifdef USE_WINDOWS_API + /* no epipe yet */ + #ifndef WSAEPIPE + #define WSAEPIPE -12345 + #endif + #define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK + #define SOCKET_EAGAIN WSAETIMEDOUT + #define SOCKET_ECONNRESET WSAECONNRESET + #define SOCKET_EINTR WSAEINTR + #define SOCKET_EPIPE WSAEPIPE + #define SOCKET_ECONNREFUSED WSAENOTCONN + #define SOCKET_ECONNABORTED WSAECONNABORTED +#elif defined(__PPU) + #define SOCKET_EWOULDBLOCK SYS_NET_EWOULDBLOCK + #define SOCKET_EAGAIN SYS_NET_EAGAIN + #define SOCKET_ECONNRESET SYS_NET_ECONNRESET + #define SOCKET_EINTR SYS_NET_EINTR + #define SOCKET_EPIPE SYS_NET_EPIPE + #define SOCKET_ECONNREFUSED SYS_NET_ECONNREFUSED + #define SOCKET_ECONNABORTED SYS_NET_ECONNABORTED +#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) + #if MQX_USE_IO_OLD + /* RTCS old I/O doesn't have an EWOULDBLOCK */ + #define SOCKET_EWOULDBLOCK EAGAIN + #define SOCKET_EAGAIN EAGAIN + #define SOCKET_ECONNRESET RTCSERR_TCP_CONN_RESET + #define SOCKET_EINTR EINTR + #define SOCKET_EPIPE EPIPE + #define SOCKET_ECONNREFUSED RTCSERR_TCP_CONN_REFUSED + #define SOCKET_ECONNABORTED RTCSERR_TCP_CONN_ABORTED + #else + #define SOCKET_EWOULDBLOCK NIO_EWOULDBLOCK + #define SOCKET_EAGAIN NIO_EAGAIN + #define SOCKET_ECONNRESET NIO_ECONNRESET + #define SOCKET_EINTR NIO_EINTR + #define SOCKET_EPIPE NIO_EPIPE + #define SOCKET_ECONNREFUSED NIO_ECONNREFUSED + #define SOCKET_ECONNABORTED NIO_ECONNABORTED + #endif +#elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_KEIL_TCP_NET) + #define SOCKET_EWOULDBLOCK BSD_ERROR_WOULDBLOCK + #define SOCKET_EAGAIN BSD_ERROR_LOCKED + #define SOCKET_ECONNRESET BSD_ERROR_CLOSED + #define SOCKET_EINTR BSD_ERROR + #define SOCKET_EPIPE BSD_ERROR + #define SOCKET_ECONNREFUSED BSD_ERROR + #define SOCKET_ECONNABORTED BSD_ERROR +#elif defined(WOLFSSL_PICOTCP) + #define SOCKET_EWOULDBLOCK PICO_ERR_EAGAIN + #define SOCKET_EAGAIN PICO_ERR_EAGAIN + #define SOCKET_ECONNRESET PICO_ERR_ECONNRESET + #define SOCKET_EINTR PICO_ERR_EINTR + #define SOCKET_EPIPE PICO_ERR_EIO + #define SOCKET_ECONNREFUSED PICO_ERR_ECONNREFUSED + #define SOCKET_ECONNABORTED PICO_ERR_ESHUTDOWN +#elif defined(FREERTOS_TCP) + #define SOCKET_EWOULDBLOCK FREERTOS_EWOULDBLOCK + #define SOCKET_EAGAIN FREERTOS_EWOULDBLOCK + #define SOCKET_ECONNRESET FREERTOS_SOCKET_ERROR + #define SOCKET_EINTR FREERTOS_SOCKET_ERROR + #define SOCKET_EPIPE FREERTOS_SOCKET_ERROR + #define SOCKET_ECONNREFUSED FREERTOS_SOCKET_ERROR + #define SOCKET_ECONNABORTED FREERTOS_SOCKET_ERROR +#elif defined(WOLFSSL_NUCLEUS_1_2) + #define SOCKET_EWOULDBLOCK NU_WOULD_BLOCK + #define SOCKET_EAGAIN NU_WOULD_BLOCK + #define SOCKET_ECONNRESET NU_NOT_CONNECTED + #define SOCKET_EINTR NU_NOT_CONNECTED + #define SOCKET_EPIPE NU_NOT_CONNECTED + #define SOCKET_ECONNREFUSED NU_CONNECTION_REFUSED + #define SOCKET_ECONNABORTED NU_NOT_CONNECTED +#elif defined(WOLFSSL_DEOS) + #define SOCKET_EWOULDBLOCK EAGAIN + #define SOCKET_EAGAIN EAGAIN + #define SOCKET_ECONNRESET EINTR + #define SOCKET_EINTR EINTR + #define SOCKET_EPIPE EPIPE + #define SOCKET_ECONNREFUSED SOCKET_ERROR + #define SOCKET_ECONNABORTED SOCKET_ERROR +#else + #define SOCKET_EWOULDBLOCK EWOULDBLOCK + #define SOCKET_EAGAIN EAGAIN + #define SOCKET_ECONNRESET ECONNRESET + #define SOCKET_EINTR EINTR + #define SOCKET_EPIPE EPIPE + #define SOCKET_ECONNREFUSED ECONNREFUSED + #define SOCKET_ECONNABORTED ECONNABORTED +#endif /* USE_WINDOWS_API */ + +#ifdef DEVKITPRO + /* from network.h */ + int net_send(int, const void*, int, unsigned int); + int net_recv(int, void*, int, unsigned int); + #define SEND_FUNCTION net_send + #define RECV_FUNCTION net_recv +#elif defined(WOLFSSL_LWIP) && !defined(WOLFSSL_APACHE_MYNEWT) + #define SEND_FUNCTION lwip_send + #define RECV_FUNCTION lwip_recv +#elif defined(WOLFSSL_PICOTCP) + #define SEND_FUNCTION pico_send + #define RECV_FUNCTION pico_recv +#elif defined(FREERTOS_TCP) + #define RECV_FUNCTION(a,b,c,d) FreeRTOS_recv((Socket_t)(a),(void*)(b), (size_t)(c), (BaseType_t)(d)) + #define SEND_FUNCTION(a,b,c,d) FreeRTOS_send((Socket_t)(a),(void*)(b), (size_t)(c), (BaseType_t)(d)) +#elif defined(WOLFSSL_VXWORKS) + #define SEND_FUNCTION send + #define RECV_FUNCTION recv +#elif defined(WOLFSSL_NUCLEUS_1_2) + #define SEND_FUNCTION NU_Send + #define RECV_FUNCTION NU_Recv +#elif defined(WOLFSSL_ZEPHYR) + #ifndef WOLFSSL_MAX_SEND_SZ + #define WOLFSSL_MAX_SEND_SZ 256 + #endif + + #define SEND_FUNCTION send + #define RECV_FUNCTION recv +#else + #define SEND_FUNCTION send + #define RECV_FUNCTION recv + #if !defined(HAVE_SOCKADDR) && !defined(WOLFSSL_NO_SOCK) + #define HAVE_SOCKADDR + #endif +#endif + +#ifdef USE_WINDOWS_API + typedef unsigned int SOCKET_T; +#else + typedef int SOCKET_T; +#endif + +#ifndef WOLFSSL_NO_SOCK + #ifndef XSOCKLENT + #ifdef USE_WINDOWS_API + #define XSOCKLENT int + #else + #define XSOCKLENT socklen_t + #endif + #endif + + /* Socket Addr Support */ + #ifdef HAVE_SOCKADDR + typedef struct sockaddr SOCKADDR; + typedef struct sockaddr_storage SOCKADDR_S; + typedef struct sockaddr_in SOCKADDR_IN; + #ifdef WOLFSSL_IPV6 + typedef struct sockaddr_in6 SOCKADDR_IN6; + #endif + typedef struct hostent HOSTENT; + #endif /* HAVE_SOCKADDR */ + + /* use gethostbyname for c99 */ + #ifdef WOLF_C99 + #undef HAVE_GETADDRINFO + #endif + + #ifdef HAVE_GETADDRINFO + typedef struct addrinfo ADDRINFO; + #endif +#endif /* WOLFSSL_NO_SOCK */ + + +/* IO API's */ +#ifdef HAVE_IO_TIMEOUT + WOLFSSL_API int wolfIO_SetBlockingMode(SOCKET_T sockfd, int non_blocking); + WOLFSSL_API void wolfIO_SetTimeout(int to_sec); + WOLFSSL_API int wolfIO_Select(SOCKET_T sockfd, int to_sec); +#endif +WOLFSSL_API int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, + unsigned short port, int to_sec); +WOLFSSL_API int wolfIO_Send(SOCKET_T sd, char *buf, int sz, int wrFlags); +WOLFSSL_API int wolfIO_Recv(SOCKET_T sd, char *buf, int sz, int rdFlags); + +#endif /* USE_WOLFSSL_IO || HAVE_HTTP_CLIENT */ + +#ifndef WOLFSSL_NO_SOCK +#ifdef USE_WINDOWS_API + #ifndef CloseSocket + #define CloseSocket(s) closesocket(s) + #endif + #define StartTCP() { WSADATA wsd; WSAStartup(0x0002, &wsd); } +#elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) + #ifndef CloseSocket + extern int closesocket(int); + #define CloseSocket(s) closesocket(s) + #endif + #define StartTCP() +#else + #ifndef CloseSocket + #define CloseSocket(s) close(s) + #endif + #define StartTCP() + #ifdef FREERTOS_TCP_WINSIM + extern int close(int); + #endif +#endif +#endif /* WOLFSSL_NO_SOCK */ + + +WOLFSSL_API int BioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx); +WOLFSSL_API int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx); +#if defined(USE_WOLFSSL_IO) + /* default IO callbacks */ + WOLFSSL_API int EmbedReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx); + WOLFSSL_API int EmbedSend(WOLFSSL* ssl, char* buf, int sz, void* ctx); + + #ifdef WOLFSSL_DTLS + WOLFSSL_API int EmbedReceiveFrom(WOLFSSL* ssl, char* buf, int sz, void*); + WOLFSSL_API int EmbedSendTo(WOLFSSL* ssl, char* buf, int sz, void* ctx); + WOLFSSL_API int EmbedGenerateCookie(WOLFSSL* ssl, unsigned char* buf, + int sz, void*); + #ifdef WOLFSSL_MULTICAST + WOLFSSL_API int EmbedReceiveFromMcast(WOLFSSL* ssl, + char* buf, int sz, void*); + #endif /* WOLFSSL_MULTICAST */ + #ifdef WOLFSSL_SESSION_EXPORT + WOLFSSL_API int EmbedGetPeer(WOLFSSL* ssl, char* ip, int* ipSz, + unsigned short* port, int* fam); + WOLFSSL_API int EmbedSetPeer(WOLFSSL* ssl, char* ip, int ipSz, + unsigned short port, int fam); + #endif /* WOLFSSL_SESSION_EXPORT */ + #endif /* WOLFSSL_DTLS */ +#endif /* USE_WOLFSSL_IO */ + +#ifdef HAVE_OCSP + WOLFSSL_API int wolfIO_HttpBuildRequestOcsp(const char* domainName, + const char* path, int ocspReqSz, unsigned char* buf, int bufSize); + WOLFSSL_API int wolfIO_HttpProcessResponseOcsp(int sfd, + unsigned char** respBuf, unsigned char* httpBuf, int httpBufSz, + void* heap); + + WOLFSSL_API int EmbedOcspLookup(void*, const char*, int, unsigned char*, + int, unsigned char**); + WOLFSSL_API void EmbedOcspRespFree(void*, unsigned char*); +#endif + +#ifdef HAVE_CRL_IO + WOLFSSL_API int wolfIO_HttpBuildRequestCrl(const char* url, int urlSz, + const char* domainName, unsigned char* buf, int bufSize); + WOLFSSL_API int wolfIO_HttpProcessResponseCrl(WOLFSSL_CRL* crl, int sfd, + unsigned char* httpBuf, int httpBufSz); + + WOLFSSL_API int EmbedCrlLookup(WOLFSSL_CRL* crl, const char* url, + int urlSz); +#endif + + +#if defined(HAVE_HTTP_CLIENT) + WOLFSSL_API int wolfIO_DecodeUrl(const char* url, int urlSz, char* outName, + char* outPath, unsigned short* outPort); + + WOLFSSL_API int wolfIO_HttpBuildRequest(const char* reqType, + const char* domainName, const char* path, int pathLen, int reqSz, + const char* contentType, unsigned char* buf, int bufSize); + WOLFSSL_LOCAL int wolfIO_HttpBuildRequest_ex(const char* reqType, + const char* domainName, const char* path, int pathLen, int reqSz, + const char* contentType, const char *exHdrs, unsigned char* buf, int bufSize); + WOLFSSL_API int wolfIO_HttpProcessResponse(int sfd, const char** appStrList, + unsigned char** respBuf, unsigned char* httpBuf, int httpBufSz, + int dynType, void* heap); +#endif /* HAVE_HTTP_CLIENT */ + + +/* I/O callbacks */ +typedef int (*CallbackIORecv)(WOLFSSL *ssl, char *buf, int sz, void *ctx); +typedef int (*CallbackIOSend)(WOLFSSL *ssl, char *buf, int sz, void *ctx); +WOLFSSL_API void wolfSSL_CTX_SetIORecv(WOLFSSL_CTX*, CallbackIORecv); +WOLFSSL_API void wolfSSL_CTX_SetIOSend(WOLFSSL_CTX*, CallbackIOSend); +WOLFSSL_API void wolfSSL_SSLSetIORecv(WOLFSSL*, CallbackIORecv); +WOLFSSL_API void wolfSSL_SSLSetIOSend(WOLFSSL*, CallbackIOSend); +/* deprecated old name */ +#define wolfSSL_SetIORecv wolfSSL_CTX_SetIORecv +#define wolfSSL_SetIOSend wolfSSL_CTX_SetIOSend + +WOLFSSL_API void wolfSSL_SetIOReadCtx( WOLFSSL* ssl, void *ctx); +WOLFSSL_API void wolfSSL_SetIOWriteCtx(WOLFSSL* ssl, void *ctx); + +WOLFSSL_API void* wolfSSL_GetIOReadCtx( WOLFSSL* ssl); +WOLFSSL_API void* wolfSSL_GetIOWriteCtx(WOLFSSL* ssl); + +WOLFSSL_API void wolfSSL_SetIOReadFlags( WOLFSSL* ssl, int flags); +WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); + + +#ifdef HAVE_NETX + WOLFSSL_LOCAL int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx); + WOLFSSL_LOCAL int NetX_Send(WOLFSSL *ssl, char *buf, int sz, void *ctx); + + WOLFSSL_API void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, + ULONG waitoption); +#endif /* HAVE_NETX */ + +#ifdef MICRIUM + WOLFSSL_LOCAL int MicriumSend(WOLFSSL* ssl, char* buf, int sz, void* ctx); + WOLFSSL_LOCAL int MicriumReceive(WOLFSSL* ssl, char* buf, int sz, + void* ctx); + WOLFSSL_LOCAL int MicriumReceiveFrom(WOLFSSL* ssl, char* buf, int sz, + void* ctx); + WOLFSSL_LOCAL int MicriumSendTo(WOLFSSL* ssl, char* buf, int sz, void* ctx); +#endif /* MICRIUM */ + +#if defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP) + WOLFSSL_LOCAL int Mynewt_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx); + WOLFSSL_LOCAL int Mynewt_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx); + WOLFSSL_API void wolfSSL_SetIO_Mynewt(WOLFSSL* ssl, struct mn_socket* mnSocket, + struct mn_sockaddr_in* mnSockAddrIn); +#endif /* defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP) */ + +#ifdef WOLFSSL_UIP + + struct uip_wolfssl_ctx { + union socket_connector { + struct tcp_socket tcp; + struct udp_socket udp; + } conn; + WOLFSSL_CTX *ctx; + WOLFSSL *ssl; + uint8_t *input_databuf; + uint8_t *output_databuf; + uint8_t *ssl_rx_databuf; + int ssl_rb_len; + int ssl_rb_off; + struct process *process; + tcp_socket_data_callback_t input_callback; + tcp_socket_event_callback_t event_callback; + int closing; + uip_ipaddr_t peer_addr; + uint16_t peer_port; + }; + + typedef struct uip_wolfssl_ctx uip_wolfssl_ctx; + + WOLFSSL_LOCAL int uIPSend(WOLFSSL* ssl, char* buf, int sz, void* ctx); + WOLFSSL_LOCAL int uIPReceive(WOLFSSL* ssl, char* buf, int sz, + void* ctx); + WOLFSSL_LOCAL int uIPReceiveFrom(WOLFSSL* ssl, char* buf, int sz, + void* ctx); + WOLFSSL_LOCAL int uIPSendTo(WOLFSSL* ssl, char* buf, int sz, void* ctx); + +#endif + +#ifdef WOLFSSL_GNRC + #include + #include + #include + #include + #include + #include + + struct gnrc_wolfssl_ctx { + union socket_connector { + #ifdef MODULE_SOCK_TCP + sock_tcp_t tcp; + #endif + sock_udp_t udp; + } conn; + WOLFSSL_CTX *ctx; + WOLFSSL *ssl; + + int closing; + struct _sock_tl_ep peer_addr; + }; + + typedef struct gnrc_wolfssl_ctx sock_tls_t; + + WOLFSSL_LOCAL int GNRC_ReceiveFrom(WOLFSSL* ssl, char* buf, int sz, + void* ctx); + WOLFSSL_LOCAL int GNRC_SendTo(WOLFSSL* ssl, char* buf, int sz, void* ctx); + +#endif + + +#ifdef WOLFSSL_DTLS + typedef int (*CallbackGenCookie)(WOLFSSL* ssl, unsigned char* buf, int sz, + void* ctx); + WOLFSSL_API void wolfSSL_CTX_SetGenCookie(WOLFSSL_CTX*, CallbackGenCookie); + WOLFSSL_API void wolfSSL_SetCookieCtx(WOLFSSL* ssl, void *ctx); + WOLFSSL_API void* wolfSSL_GetCookieCtx(WOLFSSL* ssl); + + #ifdef WOLFSSL_SESSION_EXPORT + typedef int (*CallbackGetPeer)(WOLFSSL* ssl, char* ip, int* ipSz, + unsigned short* port, int* fam); + typedef int (*CallbackSetPeer)(WOLFSSL* ssl, char* ip, int ipSz, + unsigned short port, int fam); + + WOLFSSL_API void wolfSSL_CTX_SetIOGetPeer(WOLFSSL_CTX*, CallbackGetPeer); + WOLFSSL_API void wolfSSL_CTX_SetIOSetPeer(WOLFSSL_CTX*, CallbackSetPeer); + #endif /* WOLFSSL_SESSION_EXPORT */ +#endif + + + +#ifndef XINET_NTOP + #define XINET_NTOP(a,b,c,d) inet_ntop((a),(b),(c),(d)) + #ifdef USE_WINDOWS_API /* Windows-friendly definition */ + #undef XINET_NTOP + #define XINET_NTOP(a,b,c,d) InetNtop((a),(b),(c),(d)) + #endif +#endif +#ifndef XINET_PTON + #define XINET_PTON(a,b,c) inet_pton((a),(b),(c)) + #ifdef USE_WINDOWS_API /* Windows-friendly definition */ + #undef XINET_PTON + #define XINET_PTON(a,b,c) InetPton((a),(b),(c)) + #endif +#endif +#ifndef XHTONS + #define XHTONS(a) htons((a)) +#endif +#ifndef XNTOHS + #define XNTOHS(a) ntohs((a)) +#endif + +#ifndef WOLFSSL_IP4 + #define WOLFSSL_IP4 AF_INET +#endif +#ifndef WOLFSSL_IP6 + #define WOLFSSL_IP6 AF_INET6 +#endif + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_IO_H */

  • ABRo&<0nY5dOq zd_G^8bEuFCwn+K1G{PoX>4S!6V(nSjM6$8pKM9&bG7b-!<&cPBV3;3wwxkg`(>p?v zQ_evA{GF%3QSSHSvSmxU4UjRGbW6@Q!Pk0Q&PpSV))mz(7^@deKGEP+#OPiUC00md3$dj<{8Zssz*IhO7mOY87M(vAH8(#@q4>CUlq z4`-#^1Ja#?bRX;;{|+WrabzcC-SJEHG|EWB=ckZj%pA7EYz5Z(1n$)efyMw3SpZ&zC)yJDp+{>K!^u~4uU;F6o%KDqb^Dl)$hkvP>di_dgSqn8%)DYr&LZzA_h@wa)C{59X>Zs7J>@)S$ z6vtqw`_wK4r3Q^qHASOBwJNlyO`2FGR41mux|(UbuIWOT-V>vOZl-iYHH8E`YB~{IY^$AUCY{Ryi zZFMVzxS{W(5p%InFD?@Ugv^E*)8O+F0qR){Erc3#;Ug=dMum^O3^mui3TO`F@S^2h zHz4kN7!db8252sPJ~9S1*Zm8K`_6&2Jk6|20CA6igVs1`Js^Aod}I?K9%U;aKH3gI zRm_@ntbGm|1SBx)c|gxFbQRFE4BZ7ZpP^Aedse4NfS&sW#z&WH@ZBvgiwj-+FXHvQRBSBt z>_-~cg&)4%Jja|dXph3hKM`cGgjkIg(->;Z?64_Y(`FM) zgB@q%9p+Gp27hn7*l|9#3CC-wh>0kgraLDLy?z2a-;V`7Jw3!oEPsA^xJQYri2{zO zrV>-BTNF_fnjXfBF-h8$WHj7i(9RT%MO1}sX~6(3G!|W#>?rg?x~4VgUF;_1_Dyjb zvzeHZFqM>Qh9hQonEwb!Ou=D+nz(eyeqHNmY1tTV*t#9!n~j@rkWzLFjiktbhR`HO literal 0 HcmV?d00001 diff --git a/rs232_kanal/wolfssl.dll b/rs232_kanal/wolfssl.dll new file mode 100644 index 0000000000000000000000000000000000000000..1d45e0fa786b72ec8f25e981697eb135ee79c786 GIT binary patch literal 811008 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 ~{rKR63PLvi{~HLUt6-i9!ysK)Ia?X1Qx9 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